diff options
Diffstat (limited to 'deps/v8/src/full-codegen/mips64/full-codegen-mips64.cc')
-rw-r--r-- | deps/v8/src/full-codegen/mips64/full-codegen-mips64.cc | 368 |
1 files changed, 93 insertions, 275 deletions
diff --git a/deps/v8/src/full-codegen/mips64/full-codegen-mips64.cc b/deps/v8/src/full-codegen/mips64/full-codegen-mips64.cc index dcdff515ef..a51e873709 100644 --- a/deps/v8/src/full-codegen/mips64/full-codegen-mips64.cc +++ b/deps/v8/src/full-codegen/mips64/full-codegen-mips64.cc @@ -15,7 +15,6 @@ #include "src/code-factory.h" #include "src/code-stubs.h" #include "src/codegen.h" -#include "src/compiler.h" #include "src/debug/debug.h" #include "src/full-codegen/full-codegen.h" #include "src/ic/ic.h" @@ -125,29 +124,21 @@ void FullCodeGenerator::Generate() { } #endif - // Sloppy mode functions and builtins need to replace the receiver with the - // global proxy when called as functions (without an explicit receiver - // object). - if (info->MustReplaceUndefinedReceiverWithGlobalProxy()) { - Label ok; + if (FLAG_debug_code && info->ExpectsJSReceiverAsReceiver()) { int receiver_offset = info->scope()->num_parameters() * kPointerSize; - __ ld(at, MemOperand(sp, receiver_offset)); - __ LoadRoot(a2, Heap::kUndefinedValueRootIndex); - __ Branch(&ok, ne, a2, Operand(at)); - - __ ld(a2, GlobalObjectOperand()); - __ ld(a2, FieldMemOperand(a2, GlobalObject::kGlobalProxyOffset)); - - __ sd(a2, MemOperand(sp, receiver_offset)); - __ bind(&ok); + __ ld(a2, MemOperand(sp, receiver_offset)); + __ AssertNotSmi(a2); + __ GetObjectType(a2, a2, a2); + __ Check(ge, kSloppyFunctionExpectsJSReceiverReceiver, a2, + Operand(FIRST_SPEC_OBJECT_TYPE)); } + // Open a frame scope to indicate that there is a frame on the stack. The // MANUAL indicates that the scope shouldn't actually generate code to set up // the frame (that is done below). FrameScope frame_scope(masm_, StackFrame::MANUAL); info->set_prologue_offset(masm_->pc_offset()); __ Prologue(info->IsCodePreAgingActive()); - info->AddNoFrameRange(0, masm_->pc_offset()); { Comment cmnt(masm_, "[ Allocate locals"); int locals_count = info->scope()->num_stack_slots(); @@ -199,6 +190,7 @@ void FullCodeGenerator::Generate() { __ push(a1); __ Push(info->scope()->GetScopeInfo(info->isolate())); __ CallRuntime(Runtime::kNewScriptContext, 2); + PrepareForBailoutForId(BailoutId::ScriptContext(), TOS_REG); } else if (slots <= FastNewContextStub::kMaximumSlots) { FastNewContextStub stub(isolate(), slots); __ CallStub(&stub); @@ -240,8 +232,8 @@ void FullCodeGenerator::Generate() { } } } + PrepareForBailoutForId(BailoutId::FunctionContext(), NO_REGISTERS); - PrepareForBailoutForId(BailoutId::Prologue(), NO_REGISTERS); // Function register is trashed in case we bailout here. But since that // could happen only when we allocate a context the value of // |function_in_register_a1| is correct. @@ -472,11 +464,9 @@ void FullCodeGenerator::EmitReturnSequence() { int32_t sp_delta = arg_count * kPointerSize; SetReturnPosition(literal()); masm_->mov(sp, fp); - int no_frame_start = masm_->pc_offset(); masm_->MultiPop(static_cast<RegList>(fp.bit() | ra.bit())); masm_->Daddu(sp, sp, Operand(sp_delta)); masm_->Jump(ra); - info_->AddNoFrameRange(no_frame_start, masm_->pc_offset()); } } } @@ -853,10 +843,8 @@ void FullCodeGenerator::VisitVariableDeclaration( __ mov(a0, zero_reg); // Smi::FromInt(0) indicates no initial value. } __ Push(a2, a0); - __ CallRuntime(IsImmutableVariableMode(mode) - ? Runtime::kDeclareReadOnlyLookupSlot - : Runtime::kDeclareLookupSlot, - 2); + __ Push(Smi::FromInt(variable->DeclarationPropertyAttributes())); + __ CallRuntime(Runtime::kDeclareLookupSlot, 3); break; } } @@ -912,7 +900,8 @@ void FullCodeGenerator::VisitFunctionDeclaration( __ Push(a2); // Push initial value for function declaration. VisitForStackValue(declaration->fun()); - __ CallRuntime(Runtime::kDeclareLookupSlot, 2); + __ Push(Smi::FromInt(variable->DeclarationPropertyAttributes())); + __ CallRuntime(Runtime::kDeclareLookupSlot, 3); break; } } @@ -1140,7 +1129,6 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) { __ Push(a1, a0); // Fixed array length (as smi) and initial index. // Generate code for doing the condition check. - PrepareForBailoutForId(stmt->BodyId(), NO_REGISTERS); __ bind(&loop); SetExpressionAsStatementPosition(stmt->each()); @@ -1192,6 +1180,8 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) { PrepareForBailoutForId(stmt->AssignmentId(), NO_REGISTERS); } + // Both Crankshaft and Turbofan expect BodyId to be right before stmt->body(). + PrepareForBailoutForId(stmt->BodyId(), NO_REGISTERS); // Generate code for the body of the loop. Visit(stmt->body()); @@ -1242,7 +1232,7 @@ void FullCodeGenerator::EmitNewClosure(Handle<SharedFunctionInfo> info, void FullCodeGenerator::EmitSetHomeObject(Expression* initializer, int offset, - FeedbackVectorICSlot slot) { + FeedbackVectorSlot slot) { DCHECK(NeedsHomeObject(initializer)); __ ld(StoreDescriptor::ReceiverRegister(), MemOperand(sp)); __ li(StoreDescriptor::NameRegister(), @@ -1254,8 +1244,9 @@ void FullCodeGenerator::EmitSetHomeObject(Expression* initializer, int offset, } -void FullCodeGenerator::EmitSetHomeObjectAccumulator( - Expression* initializer, int offset, FeedbackVectorICSlot slot) { +void FullCodeGenerator::EmitSetHomeObjectAccumulator(Expression* initializer, + int offset, + FeedbackVectorSlot slot) { DCHECK(NeedsHomeObject(initializer)); __ Move(StoreDescriptor::ReceiverRegister(), v0); __ li(StoreDescriptor::NameRegister(), @@ -1387,27 +1378,11 @@ void FullCodeGenerator::EmitGlobalVariableLoad(VariableProxy* proxy, Variable* var = proxy->var(); DCHECK(var->IsUnallocatedOrGlobalSlot() || (var->IsLookupSlot() && var->mode() == DYNAMIC_GLOBAL)); - if (var->IsGlobalSlot()) { - DCHECK(var->index() > 0); - DCHECK(var->IsStaticGlobalObjectProperty()); - int const slot = var->index(); - int const depth = scope()->ContextChainLength(var->scope()); - if (depth <= LoadGlobalViaContextStub::kMaximumDepth) { - __ li(LoadGlobalViaContextDescriptor::SlotRegister(), Operand(slot)); - LoadGlobalViaContextStub stub(isolate(), depth); - __ CallStub(&stub); - } else { - __ Push(Smi::FromInt(slot)); - __ CallRuntime(Runtime::kLoadGlobalViaContext, 1); - } - - } else { - __ ld(LoadDescriptor::ReceiverRegister(), GlobalObjectOperand()); - __ li(LoadDescriptor::NameRegister(), Operand(var->name())); - __ li(LoadDescriptor::SlotRegister(), - Operand(SmiFromSlot(proxy->VariableFeedbackSlot()))); - CallLoadIC(typeof_mode); - } + __ ld(LoadDescriptor::ReceiverRegister(), GlobalObjectOperand()); + __ li(LoadDescriptor::NameRegister(), Operand(var->name())); + __ li(LoadDescriptor::SlotRegister(), + Operand(SmiFromSlot(proxy->VariableFeedbackSlot()))); + CallLoadIC(typeof_mode); } @@ -1751,8 +1726,6 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) { void FullCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) { Comment cmnt(masm_, "[ ArrayLiteral"); - expr->BuildConstantElements(isolate()); - Handle<FixedArray> constant_elements = expr->constant_elements(); bool has_fast_elements = IsFastObjectElementsKind(expr->constant_elements_kind()); @@ -1802,7 +1775,16 @@ void FullCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) { VisitForAccumulatorValue(subexpr); - if (has_fast_elements) { + if (FLAG_vector_stores) { + __ li(StoreDescriptor::NameRegister(), + Operand(Smi::FromInt(array_index))); + __ ld(StoreDescriptor::ReceiverRegister(), MemOperand(sp, kPointerSize)); + __ mov(StoreDescriptor::ValueRegister(), result_register()); + EmitLoadStoreICSlot(expr->LiteralFeedbackSlot()); + Handle<Code> ic = + CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); + CallIC(ic); + } else if (has_fast_elements) { int offset = FixedArray::kHeaderSize + (array_index * kPointerSize); __ ld(a6, MemOperand(sp, kPointerSize)); // Copy of array literal. __ ld(a1, FieldMemOperand(a6, JSObject::kElementsOffset)); @@ -2132,8 +2114,10 @@ void FullCodeGenerator::VisitYield(Yield* expr) { __ mov(a1, a0); __ sd(a1, MemOperand(sp, 2 * kPointerSize)); SetCallPosition(expr, 1); - CallFunctionStub stub(isolate(), 1, CALL_AS_METHOD); - __ CallStub(&stub); + __ li(a0, Operand(1)); + __ Call( + isolate()->builtins()->Call(ConvertReceiverMode::kNotNullOrUndefined), + RelocInfo::CODE_TARGET); __ ld(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); __ Drop(1); // The function is still on the stack; drop it. @@ -2265,7 +2249,7 @@ void FullCodeGenerator::EmitCreateIteratorResult(bool done) { __ bind(&done_allocate); __ ld(a1, ContextOperand(cp, Context::GLOBAL_OBJECT_INDEX)); - __ ld(a1, FieldMemOperand(a1, GlobalObject::kNativeContextOffset)); + __ ld(a1, FieldMemOperand(a1, JSGlobalObject::kNativeContextOffset)); __ ld(a1, ContextOperand(a1, Context::ITERATOR_RESULT_MAP_INDEX)); __ pop(a2); __ LoadRoot(a3, @@ -2500,7 +2484,7 @@ void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr, Token::Value op) { void FullCodeGenerator::EmitAssignment(Expression* expr, - FeedbackVectorICSlot slot) { + FeedbackVectorSlot slot) { DCHECK(expr->IsValidReferenceExpressionOrThis()); Property* prop = expr->AsProperty(); @@ -2593,7 +2577,7 @@ void FullCodeGenerator::EmitStoreToStackLocalOrContextSlot( void FullCodeGenerator::EmitVariableAssignment(Variable* var, Token::Value op, - FeedbackVectorICSlot slot) { + FeedbackVectorSlot slot) { if (var->IsUnallocated()) { // Global var, const, or let. __ mov(StoreDescriptor::ValueRegister(), result_register()); @@ -2602,27 +2586,6 @@ void FullCodeGenerator::EmitVariableAssignment(Variable* var, Token::Value op, if (FLAG_vector_stores) EmitLoadStoreICSlot(slot); CallStoreIC(); - } else if (var->IsGlobalSlot()) { - // Global var, const, or let. - DCHECK(var->index() > 0); - DCHECK(var->IsStaticGlobalObjectProperty()); - DCHECK(StoreGlobalViaContextDescriptor::ValueRegister().is(a0)); - __ mov(StoreGlobalViaContextDescriptor::ValueRegister(), result_register()); - int const slot = var->index(); - int const depth = scope()->ContextChainLength(var->scope()); - if (depth <= StoreGlobalViaContextStub::kMaximumDepth) { - __ li(StoreGlobalViaContextDescriptor::SlotRegister(), Operand(slot)); - StoreGlobalViaContextStub stub(isolate(), depth, language_mode()); - __ CallStub(&stub); - } else { - __ Push(Smi::FromInt(slot)); - __ Push(a0); - __ CallRuntime(is_strict(language_mode()) - ? Runtime::kStoreGlobalViaContext_Strict - : Runtime::kStoreGlobalViaContext_Sloppy, - 2); - } - } else if (var->mode() == LET && op != Token::INIT_LET) { // Non-initializing assignment to let variable needs a write barrier. DCHECK(!var->IsLookupSlot()); @@ -2846,11 +2809,9 @@ void FullCodeGenerator::CallIC(Handle<Code> code, void FullCodeGenerator::EmitCallWithLoadIC(Call* expr) { Expression* callee = expr->expression(); - CallICState::CallType call_type = - callee->IsVariableProxy() ? CallICState::FUNCTION : CallICState::METHOD; - // Get the target function. - if (call_type == CallICState::FUNCTION) { + ConvertReceiverMode convert_mode; + if (callee->IsVariableProxy()) { { StackValueContext context(this); EmitVariableLoad(callee->AsVariableProxy()); PrepareForBailout(callee, NO_REGISTERS); @@ -2859,6 +2820,7 @@ void FullCodeGenerator::EmitCallWithLoadIC(Call* expr) { // is a sloppy mode method. __ LoadRoot(at, Heap::kUndefinedValueRootIndex); __ push(at); + convert_mode = ConvertReceiverMode::kNullOrUndefined; } else { // Load the function from the receiver. DCHECK(callee->IsProperty()); @@ -2870,9 +2832,10 @@ void FullCodeGenerator::EmitCallWithLoadIC(Call* expr) { __ ld(at, MemOperand(sp, 0)); __ push(at); __ sd(v0, MemOperand(sp, kPointerSize)); + convert_mode = ConvertReceiverMode::kNotNullOrUndefined; } - EmitCall(expr, call_type); + EmitCall(expr, convert_mode); } @@ -2910,7 +2873,7 @@ void FullCodeGenerator::EmitSuperCallWithLoadIC(Call* expr) { // Stack here: // - target function // - this (receiver) - EmitCall(expr, CallICState::METHOD); + EmitCall(expr); } @@ -2934,7 +2897,7 @@ void FullCodeGenerator::EmitKeyedCallWithLoadIC(Call* expr, __ push(at); __ sd(v0, MemOperand(sp, kPointerSize)); - EmitCall(expr, CallICState::METHOD); + EmitCall(expr, ConvertReceiverMode::kNotNullOrUndefined); } @@ -2970,11 +2933,11 @@ void FullCodeGenerator::EmitKeyedSuperCallWithLoadIC(Call* expr) { // Stack here: // - target function // - this (receiver) - EmitCall(expr, CallICState::METHOD); + EmitCall(expr); } -void FullCodeGenerator::EmitCall(Call* expr, CallICState::CallType call_type) { +void FullCodeGenerator::EmitCall(Call* expr, ConvertReceiverMode mode) { // Load the arguments. ZoneList<Expression*>* args = expr->arguments(); int arg_count = args->length(); @@ -2982,9 +2945,10 @@ void FullCodeGenerator::EmitCall(Call* expr, CallICState::CallType call_type) { VisitForStackValue(args->at(i)); } + PrepareForBailoutForId(expr->CallId(), NO_REGISTERS); // Record source position of the IC call. SetCallPosition(expr, arg_count); - Handle<Code> ic = CodeFactory::CallIC(isolate(), arg_count, call_type).code(); + Handle<Code> ic = CodeFactory::CallIC(isolate(), arg_count, mode).code(); __ li(a3, Operand(SmiFromSlot(expr->CallFeedbackICSlot()))); __ ld(a1, MemOperand(sp, (arg_count + 1) * kPointerSize)); // Don't assign a type feedback id to the IC, since type feedback is provided @@ -3065,88 +3029,38 @@ void FullCodeGenerator::PushCalleeAndWithBaseObject(Call* expr) { } -void FullCodeGenerator::VisitCall(Call* expr) { -#ifdef DEBUG - // We want to verify that RecordJSReturnSite gets called on all paths - // through this function. Avoid early returns. - expr->return_is_recorded_ = false; -#endif - - Comment cmnt(masm_, "[ Call"); - Expression* callee = expr->expression(); - Call::CallType call_type = expr->GetCallType(isolate()); - - if (call_type == Call::POSSIBLY_EVAL_CALL) { - // In a call to eval, we first call RuntimeHidden_ResolvePossiblyDirectEval - // to resolve the function we need to call. Then we call the resolved - // function using the given arguments. - ZoneList<Expression*>* args = expr->arguments(); - int arg_count = args->length(); - PushCalleeAndWithBaseObject(expr); - - // Push the arguments. - for (int i = 0; i < arg_count; i++) { - VisitForStackValue(args->at(i)); - } +void FullCodeGenerator::EmitPossiblyEvalCall(Call* expr) { + // In a call to eval, we first call RuntimeHidden_ResolvePossiblyDirectEval + // to resolve the function we need to call. Then we call the resolved + // function using the given arguments. + ZoneList<Expression*>* args = expr->arguments(); + int arg_count = args->length(); + PushCalleeAndWithBaseObject(expr); - // Push a copy of the function (found below the arguments) and - // resolve eval. - __ ld(a1, MemOperand(sp, (arg_count + 1) * kPointerSize)); - __ push(a1); - EmitResolvePossiblyDirectEval(arg_count); + // Push the arguments. + for (int i = 0; i < arg_count; i++) { + VisitForStackValue(args->at(i)); + } - // Touch up the stack with the resolved function. - __ sd(v0, MemOperand(sp, (arg_count + 1) * kPointerSize)); + // Push a copy of the function (found below the arguments) and + // resolve eval. + __ ld(a1, MemOperand(sp, (arg_count + 1) * kPointerSize)); + __ push(a1); + EmitResolvePossiblyDirectEval(arg_count); - PrepareForBailoutForId(expr->EvalId(), NO_REGISTERS); - // Record source position for debugger. - SetCallPosition(expr, arg_count); - CallFunctionStub stub(isolate(), arg_count, NO_CALL_FUNCTION_FLAGS); - __ ld(a1, MemOperand(sp, (arg_count + 1) * kPointerSize)); - __ CallStub(&stub); - RecordJSReturnSite(expr); - // Restore context register. - __ ld(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); - context()->DropAndPlug(1, v0); - } else if (call_type == Call::GLOBAL_CALL) { - EmitCallWithLoadIC(expr); - } else if (call_type == Call::LOOKUP_SLOT_CALL) { - // Call to a lookup slot (dynamically introduced variable). - PushCalleeAndWithBaseObject(expr); - EmitCall(expr); - } else if (call_type == Call::PROPERTY_CALL) { - Property* property = callee->AsProperty(); - bool is_named_call = property->key()->IsPropertyName(); - if (property->IsSuperAccess()) { - if (is_named_call) { - EmitSuperCallWithLoadIC(expr); - } else { - EmitKeyedSuperCallWithLoadIC(expr); - } - } else { - VisitForStackValue(property->obj()); - if (is_named_call) { - EmitCallWithLoadIC(expr); - } else { - EmitKeyedCallWithLoadIC(expr, property->key()); - } - } - } else if (call_type == Call::SUPER_CALL) { - EmitSuperConstructorCall(expr); - } else { - DCHECK(call_type == Call::OTHER_CALL); - // Call to an arbitrary expression not handled specially above. - VisitForStackValue(callee); - __ LoadRoot(a1, Heap::kUndefinedValueRootIndex); - __ push(a1); - // Emit function call. - EmitCall(expr); - } + // Touch up the stack with the resolved function. + __ sd(v0, MemOperand(sp, (arg_count + 1) * kPointerSize)); -#ifdef DEBUG - // RecordJSReturnSite should have been called. - DCHECK(expr->return_is_recorded_); -#endif + PrepareForBailoutForId(expr->EvalId(), NO_REGISTERS); + // Record source position for debugger. + SetCallPosition(expr, arg_count); + __ ld(a1, MemOperand(sp, (arg_count + 1) * kPointerSize)); + __ li(a0, Operand(arg_count)); + __ Call(isolate()->builtins()->Call(), RelocInfo::CODE_TARGET); + RecordJSReturnSite(expr); + // Restore context register. + __ ld(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); + context()->DropAndPlug(1, v0); } @@ -3797,34 +3711,6 @@ void FullCodeGenerator::EmitToInteger(CallRuntime* expr) { } -void FullCodeGenerator::EmitNumberToString(CallRuntime* expr) { - ZoneList<Expression*>* args = expr->arguments(); - DCHECK_EQ(args->length(), 1); - - // Load the argument into a0 and call the stub. - VisitForAccumulatorValue(args->at(0)); - __ mov(a0, result_register()); - - NumberToStringStub stub(isolate()); - __ CallStub(&stub); - context()->Plug(v0); -} - - -void FullCodeGenerator::EmitToString(CallRuntime* expr) { - ZoneList<Expression*>* args = expr->arguments(); - DCHECK_EQ(1, args->length()); - - // Load the argument into a0 and convert it. - VisitForAccumulatorValue(args->at(0)); - __ mov(a0, result_register()); - - ToStringStub stub(isolate()); - __ CallStub(&stub); - context()->Plug(v0); -} - - void FullCodeGenerator::EmitToName(CallRuntime* expr) { ZoneList<Expression*>* args = expr->arguments(); DCHECK_EQ(1, args->length()); @@ -3845,20 +3731,6 @@ void FullCodeGenerator::EmitToName(CallRuntime* expr) { } -void FullCodeGenerator::EmitToObject(CallRuntime* expr) { - ZoneList<Expression*>* args = expr->arguments(); - DCHECK_EQ(1, args->length()); - - // Load the argument into a0 and convert it. - VisitForAccumulatorValue(args->at(0)); - __ mov(a0, result_register()); - - ToObjectStub stub(isolate()); - __ CallStub(&stub); - context()->Plug(v0); -} - - void FullCodeGenerator::EmitStringCharFromCode(CallRuntime* expr) { ZoneList<Expression*>* args = expr->arguments(); DCHECK(args->length() == 1); @@ -3974,20 +3846,6 @@ void FullCodeGenerator::EmitStringCharAt(CallRuntime* expr) { } -void FullCodeGenerator::EmitStringAdd(CallRuntime* expr) { - ZoneList<Expression*>* args = expr->arguments(); - DCHECK_EQ(2, args->length()); - VisitForStackValue(args->at(0)); - VisitForAccumulatorValue(args->at(1)); - - __ pop(a1); - __ mov(a0, result_register()); // StringAddStub requires args in a0, a1. - StringAddStub stub(isolate(), STRING_ADD_CHECK_BOTH, NOT_TENURED); - __ CallStub(&stub); - context()->Plug(v0); -} - - void FullCodeGenerator::EmitCall(CallRuntime* expr) { ZoneList<Expression*>* args = expr->arguments(); DCHECK_LE(2, args->length()); @@ -3995,6 +3853,7 @@ void FullCodeGenerator::EmitCall(CallRuntime* expr) { for (Expression* const arg : *args) { VisitForStackValue(arg); } + PrepareForBailoutForId(expr->CallId(), NO_REGISTERS); // Move target to a1. int const argc = args->length() - 2; __ ld(a1, MemOperand(sp, (argc + 1) * kPointerSize)); @@ -4008,38 +3867,6 @@ void FullCodeGenerator::EmitCall(CallRuntime* expr) { } -void FullCodeGenerator::EmitCallFunction(CallRuntime* expr) { - ZoneList<Expression*>* args = expr->arguments(); - DCHECK(args->length() >= 2); - - int arg_count = args->length() - 2; // 2 ~ receiver and function. - for (int i = 0; i < arg_count + 1; i++) { - VisitForStackValue(args->at(i)); - } - VisitForAccumulatorValue(args->last()); // Function. - - Label runtime, done; - // Check for non-function argument (including proxy). - __ JumpIfSmi(v0, &runtime); - __ GetObjectType(v0, a1, a1); - __ Branch(&runtime, ne, a1, Operand(JS_FUNCTION_TYPE)); - - // InvokeFunction requires the function in a1. Move it in there. - __ mov(a1, result_register()); - ParameterCount count(arg_count); - __ InvokeFunction(a1, count, CALL_FUNCTION, NullCallWrapper()); - __ ld(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); - __ jmp(&done); - - __ bind(&runtime); - __ push(v0); - __ CallRuntime(Runtime::kCallFunction, args->length()); - __ bind(&done); - - context()->Plug(v0); -} - - void FullCodeGenerator::EmitDefaultConstructorCallSuper(CallRuntime* expr) { ZoneList<Expression*>* args = expr->arguments(); DCHECK(args->length() == 2); @@ -4097,21 +3924,6 @@ void FullCodeGenerator::EmitDefaultConstructorCallSuper(CallRuntime* expr) { } -void FullCodeGenerator::EmitRegExpConstructResult(CallRuntime* expr) { - RegExpConstructResultStub stub(isolate()); - ZoneList<Expression*>* args = expr->arguments(); - DCHECK(args->length() == 3); - VisitForStackValue(args->at(0)); - VisitForStackValue(args->at(1)); - VisitForAccumulatorValue(args->at(2)); - __ mov(a0, result_register()); - __ pop(a1); - __ pop(a2); - __ CallStub(&stub); - context()->Plug(v0); -} - - void FullCodeGenerator::EmitHasCachedArrayIndex(CallRuntime* expr) { ZoneList<Expression*>* args = expr->arguments(); VisitForAccumulatorValue(args->at(0)); @@ -4262,6 +4074,10 @@ void FullCodeGenerator::EmitFastOneByteArrayJoin(CallRuntime* expr) { __ AdduAndCheckForOverflow(string_length, string_length, scratch2, scratch3); __ BranchOnOverflow(&bailout, scratch3); + // Bailout for large object allocations. + __ Branch(&bailout, gt, string_length, + Operand(Page::kMaxRegularHeapObjectSize)); + // Get first element in the array to free up the elements register to be used // for the result. __ Daddu(element, @@ -4400,7 +4216,7 @@ void FullCodeGenerator::EmitCreateIterResultObject(CallRuntime* expr) { __ Allocate(JSIteratorResult::kSize, v0, a2, a3, &runtime, TAG_OBJECT); __ ld(a1, ContextOperand(cp, Context::GLOBAL_OBJECT_INDEX)); - __ ld(a1, FieldMemOperand(a1, GlobalObject::kNativeContextOffset)); + __ ld(a1, FieldMemOperand(a1, JSGlobalObject::kNativeContextOffset)); __ ld(a1, ContextOperand(a1, Context::ITERATOR_RESULT_MAP_INDEX)); __ Pop(a2, a3); __ LoadRoot(a4, Heap::kEmptyFixedArrayRootIndex); @@ -4426,7 +4242,7 @@ void FullCodeGenerator::EmitLoadJSRuntimeFunction(CallRuntime* expr) { __ push(v0); __ ld(v0, GlobalObjectOperand()); - __ ld(v0, FieldMemOperand(v0, GlobalObject::kNativeContextOffset)); + __ ld(v0, FieldMemOperand(v0, JSGlobalObject::kNativeContextOffset)); __ ld(v0, ContextOperand(v0, expr->context_index())); } @@ -4436,9 +4252,10 @@ void FullCodeGenerator::EmitCallJSRuntimeFunction(CallRuntime* expr) { int arg_count = args->length(); SetCallPosition(expr, arg_count); - CallFunctionStub stub(isolate(), arg_count, NO_CALL_FUNCTION_FLAGS); __ ld(a1, MemOperand(sp, (arg_count + 1) * kPointerSize)); - __ CallStub(&stub); + __ li(a0, Operand(arg_count)); + __ Call(isolate()->builtins()->Call(ConvertReceiverMode::kNullOrUndefined), + RelocInfo::CODE_TARGET); } @@ -5045,7 +4862,8 @@ void FullCodeGenerator::EmitLiteralCompareNil(CompareOperation* expr, } else { Handle<Code> ic = CompareNilICStub::GetUninitialized(isolate(), nil); CallIC(ic, expr->CompareOperationFeedbackId()); - Split(ne, v0, Operand(zero_reg), if_true, if_false, fall_through); + __ LoadRoot(a1, Heap::kTrueValueRootIndex); + Split(eq, v0, Operand(a1), if_true, if_false, fall_through); } context()->Plug(if_true, if_false); } @@ -5158,7 +4976,7 @@ void FullCodeGenerator::ClearPendingMessage() { } -void FullCodeGenerator::EmitLoadStoreICSlot(FeedbackVectorICSlot slot) { +void FullCodeGenerator::EmitLoadStoreICSlot(FeedbackVectorSlot slot) { DCHECK(FLAG_vector_stores && !slot.IsInvalid()); __ li(VectorStoreICTrampolineDescriptor::SlotRegister(), Operand(SmiFromSlot(slot))); |