Index: src/codegen-arm.cc |
=================================================================== |
--- src/codegen-arm.cc (revision 441) |
+++ src/codegen-arm.cc (working copy) |
@@ -4403,102 +4403,96 @@ |
} |
-void ArgumentsAccessStub::Generate(MacroAssembler* masm) { |
- // ----------- S t a t e ------------- |
- // -- r0: formal number of parameters for the calling function |
- // -- r1: key (if value access) |
- // -- lr: return address |
- // ----------------------------------- |
+void ArgumentsAccessStub::GenerateReadLength(MacroAssembler* masm) { |
+ // Check if the calling frame is an arguments adaptor frame. |
+ Label adaptor; |
+ __ ldr(r2, MemOperand(fp, StandardFrameConstants::kCallerFPOffset)); |
+ __ ldr(r3, MemOperand(r2, StandardFrameConstants::kContextOffset)); |
+ __ cmp(r3, Operand(ArgumentsAdaptorFrame::SENTINEL)); |
+ __ b(eq, &adaptor); |
- // If we're reading an element we need to check that the key is a smi. |
+ // Nothing to do: The formal number of parameters has already been |
+ // passed in register r0 by calling function. Just return it. |
+ __ mov(pc, lr); |
+ |
+ // Arguments adaptor case: Read the arguments length from the |
+ // adaptor frame and return it. |
+ __ bind(&adaptor); |
+ __ ldr(r0, MemOperand(r2, ArgumentsAdaptorFrameConstants::kLengthOffset)); |
+ __ mov(pc, lr); |
+} |
+ |
+ |
+void ArgumentsAccessStub::GenerateReadElement(MacroAssembler* masm) { |
+ // The displacement is the offset of the last parameter (if any) |
+ // relative to the frame pointer. |
+ static const int kDisplacement = |
+ StandardFrameConstants::kCallerSPOffset - kPointerSize; |
+ |
+ // Check that the key is a smi. |
Label slow; |
- if (type_ == READ_ELEMENT) { |
- __ tst(r1, Operand(kSmiTagMask)); |
- __ b(ne, &slow); |
- } |
+ __ tst(r1, Operand(kSmiTagMask)); |
+ __ b(ne, &slow); |
// Check if the calling frame is an arguments adaptor frame. |
- // r0: formal number of parameters |
- // r1: key (if access) |
Label adaptor; |
__ ldr(r2, MemOperand(fp, StandardFrameConstants::kCallerFPOffset)); |
__ ldr(r3, MemOperand(r2, StandardFrameConstants::kContextOffset)); |
__ cmp(r3, Operand(ArgumentsAdaptorFrame::SENTINEL)); |
- if (type_ == NEW_OBJECT) { |
- __ b(ne, &slow); |
- } else { |
- __ b(eq, &adaptor); |
- } |
+ __ b(eq, &adaptor); |
- static const int kParamDisplacement = |
- StandardFrameConstants::kCallerSPOffset - kPointerSize; |
+ // Check index against formal parameters count limit passed in |
+ // through register eax. Use unsigned comparison to get negative |
+ // check for free. |
+ __ cmp(r1, r0); |
+ __ b(cs, &slow); |
- 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 |
- // r1: index |
- __ cmp(r1, r0); |
- __ b(cs, &slow); |
+ // Read the argument from the stack and return it. |
+ __ sub(r3, r0, r1); |
+ __ add(r3, fp, Operand(r3, LSL, kPointerSizeLog2 - kSmiTagSize)); |
+ __ ldr(r0, MemOperand(r3, kDisplacement)); |
+ __ mov(pc, lr); |
- // 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. |
- } |
- |
- // An arguments adaptor frame is present. Find the length or the actual |
- // argument in the calling frame. |
- // r0: formal number of parameters |
- // r1: key |
- // r2: adaptor frame pointer |
+ // Arguments adaptor case: Check index against actual arguments |
+ // limit found in the arguments adaptor frame. Use unsigned |
+ // comparison to get negative check for free. |
__ bind(&adaptor); |
- // Read the arguments length from the adaptor frame. This is the result if |
- // only accessing the length, otherwise it is used in accessing the value |
__ ldr(r0, MemOperand(r2, ArgumentsAdaptorFrameConstants::kLengthOffset)); |
+ __ cmp(r1, r0); |
+ __ b(cs, &slow); |
- 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 |
- // r1: index |
- // r2: adaptor frame point |
- __ cmp(r1, r0); |
- __ b(cs, &slow); |
+ // 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, kDisplacement)); |
+ __ mov(pc, lr); |
- // 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); |
- } |
+ // Slow-case: Handle non-smi or out-of-bounds access to arguments |
+ // by calling the runtime system. |
+ __ bind(&slow); |
+ __ push(r1); |
+ __ TailCallRuntime(ExternalReference(Runtime::kGetArgumentsProperty), 1); |
+} |
- // Return to the calling function. |
- if (type_ == READ_ELEMENT) { |
- __ bind(&slow); |
- __ push(r1); |
- __ TailCallRuntime(ExternalReference(Runtime::kGetArgumentsProperty), 1); |
- } |
+ |
+void ArgumentsAccessStub::GenerateNewObject(MacroAssembler* masm) { |
+ // Check if the calling frame is an arguments adaptor frame. |
+ Label runtime; |
+ __ ldr(r2, MemOperand(fp, StandardFrameConstants::kCallerFPOffset)); |
+ __ ldr(r3, MemOperand(r2, StandardFrameConstants::kContextOffset)); |
+ __ cmp(r3, Operand(ArgumentsAdaptorFrame::SENTINEL)); |
+ __ b(ne, &runtime); |
+ |
+ // Patch the arguments.length and the parameters pointer. |
+ __ ldr(r0, MemOperand(r2, ArgumentsAdaptorFrameConstants::kLengthOffset)); |
+ __ str(r0, MemOperand(sp, 0 * kPointerSize)); |
+ __ add(r3, r2, Operand(r0, LSL, kPointerSizeLog2 - kSmiTagSize)); |
+ __ add(r3, r3, Operand(StandardFrameConstants::kCallerSPOffset)); |
+ __ str(r3, MemOperand(sp, 1 * kPointerSize)); |
+ |
+ // Do the runtime call to allocate the arguments object. |
+ __ bind(&runtime); |
+ __ TailCallRuntime(ExternalReference(Runtime::kNewArgumentsFast), 3); |
} |