Index: src/codegen-ia32.cc |
=================================================================== |
--- src/codegen-ia32.cc (revision 441) |
+++ src/codegen-ia32.cc (working copy) |
@@ -4795,93 +4795,105 @@ |
} |
-void ArgumentsAccessStub::Generate(MacroAssembler* masm) { |
- // If we're reading an element we need to check that the key is a smi. |
- Label slow; |
- if (type_ == READ_ELEMENT) { |
- __ mov(ebx, Operand(esp, 1 * kPointerSize)); // skip return address |
- __ test(ebx, Immediate(kSmiTagMask)); |
- __ j(not_zero, &slow, not_taken); |
- } |
- |
+void ArgumentsAccessStub::GenerateReadLength(MacroAssembler* masm) { |
// Check if the calling frame is an arguments adaptor frame. |
Label adaptor; |
__ mov(edx, Operand(ebp, StandardFrameConstants::kCallerFPOffset)); |
__ mov(ecx, Operand(edx, StandardFrameConstants::kContextOffset)); |
__ cmp(ecx, ArgumentsAdaptorFrame::SENTINEL); |
- if (type_ == NEW_OBJECT) { |
- __ j(not_equal, &slow); |
- } else { |
- __ j(equal, &adaptor); |
- } |
+ __ j(equal, &adaptor); |
- // The displacement is used for skipping the return address on the |
+ // Nothing to do: The formal number of parameters has already been |
+ // passed in register eax by calling function. Just return it. |
+ __ ret(0); |
+ |
+ // Arguments adaptor case: Read the arguments length from the |
+ // adaptor frame and return it. |
+ __ bind(&adaptor); |
+ __ mov(eax, Operand(edx, ArgumentsAdaptorFrameConstants::kLengthOffset)); |
+ __ ret(0); |
+} |
+ |
+ |
+void ArgumentsAccessStub::GenerateReadElement(MacroAssembler* masm) { |
+ // The displacement is used for skipping the frame pointer on the |
// stack. It is the offset of the last parameter (if any) relative |
// to the frame pointer. |
static const int kDisplacement = 1 * kPointerSize; |
- ASSERT(kSmiTagSize == 1 && kSmiTag == 0); // shifting code depends on this |
- if (type_ == READ_LENGTH) { |
- // Nothing to do: The formal number of parameters has already been |
- // passed in register eax by calling function. Just return it. |
- __ ret(0); |
- } else if (type_ == READ_ELEMENT) { |
- // Check index against formal parameters count limit passed in |
- // through register eax. Use unsigned comparison to get negative |
- // check for free. |
- __ cmp(ebx, Operand(eax)); |
- __ j(above_equal, &slow, not_taken); |
+ // Check that the key is a smi. |
+ Label slow; |
+ __ mov(ebx, Operand(esp, 1 * kPointerSize)); // skip return address |
+ __ test(ebx, Immediate(kSmiTagMask)); |
+ __ j(not_zero, &slow, not_taken); |
- // Read the argument from the stack and return it. |
- __ lea(edx, Operand(ebp, eax, times_2, 0)); |
- __ neg(ebx); |
- __ mov(eax, Operand(edx, ebx, times_2, kDisplacement)); |
- __ ret(0); |
- } else { |
- ASSERT(type_ == NEW_OBJECT); |
- // Do nothing here. |
- } |
+ // Check if the calling frame is an arguments adaptor frame. |
+ Label adaptor; |
+ __ mov(edx, Operand(ebp, StandardFrameConstants::kCallerFPOffset)); |
+ __ mov(ecx, Operand(edx, StandardFrameConstants::kContextOffset)); |
+ __ cmp(ecx, ArgumentsAdaptorFrame::SENTINEL); |
+ __ j(equal, &adaptor); |
- // Arguments adaptor case: Find the length or the actual argument in |
- // the calling frame. |
+ // Check index against formal parameters count limit passed in |
+ // through register eax. Use unsigned comparison to get negative |
+ // check for free. |
+ __ cmp(ebx, Operand(eax)); |
+ __ j(above_equal, &slow, not_taken); |
+ |
+ // Read the argument from the stack and return it. |
+ ASSERT(kSmiTagSize == 1 && kSmiTag == 0); // shifting code depends on this |
+ __ lea(edx, Operand(ebp, eax, times_2, 0)); |
+ __ neg(ebx); |
+ __ mov(eax, Operand(edx, ebx, times_2, kDisplacement)); |
+ __ ret(0); |
+ |
+ // 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); |
- if (type_ == READ_LENGTH) { |
- // Read the arguments length from the adaptor frame and return it. |
- __ mov(eax, Operand(edx, ArgumentsAdaptorFrameConstants::kLengthOffset)); |
- __ ret(0); |
- } else if (type_ == READ_ELEMENT) { |
- // Check index against actual arguments limit found in the |
- // arguments adaptor frame. Use unsigned comparison to get |
- // negative check for free. |
- __ mov(ecx, Operand(edx, ArgumentsAdaptorFrameConstants::kLengthOffset)); |
- __ cmp(ebx, Operand(ecx)); |
- __ j(above_equal, &slow, not_taken); |
+ __ mov(ecx, Operand(edx, ArgumentsAdaptorFrameConstants::kLengthOffset)); |
+ __ cmp(ebx, Operand(ecx)); |
+ __ j(above_equal, &slow, not_taken); |
- // Read the argument from the stack and return it. |
- __ lea(edx, Operand(edx, ecx, times_2, 0)); |
- __ neg(ebx); |
- __ mov(eax, Operand(edx, ebx, times_2, kDisplacement)); |
- __ ret(0); |
- } else { |
- ASSERT(type_ == NEW_OBJECT); |
- // Patch the arguments.length and the parameters pointer. |
- __ mov(ecx, Operand(edx, ArgumentsAdaptorFrameConstants::kLengthOffset)); |
- __ mov(Operand(esp, 1 * kPointerSize), ecx); |
- __ lea(edx, Operand(edx, ecx, times_2, kDisplacement + 1 * kPointerSize)); |
- __ mov(Operand(esp, 2 * kPointerSize), edx); |
- __ bind(&slow); |
- __ TailCallRuntime(ExternalReference(Runtime::kNewArgumentsFast), 3); |
- } |
+ // Read the argument from the stack and return it. |
+ ASSERT(kSmiTagSize == 1 && kSmiTag == 0); // shifting code depends on this |
+ __ lea(edx, Operand(edx, ecx, times_2, 0)); |
+ __ neg(ebx); |
+ __ mov(eax, Operand(edx, ebx, times_2, kDisplacement)); |
+ __ ret(0); |
// Slow-case: Handle non-smi or out-of-bounds access to arguments |
// by calling the runtime system. |
- if (type_ == READ_ELEMENT) { |
- __ bind(&slow); |
- __ TailCallRuntime(ExternalReference(Runtime::kGetArgumentsProperty), 1); |
- } |
+ __ bind(&slow); |
+ __ TailCallRuntime(ExternalReference(Runtime::kGetArgumentsProperty), 1); |
} |
+void ArgumentsAccessStub::GenerateNewObject(MacroAssembler* masm) { |
+ // The displacement is used for skipping the return address and the |
+ // frame pointer on the stack. It is the offset of the last |
+ // parameter (if any) relative to the frame pointer. |
+ static const int kDisplacement = 2 * kPointerSize; |
+ |
+ // Check if the calling frame is an arguments adaptor frame. |
+ Label runtime; |
+ __ mov(edx, Operand(ebp, StandardFrameConstants::kCallerFPOffset)); |
+ __ mov(ecx, Operand(edx, StandardFrameConstants::kContextOffset)); |
+ __ cmp(ecx, ArgumentsAdaptorFrame::SENTINEL); |
+ __ j(not_equal, &runtime); |
+ |
+ // Patch the arguments.length and the parameters pointer. |
+ __ mov(ecx, Operand(edx, ArgumentsAdaptorFrameConstants::kLengthOffset)); |
+ __ mov(Operand(esp, 1 * kPointerSize), ecx); |
+ __ lea(edx, Operand(edx, ecx, times_2, kDisplacement)); |
+ __ mov(Operand(esp, 2 * kPointerSize), edx); |
+ |
+ // Do the runtime call to allocate the arguments object. |
+ __ bind(&runtime); |
+ __ TailCallRuntime(ExternalReference(Runtime::kNewArgumentsFast), 3); |
+} |
+ |
+ |
void CompareStub::Generate(MacroAssembler* masm) { |
Label call_builtin, done; |
// Save the return address (and get it off the stack). |