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:
parent
00346bd1da
commit
9da07882c8
@ -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());
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
@ -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")
|
||||
|
Loading…
Reference in New Issue
Block a user