MIPS: Support arguments object access from inlined functions.

Port r11109 (a7770bdd7c).

BUG=
TEST=

Review URL: https://chromiumcodereview.appspot.com/9808058
Patch from Daniel Kalmar <kalmard@homejinni.com>.

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@11118 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
vegorov@chromium.org 2012-03-23 11:38:40 +00:00
parent 00346bd1da
commit 9da07882c8
3 changed files with 57 additions and 13 deletions

View File

@ -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());

View File

@ -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;
}

View File

@ -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")