| OLD | NEW | 
|---|
| 1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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_X64 | 5 #if V8_TARGET_ARCH_X64 | 
| 6 | 6 | 
| 7 #include "src/bootstrapper.h" | 7 #include "src/bootstrapper.h" | 
| 8 #include "src/code-stubs.h" | 8 #include "src/code-stubs.h" | 
| 9 #include "src/codegen.h" | 9 #include "src/codegen.h" | 
| 10 #include "src/ic/handler-compiler.h" | 10 #include "src/ic/handler-compiler.h" | 
| (...skipping 578 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 589   // by calling the runtime system. | 589   // by calling the runtime system. | 
| 590   __ bind(&slow); | 590   __ bind(&slow); | 
| 591   __ PopReturnAddressTo(rbx); | 591   __ PopReturnAddressTo(rbx); | 
| 592   __ Push(rdx); | 592   __ Push(rdx); | 
| 593   __ PushReturnAddressFrom(rbx); | 593   __ PushReturnAddressFrom(rbx); | 
| 594   __ TailCallRuntime(Runtime::kArguments, 1, 1); | 594   __ TailCallRuntime(Runtime::kArguments, 1, 1); | 
| 595 } | 595 } | 
| 596 | 596 | 
| 597 | 597 | 
| 598 void ArgumentsAccessStub::GenerateNewSloppyFast(MacroAssembler* masm) { | 598 void ArgumentsAccessStub::GenerateNewSloppyFast(MacroAssembler* masm) { | 
| 599   // Stack layout: | 599   // rcx : number of parameters (tagged) | 
| 600   //  rsp[0]  : return address | 600   // rdx : parameters pointer | 
| 601   //  rsp[8]  : number of parameters (tagged) | 601   // rdi : function | 
| 602   //  rsp[16] : receiver displacement | 602   // rsp[0] : return address | 
| 603   //  rsp[24] : function |  | 
| 604   // Registers used over the whole function: | 603   // Registers used over the whole function: | 
| 605   //  rbx: the mapped parameter count (untagged) | 604   //  rbx: the mapped parameter count (untagged) | 
| 606   //  rax: the allocated object (tagged). | 605   //  rax: the allocated object (tagged). | 
| 607   Factory* factory = isolate()->factory(); | 606   Factory* factory = isolate()->factory(); | 
| 608 | 607 | 
| 609   StackArgumentsAccessor args(rsp, 3, ARGUMENTS_DONT_CONTAIN_RECEIVER); | 608   DCHECK(rdi.is(ArgumentsAccessNewDescriptor::function())); | 
| 610   __ SmiToInteger64(rbx, args.GetArgumentOperand(2)); | 609   DCHECK(rcx.is(ArgumentsAccessNewDescriptor::parameter_count())); | 
|  | 610   DCHECK(rdx.is(ArgumentsAccessNewDescriptor::parameter_pointer())); | 
|  | 611 | 
|  | 612   __ SmiToInteger64(rbx, rcx); | 
| 611   // rbx = parameter count (untagged) | 613   // rbx = parameter count (untagged) | 
| 612 | 614 | 
| 613   // Check if the calling frame is an arguments adaptor frame. | 615   // Check if the calling frame is an arguments adaptor frame. | 
| 614   Label runtime; | 616   Label adaptor_frame, try_allocate, runtime; | 
| 615   Label adaptor_frame, try_allocate; | 617   __ movp(rax, Operand(rbp, StandardFrameConstants::kCallerFPOffset)); | 
| 616   __ movp(rdx, Operand(rbp, StandardFrameConstants::kCallerFPOffset)); | 618   __ movp(r8, Operand(rax, StandardFrameConstants::kContextOffset)); | 
| 617   __ movp(rcx, Operand(rdx, StandardFrameConstants::kContextOffset)); | 619   __ Cmp(r8, Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)); | 
| 618   __ Cmp(rcx, Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)); |  | 
| 619   __ j(equal, &adaptor_frame); | 620   __ j(equal, &adaptor_frame); | 
| 620 | 621 | 
| 621   // No adaptor, parameter count = argument count. | 622   // No adaptor, parameter count = argument count. | 
| 622   __ movp(rcx, rbx); | 623   __ movp(r11, rbx); | 
| 623   __ jmp(&try_allocate, Label::kNear); | 624   __ jmp(&try_allocate, Label::kNear); | 
| 624 | 625 | 
| 625   // We have an adaptor frame. Patch the parameters pointer. | 626   // We have an adaptor frame. Patch the parameters pointer. | 
| 626   __ bind(&adaptor_frame); | 627   __ bind(&adaptor_frame); | 
| 627   __ SmiToInteger64(rcx, | 628   __ SmiToInteger64( | 
| 628                     Operand(rdx, | 629       r11, Operand(rax, ArgumentsAdaptorFrameConstants::kLengthOffset)); | 
| 629                             ArgumentsAdaptorFrameConstants::kLengthOffset)); | 630   __ leap(rdx, Operand(rax, r11, times_pointer_size, | 
| 630   __ leap(rdx, Operand(rdx, rcx, times_pointer_size, | 631                        StandardFrameConstants::kCallerSPOffset)); | 
| 631                       StandardFrameConstants::kCallerSPOffset)); |  | 
| 632   __ movp(args.GetArgumentOperand(1), rdx); |  | 
| 633 | 632 | 
| 634   // rbx = parameter count (untagged) | 633   // rbx = parameter count (untagged) | 
| 635   // rcx = argument count (untagged) | 634   // r11 = argument count (untagged) | 
| 636   // Compute the mapped parameter count = min(rbx, rcx) in rbx. | 635   // Compute the mapped parameter count = min(rbx, r11) in rbx. | 
| 637   __ cmpp(rbx, rcx); | 636   __ cmpp(rbx, r11); | 
| 638   __ j(less_equal, &try_allocate, Label::kNear); | 637   __ j(less_equal, &try_allocate, Label::kNear); | 
| 639   __ movp(rbx, rcx); | 638   __ movp(rbx, r11); | 
| 640 | 639 | 
| 641   __ bind(&try_allocate); | 640   __ bind(&try_allocate); | 
| 642 | 641 | 
| 643   // Compute the sizes of backing store, parameter map, and arguments object. | 642   // Compute the sizes of backing store, parameter map, and arguments object. | 
| 644   // 1. Parameter map, has 2 extra words containing context and backing store. | 643   // 1. Parameter map, has 2 extra words containing context and backing store. | 
| 645   const int kParameterMapHeaderSize = | 644   const int kParameterMapHeaderSize = | 
| 646       FixedArray::kHeaderSize + 2 * kPointerSize; | 645       FixedArray::kHeaderSize + 2 * kPointerSize; | 
| 647   Label no_parameter_map; | 646   Label no_parameter_map; | 
| 648   __ xorp(r8, r8); | 647   __ xorp(r8, r8); | 
| 649   __ testp(rbx, rbx); | 648   __ testp(rbx, rbx); | 
| 650   __ j(zero, &no_parameter_map, Label::kNear); | 649   __ j(zero, &no_parameter_map, Label::kNear); | 
| 651   __ leap(r8, Operand(rbx, times_pointer_size, kParameterMapHeaderSize)); | 650   __ leap(r8, Operand(rbx, times_pointer_size, kParameterMapHeaderSize)); | 
| 652   __ bind(&no_parameter_map); | 651   __ bind(&no_parameter_map); | 
| 653 | 652 | 
| 654   // 2. Backing store. | 653   // 2. Backing store. | 
| 655   __ leap(r8, Operand(r8, rcx, times_pointer_size, FixedArray::kHeaderSize)); | 654   __ leap(r8, Operand(r8, r11, times_pointer_size, FixedArray::kHeaderSize)); | 
| 656 | 655 | 
| 657   // 3. Arguments object. | 656   // 3. Arguments object. | 
| 658   __ addp(r8, Immediate(Heap::kSloppyArgumentsObjectSize)); | 657   __ addp(r8, Immediate(Heap::kSloppyArgumentsObjectSize)); | 
| 659 | 658 | 
| 660   // Do the allocation of all three objects in one go. | 659   // Do the allocation of all three objects in one go. | 
| 661   __ Allocate(r8, rax, rdx, rdi, &runtime, TAG_OBJECT); | 660   __ Allocate(r8, rax, r9, no_reg, &runtime, TAG_OBJECT); | 
| 662 | 661 | 
| 663   // rax = address of new object(s) (tagged) | 662   // rax = address of new object(s) (tagged) | 
| 664   // rcx = argument count (untagged) | 663   // r11 = argument count (untagged) | 
| 665   // Get the arguments map from the current native context into rdi. | 664   // Get the arguments map from the current native context into r9. | 
| 666   Label has_mapped_parameters, instantiate; | 665   Label has_mapped_parameters, instantiate; | 
| 667   __ movp(rdi, Operand(rsi, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX))); | 666   __ movp(r9, Operand(rsi, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX))); | 
| 668   __ movp(rdi, FieldOperand(rdi, GlobalObject::kNativeContextOffset)); | 667   __ movp(r9, FieldOperand(r9, GlobalObject::kNativeContextOffset)); | 
| 669   __ testp(rbx, rbx); | 668   __ testp(rbx, rbx); | 
| 670   __ j(not_zero, &has_mapped_parameters, Label::kNear); | 669   __ j(not_zero, &has_mapped_parameters, Label::kNear); | 
| 671 | 670 | 
| 672   const int kIndex = Context::SLOPPY_ARGUMENTS_MAP_INDEX; | 671   const int kIndex = Context::SLOPPY_ARGUMENTS_MAP_INDEX; | 
| 673   __ movp(rdi, Operand(rdi, Context::SlotOffset(kIndex))); | 672   __ movp(r9, Operand(r9, Context::SlotOffset(kIndex))); | 
| 674   __ jmp(&instantiate, Label::kNear); | 673   __ jmp(&instantiate, Label::kNear); | 
| 675 | 674 | 
| 676   const int kAliasedIndex = Context::FAST_ALIASED_ARGUMENTS_MAP_INDEX; | 675   const int kAliasedIndex = Context::FAST_ALIASED_ARGUMENTS_MAP_INDEX; | 
| 677   __ bind(&has_mapped_parameters); | 676   __ bind(&has_mapped_parameters); | 
| 678   __ movp(rdi, Operand(rdi, Context::SlotOffset(kAliasedIndex))); | 677   __ movp(r9, Operand(r9, Context::SlotOffset(kAliasedIndex))); | 
| 679   __ bind(&instantiate); | 678   __ bind(&instantiate); | 
| 680 | 679 | 
| 681   // rax = address of new object (tagged) | 680   // rax = address of new object (tagged) | 
| 682   // rbx = mapped parameter count (untagged) | 681   // rbx = mapped parameter count (untagged) | 
| 683   // rcx = argument count (untagged) | 682   // r11 = argument count (untagged) | 
| 684   // rdi = address of arguments map (tagged) | 683   // r9 = address of arguments map (tagged) | 
| 685   __ movp(FieldOperand(rax, JSObject::kMapOffset), rdi); | 684   __ movp(FieldOperand(rax, JSObject::kMapOffset), r9); | 
| 686   __ LoadRoot(kScratchRegister, Heap::kEmptyFixedArrayRootIndex); | 685   __ LoadRoot(kScratchRegister, Heap::kEmptyFixedArrayRootIndex); | 
| 687   __ movp(FieldOperand(rax, JSObject::kPropertiesOffset), kScratchRegister); | 686   __ movp(FieldOperand(rax, JSObject::kPropertiesOffset), kScratchRegister); | 
| 688   __ movp(FieldOperand(rax, JSObject::kElementsOffset), kScratchRegister); | 687   __ movp(FieldOperand(rax, JSObject::kElementsOffset), kScratchRegister); | 
| 689 | 688 | 
| 690   // Set up the callee in-object property. | 689   // Set up the callee in-object property. | 
| 691   STATIC_ASSERT(Heap::kArgumentsCalleeIndex == 1); | 690   STATIC_ASSERT(Heap::kArgumentsCalleeIndex == 1); | 
| 692   __ movp(rdx, args.GetArgumentOperand(0)); | 691   __ AssertNotSmi(rdi); | 
| 693   __ AssertNotSmi(rdx); |  | 
| 694   __ movp(FieldOperand(rax, JSObject::kHeaderSize + | 692   __ movp(FieldOperand(rax, JSObject::kHeaderSize + | 
| 695                        Heap::kArgumentsCalleeIndex * kPointerSize), | 693                                 Heap::kArgumentsCalleeIndex * kPointerSize), | 
| 696           rdx); | 694           rdi); | 
| 697 | 695 | 
| 698   // Use the length (smi tagged) and set that as an in-object property too. | 696   // Use the length (smi tagged) and set that as an in-object property too. | 
| 699   // Note: rcx is tagged from here on. | 697   // Note: r11 is tagged from here on. | 
| 700   STATIC_ASSERT(Heap::kArgumentsLengthIndex == 0); | 698   STATIC_ASSERT(Heap::kArgumentsLengthIndex == 0); | 
| 701   __ Integer32ToSmi(rcx, rcx); | 699   __ Integer32ToSmi(r11, r11); | 
| 702   __ movp(FieldOperand(rax, JSObject::kHeaderSize + | 700   __ movp(FieldOperand(rax, JSObject::kHeaderSize + | 
| 703                        Heap::kArgumentsLengthIndex * kPointerSize), | 701                                 Heap::kArgumentsLengthIndex * kPointerSize), | 
| 704           rcx); | 702           r11); | 
| 705 | 703 | 
| 706   // Set up the elements pointer in the allocated arguments object. | 704   // Set up the elements pointer in the allocated arguments object. | 
| 707   // If we allocated a parameter map, edi will point there, otherwise to the | 705   // If we allocated a parameter map, rdi will point there, otherwise to the | 
| 708   // backing store. | 706   // backing store. | 
| 709   __ leap(rdi, Operand(rax, Heap::kSloppyArgumentsObjectSize)); | 707   __ leap(rdi, Operand(rax, Heap::kSloppyArgumentsObjectSize)); | 
| 710   __ movp(FieldOperand(rax, JSObject::kElementsOffset), rdi); | 708   __ movp(FieldOperand(rax, JSObject::kElementsOffset), rdi); | 
| 711 | 709 | 
| 712   // rax = address of new object (tagged) | 710   // rax = address of new object (tagged) | 
| 713   // rbx = mapped parameter count (untagged) | 711   // rbx = mapped parameter count (untagged) | 
| 714   // rcx = argument count (tagged) | 712   // r11 = argument count (tagged) | 
| 715   // rdi = address of parameter map or backing store (tagged) | 713   // rdi = address of parameter map or backing store (tagged) | 
| 716 | 714 | 
| 717   // Initialize parameter map. If there are no mapped arguments, we're done. | 715   // Initialize parameter map. If there are no mapped arguments, we're done. | 
| 718   Label skip_parameter_map; | 716   Label skip_parameter_map; | 
| 719   __ testp(rbx, rbx); | 717   __ testp(rbx, rbx); | 
| 720   __ j(zero, &skip_parameter_map); | 718   __ j(zero, &skip_parameter_map); | 
| 721 | 719 | 
| 722   __ LoadRoot(kScratchRegister, Heap::kSloppyArgumentsElementsMapRootIndex); | 720   __ LoadRoot(kScratchRegister, Heap::kSloppyArgumentsElementsMapRootIndex); | 
| 723   // rbx contains the untagged argument count. Add 2 and tag to write. | 721   // rbx contains the untagged argument count. Add 2 and tag to write. | 
| 724   __ movp(FieldOperand(rdi, FixedArray::kMapOffset), kScratchRegister); | 722   __ movp(FieldOperand(rdi, FixedArray::kMapOffset), kScratchRegister); | 
| 725   __ Integer64PlusConstantToSmi(r9, rbx, 2); | 723   __ Integer64PlusConstantToSmi(r9, rbx, 2); | 
| 726   __ movp(FieldOperand(rdi, FixedArray::kLengthOffset), r9); | 724   __ movp(FieldOperand(rdi, FixedArray::kLengthOffset), r9); | 
| 727   __ movp(FieldOperand(rdi, FixedArray::kHeaderSize + 0 * kPointerSize), rsi); | 725   __ movp(FieldOperand(rdi, FixedArray::kHeaderSize + 0 * kPointerSize), rsi); | 
| 728   __ leap(r9, Operand(rdi, rbx, times_pointer_size, kParameterMapHeaderSize)); | 726   __ leap(r9, Operand(rdi, rbx, times_pointer_size, kParameterMapHeaderSize)); | 
| 729   __ movp(FieldOperand(rdi, FixedArray::kHeaderSize + 1 * kPointerSize), r9); | 727   __ movp(FieldOperand(rdi, FixedArray::kHeaderSize + 1 * kPointerSize), r9); | 
| 730 | 728 | 
| 731   // Copy the parameter slots and the holes in the arguments. | 729   // Copy the parameter slots and the holes in the arguments. | 
| 732   // We need to fill in mapped_parameter_count slots. They index the context, | 730   // We need to fill in mapped_parameter_count slots. They index the context, | 
| 733   // where parameters are stored in reverse order, at | 731   // where parameters are stored in reverse order, at | 
| 734   //   MIN_CONTEXT_SLOTS .. MIN_CONTEXT_SLOTS+parameter_count-1 | 732   //   MIN_CONTEXT_SLOTS .. MIN_CONTEXT_SLOTS+parameter_count-1 | 
| 735   // The mapped parameter thus need to get indices | 733   // The mapped parameter thus need to get indices | 
| 736   //   MIN_CONTEXT_SLOTS+parameter_count-1 .. | 734   //   MIN_CONTEXT_SLOTS+parameter_count-1 .. | 
| 737   //       MIN_CONTEXT_SLOTS+parameter_count-mapped_parameter_count | 735   //       MIN_CONTEXT_SLOTS+parameter_count-mapped_parameter_count | 
| 738   // We loop from right to left. | 736   // We loop from right to left. | 
| 739   Label parameters_loop, parameters_test; | 737   Label parameters_loop, parameters_test; | 
| 740 | 738 | 
| 741   // Load tagged parameter count into r9. | 739   // Load tagged parameter count into r9. | 
| 742   __ Integer32ToSmi(r9, rbx); | 740   __ Integer32ToSmi(r9, rbx); | 
| 743   __ Move(r8, Smi::FromInt(Context::MIN_CONTEXT_SLOTS)); | 741   __ Move(r8, Smi::FromInt(Context::MIN_CONTEXT_SLOTS)); | 
| 744   __ addp(r8, args.GetArgumentOperand(2)); | 742   __ addp(r8, rcx); | 
| 745   __ subp(r8, r9); | 743   __ subp(r8, r9); | 
| 746   __ Move(r11, factory->the_hole_value()); | 744   __ movp(rcx, rdi); | 
| 747   __ movp(rdx, rdi); |  | 
| 748   __ leap(rdi, Operand(rdi, rbx, times_pointer_size, kParameterMapHeaderSize)); | 745   __ leap(rdi, Operand(rdi, rbx, times_pointer_size, kParameterMapHeaderSize)); | 
| 749   // r9 = loop variable (tagged) | 746   __ SmiToInteger64(r9, r9); | 
|  | 747   // r9 = loop variable (untagged) | 
| 750   // r8 = mapping index (tagged) | 748   // r8 = mapping index (tagged) | 
| 751   // r11 = the hole value | 749   // rcx = address of parameter map (tagged) | 
| 752   // rdx = address of parameter map (tagged) |  | 
| 753   // rdi = address of backing store (tagged) | 750   // rdi = address of backing store (tagged) | 
| 754   __ jmp(¶meters_test, Label::kNear); | 751   __ jmp(¶meters_test, Label::kNear); | 
| 755 | 752 | 
| 756   __ bind(¶meters_loop); | 753   __ bind(¶meters_loop); | 
| 757   __ SmiSubConstant(r9, r9, Smi::FromInt(1)); | 754   __ subp(r9, Immediate(1)); | 
| 758   __ SmiToInteger64(kScratchRegister, r9); | 755   __ LoadRoot(kScratchRegister, Heap::kTheHoleValueRootIndex); | 
| 759   __ movp(FieldOperand(rdx, kScratchRegister, | 756   __ movp(FieldOperand(rcx, r9, times_pointer_size, kParameterMapHeaderSize), | 
| 760                        times_pointer_size, |  | 
| 761                        kParameterMapHeaderSize), |  | 
| 762           r8); | 757           r8); | 
| 763   __ movp(FieldOperand(rdi, kScratchRegister, | 758   __ movp(FieldOperand(rdi, r9, times_pointer_size, FixedArray::kHeaderSize), | 
| 764                        times_pointer_size, | 759           kScratchRegister); | 
| 765                        FixedArray::kHeaderSize), |  | 
| 766           r11); |  | 
| 767   __ SmiAddConstant(r8, r8, Smi::FromInt(1)); | 760   __ SmiAddConstant(r8, r8, Smi::FromInt(1)); | 
| 768   __ bind(¶meters_test); | 761   __ bind(¶meters_test); | 
| 769   __ SmiTest(r9); | 762   __ testp(r9, r9); | 
| 770   __ j(not_zero, ¶meters_loop, Label::kNear); | 763   __ j(not_zero, ¶meters_loop, Label::kNear); | 
| 771 | 764 | 
| 772   __ bind(&skip_parameter_map); | 765   __ bind(&skip_parameter_map); | 
| 773 | 766 | 
| 774   // rcx = argument count (tagged) | 767   // r11 = argument count (tagged) | 
| 775   // rdi = address of backing store (tagged) | 768   // rdi = address of backing store (tagged) | 
| 776   // Copy arguments header and remaining slots (if there are any). | 769   // Copy arguments header and remaining slots (if there are any). | 
| 777   __ Move(FieldOperand(rdi, FixedArray::kMapOffset), | 770   __ Move(FieldOperand(rdi, FixedArray::kMapOffset), | 
| 778           factory->fixed_array_map()); | 771           factory->fixed_array_map()); | 
| 779   __ movp(FieldOperand(rdi, FixedArray::kLengthOffset), rcx); | 772   __ movp(FieldOperand(rdi, FixedArray::kLengthOffset), r11); | 
| 780 | 773 | 
| 781   Label arguments_loop, arguments_test; | 774   Label arguments_loop, arguments_test; | 
| 782   __ movp(r8, rbx); | 775   __ movp(r8, rbx); | 
| 783   __ movp(rdx, args.GetArgumentOperand(1)); | 776   // Untag r11 for the loop below. | 
| 784   // Untag rcx for the loop below. | 777   __ SmiToInteger64(r11, r11); | 
| 785   __ SmiToInteger64(rcx, rcx); |  | 
| 786   __ leap(kScratchRegister, Operand(r8, times_pointer_size, 0)); | 778   __ leap(kScratchRegister, Operand(r8, times_pointer_size, 0)); | 
| 787   __ subp(rdx, kScratchRegister); | 779   __ subp(rdx, kScratchRegister); | 
| 788   __ jmp(&arguments_test, Label::kNear); | 780   __ jmp(&arguments_test, Label::kNear); | 
| 789 | 781 | 
| 790   __ bind(&arguments_loop); | 782   __ bind(&arguments_loop); | 
| 791   __ subp(rdx, Immediate(kPointerSize)); | 783   __ subp(rdx, Immediate(kPointerSize)); | 
| 792   __ movp(r9, Operand(rdx, 0)); | 784   __ movp(r9, Operand(rdx, 0)); | 
| 793   __ movp(FieldOperand(rdi, r8, | 785   __ movp(FieldOperand(rdi, r8, | 
| 794                        times_pointer_size, | 786                        times_pointer_size, | 
| 795                        FixedArray::kHeaderSize), | 787                        FixedArray::kHeaderSize), | 
| 796           r9); | 788           r9); | 
| 797   __ addp(r8, Immediate(1)); | 789   __ addp(r8, Immediate(1)); | 
| 798 | 790 | 
| 799   __ bind(&arguments_test); | 791   __ bind(&arguments_test); | 
| 800   __ cmpp(r8, rcx); | 792   __ cmpp(r8, r11); | 
| 801   __ j(less, &arguments_loop, Label::kNear); | 793   __ j(less, &arguments_loop, Label::kNear); | 
| 802 | 794 | 
| 803   // Return and remove the on-stack parameters. | 795   // Return. | 
| 804   __ ret(3 * kPointerSize); | 796   __ ret(0); | 
| 805 | 797 | 
| 806   // Do the runtime call to allocate the arguments object. | 798   // Do the runtime call to allocate the arguments object. | 
| 807   // rcx = argument count (untagged) | 799   // r11 = argument count (untagged) | 
| 808   __ bind(&runtime); | 800   __ bind(&runtime); | 
| 809   __ Integer32ToSmi(rcx, rcx); | 801   __ Integer32ToSmi(r11, r11); | 
| 810   __ movp(args.GetArgumentOperand(2), rcx);  // Patch argument count. | 802   __ PopReturnAddressTo(rax); | 
|  | 803   __ Push(rdi);  // Push function. | 
|  | 804   __ Push(rdx);  // Push parameters pointer. | 
|  | 805   __ Push(r11);  // Push parameter count. | 
|  | 806   __ PushReturnAddressFrom(rax); | 
| 811   __ TailCallRuntime(Runtime::kNewSloppyArguments, 3, 1); | 807   __ TailCallRuntime(Runtime::kNewSloppyArguments, 3, 1); | 
| 812 } | 808 } | 
| 813 | 809 | 
| 814 | 810 | 
| 815 void ArgumentsAccessStub::GenerateNewSloppySlow(MacroAssembler* masm) { | 811 void ArgumentsAccessStub::GenerateNewSloppySlow(MacroAssembler* masm) { | 
| 816   // rsp[0]  : return address | 812   // rcx : number of parameters (tagged) | 
| 817   // rsp[8]  : number of parameters | 813   // rdx : parameters pointer | 
| 818   // rsp[16] : receiver displacement | 814   // rdi : function | 
| 819   // rsp[24] : function | 815   // rsp[0] : return address | 
|  | 816 | 
|  | 817   DCHECK(rdi.is(ArgumentsAccessNewDescriptor::function())); | 
|  | 818   DCHECK(rcx.is(ArgumentsAccessNewDescriptor::parameter_count())); | 
|  | 819   DCHECK(rdx.is(ArgumentsAccessNewDescriptor::parameter_pointer())); | 
| 820 | 820 | 
| 821   // Check if the calling frame is an arguments adaptor frame. | 821   // Check if the calling frame is an arguments adaptor frame. | 
| 822   Label runtime; | 822   Label runtime; | 
| 823   __ movp(rdx, Operand(rbp, StandardFrameConstants::kCallerFPOffset)); | 823   __ movp(rbx, Operand(rbp, StandardFrameConstants::kCallerFPOffset)); | 
| 824   __ movp(rcx, Operand(rdx, StandardFrameConstants::kContextOffset)); | 824   __ movp(rax, Operand(rbx, StandardFrameConstants::kContextOffset)); | 
| 825   __ Cmp(rcx, Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)); | 825   __ Cmp(rax, Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)); | 
| 826   __ j(not_equal, &runtime); | 826   __ j(not_equal, &runtime); | 
| 827 | 827 | 
| 828   // Patch the arguments.length and the parameters pointer. | 828   // Patch the arguments.length and the parameters pointer. | 
| 829   StackArgumentsAccessor args(rsp, 3, ARGUMENTS_DONT_CONTAIN_RECEIVER); | 829   StackArgumentsAccessor args(rsp, 3, ARGUMENTS_DONT_CONTAIN_RECEIVER); | 
| 830   __ movp(rcx, Operand(rdx, ArgumentsAdaptorFrameConstants::kLengthOffset)); | 830   __ movp(rcx, Operand(rbx, ArgumentsAdaptorFrameConstants::kLengthOffset)); | 
| 831   __ movp(args.GetArgumentOperand(2), rcx); | 831   __ SmiToInteger64(rax, rcx); | 
| 832   __ SmiToInteger64(rcx, rcx); | 832   __ leap(rdx, Operand(rbx, rax, times_pointer_size, | 
| 833   __ leap(rdx, Operand(rdx, rcx, times_pointer_size, | 833                        StandardFrameConstants::kCallerSPOffset)); | 
| 834               StandardFrameConstants::kCallerSPOffset)); |  | 
| 835   __ movp(args.GetArgumentOperand(1), rdx); |  | 
| 836 | 834 | 
| 837   __ bind(&runtime); | 835   __ bind(&runtime); | 
|  | 836   __ PopReturnAddressTo(rax); | 
|  | 837   __ Push(rdi);  // Push function. | 
|  | 838   __ Push(rdx);  // Push parameters pointer. | 
|  | 839   __ Push(rcx);  // Push parameter count. | 
|  | 840   __ PushReturnAddressFrom(rax); | 
| 838   __ TailCallRuntime(Runtime::kNewSloppyArguments, 3, 1); | 841   __ TailCallRuntime(Runtime::kNewSloppyArguments, 3, 1); | 
| 839 } | 842 } | 
| 840 | 843 | 
| 841 | 844 | 
| 842 void LoadIndexedInterceptorStub::Generate(MacroAssembler* masm) { | 845 void LoadIndexedInterceptorStub::Generate(MacroAssembler* masm) { | 
| 843   // Return address is on the stack. | 846   // Return address is on the stack. | 
| 844   Label slow; | 847   Label slow; | 
| 845 | 848 | 
| 846   Register receiver = LoadDescriptor::ReceiverRegister(); | 849   Register receiver = LoadDescriptor::ReceiverRegister(); | 
| 847   Register key = LoadDescriptor::NameRegister(); | 850   Register key = LoadDescriptor::NameRegister(); | 
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 894   StubRuntimeCallHelper call_helper; | 897   StubRuntimeCallHelper call_helper; | 
| 895   char_at_generator.GenerateSlow(masm, PART_OF_IC_HANDLER, call_helper); | 898   char_at_generator.GenerateSlow(masm, PART_OF_IC_HANDLER, call_helper); | 
| 896 | 899 | 
| 897   __ bind(&miss); | 900   __ bind(&miss); | 
| 898   PropertyAccessCompiler::TailCallBuiltin( | 901   PropertyAccessCompiler::TailCallBuiltin( | 
| 899       masm, PropertyAccessCompiler::MissBuiltin(Code::KEYED_LOAD_IC)); | 902       masm, PropertyAccessCompiler::MissBuiltin(Code::KEYED_LOAD_IC)); | 
| 900 } | 903 } | 
| 901 | 904 | 
| 902 | 905 | 
| 903 void ArgumentsAccessStub::GenerateNewStrict(MacroAssembler* masm) { | 906 void ArgumentsAccessStub::GenerateNewStrict(MacroAssembler* masm) { | 
| 904   // rsp[0]  : return address | 907   // rcx : number of parameters (tagged) | 
| 905   // rsp[8]  : number of parameters | 908   // rdx : parameters pointer | 
| 906   // rsp[16] : receiver displacement | 909   // rdi : function | 
| 907   // rsp[24] : function | 910   // rsp[0] : return address | 
|  | 911 | 
|  | 912   DCHECK(rdi.is(ArgumentsAccessNewDescriptor::function())); | 
|  | 913   DCHECK(rcx.is(ArgumentsAccessNewDescriptor::parameter_count())); | 
|  | 914   DCHECK(rdx.is(ArgumentsAccessNewDescriptor::parameter_pointer())); | 
| 908 | 915 | 
| 909   // Check if the calling frame is an arguments adaptor frame. | 916   // Check if the calling frame is an arguments adaptor frame. | 
| 910   Label adaptor_frame, try_allocate, runtime; | 917   Label adaptor_frame, try_allocate, runtime; | 
| 911   __ movp(rdx, Operand(rbp, StandardFrameConstants::kCallerFPOffset)); | 918   __ movp(rbx, Operand(rbp, StandardFrameConstants::kCallerFPOffset)); | 
| 912   __ movp(rcx, Operand(rdx, StandardFrameConstants::kContextOffset)); | 919   __ movp(rax, Operand(rbx, StandardFrameConstants::kContextOffset)); | 
| 913   __ Cmp(rcx, Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)); | 920   __ Cmp(rax, Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)); | 
| 914   __ j(equal, &adaptor_frame); | 921   __ j(equal, &adaptor_frame); | 
| 915 | 922 | 
| 916   // Get the length from the frame. | 923   // Get the length from the frame. | 
| 917   StackArgumentsAccessor args(rsp, 3, ARGUMENTS_DONT_CONTAIN_RECEIVER); | 924   __ SmiToInteger64(rax, rcx); | 
| 918   __ movp(rcx, args.GetArgumentOperand(2)); |  | 
| 919   __ SmiToInteger64(rcx, rcx); |  | 
| 920   __ jmp(&try_allocate); | 925   __ jmp(&try_allocate); | 
| 921 | 926 | 
| 922   // Patch the arguments.length and the parameters pointer. | 927   // Patch the arguments.length and the parameters pointer. | 
| 923   __ bind(&adaptor_frame); | 928   __ bind(&adaptor_frame); | 
| 924   __ movp(rcx, Operand(rdx, ArgumentsAdaptorFrameConstants::kLengthOffset)); | 929   __ movp(rcx, Operand(rbx, ArgumentsAdaptorFrameConstants::kLengthOffset)); | 
| 925 | 930   __ SmiToInteger64(rax, rcx); | 
| 926   __ movp(args.GetArgumentOperand(2), rcx); | 931   __ leap(rdx, Operand(rbx, rax, times_pointer_size, | 
| 927   __ SmiToInteger64(rcx, rcx); | 932                        StandardFrameConstants::kCallerSPOffset)); | 
| 928   __ leap(rdx, Operand(rdx, rcx, times_pointer_size, |  | 
| 929                       StandardFrameConstants::kCallerSPOffset)); |  | 
| 930   __ movp(args.GetArgumentOperand(1), rdx); |  | 
| 931 | 933 | 
| 932   // Try the new space allocation. Start out with computing the size of | 934   // Try the new space allocation. Start out with computing the size of | 
| 933   // the arguments object and the elements array. | 935   // the arguments object and the elements array. | 
| 934   Label add_arguments_object; | 936   Label add_arguments_object; | 
| 935   __ bind(&try_allocate); | 937   __ bind(&try_allocate); | 
| 936   __ testp(rcx, rcx); | 938   __ testp(rax, rax); | 
| 937   __ j(zero, &add_arguments_object, Label::kNear); | 939   __ j(zero, &add_arguments_object, Label::kNear); | 
| 938   __ leap(rcx, Operand(rcx, times_pointer_size, FixedArray::kHeaderSize)); | 940   __ leap(rax, Operand(rax, times_pointer_size, FixedArray::kHeaderSize)); | 
| 939   __ bind(&add_arguments_object); | 941   __ bind(&add_arguments_object); | 
| 940   __ addp(rcx, Immediate(Heap::kStrictArgumentsObjectSize)); | 942   __ addp(rax, Immediate(Heap::kStrictArgumentsObjectSize)); | 
| 941 | 943 | 
| 942   // Do the allocation of both objects in one go. | 944   // Do the allocation of both objects in one go. | 
| 943   __ Allocate(rcx, rax, rdx, rbx, &runtime, TAG_OBJECT); | 945   __ Allocate(rax, rax, rbx, no_reg, &runtime, TAG_OBJECT); | 
| 944 | 946 | 
| 945   // Get the arguments map from the current native context. | 947   // Get the arguments map from the current native context. | 
| 946   __ movp(rdi, Operand(rsi, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX))); | 948   __ movp(rdi, Operand(rsi, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX))); | 
| 947   __ movp(rdi, FieldOperand(rdi, GlobalObject::kNativeContextOffset)); | 949   __ movp(rdi, FieldOperand(rdi, GlobalObject::kNativeContextOffset)); | 
| 948   const int offset = Context::SlotOffset(Context::STRICT_ARGUMENTS_MAP_INDEX); | 950   const int offset = Context::SlotOffset(Context::STRICT_ARGUMENTS_MAP_INDEX); | 
| 949   __ movp(rdi, Operand(rdi, offset)); | 951   __ movp(rdi, Operand(rdi, offset)); | 
| 950 | 952 | 
| 951   __ movp(FieldOperand(rax, JSObject::kMapOffset), rdi); | 953   __ movp(FieldOperand(rax, JSObject::kMapOffset), rdi); | 
| 952   __ LoadRoot(kScratchRegister, Heap::kEmptyFixedArrayRootIndex); | 954   __ LoadRoot(kScratchRegister, Heap::kEmptyFixedArrayRootIndex); | 
| 953   __ movp(FieldOperand(rax, JSObject::kPropertiesOffset), kScratchRegister); | 955   __ movp(FieldOperand(rax, JSObject::kPropertiesOffset), kScratchRegister); | 
| 954   __ movp(FieldOperand(rax, JSObject::kElementsOffset), kScratchRegister); | 956   __ movp(FieldOperand(rax, JSObject::kElementsOffset), kScratchRegister); | 
| 955 | 957 | 
| 956   // Get the length (smi tagged) and set that as an in-object property too. | 958   // Get the length (smi tagged) and set that as an in-object property too. | 
| 957   STATIC_ASSERT(Heap::kArgumentsLengthIndex == 0); | 959   STATIC_ASSERT(Heap::kArgumentsLengthIndex == 0); | 
| 958   __ movp(rcx, args.GetArgumentOperand(2)); |  | 
| 959   __ movp(FieldOperand(rax, JSObject::kHeaderSize + | 960   __ movp(FieldOperand(rax, JSObject::kHeaderSize + | 
| 960                        Heap::kArgumentsLengthIndex * kPointerSize), | 961                        Heap::kArgumentsLengthIndex * kPointerSize), | 
| 961           rcx); | 962           rcx); | 
| 962 | 963 | 
| 963   // If there are no actual arguments, we're done. | 964   // If there are no actual arguments, we're done. | 
| 964   Label done; | 965   Label done; | 
| 965   __ testp(rcx, rcx); | 966   __ testp(rcx, rcx); | 
| 966   __ j(zero, &done); | 967   __ j(zero, &done); | 
| 967 | 968 | 
| 968   // Get the parameters pointer from the stack. |  | 
| 969   __ movp(rdx, args.GetArgumentOperand(1)); |  | 
| 970 |  | 
| 971   // Set up the elements pointer in the allocated arguments object and | 969   // Set up the elements pointer in the allocated arguments object and | 
| 972   // initialize the header in the elements fixed array. | 970   // initialize the header in the elements fixed array. | 
| 973   __ leap(rdi, Operand(rax, Heap::kStrictArgumentsObjectSize)); | 971   __ leap(rdi, Operand(rax, Heap::kStrictArgumentsObjectSize)); | 
| 974   __ movp(FieldOperand(rax, JSObject::kElementsOffset), rdi); | 972   __ movp(FieldOperand(rax, JSObject::kElementsOffset), rdi); | 
| 975   __ LoadRoot(kScratchRegister, Heap::kFixedArrayMapRootIndex); | 973   __ LoadRoot(kScratchRegister, Heap::kFixedArrayMapRootIndex); | 
| 976   __ movp(FieldOperand(rdi, FixedArray::kMapOffset), kScratchRegister); | 974   __ movp(FieldOperand(rdi, FixedArray::kMapOffset), kScratchRegister); | 
|  | 975   __ movp(FieldOperand(rdi, FixedArray::kLengthOffset), rcx); | 
| 977 | 976 | 
| 978 |  | 
| 979   __ movp(FieldOperand(rdi, FixedArray::kLengthOffset), rcx); |  | 
| 980   // Untag the length for the loop below. | 977   // Untag the length for the loop below. | 
| 981   __ SmiToInteger64(rcx, rcx); | 978   __ SmiToInteger64(rcx, rcx); | 
| 982 | 979 | 
| 983   // Copy the fixed array slots. | 980   // Copy the fixed array slots. | 
| 984   Label loop; | 981   Label loop; | 
| 985   __ bind(&loop); | 982   __ bind(&loop); | 
| 986   __ movp(rbx, Operand(rdx, -1 * kPointerSize));  // Skip receiver. | 983   __ movp(rbx, Operand(rdx, -1 * kPointerSize));  // Skip receiver. | 
| 987   __ movp(FieldOperand(rdi, FixedArray::kHeaderSize), rbx); | 984   __ movp(FieldOperand(rdi, FixedArray::kHeaderSize), rbx); | 
| 988   __ addp(rdi, Immediate(kPointerSize)); | 985   __ addp(rdi, Immediate(kPointerSize)); | 
| 989   __ subp(rdx, Immediate(kPointerSize)); | 986   __ subp(rdx, Immediate(kPointerSize)); | 
| 990   __ decp(rcx); | 987   __ decp(rcx); | 
| 991   __ j(not_zero, &loop); | 988   __ j(not_zero, &loop); | 
| 992 | 989 | 
| 993   // Return and remove the on-stack parameters. | 990   // Return. | 
| 994   __ bind(&done); | 991   __ bind(&done); | 
| 995   __ ret(3 * kPointerSize); | 992   __ ret(0); | 
| 996 | 993 | 
| 997   // Do the runtime call to allocate the arguments object. | 994   // Do the runtime call to allocate the arguments object. | 
| 998   __ bind(&runtime); | 995   __ bind(&runtime); | 
|  | 996   __ PopReturnAddressTo(rax); | 
|  | 997   __ Push(rdi);  // Push function. | 
|  | 998   __ Push(rdx);  // Push parameters pointer. | 
|  | 999   __ Push(rcx);  // Push parameter count. | 
|  | 1000   __ PushReturnAddressFrom(rax); | 
| 999   __ TailCallRuntime(Runtime::kNewStrictArguments, 3, 1); | 1001   __ TailCallRuntime(Runtime::kNewStrictArguments, 3, 1); | 
| 1000 } | 1002 } | 
| 1001 | 1003 | 
| 1002 | 1004 | 
| 1003 void RegExpExecStub::Generate(MacroAssembler* masm) { | 1005 void RegExpExecStub::Generate(MacroAssembler* masm) { | 
| 1004   // Just jump directly to runtime if native RegExp is not selected at compile | 1006   // Just jump directly to runtime if native RegExp is not selected at compile | 
| 1005   // time or if regexp entry in generated code is turned off runtime switch or | 1007   // time or if regexp entry in generated code is turned off runtime switch or | 
| 1006   // at compilation. | 1008   // at compilation. | 
| 1007 #ifdef V8_INTERPRETED_REGEXP | 1009 #ifdef V8_INTERPRETED_REGEXP | 
| 1008   __ TailCallRuntime(Runtime::kRegExpExec, 4, 1); | 1010   __ TailCallRuntime(Runtime::kRegExpExec, 4, 1); | 
| (...skipping 4563 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 5572                            kStackSpace, nullptr, return_value_operand, NULL); | 5574                            kStackSpace, nullptr, return_value_operand, NULL); | 
| 5573 } | 5575 } | 
| 5574 | 5576 | 
| 5575 | 5577 | 
| 5576 #undef __ | 5578 #undef __ | 
| 5577 | 5579 | 
| 5578 }  // namespace internal | 5580 }  // namespace internal | 
| 5579 }  // namespace v8 | 5581 }  // namespace v8 | 
| 5580 | 5582 | 
| 5581 #endif  // V8_TARGET_ARCH_X64 | 5583 #endif  // V8_TARGET_ARCH_X64 | 
| OLD | NEW | 
|---|