diff --git a/src/mips/lithium-codegen-mips.cc b/src/mips/lithium-codegen-mips.cc index 94e8979ba3..f6f0c94aff 100644 --- a/src/mips/lithium-codegen-mips.cc +++ b/src/mips/lithium-codegen-mips.cc @@ -2651,16 +2651,20 @@ void LCodeGen::DoArgumentsElements(LArgumentsElements* instr) { Register temp = scratch1(); Register result = ToRegister(instr->result()); - // Check if the calling frame is an arguments adaptor frame. - Label done, adapted; - __ lw(scratch, MemOperand(fp, StandardFrameConstants::kCallerFPOffset)); - __ lw(result, MemOperand(scratch, StandardFrameConstants::kContextOffset)); - __ Xor(temp, result, Operand(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR))); + if (instr->from_inlined()) { + __ Subu(result, sp, 2 * kPointerSize); + } else { + // Check if the calling frame is an arguments adaptor frame. + Label done, adapted; + __ lw(scratch, MemOperand(fp, StandardFrameConstants::kCallerFPOffset)); + __ lw(result, MemOperand(scratch, StandardFrameConstants::kContextOffset)); + __ Xor(temp, result, Operand(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR))); - // Result is the frame pointer for the frame if not adapted and for the real - // frame below the adaptor frame if adapted. - __ Movn(result, fp, temp); // Move only if temp is not equal to zero (ne). - __ Movz(result, scratch, temp); // Move only if temp is equal to zero (eq). + // Result is the frame pointer for the frame if not adapted and for the real + // frame below the adaptor frame if adapted. + __ Movn(result, fp, temp); // Move only if temp is not equal to zero (ne). + __ Movz(result, scratch, temp); // Move only if temp is equal to zero (eq). + } } @@ -2793,6 +2797,11 @@ void LCodeGen::DoPushArgument(LPushArgument* instr) { } +void LCodeGen::DoPop(LPop* instr) { + __ Drop(instr->count()); +} + + void LCodeGen::DoThisFunction(LThisFunction* instr) { Register result = ToRegister(instr->result()); __ LoadHeapObject(result, instr->hydrogen()->closure()); diff --git a/src/mips/lithium-mips.cc b/src/mips/lithium-mips.cc index 1e0c2160aa..dca90a151f 100644 --- a/src/mips/lithium-mips.cc +++ b/src/mips/lithium-mips.cc @@ -1076,7 +1076,8 @@ LInstruction* LChunkBuilder::DoArgumentsLength(HArgumentsLength* length) { LInstruction* LChunkBuilder::DoArgumentsElements(HArgumentsElements* elems) { - return DefineAsRegister(new(zone()) LArgumentsElements); + return DefineAsRegister(new(zone()) LArgumentsElements( + current_block_->last_environment()->outer() != NULL)); } @@ -2277,6 +2278,9 @@ LInstruction* LChunkBuilder::DoEnterInlined(HEnterInlined* instr) { undefined, instr->call_kind(), instr->is_construct()); + if (instr->materializes_arguments()) { + inner->Bind(instr->arguments(), graph()->GetArgumentsObject()); + } current_block_->UpdateEnvironment(inner); chunk_->AddInlinedClosure(instr->closure()); return NULL; @@ -2284,10 +2288,21 @@ LInstruction* LChunkBuilder::DoEnterInlined(HEnterInlined* instr) { LInstruction* LChunkBuilder::DoLeaveInlined(HLeaveInlined* instr) { + LInstruction* pop = NULL; + + HEnvironment* env = current_block_->last_environment(); + + if (instr->arguments_pushed()) { + int argument_count = env->arguments_environment()->parameter_count(); + pop = new(zone()) LPop(argument_count); + argument_count_ -= argument_count; + } + HEnvironment* outer = current_block_->last_environment()-> DiscardInlined(false); current_block_->UpdateEnvironment(outer); - return NULL; + + return pop; } diff --git a/src/mips/lithium-mips.h b/src/mips/lithium-mips.h index 5a7bf4d941..8fb80b6c78 100644 --- a/src/mips/lithium-mips.h +++ b/src/mips/lithium-mips.h @@ -179,7 +179,8 @@ class LCodeGen; V(CheckMapValue) \ V(LoadFieldByIndex) \ V(DateField) \ - V(WrapReceiver) + V(WrapReceiver) \ + V(Pop) #define DECLARE_CONCRETE_INSTRUCTION(type, mnemonic) \ virtual Opcode opcode() const { return LInstruction::k##type; } \ @@ -533,9 +534,15 @@ class LArgumentsLength: public LTemplateInstruction<1, 1, 0> { class LArgumentsElements: public LTemplateInstruction<1, 0, 0> { public: - LArgumentsElements() { } + explicit LArgumentsElements(bool from_inlined) + : from_inlined_(from_inlined) { } + + bool from_inlined() const { return from_inlined_; } DECLARE_CONCRETE_INSTRUCTION(ArgumentsElements, "arguments-elements") + + private: + bool from_inlined_; }; @@ -1358,6 +1365,19 @@ class LPushArgument: public LTemplateInstruction<0, 1, 0> { }; +class LPop: public LTemplateInstruction<0, 0, 0> { + public: + explicit LPop(int count) : count_(count) { } + + int count() const { return count_; } + + DECLARE_CONCRETE_INSTRUCTION(Pop, "pop") + + private: + int count_; +}; + + class LThisFunction: public LTemplateInstruction<1, 0, 0> { public: DECLARE_CONCRETE_INSTRUCTION(ThisFunction, "this-function")