MIPS: Inline functions that use arguments object in f.apply(o, arguments) pattern.

Port r11008 (f7a04e6f9).

Original commit message:

Support arguments materialization after deoptimization in all frames (not only in topmost one).

BUG=
TEST=

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

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@11056 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
vegorov@chromium.org 2012-03-15 12:29:20 +00:00
parent 211a867943
commit c9b0d104d1
3 changed files with 36 additions and 7 deletions

View File

@ -2690,15 +2690,10 @@ void LCodeGen::DoArgumentsLength(LArgumentsLength* instr) {
} }
void LCodeGen::DoApplyArguments(LApplyArguments* instr) { void LCodeGen::DoWrapReceiver(LWrapReceiver* instr) {
Register receiver = ToRegister(instr->receiver()); Register receiver = ToRegister(instr->receiver());
Register function = ToRegister(instr->function()); Register function = ToRegister(instr->function());
Register length = ToRegister(instr->length());
Register elements = ToRegister(instr->elements());
Register scratch = scratch0(); Register scratch = scratch0();
ASSERT(receiver.is(a0)); // Used for parameter count.
ASSERT(function.is(a1)); // Required by InvokeFunction.
ASSERT(ToRegister(instr->result()).is(v0));
// If the receiver is null or undefined, we have to pass the global // If the receiver is null or undefined, we have to pass the global
// object as a receiver to normal functions. Values have to be // object as a receiver to normal functions. Values have to be
@ -2739,6 +2734,17 @@ void LCodeGen::DoApplyArguments(LApplyArguments* instr) {
__ lw(receiver, __ lw(receiver,
FieldMemOperand(receiver, JSGlobalObject::kGlobalReceiverOffset)); FieldMemOperand(receiver, JSGlobalObject::kGlobalReceiverOffset));
__ bind(&receiver_ok); __ bind(&receiver_ok);
}
void LCodeGen::DoApplyArguments(LApplyArguments* instr) {
Register receiver = ToRegister(instr->receiver());
Register function = ToRegister(instr->function());
Register length = ToRegister(instr->length());
Register elements = ToRegister(instr->elements());
Register scratch = scratch0();
ASSERT(receiver.is(a0)); // Used for parameter count.
ASSERT(function.is(a1)); // Required by InvokeFunction.
ASSERT(ToRegister(instr->result()).is(v0));
// Copy the arguments to this function possibly from the // Copy the arguments to this function possibly from the
// adaptor frame below it. // adaptor frame below it.

View File

@ -1097,6 +1097,14 @@ LInstruction* LChunkBuilder::DoInstanceOfKnownGlobal(
} }
LInstruction* LChunkBuilder::DoWrapReceiver(HWrapReceiver* instr) {
LOperand* receiver = UseRegisterAtStart(instr->receiver());
LOperand* function = UseRegisterAtStart(instr->function());
LWrapReceiver* result = new(zone()) LWrapReceiver(receiver, function);
return AssignEnvironment(DefineSameAsFirst(result));
}
LInstruction* LChunkBuilder::DoApplyArguments(HApplyArguments* instr) { LInstruction* LChunkBuilder::DoApplyArguments(HApplyArguments* instr) {
LOperand* function = UseFixed(instr->function(), a1); LOperand* function = UseFixed(instr->function(), a1);
LOperand* receiver = UseFixed(instr->receiver(), a0); LOperand* receiver = UseFixed(instr->receiver(), a0);

View File

@ -178,7 +178,8 @@ class LCodeGen;
V(ForInCacheArray) \ V(ForInCacheArray) \
V(CheckMapValue) \ V(CheckMapValue) \
V(LoadFieldByIndex) \ V(LoadFieldByIndex) \
V(DateField) V(DateField) \
V(WrapReceiver)
#define DECLARE_CONCRETE_INSTRUCTION(type, mnemonic) \ #define DECLARE_CONCRETE_INSTRUCTION(type, mnemonic) \
virtual Opcode opcode() const { return LInstruction::k##type; } \ virtual Opcode opcode() const { return LInstruction::k##type; } \
@ -467,6 +468,20 @@ class LControlInstruction: public LTemplateInstruction<0, I, T> {
}; };
class LWrapReceiver: public LTemplateInstruction<1, 2, 0> {
public:
LWrapReceiver(LOperand* receiver, LOperand* function) {
inputs_[0] = receiver;
inputs_[1] = function;
}
DECLARE_CONCRETE_INSTRUCTION(WrapReceiver, "wrap-receiver")
LOperand* receiver() { return inputs_[0]; }
LOperand* function() { return inputs_[1]; }
};
class LApplyArguments: public LTemplateInstruction<1, 4, 0> { class LApplyArguments: public LTemplateInstruction<1, 4, 0> {
public: public:
LApplyArguments(LOperand* function, LApplyArguments(LOperand* function,