Chromium Code Reviews| 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); |