Index: src/codegen-arm.cc |
=================================================================== |
--- src/codegen-arm.cc (revision 433) |
+++ src/codegen-arm.cc (working copy) |
@@ -587,10 +587,13 @@ |
Comment cmnt(masm_, "[ allocate arguments object"); |
{ Reference shadow_ref(this, scope->arguments_shadow()); |
{ Reference arguments_ref(this, scope->arguments()); |
- __ ldr(r0, FunctionOperand()); |
+ ArgumentsAccessStub stub(ArgumentsAccessStub::NEW_OBJECT); |
+ __ ldr(r2, FunctionOperand()); |
+ __ add(r1, fp, Operand((2 + scope->num_parameters()) * kPointerSize)); |
Mads Ager (chromium)
2008/10/06 06:05:59
Could you add a comment to say what the constant 2
|
+ __ mov(r0, Operand(Smi::FromInt(scope->num_parameters()))); |
+ __ stm(db_w, sp, r0.bit() | r1.bit() | r2.bit()); |
+ __ CallStub(&stub); |
__ push(r0); |
- __ CallRuntime(Runtime::kNewArguments, 1); |
- __ push(r0); |
SetValue(&arguments_ref); |
} |
SetValue(&shadow_ref); |
@@ -963,28 +966,6 @@ |
}; |
-class ArgumentsAccessStub: public CodeStub { |
- public: |
- explicit ArgumentsAccessStub(bool is_length) : is_length_(is_length) { } |
- |
- private: |
- bool is_length_; |
- |
- Major MajorKey() { return ArgumentsAccess; } |
- int MinorKey() { return is_length_ ? 1 : 0; } |
- void Generate(MacroAssembler* masm); |
- |
- const char* GetName() { return "ArgumentsAccessStub"; } |
- |
-#ifdef DEBUG |
- void Print() { |
- PrintF("ArgumentsAccessStub (is_length %s)\n", |
- is_length_ ? "true" : "false"); |
- } |
-#endif |
-}; |
- |
- |
void ArmCodeGenerator::GetReferenceProperty(Expression* key) { |
ASSERT(!ref()->is_illegal()); |
Reference::Type type = ref()->type(); |
@@ -2857,7 +2838,7 @@ |
__ mov(r0, Operand(Smi::FromInt(scope_->num_parameters()))); |
// Call the shared stub to get to the arguments.length. |
- ArgumentsAccessStub stub(true); |
+ ArgumentsAccessStub stub(ArgumentsAccessStub::READ_LENGTH); |
__ CallStub(&stub); |
__ push(r0); |
} |
@@ -2873,7 +2854,7 @@ |
__ mov(r0, Operand(Smi::FromInt(scope_->num_parameters()))); |
// Call the shared stub to get to arguments[key]. |
- ArgumentsAccessStub stub(false); |
+ ArgumentsAccessStub stub(ArgumentsAccessStub::READ_ELEMENT); |
__ CallStub(&stub); |
__ push(r0); |
} |
@@ -4426,9 +4407,9 @@ |
// -- lr: return address |
// ----------------------------------- |
- // Check that the key is a smi for non-length accesses. |
+ // If we're reading an element we need to check that the key is a smi. |
Label slow; |
- if (!is_length_) { |
+ if (type_ == READ_ELEMENT) { |
__ tst(r1, Operand(kSmiTagMask)); |
__ b(ne, &slow); |
} |
@@ -4440,15 +4421,20 @@ |
__ ldr(r2, MemOperand(fp, StandardFrameConstants::kCallerFPOffset)); |
__ ldr(r3, MemOperand(r2, StandardFrameConstants::kContextOffset)); |
__ cmp(r3, Operand(ArgumentsAdaptorFrame::SENTINEL)); |
- __ b(eq, &adaptor); |
+ if (type_ == NEW_OBJECT) { |
+ __ b(ne, &slow); |
+ } else { |
+ __ b(eq, &adaptor); |
+ } |
static const int kParamDisplacement = |
StandardFrameConstants::kCallerSPOffset - kPointerSize; |
- if (is_length_) { |
- // Nothing to do: the formal length of parameters has been passed in r0 |
- // by the calling function. |
- } else { |
+ if (type_ == READ_LENGTH) { |
+ // Nothing to do: The formal number of parameters has already been |
+ // passed in register r0 by calling function. Just return it. |
+ __ mov(pc, lr); |
+ } else if (type_ == READ_ELEMENT) { |
// Check index against formal parameter count. Use unsigned comparison to |
// get the negative check for free. |
// r0: formal number of parameters |
@@ -4456,15 +4442,16 @@ |
__ cmp(r1, r0); |
__ b(cs, &slow); |
- // Read the argument from the current frame. |
+ // Read the argument from the current frame and return it. |
__ sub(r3, r0, r1); |
__ add(r3, fp, Operand(r3, LSL, kPointerSizeLog2 - kSmiTagSize)); |
__ ldr(r0, MemOperand(r3, kParamDisplacement)); |
+ __ mov(pc, lr); |
+ } else { |
+ ASSERT(type_ == NEW_OBJECT); |
+ // Do nothing here. |
} |
- // Return to the calling function. |
- __ mov(pc, lr); |
- |
// An arguments adaptor frame is present. Find the length or the actual |
// argument in the calling frame. |
// r0: formal number of parameters |
@@ -4475,7 +4462,10 @@ |
// only accessing the length, otherwise it is used in accessing the value |
__ ldr(r0, MemOperand(r2, ArgumentsAdaptorFrameConstants::kLengthOffset)); |
- if (!is_length_) { |
+ if (type_ == READ_LENGTH) { |
+ // Return the length in r0. |
+ __ mov(pc, lr); |
+ } else if (type_ == READ_ELEMENT) { |
// Check index against actual arguments count. Use unsigned comparison to |
// get the negative check for free. |
// r0: actual number of parameter |
@@ -4484,16 +4474,24 @@ |
__ cmp(r1, r0); |
__ b(cs, &slow); |
- // Read the argument from the adaptor frame. |
+ // Read the argument from the adaptor frame and return it. |
__ sub(r3, r0, r1); |
__ add(r3, r2, Operand(r3, LSL, kPointerSizeLog2 - kSmiTagSize)); |
__ ldr(r0, MemOperand(r3, kParamDisplacement)); |
+ __ mov(pc, lr); |
+ } else { |
+ ASSERT(type_ == NEW_OBJECT); |
+ // Patch the arguments.length and the parameters pointer. |
+ __ str(r0, MemOperand(sp, 0 * kPointerSize)); |
+ __ add(r3, r2, Operand(r0, LSL, kPointerSizeLog2 - kSmiTagSize)); |
+ __ add(r3, r3, Operand(kParamDisplacement + 1 * kPointerSize)); |
+ __ str(r3, MemOperand(sp, 1 * kPointerSize)); |
+ __ bind(&slow); |
+ __ TailCallRuntime(ExternalReference(Runtime::kNewArgumentsFast), 3); |
} |
// Return to the calling function. |
- __ mov(pc, lr); |
- |
- if (!is_length_) { |
+ if (type_ == READ_ELEMENT) { |
__ bind(&slow); |
__ push(r1); |
__ TailCallRuntime(ExternalReference(Runtime::kGetArgumentsProperty), 1); |