Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(72)

Side by Side Diff: src/ia32/code-stubs-ia32.cc

Issue 6725030: [Arguments] Introduce a new backing store for non-strict arguments objects. (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/arguments
Patch Set: Created 9 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 3592 matching lines...) Expand 10 before | Expand all | Expand 10 after
3603 __ push(edx); 3603 __ push(edx);
3604 __ push(ebx); 3604 __ push(ebx);
3605 __ TailCallRuntime(Runtime::kGetArgumentsProperty, 1, 1); 3605 __ TailCallRuntime(Runtime::kGetArgumentsProperty, 1, 1);
3606 } 3606 }
3607 3607
3608 3608
3609 void ArgumentsAccessStub::GenerateNewObject(MacroAssembler* masm) { 3609 void ArgumentsAccessStub::GenerateNewObject(MacroAssembler* masm) {
3610 // esp[0] : return address 3610 // esp[0] : return address
3611 // esp[4] : number of parameters 3611 // esp[4] : number of parameters
3612 // esp[8] : receiver displacement 3612 // esp[8] : receiver displacement
3613 // esp[16] : function 3613 // esp[12] : function
3614 3614
3615 // The displacement is used for skipping the return address and the 3615 // The displacement is used for skipping the return address and the
3616 // frame pointer on the stack. It is the offset of the last 3616 // frame pointer on the stack. It is the offset of the last
3617 // parameter (if any) relative to the frame pointer. 3617 // parameter (if any) relative to the frame pointer.
3618 static const int kDisplacement = 2 * kPointerSize; 3618 static const int kDisplacement = 2 * kPointerSize;
3619 3619
3620 // Check if the calling frame is an arguments adaptor frame. 3620 // Check if the calling frame is an arguments adaptor frame.
3621 Label adaptor_frame, try_allocate, runtime; 3621 Label adaptor_frame, try_allocate, runtime;
3622 __ mov(edx, Operand(ebp, StandardFrameConstants::kCallerFPOffset)); 3622 __ mov(edx, Operand(ebp, StandardFrameConstants::kCallerFPOffset));
3623 __ mov(ecx, Operand(edx, StandardFrameConstants::kContextOffset)); 3623 __ mov(ecx, Operand(edx, StandardFrameConstants::kContextOffset));
3624 __ cmp(Operand(ecx), Immediate(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR))); 3624 __ cmp(Operand(ecx), Immediate(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)));
3625 __ j(equal, &adaptor_frame); 3625 __ j(equal, &adaptor_frame);
3626 3626
3627 // Get the length from the frame. 3627 // Get the length from the frame.
3628 __ mov(ecx, Operand(esp, 1 * kPointerSize)); 3628 __ mov(ecx, Operand(esp, 1 * kPointerSize));
3629 __ jmp(&try_allocate); 3629 __ jmp(&try_allocate);
3630 3630
3631 // Patch the arguments.length and the parameters pointer. 3631 // Patch the arguments.length and the parameters pointer.
3632 __ bind(&adaptor_frame); 3632 __ bind(&adaptor_frame);
3633 __ mov(ecx, Operand(edx, ArgumentsAdaptorFrameConstants::kLengthOffset)); 3633 __ mov(ecx, Operand(edx, ArgumentsAdaptorFrameConstants::kLengthOffset));
3634 __ mov(Operand(esp, 1 * kPointerSize), ecx); 3634 __ mov(Operand(esp, 1 * kPointerSize), ecx);
3635 __ lea(edx, Operand(edx, ecx, times_2, kDisplacement)); 3635 __ lea(edx, Operand(edx, ecx, times_2, kDisplacement));
3636 __ mov(Operand(esp, 2 * kPointerSize), edx); 3636 __ mov(Operand(esp, 2 * kPointerSize), edx);
3637 3637
3638 // Try the new space allocation. Start out with computing the size of 3638 // Try the new space allocation. Start out with computing the size of
3639 // the arguments object and the elements array. 3639 // the arguments object and the elements array.
3640 NearLabel add_arguments_object; 3640 NearLabel add_arguments_object;
3641 __ bind(&try_allocate); 3641 __ bind(&try_allocate);
3642 __ test(ecx, Operand(ecx)); 3642 if (type_ == NEW_NON_STRICT) {
3643 __ j(zero, &add_arguments_object); 3643 __ TailCallRuntime(Runtime::kNewArgumentsFast, 3, 1);
3644 __ lea(ecx, Operand(ecx, times_2, FixedArray::kHeaderSize)); 3644 } else {
3645 __ bind(&add_arguments_object); 3645 __ test(ecx, Operand(ecx));
3646 __ add(Operand(ecx), Immediate(GetArgumentsObjectSize())); 3646 __ j(zero, &add_arguments_object);
3647 __ lea(ecx, Operand(ecx, times_2, FixedArray::kHeaderSize));
3648 __ bind(&add_arguments_object);
3649 __ add(Operand(ecx), Immediate(GetArgumentsObjectSize()));
3647 3650
3648 // Do the allocation of both objects in one go. 3651 // Do the allocation of both objects in one go.
3649 __ AllocateInNewSpace(ecx, eax, edx, ebx, &runtime, TAG_OBJECT); 3652 __ AllocateInNewSpace(ecx, eax, edx, ebx, &runtime, TAG_OBJECT);
3650 3653
3651 // Get the arguments boilerplate from the current (global) context. 3654 // Get the arguments boilerplate from the current (global) context.
3652 __ mov(edi, Operand(esi, Context::SlotOffset(Context::GLOBAL_INDEX))); 3655 __ mov(edi, Operand(esi, Context::SlotOffset(Context::GLOBAL_INDEX)));
3653 __ mov(edi, FieldOperand(edi, GlobalObject::kGlobalContextOffset)); 3656 __ mov(edi, FieldOperand(edi, GlobalObject::kGlobalContextOffset));
3654 __ mov(edi, Operand(edi, 3657 __ mov(edi, Operand(edi,
3655 Context::SlotOffset(GetArgumentsBoilerplateIndex()))); 3658 Context::SlotOffset(GetArgumentsBoilerplateIndex())));
3656 3659
3657 // Copy the JS object part. 3660 // Copy the JS object part.
3658 for (int i = 0; i < JSObject::kHeaderSize; i += kPointerSize) { 3661 for (int i = 0; i < JSObject::kHeaderSize; i += kPointerSize) {
3659 __ mov(ebx, FieldOperand(edi, i)); 3662 __ mov(ebx, FieldOperand(edi, i));
3660 __ mov(FieldOperand(eax, i), ebx); 3663 __ mov(FieldOperand(eax, i), ebx);
3664 }
3665
3666 if (type_ == NEW_NON_STRICT) {
3667 // Setup the callee in-object property.
3668 STATIC_ASSERT(Heap::kArgumentsCalleeIndex == 1);
3669 __ mov(ebx, Operand(esp, 3 * kPointerSize));
3670 __ mov(FieldOperand(eax, JSObject::kHeaderSize +
3671 Heap::kArgumentsCalleeIndex * kPointerSize),
3672 ebx);
3673 }
3674
3675 // Get the length (smi tagged) and set that as an in-object property too.
3676 STATIC_ASSERT(Heap::kArgumentsLengthIndex == 0);
3677 __ mov(ecx, Operand(esp, 1 * kPointerSize));
3678 __ mov(FieldOperand(eax, JSObject::kHeaderSize +
3679 Heap::kArgumentsLengthIndex * kPointerSize),
3680 ecx);
3681
3682 // If there are no actual arguments, we're done.
3683 Label done;
3684 __ test(ecx, Operand(ecx));
3685 __ j(zero, &done);
3686
3687 // Get the parameters pointer from the stack.
3688 __ mov(edx, Operand(esp, 2 * kPointerSize));
3689
3690 // Setup the elements pointer in the allocated arguments object and
3691 // initialize the header in the elements fixed array.
3692 __ lea(edi, Operand(eax, GetArgumentsObjectSize()));
3693 __ mov(FieldOperand(eax, JSObject::kElementsOffset), edi);
3694 __ mov(FieldOperand(edi, FixedArray::kMapOffset),
3695 Immediate(FACTORY->fixed_array_map()));
3696
3697 __ mov(FieldOperand(edi, FixedArray::kLengthOffset), ecx);
3698 // Untag the length for the loop below.
3699 __ SmiUntag(ecx);
3700
3701 // Copy the fixed array slots.
3702 NearLabel loop;
3703 __ bind(&loop);
3704 __ mov(ebx, Operand(edx, -1 * kPointerSize)); // Skip receiver.
3705 __ mov(FieldOperand(edi, FixedArray::kHeaderSize), ebx);
3706 __ add(Operand(edi), Immediate(kPointerSize));
3707 __ sub(Operand(edx), Immediate(kPointerSize));
3708 __ dec(ecx);
3709 __ j(not_zero, &loop);
3710
3711 // Return and remove the on-stack parameters.
3712 __ bind(&done);
3713 __ ret(3 * kPointerSize);
3714
3715 // Do the runtime call to allocate the arguments object.
3716 __ bind(&runtime);
3717 __ TailCallRuntime(Runtime::kNewStrictArgumentsFast, 3, 1);
3661 } 3718 }
3662
3663 if (type_ == NEW_NON_STRICT) {
3664 // Setup the callee in-object property.
3665 STATIC_ASSERT(Heap::kArgumentsCalleeIndex == 1);
3666 __ mov(ebx, Operand(esp, 3 * kPointerSize));
3667 __ mov(FieldOperand(eax, JSObject::kHeaderSize +
3668 Heap::kArgumentsCalleeIndex * kPointerSize),
3669 ebx);
3670 }
3671
3672 // Get the length (smi tagged) and set that as an in-object property too.
3673 STATIC_ASSERT(Heap::kArgumentsLengthIndex == 0);
3674 __ mov(ecx, Operand(esp, 1 * kPointerSize));
3675 __ mov(FieldOperand(eax, JSObject::kHeaderSize +
3676 Heap::kArgumentsLengthIndex * kPointerSize),
3677 ecx);
3678
3679 // If there are no actual arguments, we're done.
3680 Label done;
3681 __ test(ecx, Operand(ecx));
3682 __ j(zero, &done);
3683
3684 // Get the parameters pointer from the stack.
3685 __ mov(edx, Operand(esp, 2 * kPointerSize));
3686
3687 // Setup the elements pointer in the allocated arguments object and
3688 // initialize the header in the elements fixed array.
3689 __ lea(edi, Operand(eax, GetArgumentsObjectSize()));
3690 __ mov(FieldOperand(eax, JSObject::kElementsOffset), edi);
3691 __ mov(FieldOperand(edi, FixedArray::kMapOffset),
3692 Immediate(FACTORY->fixed_array_map()));
3693
3694 __ mov(FieldOperand(edi, FixedArray::kLengthOffset), ecx);
3695 // Untag the length for the loop below.
3696 __ SmiUntag(ecx);
3697
3698 // Copy the fixed array slots.
3699 NearLabel loop;
3700 __ bind(&loop);
3701 __ mov(ebx, Operand(edx, -1 * kPointerSize)); // Skip receiver.
3702 __ mov(FieldOperand(edi, FixedArray::kHeaderSize), ebx);
3703 __ add(Operand(edi), Immediate(kPointerSize));
3704 __ sub(Operand(edx), Immediate(kPointerSize));
3705 __ dec(ecx);
3706 __ j(not_zero, &loop);
3707
3708 // Return and remove the on-stack parameters.
3709 __ bind(&done);
3710 __ ret(3 * kPointerSize);
3711
3712 // Do the runtime call to allocate the arguments object.
3713 __ bind(&runtime);
3714 __ TailCallRuntime(Runtime::kNewArgumentsFast, 3, 1);
3715 } 3719 }
3716 3720
3717 3721
3718 void RegExpExecStub::Generate(MacroAssembler* masm) { 3722 void RegExpExecStub::Generate(MacroAssembler* masm) {
3719 // Just jump directly to runtime if native RegExp is not selected at compile 3723 // Just jump directly to runtime if native RegExp is not selected at compile
3720 // time or if regexp entry in generated code is turned off runtime switch or 3724 // time or if regexp entry in generated code is turned off runtime switch or
3721 // at compilation. 3725 // at compilation.
3722 #ifdef V8_INTERPRETED_REGEXP 3726 #ifdef V8_INTERPRETED_REGEXP
3723 __ TailCallRuntime(Runtime::kRegExpExec, 4, 1); 3727 __ TailCallRuntime(Runtime::kRegExpExec, 4, 1);
3724 #else // V8_INTERPRETED_REGEXP 3728 #else // V8_INTERPRETED_REGEXP
(...skipping 2754 matching lines...) Expand 10 before | Expand all | Expand 10 after
6479 // Do a tail call to the rewritten stub. 6483 // Do a tail call to the rewritten stub.
6480 __ jmp(Operand(edi)); 6484 __ jmp(Operand(edi));
6481 } 6485 }
6482 6486
6483 6487
6484 #undef __ 6488 #undef __
6485 6489
6486 } } // namespace v8::internal 6490 } } // namespace v8::internal
6487 6491
6488 #endif // V8_TARGET_ARCH_IA32 6492 #endif // V8_TARGET_ARCH_IA32
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698