Index: src/arm/lithium-codegen-arm.cc |
diff --git a/src/arm/lithium-codegen-arm.cc b/src/arm/lithium-codegen-arm.cc |
index dbcf4e4157d3f0399d88ddb80927ae6d527b625f..d918cc9337ee874cd8424ddb4ccf090df3642559 100644 |
--- a/src/arm/lithium-codegen-arm.cc |
+++ b/src/arm/lithium-codegen-arm.cc |
@@ -150,11 +150,12 @@ bool LCodeGen::GeneratePrologue() { |
info()->set_prologue_offset(masm_->pc_offset()); |
if (NeedsEagerFrame()) { |
+ fp_sp_delta_ = 2 * kPointerSize; |
if (info()->IsStub()) { |
__ stm(db_w, sp, cp.bit() | fp.bit() | lr.bit()); |
__ Push(Smi::FromInt(StackFrame::STUB)); |
// Adjust FP to point to saved FP. |
- __ add(fp, sp, Operand(2 * kPointerSize)); |
+ __ add(fp, sp, Operand(fp_sp_delta_)); |
} else { |
PredictableCodeSizeScope predictible_code_size_scope( |
masm_, kNoCodeAgeSequenceLength * Assembler::kInstrSize); |
@@ -166,7 +167,7 @@ bool LCodeGen::GeneratePrologue() { |
__ nop(ip.code()); |
} |
// Adjust FP to point to saved FP. |
- __ add(fp, sp, Operand(2 * kPointerSize)); |
+ __ add(fp, sp, Operand(fp_sp_delta_)); |
} |
frame_is_built_ = true; |
info_->AddNoFrameRange(0, masm_->pc_offset()); |
@@ -175,11 +176,13 @@ bool LCodeGen::GeneratePrologue() { |
// Reserve space for the stack slots needed by the code. |
int slots = GetStackSlotCount(); |
if (slots > 0) { |
+ int slots_size = slots * kPointerSize; |
+ fp_sp_delta_ += slots_size; |
if (FLAG_debug_code) { |
- __ sub(sp, sp, Operand(slots * kPointerSize)); |
+ __ sub(sp, sp, Operand(slots_size)); |
__ push(r0); |
__ push(r1); |
- __ add(r0, sp, Operand(slots * kPointerSize)); |
+ __ add(r0, sp, Operand(slots_size)); |
__ mov(r1, Operand(kSlotsZapValue)); |
Label loop; |
__ bind(&loop); |
@@ -190,7 +193,7 @@ bool LCodeGen::GeneratePrologue() { |
__ pop(r1); |
__ pop(r0); |
} else { |
- __ sub(sp, sp, Operand(slots * kPointerSize)); |
+ __ sub(sp, sp, Operand(slots_size)); |
} |
} |
@@ -210,6 +213,7 @@ bool LCodeGen::GeneratePrologue() { |
// Possibly allocate a local context. |
int heap_slots = info()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS; |
if (heap_slots > 0) { |
+ ASSERT(frame_is_built_); |
Comment(";;; Allocate local context"); |
// Argument to NewContext is the function, which is in r1. |
__ push(r1); |
@@ -222,16 +226,17 @@ bool LCodeGen::GeneratePrologue() { |
RecordSafepoint(Safepoint::kNoLazyDeopt); |
// Context is returned in both r0 and cp. It replaces the context |
// passed to us. It's saved in the stack and kept live in cp. |
- __ str(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
+ int cp_offset = StandardFrameConstants::kContextOffset + fp_sp_delta_; |
+ __ str(cp, MemOperand(sp, cp_offset)); |
// Copy any necessary parameters into the context. |
int num_parameters = scope()->num_parameters(); |
for (int i = 0; i < num_parameters; i++) { |
Variable* var = scope()->parameter(i); |
if (var->IsContextSlot()) { |
int parameter_offset = StandardFrameConstants::kCallerSPOffset + |
- (num_parameters - 1 - i) * kPointerSize; |
+ (num_parameters - 1 - i) * kPointerSize + fp_sp_delta_; |
// Load parameter from stack. |
- __ ldr(r0, MemOperand(fp, parameter_offset)); |
+ __ ldr(r0, MemOperand(sp, parameter_offset)); |
// Store it in the context. |
MemOperand target = ContextOperand(cp, var->index()); |
__ str(r0, target); |
@@ -266,7 +271,15 @@ bool LCodeGen::GenerateBody() { |
// Don't emit code for basic blocks with a replacement. |
if (instr->IsLabel()) { |
- emit_instructions = !LLabel::cast(instr)->HasReplacement(); |
+ LLabel* label = LLabel::cast(instr); |
+ emit_instructions = !label->HasReplacement(); |
+ if (emit_instructions) { |
+ HBasicBlock* block = label->block(); |
+ int argument_count = block->HasPredecessor() |
+ ? block->predecessors()->at(0)->argument_count() |
+ : 0; |
+ SetFpSpDelta(argument_count); |
+ } |
} |
if (!emit_instructions) continue; |
@@ -307,10 +320,11 @@ bool LCodeGen::GenerateDeferredCode() { |
ASSERT(!frame_is_built_); |
ASSERT(info()->IsStub()); |
frame_is_built_ = true; |
+ fp_sp_delta_ = 2 * kPointerSize; |
__ stm(db_w, sp, cp.bit() | fp.bit() | lr.bit()); |
__ mov(scratch0(), Operand(Smi::FromInt(StackFrame::STUB))); |
__ push(scratch0()); |
- __ add(fp, sp, Operand(2 * kPointerSize)); |
+ __ add(fp, sp, Operand(fp_sp_delta_)); |
Comment(";;; Deferred code"); |
} |
code->Generate(); |
@@ -320,6 +334,7 @@ bool LCodeGen::GenerateDeferredCode() { |
__ pop(ip); |
__ ldm(ia_w, sp, cp.bit() | fp.bit() | lr.bit()); |
frame_is_built_ = false; |
+ fp_sp_delta_ = -1; |
} |
__ jmp(code->exit()); |
} |
@@ -375,7 +390,8 @@ bool LCodeGen::GenerateDeoptJumpTable() { |
ASSERT(info()->IsStub()); |
__ mov(scratch0(), Operand(Smi::FromInt(StackFrame::STUB))); |
__ push(scratch0()); |
- __ add(fp, sp, Operand(2 * kPointerSize)); |
+ fp_sp_delta_ = 2 * kPointerSize; |
+ __ add(fp, sp, Operand(fp_sp_delta_)); |
__ mov(lr, Operand(pc), LeaveCC, al); |
__ mov(pc, ip); |
} |
@@ -563,13 +579,14 @@ MemOperand LCodeGen::ToMemOperand(LOperand* op) const { |
ASSERT(!op->IsRegister()); |
ASSERT(!op->IsDoubleRegister()); |
ASSERT(op->IsStackSlot() || op->IsDoubleStackSlot()); |
- return MemOperand(fp, StackSlotOffset(op->index())); |
+ return MemOperand(sp, StackSlotOffset(op->index(), fp_sp_delta_)); |
} |
MemOperand LCodeGen::ToHighMemOperand(LOperand* op) const { |
ASSERT(op->IsDoubleStackSlot()); |
- return MemOperand(fp, StackSlotOffset(op->index()) + kPointerSize); |
+ int offset = StackSlotOffset(op->index(), fp_sp_delta_) + kPointerSize; |
+ return MemOperand(sp, offset); |
} |
@@ -701,16 +718,67 @@ void LCodeGen::AddToTranslation(LEnvironment* environment, |
} |
+void LCodeGen::SetFpSpDelta(int argument_count) { |
+ int slots_size = GetStackSlotCount() * kPointerSize; |
+ int args_size = argument_count * kPointerSize; |
+ int fixed_size = 2 * kPointerSize; |
+ fp_sp_delta_ = slots_size + args_size + fixed_size; |
+} |
+ |
+ |
+void LCodeGen::Push(Register src1) { |
+ fp_sp_delta_ += kPointerSize; |
+ __ push(src1); |
+} |
+ |
+ |
+void LCodeGen::Push(Register src1, Register src2) { |
+ fp_sp_delta_ += 2 * kPointerSize; |
+ __ Push(src1, src2); |
+} |
+ |
+ |
+void LCodeGen::Push(Register src1, Register src2, Register src3) { |
+ fp_sp_delta_ += 3 * kPointerSize; |
+ __ Push(src1, src2, src3); |
+} |
+ |
+ |
+void LCodeGen::Push(Register src1, |
+ Register src2, |
+ Register src3, |
+ Register src4) { |
+ fp_sp_delta_ += 4 * kPointerSize; |
+ __ Push(src1, src2, src3, src4); |
+} |
+ |
+ |
+#ifdef DEBUG |
+void LCodeGen::CheckFpSpDelta(LInstruction* instr) { |
+ if (fp_sp_delta_ == -1 || !instr->HasEnvironment()) |
+ return; |
+ int slots_size = GetStackSlotCount() * kPointerSize; |
+ int args_size = instr->environment()->arguments_stack_height() * kPointerSize; |
+ int fixed_size = 2 * kPointerSize; |
+ int expected_delta = slots_size + args_size + fixed_size; |
+ ASSERT_EQ(expected_delta, fp_sp_delta_); |
+} |
+#endif // DEBUG |
+ |
+ |
void LCodeGen::CallCode(Handle<Code> code, |
RelocInfo::Mode mode, |
+ int num_arguments, |
LInstruction* instr, |
TargetAddressStorageMode storage_mode) { |
- CallCodeGeneric(code, mode, instr, RECORD_SIMPLE_SAFEPOINT, storage_mode); |
+ CallCodeGeneric(code, mode, num_arguments, instr, RECORD_SIMPLE_SAFEPOINT, |
+ storage_mode); |
} |
void LCodeGen::CallCodeGeneric(Handle<Code> code, |
RelocInfo::Mode mode, |
+ int num_arguments, |
LInstruction* instr, |
SafepointMode safepoint_mode, |
TargetAddressStorageMode storage_mode) { |
@@ -722,6 +790,7 @@ void LCodeGen::CallCodeGeneric(Handle<Code> code, |
LPointerMap* pointers = instr->pointer_map(); |
RecordPosition(pointers->position()); |
__ Call(code, mode, TypeFeedbackId::None(), al, storage_mode); |
+ fp_sp_delta_ -= num_arguments * kPointerSize; |
RecordSafepointWithLazyDeopt(instr, safepoint_mode); |
// Signal that we don't inline smi code before these stubs in the |
@@ -742,6 +811,7 @@ void LCodeGen::CallRuntime(const Runtime::Function* function, |
RecordPosition(pointers->position()); |
__ CallRuntime(function, num_arguments); |
+ fp_sp_delta_ -= num_arguments * kPointerSize; |
RecordSafepointWithLazyDeopt(instr, RECORD_SIMPLE_SAFEPOINT); |
} |
@@ -750,6 +820,7 @@ void LCodeGen::CallRuntimeFromDeferred(Runtime::FunctionId id, |
int argc, |
LInstruction* instr) { |
__ CallRuntimeSaveDoubles(id); |
+ fp_sp_delta_ -= argc * kPointerSize; |
RecordSafepointWithRegisters( |
instr->pointer_map(), argc, Safepoint::kNoLazyDeopt); |
} |
@@ -1069,34 +1140,34 @@ void LCodeGen::DoCallStub(LCallStub* instr) { |
switch (instr->hydrogen()->major_key()) { |
case CodeStub::RegExpConstructResult: { |
RegExpConstructResultStub stub; |
- CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); |
+ CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, 3, instr); |
break; |
} |
case CodeStub::RegExpExec: { |
RegExpExecStub stub; |
- CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); |
+ CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, 4, instr); |
break; |
} |
case CodeStub::SubString: { |
SubStringStub stub; |
- CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); |
+ CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, 3, instr); |
break; |
} |
case CodeStub::NumberToString: { |
NumberToStringStub stub; |
- CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); |
+ CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, 1, instr); |
break; |
} |
case CodeStub::StringCompare: { |
StringCompareStub stub; |
- CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); |
+ CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, 2, instr); |
break; |
} |
case CodeStub::TranscendentalCache: { |
__ ldr(r0, MemOperand(sp, 0)); |
TranscendentalCacheStub stub(instr->transcendental_type(), |
TranscendentalCacheStub::TAGGED); |
- CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); |
+ CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, 1, instr); |
break; |
} |
default: |
@@ -2002,7 +2073,7 @@ void LCodeGen::DoSeqStringSetChar(LSeqStringSetChar* instr) { |
void LCodeGen::DoThrow(LThrow* instr) { |
Register input_reg = EmitLoadRegister(instr->value(), ip); |
- __ push(input_reg); |
+ Push(input_reg); |
CallRuntime(Runtime::kThrow, 1, instr); |
if (FLAG_debug_code) { |
@@ -2119,7 +2190,7 @@ void LCodeGen::DoArithmeticD(LArithmeticD* instr) { |
case Token::MOD: { |
// Save r0-r3 on the stack. |
__ stm(db_w, sp, r0.bit() | r1.bit() | r2.bit() | r3.bit()); |
- |
+ fp_sp_delta_ += 4 * kPointerSize; |
__ PrepareCallCFunction(0, 2, scratch0()); |
__ SetCallCDoubleArguments(left, right); |
__ CallCFunction( |
@@ -2130,6 +2201,7 @@ void LCodeGen::DoArithmeticD(LArithmeticD* instr) { |
// Restore r0-r3. |
__ ldm(ia_w, sp, r0.bit() | r1.bit() | r2.bit() | r3.bit()); |
+ fp_sp_delta_ -= 4 * kPointerSize; |
break; |
} |
default: |
@@ -2148,7 +2220,7 @@ void LCodeGen::DoArithmeticT(LArithmeticT* instr) { |
// Block literal pool emission to ensure nop indicating no inlined smi code |
// is in the correct position. |
Assembler::BlockConstPoolScope block_const_pool(masm()); |
- CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); |
+ CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, 0, instr); |
__ nop(); // Signals no inlined code. |
} |
@@ -2573,7 +2645,7 @@ void LCodeGen::DoStringCompareAndBranch(LStringCompareAndBranch* instr) { |
Token::Value op = instr->op(); |
Handle<Code> ic = CompareIC::GetUninitialized(isolate(), op); |
- CallCode(ic, RelocInfo::CODE_TARGET, instr); |
+ CallCode(ic, RelocInfo::CODE_TARGET, 0, instr); |
// This instruction also signals no smi code inlined. |
__ cmp(r0, Operand::Zero()); |
@@ -2734,7 +2806,7 @@ void LCodeGen::DoInstanceOf(LInstanceOf* instr) { |
ASSERT(ToRegister(instr->right()).is(r1)); // Function is in r1. |
InstanceofStub stub(InstanceofStub::kArgsInRegisters); |
- CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); |
+ CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, 0, instr); |
__ cmp(r0, Operand::Zero()); |
__ mov(r0, Operand(factory()->false_value()), LeaveCC, ne); |
@@ -2876,6 +2948,7 @@ void LCodeGen::DoDeferredInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr, |
__ StoreToSafepointRegisterSlot(temp, temp); |
CallCodeGeneric(stub.GetCode(isolate()), |
RelocInfo::CODE_TARGET, |
+ 0, |
instr, |
RECORD_SAFEPOINT_WITH_REGISTERS_AND_NO_ARGUMENTS); |
LEnvironment* env = instr->GetDeferredLazyDeoptimizationEnvironment(); |
@@ -2898,7 +2971,7 @@ void LCodeGen::DoCmpT(LCmpT* instr) { |
Token::Value op = instr->op(); |
Handle<Code> ic = CompareIC::GetUninitialized(isolate(), op); |
- CallCode(ic, RelocInfo::CODE_TARGET, instr); |
+ CallCode(ic, RelocInfo::CODE_TARGET, 0, instr); |
// This instruction also signals no smi code inlined. |
__ cmp(r0, Operand::Zero()); |
@@ -2978,7 +3051,7 @@ void LCodeGen::DoLoadGlobalGeneric(LLoadGlobalGeneric* instr) { |
RelocInfo::Mode mode = instr->for_typeof() ? RelocInfo::CODE_TARGET |
: RelocInfo::CODE_TARGET_CONTEXT; |
Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); |
- CallCode(ic, mode, instr); |
+ CallCode(ic, mode, 0, instr); |
} |
@@ -3015,7 +3088,7 @@ void LCodeGen::DoStoreGlobalGeneric(LStoreGlobalGeneric* instr) { |
Handle<Code> ic = (instr->strict_mode_flag() == kStrictMode) |
? isolate()->builtins()->StoreIC_Initialize_Strict() |
: isolate()->builtins()->StoreIC_Initialize(); |
- CallCode(ic, RelocInfo::CODE_TARGET_CONTEXT, instr); |
+ CallCode(ic, RelocInfo::CODE_TARGET_CONTEXT, 0, instr); |
} |
@@ -3107,7 +3180,7 @@ void LCodeGen::DoLoadNamedGeneric(LLoadNamedGeneric* instr) { |
// Name is always in r2. |
__ mov(r2, Operand(instr->name())); |
Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); |
- CallCode(ic, RelocInfo::CODE_TARGET, instr, NEVER_INLINE_TARGET_ADDRESS); |
+ CallCode(ic, RelocInfo::CODE_TARGET, 0, instr, NEVER_INLINE_TARGET_ADDRESS); |
} |
@@ -3392,7 +3465,7 @@ void LCodeGen::DoLoadKeyedGeneric(LLoadKeyedGeneric* instr) { |
ASSERT(ToRegister(instr->key()).is(r0)); |
Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); |
- CallCode(ic, RelocInfo::CODE_TARGET, instr, NEVER_INLINE_TARGET_ADDRESS); |
+ CallCode(ic, RelocInfo::CODE_TARGET, 0, instr, NEVER_INLINE_TARGET_ADDRESS); |
} |
@@ -3405,7 +3478,8 @@ void LCodeGen::DoArgumentsElements(LArgumentsElements* instr) { |
} else { |
// Check if the calling frame is an arguments adaptor frame. |
Label done, adapted; |
- __ ldr(scratch, MemOperand(fp, StandardFrameConstants::kCallerFPOffset)); |
+ int fp_offset = StandardFrameConstants::kCallerFPOffset + fp_sp_delta_; |
+ __ ldr(scratch, MemOperand(sp, fp_offset)); |
__ ldr(result, MemOperand(scratch, StandardFrameConstants::kContextOffset)); |
__ cmp(result, Operand(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR))); |
@@ -3429,7 +3503,8 @@ void LCodeGen::DoArgumentsLength(LArgumentsLength* instr) { |
__ b(eq, &done); |
// Arguments adaptor frame present. Get argument length from there. |
- __ ldr(result, MemOperand(fp, StandardFrameConstants::kCallerFPOffset)); |
+ int fp_offset = StandardFrameConstants::kCallerFPOffset + fp_sp_delta_; |
+ __ ldr(result, MemOperand(sp, fp_offset)); |
__ ldr(result, |
MemOperand(result, ArgumentsAdaptorFrameConstants::kLengthOffset)); |
__ SmiUntag(result); |
@@ -3532,7 +3607,8 @@ void LCodeGen::DoApplyArguments(LApplyArguments* instr) { |
ParameterCount actual(receiver); |
__ InvokeFunction(function, actual, CALL_FUNCTION, |
safepoint_generator, CALL_AS_METHOD); |
- __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
+ int cp_offset = StandardFrameConstants::kContextOffset + fp_sp_delta_; |
+ __ ldr(cp, MemOperand(sp, cp_offset)); |
} |
@@ -3542,19 +3618,21 @@ void LCodeGen::DoPushArgument(LPushArgument* instr) { |
Abort(kDoPushArgumentNotImplementedForDoubleType); |
} else { |
Register argument_reg = EmitLoadRegister(argument, ip); |
- __ push(argument_reg); |
+ Push(argument_reg); |
} |
} |
void LCodeGen::DoDrop(LDrop* instr) { |
__ Drop(instr->count()); |
+ fp_sp_delta_ -= instr->count() * kPointerSize; |
} |
void LCodeGen::DoThisFunction(LThisFunction* instr) { |
Register result = ToRegister(instr->result()); |
- __ ldr(result, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); |
+ int offset = JavaScriptFrameConstants::kFunctionOffset + fp_sp_delta_; |
+ __ ldr(result, MemOperand(sp, offset)); |
} |
@@ -3579,11 +3657,11 @@ void LCodeGen::DoOuterContext(LOuterContext* instr) { |
void LCodeGen::DoDeclareGlobals(LDeclareGlobals* instr) { |
- __ push(cp); // The context is the first argument. |
+ Push(cp); // The context is the first argument. |
__ LoadHeapObject(scratch0(), instr->hydrogen()->pairs()); |
- __ push(scratch0()); |
+ Push(scratch0()); |
__ mov(scratch0(), Operand(Smi::FromInt(instr->hydrogen()->flags()))); |
- __ push(scratch0()); |
+ Push(scratch0()); |
CallRuntime(Runtime::kDeclareGlobals, 3, instr); |
} |
@@ -3643,9 +3721,11 @@ void LCodeGen::CallKnownFunction(Handle<JSFunction> function, |
__ InvokeFunction( |
function, expected, count, CALL_FUNCTION, generator, call_kind); |
} |
+ fp_sp_delta_ -= (arity + 1) * kPointerSize; |
// Restore context. |
- __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
+ int cp_offset = StandardFrameConstants::kContextOffset + fp_sp_delta_; |
+ __ ldr(cp, MemOperand(sp, cp_offset)); |
} |
@@ -3993,7 +4073,7 @@ void LCodeGen::DoMathLog(LMathLog* instr) { |
ASSERT(ToDoubleRegister(instr->result()).is(d2)); |
TranscendentalCacheStub stub(TranscendentalCache::LOG, |
TranscendentalCacheStub::UNTAGGED); |
- CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); |
+ CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, 0, instr); |
} |
@@ -4001,7 +4081,7 @@ void LCodeGen::DoMathTan(LMathTan* instr) { |
ASSERT(ToDoubleRegister(instr->result()).is(d2)); |
TranscendentalCacheStub stub(TranscendentalCache::TAN, |
TranscendentalCacheStub::UNTAGGED); |
- CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); |
+ CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, 0, instr); |
} |
@@ -4009,7 +4089,7 @@ void LCodeGen::DoMathCos(LMathCos* instr) { |
ASSERT(ToDoubleRegister(instr->result()).is(d2)); |
TranscendentalCacheStub stub(TranscendentalCache::COS, |
TranscendentalCacheStub::UNTAGGED); |
- CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); |
+ CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, 0, instr); |
} |
@@ -4017,7 +4097,7 @@ void LCodeGen::DoMathSin(LMathSin* instr) { |
ASSERT(ToDoubleRegister(instr->result()).is(d2)); |
TranscendentalCacheStub stub(TranscendentalCache::SIN, |
TranscendentalCacheStub::UNTAGGED); |
- CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); |
+ CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, 0, instr); |
} |
@@ -4032,7 +4112,9 @@ void LCodeGen::DoInvokeFunction(LInvokeFunction* instr) { |
SafepointGenerator generator(this, pointers, Safepoint::kLazyDeopt); |
ParameterCount count(instr->arity()); |
__ InvokeFunction(r1, count, CALL_FUNCTION, generator, CALL_AS_METHOD); |
- __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
+ fp_sp_delta_ -= (instr->arity() + 1) * kPointerSize; |
+ int cp_offset = StandardFrameConstants::kContextOffset + fp_sp_delta_; |
+ __ ldr(cp, MemOperand(sp, cp_offset)); |
} else { |
CallKnownFunction(known_function, |
instr->hydrogen()->formal_parameter_count(), |
@@ -4050,8 +4132,10 @@ void LCodeGen::DoCallKeyed(LCallKeyed* instr) { |
int arity = instr->arity(); |
Handle<Code> ic = |
isolate()->stub_cache()->ComputeKeyedCallInitialize(arity); |
- CallCode(ic, RelocInfo::CODE_TARGET, instr, NEVER_INLINE_TARGET_ADDRESS); |
- __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
+ CallCode(ic, RelocInfo::CODE_TARGET, arity + 1, instr, |
+ NEVER_INLINE_TARGET_ADDRESS); |
+ int cp_offset = StandardFrameConstants::kContextOffset + fp_sp_delta_; |
+ __ ldr(cp, MemOperand(sp, cp_offset)); |
} |
@@ -4063,9 +4147,10 @@ void LCodeGen::DoCallNamed(LCallNamed* instr) { |
Handle<Code> ic = |
isolate()->stub_cache()->ComputeCallInitialize(arity, mode); |
__ mov(r2, Operand(instr->name())); |
- CallCode(ic, mode, instr, NEVER_INLINE_TARGET_ADDRESS); |
+ CallCode(ic, mode, arity + 1, instr, NEVER_INLINE_TARGET_ADDRESS); |
// Restore context register. |
- __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
+ int cp_offset = StandardFrameConstants::kContextOffset + fp_sp_delta_; |
+ __ ldr(cp, MemOperand(sp, cp_offset)); |
} |
@@ -4075,8 +4160,9 @@ void LCodeGen::DoCallFunction(LCallFunction* instr) { |
int arity = instr->arity(); |
CallFunctionStub stub(arity, NO_CALL_FUNCTION_FLAGS); |
- CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); |
- __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
+ CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, arity + 1, instr); |
+ int cp_offset = StandardFrameConstants::kContextOffset + fp_sp_delta_; |
+ __ ldr(cp, MemOperand(sp, cp_offset)); |
} |
@@ -4088,8 +4174,9 @@ void LCodeGen::DoCallGlobal(LCallGlobal* instr) { |
Handle<Code> ic = |
isolate()->stub_cache()->ComputeCallInitialize(arity, mode); |
__ mov(r2, Operand(instr->name())); |
- CallCode(ic, mode, instr, NEVER_INLINE_TARGET_ADDRESS); |
- __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
+ CallCode(ic, mode, arity + 1, instr, NEVER_INLINE_TARGET_ADDRESS); |
+ int cp_offset = StandardFrameConstants::kContextOffset + fp_sp_delta_; |
+ __ ldr(cp, MemOperand(sp, cp_offset)); |
} |
@@ -4113,7 +4200,8 @@ void LCodeGen::DoCallNew(LCallNew* instr) { |
Handle<Object> undefined_value(isolate()->factory()->undefined_value()); |
__ mov(r2, Operand(undefined_value)); |
CallConstructStub stub(NO_CALL_FUNCTION_FLAGS); |
- CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr); |
+ CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, |
+ instr->arity() + 1, instr); |
} |
@@ -4132,7 +4220,8 @@ void LCodeGen::DoCallNewArray(LCallNewArray* instr) { |
if (instr->arity() == 0) { |
ArrayNoArgumentConstructorStub stub(kind, context_mode, override_mode); |
- CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr); |
+ CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, |
+ instr->arity() + 1, instr); |
} else if (instr->arity() == 1) { |
Label done; |
if (IsFastPackedElementsKind(kind)) { |
@@ -4146,17 +4235,21 @@ void LCodeGen::DoCallNewArray(LCallNewArray* instr) { |
ElementsKind holey_kind = GetHoleyElementsKind(kind); |
ArraySingleArgumentConstructorStub stub(holey_kind, context_mode, |
override_mode); |
- CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr); |
+ CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, |
+ instr->arity() + 1, instr); |
__ jmp(&done); |
__ bind(&packed_case); |
+ fp_sp_delta_ += (instr->arity() + 1) * kPointerSize; |
} |
ArraySingleArgumentConstructorStub stub(kind, context_mode, override_mode); |
- CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr); |
+ CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, |
+ instr->arity() + 1, instr); |
__ bind(&done); |
} else { |
ArrayNArgumentsConstructorStub stub(kind, context_mode, override_mode); |
- CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr); |
+ CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, |
+ instr->arity() + 1, instr); |
} |
} |
@@ -4268,7 +4361,7 @@ void LCodeGen::DoStoreNamedGeneric(LStoreNamedGeneric* instr) { |
Handle<Code> ic = (instr->strict_mode_flag() == kStrictMode) |
? isolate()->builtins()->StoreIC_Initialize_Strict() |
: isolate()->builtins()->StoreIC_Initialize(); |
- CallCode(ic, RelocInfo::CODE_TARGET, instr, NEVER_INLINE_TARGET_ADDRESS); |
+ CallCode(ic, RelocInfo::CODE_TARGET, 0, instr, NEVER_INLINE_TARGET_ADDRESS); |
} |
@@ -4484,7 +4577,7 @@ void LCodeGen::DoStoreKeyedGeneric(LStoreKeyedGeneric* instr) { |
Handle<Code> ic = (instr->strict_mode_flag() == kStrictMode) |
? isolate()->builtins()->KeyedStoreIC_Initialize_Strict() |
: isolate()->builtins()->KeyedStoreIC_Initialize(); |
- CallCode(ic, RelocInfo::CODE_TARGET, instr, NEVER_INLINE_TARGET_ADDRESS); |
+ CallCode(ic, RelocInfo::CODE_TARGET, 0, instr, NEVER_INLINE_TARGET_ADDRESS); |
} |
@@ -4532,10 +4625,10 @@ void LCodeGen::DoTrapAllocationMemento(LTrapAllocationMemento* instr) { |
void LCodeGen::DoStringAdd(LStringAdd* instr) { |
- __ push(ToRegister(instr->left())); |
- __ push(ToRegister(instr->right())); |
+ Push(ToRegister(instr->left())); |
+ Push(ToRegister(instr->right())); |
StringAddStub stub(instr->hydrogen()->flags()); |
- CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); |
+ CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, 2, instr); |
} |
@@ -4573,17 +4666,17 @@ void LCodeGen::DoDeferredStringCharCodeAt(LStringCharCodeAt* instr) { |
__ mov(result, Operand::Zero()); |
PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters); |
- __ push(string); |
+ Push(string); |
// Push the index as a smi. This is safe because of the checks in |
// DoStringCharCodeAt above. |
if (instr->index()->IsConstantOperand()) { |
int const_index = ToInteger32(LConstantOperand::cast(instr->index())); |
__ mov(scratch, Operand(Smi::FromInt(const_index))); |
- __ push(scratch); |
+ Push(scratch); |
} else { |
Register index = ToRegister(instr->index()); |
__ SmiTag(index); |
- __ push(index); |
+ Push(index); |
} |
CallRuntimeFromDeferred(Runtime::kStringCharCodeAt, 2, instr); |
__ AssertSmi(r0); |
@@ -4634,7 +4727,7 @@ void LCodeGen::DoDeferredStringCharFromCode(LStringCharFromCode* instr) { |
PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters); |
__ SmiTag(char_code); |
- __ push(char_code); |
+ Push(char_code); |
CallRuntimeFromDeferred(Runtime::kCharFromCode, 1, instr); |
__ StoreToSafepointRegisterSlot(r0, result); |
} |
@@ -5365,7 +5458,7 @@ void LCodeGen::DoDeferredAllocate(LAllocate* instr) { |
Register size = ToRegister(instr->size()); |
ASSERT(!size.is(result)); |
__ SmiTag(size); |
- __ push(size); |
+ Push(size); |
} else { |
int32_t size = ToInteger32(LConstantOperand::cast(instr->size())); |
__ Push(Smi::FromInt(size)); |
@@ -5387,7 +5480,7 @@ void LCodeGen::DoDeferredAllocate(LAllocate* instr) { |
void LCodeGen::DoToFastProperties(LToFastProperties* instr) { |
ASSERT(ToRegister(instr->value()).is(r0)); |
- __ push(r0); |
+ Push(r0); |
CallRuntime(Runtime::kToFastProperties, 1, instr); |
} |
@@ -5412,7 +5505,7 @@ void LCodeGen::DoRegExpLiteral(LRegExpLiteral* instr) { |
__ mov(r6, Operand(Smi::FromInt(instr->hydrogen()->literal_index()))); |
__ mov(r5, Operand(instr->hydrogen()->pattern())); |
__ mov(r4, Operand(instr->hydrogen()->flags())); |
- __ Push(r7, r6, r5, r4); |
+ Push(r7, r6, r5, r4); |
CallRuntime(Runtime::kMaterializeRegExpLiteral, 4, instr); |
__ mov(r1, r0); |
@@ -5425,9 +5518,10 @@ void LCodeGen::DoRegExpLiteral(LRegExpLiteral* instr) { |
__ bind(&runtime_allocate); |
__ mov(r0, Operand(Smi::FromInt(size))); |
- __ Push(r1, r0); |
+ Push(r1, r0); |
CallRuntime(Runtime::kAllocateInNewSpace, 1, instr); |
__ pop(r1); |
+ fp_sp_delta_ -= kPointerSize; |
__ bind(&allocated); |
// Copy the content into the newly allocated memory. |
@@ -5443,13 +5537,13 @@ void LCodeGen::DoFunctionLiteral(LFunctionLiteral* instr) { |
FastNewClosureStub stub(instr->hydrogen()->language_mode(), |
instr->hydrogen()->is_generator()); |
__ mov(r1, Operand(instr->hydrogen()->shared_info())); |
- __ push(r1); |
- CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); |
+ Push(r1); |
+ CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, 1, instr); |
} else { |
__ mov(r2, Operand(instr->hydrogen()->shared_info())); |
__ mov(r1, Operand(pretenure ? factory()->true_value() |
: factory()->false_value())); |
- __ Push(cp, r2, r1); |
+ Push(cp, r2, r1); |
CallRuntime(Runtime::kNewClosure, 3, instr); |
} |
} |
@@ -5457,7 +5551,7 @@ void LCodeGen::DoFunctionLiteral(LFunctionLiteral* instr) { |
void LCodeGen::DoTypeof(LTypeof* instr) { |
Register input = ToRegister(instr->value()); |
- __ push(input); |
+ Push(input); |
CallRuntime(Runtime::kTypeof, 1, instr); |
} |
@@ -5662,7 +5756,7 @@ void LCodeGen::DoStackCheck(LStackCheck* instr) { |
__ b(hs, &done); |
StackCheckStub stub; |
PredictableCodeSizeScope predictable(masm_, 2 * Assembler::kInstrSize); |
- CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); |
+ CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, 0, instr); |
EnsureSpaceForLazyDeopt(); |
last_lazy_deopt_pc_ = masm()->pc_offset(); |
__ bind(&done); |
@@ -5730,7 +5824,7 @@ void LCodeGen::DoForInPrepareMap(LForInPrepareMap* instr) { |
// Get the set of properties to enumerate. |
__ bind(&call_runtime); |
- __ push(r0); |
+ Push(r0); |
CallRuntime(Runtime::kGetPropertyNamesFast, 1, instr); |
__ ldr(r1, FieldMemOperand(r0, HeapObject::kMapOffset)); |