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

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

Issue 1706703002: X87: [runtime] Introduce FastNewStrictArgumentsStub to optimize strict arguments. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 4 years, 10 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
« no previous file with comments | « src/x87/builtins-x87.cc ('k') | src/x87/interface-descriptors-x87.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #if V8_TARGET_ARCH_X87 5 #if V8_TARGET_ARCH_X87
6 6
7 #include "src/base/bits.h" 7 #include "src/base/bits.h"
8 #include "src/bootstrapper.h" 8 #include "src/bootstrapper.h"
9 #include "src/code-stubs.h" 9 #include "src/code-stubs.h"
10 #include "src/codegen.h" 10 #include "src/codegen.h"
(...skipping 500 matching lines...) Expand 10 before | Expand all | Expand 10 after
511 Label no_parameter_map; 511 Label no_parameter_map;
512 __ test(ebx, ebx); 512 __ test(ebx, ebx);
513 __ j(zero, &no_parameter_map, Label::kNear); 513 __ j(zero, &no_parameter_map, Label::kNear);
514 __ lea(ebx, Operand(ebx, times_2, kParameterMapHeaderSize)); 514 __ lea(ebx, Operand(ebx, times_2, kParameterMapHeaderSize));
515 __ bind(&no_parameter_map); 515 __ bind(&no_parameter_map);
516 516
517 // 2. Backing store. 517 // 2. Backing store.
518 __ lea(ebx, Operand(ebx, ecx, times_2, FixedArray::kHeaderSize)); 518 __ lea(ebx, Operand(ebx, ecx, times_2, FixedArray::kHeaderSize));
519 519
520 // 3. Arguments object. 520 // 3. Arguments object.
521 __ add(ebx, Immediate(Heap::kSloppyArgumentsObjectSize)); 521 __ add(ebx, Immediate(JSSloppyArgumentsObject::kSize));
522 522
523 // Do the allocation of all three objects in one go. 523 // Do the allocation of all three objects in one go.
524 __ Allocate(ebx, eax, edi, no_reg, &runtime, TAG_OBJECT); 524 __ Allocate(ebx, eax, edi, no_reg, &runtime, TAG_OBJECT);
525 525
526 // eax = address of new object(s) (tagged) 526 // eax = address of new object(s) (tagged)
527 // ecx = argument count (smi-tagged) 527 // ecx = argument count (smi-tagged)
528 // esp[0] = mapped parameter count (tagged) 528 // esp[0] = mapped parameter count (tagged)
529 // esp[4] = function 529 // esp[4] = function
530 // esp[8] = parameter count (tagged) 530 // esp[8] = parameter count (tagged)
531 // Get the arguments map from the current native context into edi. 531 // Get the arguments map from the current native context into edi.
(...skipping 20 matching lines...) Expand all
552 // esp[4] = function 552 // esp[4] = function
553 // esp[8] = parameter count (tagged) 553 // esp[8] = parameter count (tagged)
554 // Copy the JS object part. 554 // Copy the JS object part.
555 __ mov(FieldOperand(eax, JSObject::kMapOffset), edi); 555 __ mov(FieldOperand(eax, JSObject::kMapOffset), edi);
556 __ mov(FieldOperand(eax, JSObject::kPropertiesOffset), 556 __ mov(FieldOperand(eax, JSObject::kPropertiesOffset),
557 masm->isolate()->factory()->empty_fixed_array()); 557 masm->isolate()->factory()->empty_fixed_array());
558 __ mov(FieldOperand(eax, JSObject::kElementsOffset), 558 __ mov(FieldOperand(eax, JSObject::kElementsOffset),
559 masm->isolate()->factory()->empty_fixed_array()); 559 masm->isolate()->factory()->empty_fixed_array());
560 560
561 // Set up the callee in-object property. 561 // Set up the callee in-object property.
562 STATIC_ASSERT(Heap::kArgumentsCalleeIndex == 1); 562 STATIC_ASSERT(JSSloppyArgumentsObject::kCalleeIndex == 1);
563 __ mov(edi, Operand(esp, 1 * kPointerSize)); 563 __ mov(edi, Operand(esp, 1 * kPointerSize));
564 __ AssertNotSmi(edi); 564 __ AssertNotSmi(edi);
565 __ mov(FieldOperand(eax, JSObject::kHeaderSize + 565 __ mov(FieldOperand(eax, JSSloppyArgumentsObject::kCalleeOffset), edi);
566 Heap::kArgumentsCalleeIndex * kPointerSize),
567 edi);
568 566
569 // Use the length (smi tagged) and set that as an in-object property too. 567 // Use the length (smi tagged) and set that as an in-object property too.
570 __ AssertSmi(ecx); 568 __ AssertSmi(ecx);
571 STATIC_ASSERT(Heap::kArgumentsLengthIndex == 0); 569 __ mov(FieldOperand(eax, JSSloppyArgumentsObject::kLengthOffset), ecx);
572 __ mov(FieldOperand(eax, JSObject::kHeaderSize +
573 Heap::kArgumentsLengthIndex * kPointerSize),
574 ecx);
575 570
576 // Set up the elements pointer in the allocated arguments object. 571 // Set up the elements pointer in the allocated arguments object.
577 // If we allocated a parameter map, edi will point there, otherwise to the 572 // If we allocated a parameter map, edi will point there, otherwise to the
578 // backing store. 573 // backing store.
579 __ lea(edi, Operand(eax, Heap::kSloppyArgumentsObjectSize)); 574 __ lea(edi, Operand(eax, JSSloppyArgumentsObject::kSize));
580 __ mov(FieldOperand(eax, JSObject::kElementsOffset), edi); 575 __ mov(FieldOperand(eax, JSObject::kElementsOffset), edi);
581 576
582 // eax = address of new object (tagged) 577 // eax = address of new object (tagged)
583 // ebx = mapped parameter count (tagged) 578 // ebx = mapped parameter count (tagged)
584 // ecx = argument count (tagged) 579 // ecx = argument count (tagged)
585 // edx = address of receiver argument 580 // edx = address of receiver argument
586 // edi = address of parameter map or backing store (tagged) 581 // edi = address of parameter map or backing store (tagged)
587 // esp[0] = mapped parameter count (tagged) 582 // esp[0] = mapped parameter count (tagged)
588 // esp[4] = function 583 // esp[4] = function
589 // esp[8] = parameter count (tagged) 584 // esp[8] = parameter count (tagged)
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
689 __ pop(eax); // Remove saved parameter count. 684 __ pop(eax); // Remove saved parameter count.
690 __ pop(eax); // Pop return address. 685 __ pop(eax); // Pop return address.
691 __ push(edi); // Push function. 686 __ push(edi); // Push function.
692 __ push(edx); // Push parameters pointer. 687 __ push(edx); // Push parameters pointer.
693 __ push(ecx); // Push parameter count. 688 __ push(ecx); // Push parameter count.
694 __ push(eax); // Push return address. 689 __ push(eax); // Push return address.
695 __ TailCallRuntime(Runtime::kNewSloppyArguments); 690 __ TailCallRuntime(Runtime::kNewSloppyArguments);
696 } 691 }
697 692
698 693
699 void ArgumentsAccessStub::GenerateNewStrict(MacroAssembler* masm) {
700 // ecx : number of parameters (tagged)
701 // edx : parameters pointer
702 // edi : function
703 // esp[0] : return address
704
705 DCHECK(edi.is(ArgumentsAccessNewDescriptor::function()));
706 DCHECK(ecx.is(ArgumentsAccessNewDescriptor::parameter_count()));
707 DCHECK(edx.is(ArgumentsAccessNewDescriptor::parameter_pointer()));
708
709 // Check if the calling frame is an arguments adaptor frame.
710 Label try_allocate, runtime;
711 __ mov(ebx, Operand(ebp, StandardFrameConstants::kCallerFPOffset));
712 __ mov(eax, Operand(ebx, StandardFrameConstants::kContextOffset));
713 __ cmp(eax, Immediate(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)));
714 __ j(not_equal, &try_allocate, Label::kNear);
715
716 // Patch the arguments.length and the parameters pointer.
717 __ mov(ecx, Operand(ebx, ArgumentsAdaptorFrameConstants::kLengthOffset));
718 __ lea(edx,
719 Operand(ebx, ecx, times_2, StandardFrameConstants::kCallerSPOffset));
720
721 // Try the new space allocation. Start out with computing the size of
722 // the arguments object and the elements array.
723 Label add_arguments_object;
724 __ bind(&try_allocate);
725 __ mov(eax, ecx);
726 __ test(eax, eax);
727 __ j(zero, &add_arguments_object, Label::kNear);
728 __ lea(eax, Operand(eax, times_2, FixedArray::kHeaderSize));
729 __ bind(&add_arguments_object);
730 __ add(eax, Immediate(Heap::kStrictArgumentsObjectSize));
731
732 // Do the allocation of both objects in one go.
733 __ Allocate(eax, eax, ebx, no_reg, &runtime, TAG_OBJECT);
734
735 // Get the arguments map from the current native context.
736 __ mov(edi, NativeContextOperand());
737 __ mov(edi, ContextOperand(edi, Context::STRICT_ARGUMENTS_MAP_INDEX));
738
739 __ mov(FieldOperand(eax, JSObject::kMapOffset), edi);
740 __ mov(FieldOperand(eax, JSObject::kPropertiesOffset),
741 masm->isolate()->factory()->empty_fixed_array());
742 __ mov(FieldOperand(eax, JSObject::kElementsOffset),
743 masm->isolate()->factory()->empty_fixed_array());
744
745 // Get the length (smi tagged) and set that as an in-object property too.
746 STATIC_ASSERT(Heap::kArgumentsLengthIndex == 0);
747 __ AssertSmi(ecx);
748 __ mov(FieldOperand(eax, JSObject::kHeaderSize +
749 Heap::kArgumentsLengthIndex * kPointerSize),
750 ecx);
751
752 // If there are no actual arguments, we're done.
753 Label done;
754 __ test(ecx, ecx);
755 __ j(zero, &done, Label::kNear);
756
757 // Set up the elements pointer in the allocated arguments object and
758 // initialize the header in the elements fixed array.
759 __ lea(edi, Operand(eax, Heap::kStrictArgumentsObjectSize));
760 __ mov(FieldOperand(eax, JSObject::kElementsOffset), edi);
761 __ mov(FieldOperand(edi, FixedArray::kMapOffset),
762 Immediate(isolate()->factory()->fixed_array_map()));
763 __ mov(FieldOperand(edi, FixedArray::kLengthOffset), ecx);
764
765 // Untag the length for the loop below.
766 __ SmiUntag(ecx);
767
768 // Copy the fixed array slots.
769 Label loop;
770 __ bind(&loop);
771 __ mov(ebx, Operand(edx, -1 * kPointerSize)); // Skip receiver.
772 __ mov(FieldOperand(edi, FixedArray::kHeaderSize), ebx);
773 __ add(edi, Immediate(kPointerSize));
774 __ sub(edx, Immediate(kPointerSize));
775 __ dec(ecx);
776 __ j(not_zero, &loop);
777
778 // Return.
779 __ bind(&done);
780 __ ret(0);
781
782 // Do the runtime call to allocate the arguments object.
783 __ bind(&runtime);
784 __ pop(eax); // Pop return address.
785 __ push(edi); // Push function.
786 __ push(edx); // Push parameters pointer.
787 __ push(ecx); // Push parameter count.
788 __ push(eax); // Push return address.
789 __ TailCallRuntime(Runtime::kNewStrictArguments);
790 }
791
792
793 void RegExpExecStub::Generate(MacroAssembler* masm) { 694 void RegExpExecStub::Generate(MacroAssembler* masm) {
794 // Just jump directly to runtime if native RegExp is not selected at compile 695 // Just jump directly to runtime if native RegExp is not selected at compile
795 // time or if regexp entry in generated code is turned off runtime switch or 696 // time or if regexp entry in generated code is turned off runtime switch or
796 // at compilation. 697 // at compilation.
797 #ifdef V8_INTERPRETED_REGEXP 698 #ifdef V8_INTERPRETED_REGEXP
798 __ TailCallRuntime(Runtime::kRegExpExec); 699 __ TailCallRuntime(Runtime::kRegExpExec);
799 #else // V8_INTERPRETED_REGEXP 700 #else // V8_INTERPRETED_REGEXP
800 701
801 // Stack frame on entry. 702 // Stack frame on entry.
802 // esp[0]: return address 703 // esp[0]: return address
(...skipping 4107 matching lines...) Expand 10 before | Expand all | Expand 10 after
4910 __ Push(ecx); 4811 __ Push(ecx);
4911 __ CallRuntime(Runtime::kAllocateInNewSpace); 4812 __ CallRuntime(Runtime::kAllocateInNewSpace);
4912 __ mov(edx, eax); 4813 __ mov(edx, eax);
4913 __ Pop(ebx); 4814 __ Pop(ebx);
4914 __ Pop(eax); 4815 __ Pop(eax);
4915 } 4816 }
4916 __ jmp(&done_allocate); 4817 __ jmp(&done_allocate);
4917 } 4818 }
4918 } 4819 }
4919 4820
4821 void FastNewStrictArgumentsStub::Generate(MacroAssembler* masm) {
4822 // ----------- S t a t e -------------
4823 // -- edi : function
4824 // -- esi : context
4825 // -- ebp : frame pointer
4826 // -- esp[0] : return address
4827 // -----------------------------------
4828 __ AssertFunction(edi);
4829
4830 // For Ignition we need to skip all possible handler/stub frames until
4831 // we reach the JavaScript frame for the function (similar to what the
4832 // runtime fallback implementation does). So make edx point to that
4833 // JavaScript frame.
4834 {
4835 Label loop, loop_entry;
4836 __ mov(edx, ebp);
4837 __ jmp(&loop_entry, Label::kNear);
4838 __ bind(&loop);
4839 __ mov(edx, Operand(edx, StandardFrameConstants::kCallerFPOffset));
4840 __ bind(&loop_entry);
4841 __ cmp(edi, Operand(edx, StandardFrameConstants::kMarkerOffset));
4842 __ j(not_equal, &loop);
4843 }
4844
4845 // Check if we have an arguments adaptor frame below the function frame.
4846 Label arguments_adaptor, arguments_done;
4847 __ mov(ebx, Operand(edx, StandardFrameConstants::kCallerFPOffset));
4848 __ cmp(Operand(ebx, StandardFrameConstants::kContextOffset),
4849 Immediate(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)));
4850 __ j(equal, &arguments_adaptor, Label::kNear);
4851 {
4852 __ mov(eax, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset));
4853 __ mov(eax,
4854 FieldOperand(eax, SharedFunctionInfo::kFormalParameterCountOffset));
4855 __ lea(ebx,
4856 Operand(edx, eax, times_half_pointer_size,
4857 StandardFrameConstants::kCallerSPOffset - 1 * kPointerSize));
4858 }
4859 __ jmp(&arguments_done, Label::kNear);
4860 __ bind(&arguments_adaptor);
4861 {
4862 __ mov(eax, Operand(ebx, ArgumentsAdaptorFrameConstants::kLengthOffset));
4863 __ lea(ebx,
4864 Operand(ebx, eax, times_half_pointer_size,
4865 StandardFrameConstants::kCallerSPOffset - 1 * kPointerSize));
4866 }
4867 __ bind(&arguments_done);
4868
4869 // ----------- S t a t e -------------
4870 // -- eax : number of arguments (tagged)
4871 // -- ebx : pointer to the first argument
4872 // -- esi : context
4873 // -- esp[0] : return address
4874 // -----------------------------------
4875
4876 // Allocate space for the strict arguments object plus the backing store.
4877 Label allocate, done_allocate;
4878 __ lea(ecx,
4879 Operand(eax, times_half_pointer_size,
4880 JSStrictArgumentsObject::kSize + FixedArray::kHeaderSize));
4881 __ Allocate(ecx, edx, edi, no_reg, &allocate, TAG_OBJECT);
4882 __ bind(&done_allocate);
4883
4884 // Setup the elements array in edx.
4885 __ mov(FieldOperand(edx, FixedArray::kMapOffset),
4886 isolate()->factory()->fixed_array_map());
4887 __ mov(FieldOperand(edx, FixedArray::kLengthOffset), eax);
4888 {
4889 Label loop, done_loop;
4890 __ Move(ecx, Smi::FromInt(0));
4891 __ bind(&loop);
4892 __ cmp(ecx, eax);
4893 __ j(equal, &done_loop, Label::kNear);
4894 __ mov(edi, Operand(ebx, 0 * kPointerSize));
4895 __ mov(FieldOperand(edx, ecx, times_half_pointer_size,
4896 FixedArray::kHeaderSize),
4897 edi);
4898 __ sub(ebx, Immediate(1 * kPointerSize));
4899 __ add(ecx, Immediate(Smi::FromInt(1)));
4900 __ jmp(&loop);
4901 __ bind(&done_loop);
4902 }
4903
4904 // Setup the rest parameter array in edi.
4905 __ lea(edi,
4906 Operand(edx, eax, times_half_pointer_size, FixedArray::kHeaderSize));
4907 __ LoadGlobalFunction(Context::STRICT_ARGUMENTS_MAP_INDEX, ecx);
4908 __ mov(FieldOperand(edi, JSStrictArgumentsObject::kMapOffset), ecx);
4909 __ mov(FieldOperand(edi, JSStrictArgumentsObject::kPropertiesOffset),
4910 isolate()->factory()->empty_fixed_array());
4911 __ mov(FieldOperand(edi, JSStrictArgumentsObject::kElementsOffset), edx);
4912 __ mov(FieldOperand(edi, JSStrictArgumentsObject::kLengthOffset), eax);
4913 STATIC_ASSERT(JSStrictArgumentsObject::kSize == 4 * kPointerSize);
4914 __ mov(eax, edi);
4915 __ Ret();
4916
4917 // Fall back to %AllocateInNewSpace.
4918 __ bind(&allocate);
4919 {
4920 FrameScope scope(masm, StackFrame::INTERNAL);
4921 __ SmiTag(ecx);
4922 __ Push(eax);
4923 __ Push(ebx);
4924 __ Push(ecx);
4925 __ CallRuntime(Runtime::kAllocateInNewSpace);
4926 __ mov(edx, eax);
4927 __ Pop(ebx);
4928 __ Pop(eax);
4929 }
4930 __ jmp(&done_allocate);
4931 }
4932
4920 void LoadGlobalViaContextStub::Generate(MacroAssembler* masm) { 4933 void LoadGlobalViaContextStub::Generate(MacroAssembler* masm) {
4921 Register context_reg = esi; 4934 Register context_reg = esi;
4922 Register slot_reg = ebx; 4935 Register slot_reg = ebx;
4923 Register result_reg = eax; 4936 Register result_reg = eax;
4924 Label slow_case; 4937 Label slow_case;
4925 4938
4926 // Go up context chain to the script context. 4939 // Go up context chain to the script context.
4927 for (int i = 0; i < depth(); ++i) { 4940 for (int i = 0; i < depth(); ++i) {
4928 __ mov(result_reg, ContextOperand(context_reg, Context::PREVIOUS_INDEX)); 4941 __ mov(result_reg, ContextOperand(context_reg, Context::PREVIOUS_INDEX));
4929 context_reg = result_reg; 4942 context_reg = result_reg;
(...skipping 538 matching lines...) Expand 10 before | Expand all | Expand 10 after
5468 return_value_operand, NULL); 5481 return_value_operand, NULL);
5469 } 5482 }
5470 5483
5471 5484
5472 #undef __ 5485 #undef __
5473 5486
5474 } // namespace internal 5487 } // namespace internal
5475 } // namespace v8 5488 } // namespace v8
5476 5489
5477 #endif // V8_TARGET_ARCH_X87 5490 #endif // V8_TARGET_ARCH_X87
OLDNEW
« no previous file with comments | « src/x87/builtins-x87.cc ('k') | src/x87/interface-descriptors-x87.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698