| 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 516 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   527                      LoadDescriptor::SlotRegister())); |   527                      LoadDescriptor::SlotRegister())); | 
|   528  |   528  | 
|   529   NamedLoadHandlerCompiler::GenerateLoadFunctionPrototype(masm, receiver, r8, |   529   NamedLoadHandlerCompiler::GenerateLoadFunctionPrototype(masm, receiver, r8, | 
|   530                                                           r9, &miss); |   530                                                           r9, &miss); | 
|   531   __ bind(&miss); |   531   __ bind(&miss); | 
|   532   PropertyAccessCompiler::TailCallBuiltin( |   532   PropertyAccessCompiler::TailCallBuiltin( | 
|   533       masm, PropertyAccessCompiler::MissBuiltin(Code::LOAD_IC)); |   533       masm, PropertyAccessCompiler::MissBuiltin(Code::LOAD_IC)); | 
|   534 } |   534 } | 
|   535  |   535  | 
|   536  |   536  | 
|   537 void ArgumentsAccessStub::GenerateNewSloppyFast(MacroAssembler* masm) { |  | 
|   538   // rcx : number of parameters (tagged) |  | 
|   539   // rdx : parameters pointer |  | 
|   540   // rdi : function |  | 
|   541   // rsp[0] : return address |  | 
|   542   // Registers used over the whole function: |  | 
|   543   //  rbx: the mapped parameter count (untagged) |  | 
|   544   //  rax: the allocated object (tagged). |  | 
|   545   Factory* factory = isolate()->factory(); |  | 
|   546  |  | 
|   547   DCHECK(rdi.is(ArgumentsAccessNewDescriptor::function())); |  | 
|   548   DCHECK(rcx.is(ArgumentsAccessNewDescriptor::parameter_count())); |  | 
|   549   DCHECK(rdx.is(ArgumentsAccessNewDescriptor::parameter_pointer())); |  | 
|   550  |  | 
|   551   __ SmiToInteger64(rbx, rcx); |  | 
|   552   // rbx = parameter count (untagged) |  | 
|   553  |  | 
|   554   // Check if the calling frame is an arguments adaptor frame. |  | 
|   555   Label adaptor_frame, try_allocate, runtime; |  | 
|   556   __ movp(rax, Operand(rbp, StandardFrameConstants::kCallerFPOffset)); |  | 
|   557   __ movp(r8, Operand(rax, StandardFrameConstants::kContextOffset)); |  | 
|   558   __ Cmp(r8, Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)); |  | 
|   559   __ j(equal, &adaptor_frame); |  | 
|   560  |  | 
|   561   // No adaptor, parameter count = argument count. |  | 
|   562   __ movp(r11, rbx); |  | 
|   563   __ jmp(&try_allocate, Label::kNear); |  | 
|   564  |  | 
|   565   // We have an adaptor frame. Patch the parameters pointer. |  | 
|   566   __ bind(&adaptor_frame); |  | 
|   567   __ SmiToInteger64( |  | 
|   568       r11, Operand(rax, ArgumentsAdaptorFrameConstants::kLengthOffset)); |  | 
|   569   __ leap(rdx, Operand(rax, r11, times_pointer_size, |  | 
|   570                        StandardFrameConstants::kCallerSPOffset)); |  | 
|   571  |  | 
|   572   // rbx = parameter count (untagged) |  | 
|   573   // r11 = argument count (untagged) |  | 
|   574   // Compute the mapped parameter count = min(rbx, r11) in rbx. |  | 
|   575   __ cmpp(rbx, r11); |  | 
|   576   __ j(less_equal, &try_allocate, Label::kNear); |  | 
|   577   __ movp(rbx, r11); |  | 
|   578  |  | 
|   579   __ bind(&try_allocate); |  | 
|   580  |  | 
|   581   // Compute the sizes of backing store, parameter map, and arguments object. |  | 
|   582   // 1. Parameter map, has 2 extra words containing context and backing store. |  | 
|   583   const int kParameterMapHeaderSize = |  | 
|   584       FixedArray::kHeaderSize + 2 * kPointerSize; |  | 
|   585   Label no_parameter_map; |  | 
|   586   __ xorp(r8, r8); |  | 
|   587   __ testp(rbx, rbx); |  | 
|   588   __ j(zero, &no_parameter_map, Label::kNear); |  | 
|   589   __ leap(r8, Operand(rbx, times_pointer_size, kParameterMapHeaderSize)); |  | 
|   590   __ bind(&no_parameter_map); |  | 
|   591  |  | 
|   592   // 2. Backing store. |  | 
|   593   __ leap(r8, Operand(r8, r11, times_pointer_size, FixedArray::kHeaderSize)); |  | 
|   594  |  | 
|   595   // 3. Arguments object. |  | 
|   596   __ addp(r8, Immediate(JSSloppyArgumentsObject::kSize)); |  | 
|   597  |  | 
|   598   // Do the allocation of all three objects in one go. |  | 
|   599   __ Allocate(r8, rax, r9, no_reg, &runtime, TAG_OBJECT); |  | 
|   600  |  | 
|   601   // rax = address of new object(s) (tagged) |  | 
|   602   // r11 = argument count (untagged) |  | 
|   603   // Get the arguments map from the current native context into r9. |  | 
|   604   Label has_mapped_parameters, instantiate; |  | 
|   605   __ movp(r9, NativeContextOperand()); |  | 
|   606   __ testp(rbx, rbx); |  | 
|   607   __ j(not_zero, &has_mapped_parameters, Label::kNear); |  | 
|   608  |  | 
|   609   const int kIndex = Context::SLOPPY_ARGUMENTS_MAP_INDEX; |  | 
|   610   __ movp(r9, Operand(r9, Context::SlotOffset(kIndex))); |  | 
|   611   __ jmp(&instantiate, Label::kNear); |  | 
|   612  |  | 
|   613   const int kAliasedIndex = Context::FAST_ALIASED_ARGUMENTS_MAP_INDEX; |  | 
|   614   __ bind(&has_mapped_parameters); |  | 
|   615   __ movp(r9, Operand(r9, Context::SlotOffset(kAliasedIndex))); |  | 
|   616   __ bind(&instantiate); |  | 
|   617  |  | 
|   618   // rax = address of new object (tagged) |  | 
|   619   // rbx = mapped parameter count (untagged) |  | 
|   620   // r11 = argument count (untagged) |  | 
|   621   // r9 = address of arguments map (tagged) |  | 
|   622   __ movp(FieldOperand(rax, JSObject::kMapOffset), r9); |  | 
|   623   __ LoadRoot(kScratchRegister, Heap::kEmptyFixedArrayRootIndex); |  | 
|   624   __ movp(FieldOperand(rax, JSObject::kPropertiesOffset), kScratchRegister); |  | 
|   625   __ movp(FieldOperand(rax, JSObject::kElementsOffset), kScratchRegister); |  | 
|   626  |  | 
|   627   // Set up the callee in-object property. |  | 
|   628   __ AssertNotSmi(rdi); |  | 
|   629   __ movp(FieldOperand(rax, JSSloppyArgumentsObject::kCalleeOffset), rdi); |  | 
|   630  |  | 
|   631   // Use the length (smi tagged) and set that as an in-object property too. |  | 
|   632   // Note: r11 is tagged from here on. |  | 
|   633   __ Integer32ToSmi(r11, r11); |  | 
|   634   __ movp(FieldOperand(rax, JSSloppyArgumentsObject::kLengthOffset), r11); |  | 
|   635  |  | 
|   636   // Set up the elements pointer in the allocated arguments object. |  | 
|   637   // If we allocated a parameter map, rdi will point there, otherwise to the |  | 
|   638   // backing store. |  | 
|   639   __ leap(rdi, Operand(rax, JSSloppyArgumentsObject::kSize)); |  | 
|   640   __ movp(FieldOperand(rax, JSObject::kElementsOffset), rdi); |  | 
|   641  |  | 
|   642   // rax = address of new object (tagged) |  | 
|   643   // rbx = mapped parameter count (untagged) |  | 
|   644   // r11 = argument count (tagged) |  | 
|   645   // rdi = address of parameter map or backing store (tagged) |  | 
|   646  |  | 
|   647   // Initialize parameter map. If there are no mapped arguments, we're done. |  | 
|   648   Label skip_parameter_map; |  | 
|   649   __ testp(rbx, rbx); |  | 
|   650   __ j(zero, &skip_parameter_map); |  | 
|   651  |  | 
|   652   __ LoadRoot(kScratchRegister, Heap::kSloppyArgumentsElementsMapRootIndex); |  | 
|   653   // rbx contains the untagged argument count. Add 2 and tag to write. |  | 
|   654   __ movp(FieldOperand(rdi, FixedArray::kMapOffset), kScratchRegister); |  | 
|   655   __ Integer64PlusConstantToSmi(r9, rbx, 2); |  | 
|   656   __ movp(FieldOperand(rdi, FixedArray::kLengthOffset), r9); |  | 
|   657   __ movp(FieldOperand(rdi, FixedArray::kHeaderSize + 0 * kPointerSize), rsi); |  | 
|   658   __ leap(r9, Operand(rdi, rbx, times_pointer_size, kParameterMapHeaderSize)); |  | 
|   659   __ movp(FieldOperand(rdi, FixedArray::kHeaderSize + 1 * kPointerSize), r9); |  | 
|   660  |  | 
|   661   // Copy the parameter slots and the holes in the arguments. |  | 
|   662   // We need to fill in mapped_parameter_count slots. They index the context, |  | 
|   663   // where parameters are stored in reverse order, at |  | 
|   664   //   MIN_CONTEXT_SLOTS .. MIN_CONTEXT_SLOTS+parameter_count-1 |  | 
|   665   // The mapped parameter thus need to get indices |  | 
|   666   //   MIN_CONTEXT_SLOTS+parameter_count-1 .. |  | 
|   667   //       MIN_CONTEXT_SLOTS+parameter_count-mapped_parameter_count |  | 
|   668   // We loop from right to left. |  | 
|   669   Label parameters_loop, parameters_test; |  | 
|   670  |  | 
|   671   // Load tagged parameter count into r9. |  | 
|   672   __ Integer32ToSmi(r9, rbx); |  | 
|   673   __ Move(r8, Smi::FromInt(Context::MIN_CONTEXT_SLOTS)); |  | 
|   674   __ addp(r8, rcx); |  | 
|   675   __ subp(r8, r9); |  | 
|   676   __ movp(rcx, rdi); |  | 
|   677   __ leap(rdi, Operand(rdi, rbx, times_pointer_size, kParameterMapHeaderSize)); |  | 
|   678   __ SmiToInteger64(r9, r9); |  | 
|   679   // r9 = loop variable (untagged) |  | 
|   680   // r8 = mapping index (tagged) |  | 
|   681   // rcx = address of parameter map (tagged) |  | 
|   682   // rdi = address of backing store (tagged) |  | 
|   683   __ jmp(¶meters_test, Label::kNear); |  | 
|   684  |  | 
|   685   __ bind(¶meters_loop); |  | 
|   686   __ subp(r9, Immediate(1)); |  | 
|   687   __ LoadRoot(kScratchRegister, Heap::kTheHoleValueRootIndex); |  | 
|   688   __ movp(FieldOperand(rcx, r9, times_pointer_size, kParameterMapHeaderSize), |  | 
|   689           r8); |  | 
|   690   __ movp(FieldOperand(rdi, r9, times_pointer_size, FixedArray::kHeaderSize), |  | 
|   691           kScratchRegister); |  | 
|   692   __ SmiAddConstant(r8, r8, Smi::FromInt(1)); |  | 
|   693   __ bind(¶meters_test); |  | 
|   694   __ testp(r9, r9); |  | 
|   695   __ j(not_zero, ¶meters_loop, Label::kNear); |  | 
|   696  |  | 
|   697   __ bind(&skip_parameter_map); |  | 
|   698  |  | 
|   699   // r11 = argument count (tagged) |  | 
|   700   // rdi = address of backing store (tagged) |  | 
|   701   // Copy arguments header and remaining slots (if there are any). |  | 
|   702   __ Move(FieldOperand(rdi, FixedArray::kMapOffset), |  | 
|   703           factory->fixed_array_map()); |  | 
|   704   __ movp(FieldOperand(rdi, FixedArray::kLengthOffset), r11); |  | 
|   705  |  | 
|   706   Label arguments_loop, arguments_test; |  | 
|   707   __ movp(r8, rbx); |  | 
|   708   // Untag r11 for the loop below. |  | 
|   709   __ SmiToInteger64(r11, r11); |  | 
|   710   __ leap(kScratchRegister, Operand(r8, times_pointer_size, 0)); |  | 
|   711   __ subp(rdx, kScratchRegister); |  | 
|   712   __ jmp(&arguments_test, Label::kNear); |  | 
|   713  |  | 
|   714   __ bind(&arguments_loop); |  | 
|   715   __ subp(rdx, Immediate(kPointerSize)); |  | 
|   716   __ movp(r9, Operand(rdx, 0)); |  | 
|   717   __ movp(FieldOperand(rdi, r8, |  | 
|   718                        times_pointer_size, |  | 
|   719                        FixedArray::kHeaderSize), |  | 
|   720           r9); |  | 
|   721   __ addp(r8, Immediate(1)); |  | 
|   722  |  | 
|   723   __ bind(&arguments_test); |  | 
|   724   __ cmpp(r8, r11); |  | 
|   725   __ j(less, &arguments_loop, Label::kNear); |  | 
|   726  |  | 
|   727   // Return. |  | 
|   728   __ ret(0); |  | 
|   729  |  | 
|   730   // Do the runtime call to allocate the arguments object. |  | 
|   731   // r11 = argument count (untagged) |  | 
|   732   __ bind(&runtime); |  | 
|   733   __ Integer32ToSmi(r11, r11); |  | 
|   734   __ PopReturnAddressTo(rax); |  | 
|   735   __ Push(rdi);  // Push function. |  | 
|   736   __ Push(rdx);  // Push parameters pointer. |  | 
|   737   __ Push(r11);  // Push parameter count. |  | 
|   738   __ PushReturnAddressFrom(rax); |  | 
|   739   __ TailCallRuntime(Runtime::kNewSloppyArguments); |  | 
|   740 } |  | 
|   741  |  | 
|   742  |  | 
|   743 void ArgumentsAccessStub::GenerateNewSloppySlow(MacroAssembler* masm) { |  | 
|   744   // rcx : number of parameters (tagged) |  | 
|   745   // rdx : parameters pointer |  | 
|   746   // rdi : function |  | 
|   747   // rsp[0] : return address |  | 
|   748  |  | 
|   749   DCHECK(rdi.is(ArgumentsAccessNewDescriptor::function())); |  | 
|   750   DCHECK(rcx.is(ArgumentsAccessNewDescriptor::parameter_count())); |  | 
|   751   DCHECK(rdx.is(ArgumentsAccessNewDescriptor::parameter_pointer())); |  | 
|   752  |  | 
|   753   // Check if the calling frame is an arguments adaptor frame. |  | 
|   754   Label runtime; |  | 
|   755   __ movp(rbx, Operand(rbp, StandardFrameConstants::kCallerFPOffset)); |  | 
|   756   __ movp(rax, Operand(rbx, StandardFrameConstants::kContextOffset)); |  | 
|   757   __ Cmp(rax, Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)); |  | 
|   758   __ j(not_equal, &runtime); |  | 
|   759  |  | 
|   760   // Patch the arguments.length and the parameters pointer. |  | 
|   761   StackArgumentsAccessor args(rsp, 3, ARGUMENTS_DONT_CONTAIN_RECEIVER); |  | 
|   762   __ movp(rcx, Operand(rbx, ArgumentsAdaptorFrameConstants::kLengthOffset)); |  | 
|   763   __ SmiToInteger64(rax, rcx); |  | 
|   764   __ leap(rdx, Operand(rbx, rax, times_pointer_size, |  | 
|   765                        StandardFrameConstants::kCallerSPOffset)); |  | 
|   766  |  | 
|   767   __ bind(&runtime); |  | 
|   768   __ PopReturnAddressTo(rax); |  | 
|   769   __ Push(rdi);  // Push function. |  | 
|   770   __ Push(rdx);  // Push parameters pointer. |  | 
|   771   __ Push(rcx);  // Push parameter count. |  | 
|   772   __ PushReturnAddressFrom(rax); |  | 
|   773   __ TailCallRuntime(Runtime::kNewSloppyArguments); |  | 
|   774 } |  | 
|   775  |  | 
|   776  |  | 
|   777 void LoadIndexedInterceptorStub::Generate(MacroAssembler* masm) { |   537 void LoadIndexedInterceptorStub::Generate(MacroAssembler* masm) { | 
|   778   // Return address is on the stack. |   538   // Return address is on the stack. | 
|   779   Label slow; |   539   Label slow; | 
|   780  |   540  | 
|   781   Register receiver = LoadDescriptor::ReceiverRegister(); |   541   Register receiver = LoadDescriptor::ReceiverRegister(); | 
|   782   Register key = LoadDescriptor::NameRegister(); |   542   Register key = LoadDescriptor::NameRegister(); | 
|   783   Register scratch = rax; |   543   Register scratch = rax; | 
|   784   DCHECK(!scratch.is(receiver) && !scratch.is(key)); |   544   DCHECK(!scratch.is(receiver) && !scratch.is(key)); | 
|   785  |   545  | 
|   786   // Check that the key is an array index, that is Uint32. |   546   // Check that the key is an array index, that is Uint32. | 
| (...skipping 4080 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  4867       __ movp(rdx, rax); |  4627       __ movp(rdx, rax); | 
|  4868       __ Pop(rbx); |  4628       __ Pop(rbx); | 
|  4869       __ Pop(rax); |  4629       __ Pop(rax); | 
|  4870       __ SmiToInteger32(rax, rax); |  4630       __ SmiToInteger32(rax, rax); | 
|  4871     } |  4631     } | 
|  4872     __ jmp(&done_allocate); |  4632     __ jmp(&done_allocate); | 
|  4873   } |  4633   } | 
|  4874 } |  4634 } | 
|  4875  |  4635  | 
|  4876  |  4636  | 
 |  4637 void FastNewSloppyArgumentsStub::Generate(MacroAssembler* masm) { | 
 |  4638   // ----------- S t a t e ------------- | 
 |  4639   //  -- rdi    : function | 
 |  4640   //  -- rsi    : context | 
 |  4641   //  -- rbp    : frame pointer | 
 |  4642   //  -- rsp[0] : return address | 
 |  4643   // ----------------------------------- | 
 |  4644   __ AssertFunction(rdi); | 
 |  4645  | 
 |  4646   // TODO(bmeurer): Cleanup to match the FastNewStrictArgumentsStub. | 
 |  4647   __ movp(rcx, FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset)); | 
 |  4648   __ LoadSharedFunctionInfoSpecialField( | 
 |  4649       rcx, rcx, SharedFunctionInfo::kFormalParameterCountOffset); | 
 |  4650   __ leap(rdx, Operand(rbp, rcx, times_pointer_size, | 
 |  4651                        StandardFrameConstants::kCallerSPOffset)); | 
 |  4652   __ Integer32ToSmi(rcx, rcx); | 
 |  4653  | 
 |  4654   // rcx : number of parameters (tagged) | 
 |  4655   // rdx : parameters pointer | 
 |  4656   // rdi : function | 
 |  4657   // rsp[0] : return address | 
 |  4658   // Registers used over the whole function: | 
 |  4659   //  rbx: the mapped parameter count (untagged) | 
 |  4660   //  rax: the allocated object (tagged). | 
 |  4661   Factory* factory = isolate()->factory(); | 
 |  4662  | 
 |  4663   __ SmiToInteger64(rbx, rcx); | 
 |  4664   // rbx = parameter count (untagged) | 
 |  4665  | 
 |  4666   // Check if the calling frame is an arguments adaptor frame. | 
 |  4667   Label adaptor_frame, try_allocate, runtime; | 
 |  4668   __ movp(rax, Operand(rbp, StandardFrameConstants::kCallerFPOffset)); | 
 |  4669   __ movp(r8, Operand(rax, StandardFrameConstants::kContextOffset)); | 
 |  4670   __ Cmp(r8, Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)); | 
 |  4671   __ j(equal, &adaptor_frame); | 
 |  4672  | 
 |  4673   // No adaptor, parameter count = argument count. | 
 |  4674   __ movp(r11, rbx); | 
 |  4675   __ jmp(&try_allocate, Label::kNear); | 
 |  4676  | 
 |  4677   // We have an adaptor frame. Patch the parameters pointer. | 
 |  4678   __ bind(&adaptor_frame); | 
 |  4679   __ SmiToInteger64( | 
 |  4680       r11, Operand(rax, ArgumentsAdaptorFrameConstants::kLengthOffset)); | 
 |  4681   __ leap(rdx, Operand(rax, r11, times_pointer_size, | 
 |  4682                        StandardFrameConstants::kCallerSPOffset)); | 
 |  4683  | 
 |  4684   // rbx = parameter count (untagged) | 
 |  4685   // r11 = argument count (untagged) | 
 |  4686   // Compute the mapped parameter count = min(rbx, r11) in rbx. | 
 |  4687   __ cmpp(rbx, r11); | 
 |  4688   __ j(less_equal, &try_allocate, Label::kNear); | 
 |  4689   __ movp(rbx, r11); | 
 |  4690  | 
 |  4691   __ bind(&try_allocate); | 
 |  4692  | 
 |  4693   // Compute the sizes of backing store, parameter map, and arguments object. | 
 |  4694   // 1. Parameter map, has 2 extra words containing context and backing store. | 
 |  4695   const int kParameterMapHeaderSize = | 
 |  4696       FixedArray::kHeaderSize + 2 * kPointerSize; | 
 |  4697   Label no_parameter_map; | 
 |  4698   __ xorp(r8, r8); | 
 |  4699   __ testp(rbx, rbx); | 
 |  4700   __ j(zero, &no_parameter_map, Label::kNear); | 
 |  4701   __ leap(r8, Operand(rbx, times_pointer_size, kParameterMapHeaderSize)); | 
 |  4702   __ bind(&no_parameter_map); | 
 |  4703  | 
 |  4704   // 2. Backing store. | 
 |  4705   __ leap(r8, Operand(r8, r11, times_pointer_size, FixedArray::kHeaderSize)); | 
 |  4706  | 
 |  4707   // 3. Arguments object. | 
 |  4708   __ addp(r8, Immediate(JSSloppyArgumentsObject::kSize)); | 
 |  4709  | 
 |  4710   // Do the allocation of all three objects in one go. | 
 |  4711   __ Allocate(r8, rax, r9, no_reg, &runtime, TAG_OBJECT); | 
 |  4712  | 
 |  4713   // rax = address of new object(s) (tagged) | 
 |  4714   // r11 = argument count (untagged) | 
 |  4715   // Get the arguments map from the current native context into r9. | 
 |  4716   Label has_mapped_parameters, instantiate; | 
 |  4717   __ movp(r9, NativeContextOperand()); | 
 |  4718   __ testp(rbx, rbx); | 
 |  4719   __ j(not_zero, &has_mapped_parameters, Label::kNear); | 
 |  4720  | 
 |  4721   const int kIndex = Context::SLOPPY_ARGUMENTS_MAP_INDEX; | 
 |  4722   __ movp(r9, Operand(r9, Context::SlotOffset(kIndex))); | 
 |  4723   __ jmp(&instantiate, Label::kNear); | 
 |  4724  | 
 |  4725   const int kAliasedIndex = Context::FAST_ALIASED_ARGUMENTS_MAP_INDEX; | 
 |  4726   __ bind(&has_mapped_parameters); | 
 |  4727   __ movp(r9, Operand(r9, Context::SlotOffset(kAliasedIndex))); | 
 |  4728   __ bind(&instantiate); | 
 |  4729  | 
 |  4730   // rax = address of new object (tagged) | 
 |  4731   // rbx = mapped parameter count (untagged) | 
 |  4732   // r11 = argument count (untagged) | 
 |  4733   // r9 = address of arguments map (tagged) | 
 |  4734   __ movp(FieldOperand(rax, JSObject::kMapOffset), r9); | 
 |  4735   __ LoadRoot(kScratchRegister, Heap::kEmptyFixedArrayRootIndex); | 
 |  4736   __ movp(FieldOperand(rax, JSObject::kPropertiesOffset), kScratchRegister); | 
 |  4737   __ movp(FieldOperand(rax, JSObject::kElementsOffset), kScratchRegister); | 
 |  4738  | 
 |  4739   // Set up the callee in-object property. | 
 |  4740   __ AssertNotSmi(rdi); | 
 |  4741   __ movp(FieldOperand(rax, JSSloppyArgumentsObject::kCalleeOffset), rdi); | 
 |  4742  | 
 |  4743   // Use the length (smi tagged) and set that as an in-object property too. | 
 |  4744   // Note: r11 is tagged from here on. | 
 |  4745   __ Integer32ToSmi(r11, r11); | 
 |  4746   __ movp(FieldOperand(rax, JSSloppyArgumentsObject::kLengthOffset), r11); | 
 |  4747  | 
 |  4748   // Set up the elements pointer in the allocated arguments object. | 
 |  4749   // If we allocated a parameter map, rdi will point there, otherwise to the | 
 |  4750   // backing store. | 
 |  4751   __ leap(rdi, Operand(rax, JSSloppyArgumentsObject::kSize)); | 
 |  4752   __ movp(FieldOperand(rax, JSObject::kElementsOffset), rdi); | 
 |  4753  | 
 |  4754   // rax = address of new object (tagged) | 
 |  4755   // rbx = mapped parameter count (untagged) | 
 |  4756   // r11 = argument count (tagged) | 
 |  4757   // rdi = address of parameter map or backing store (tagged) | 
 |  4758  | 
 |  4759   // Initialize parameter map. If there are no mapped arguments, we're done. | 
 |  4760   Label skip_parameter_map; | 
 |  4761   __ testp(rbx, rbx); | 
 |  4762   __ j(zero, &skip_parameter_map); | 
 |  4763  | 
 |  4764   __ LoadRoot(kScratchRegister, Heap::kSloppyArgumentsElementsMapRootIndex); | 
 |  4765   // rbx contains the untagged argument count. Add 2 and tag to write. | 
 |  4766   __ movp(FieldOperand(rdi, FixedArray::kMapOffset), kScratchRegister); | 
 |  4767   __ Integer64PlusConstantToSmi(r9, rbx, 2); | 
 |  4768   __ movp(FieldOperand(rdi, FixedArray::kLengthOffset), r9); | 
 |  4769   __ movp(FieldOperand(rdi, FixedArray::kHeaderSize + 0 * kPointerSize), rsi); | 
 |  4770   __ leap(r9, Operand(rdi, rbx, times_pointer_size, kParameterMapHeaderSize)); | 
 |  4771   __ movp(FieldOperand(rdi, FixedArray::kHeaderSize + 1 * kPointerSize), r9); | 
 |  4772  | 
 |  4773   // Copy the parameter slots and the holes in the arguments. | 
 |  4774   // We need to fill in mapped_parameter_count slots. They index the context, | 
 |  4775   // where parameters are stored in reverse order, at | 
 |  4776   //   MIN_CONTEXT_SLOTS .. MIN_CONTEXT_SLOTS+parameter_count-1 | 
 |  4777   // The mapped parameter thus need to get indices | 
 |  4778   //   MIN_CONTEXT_SLOTS+parameter_count-1 .. | 
 |  4779   //       MIN_CONTEXT_SLOTS+parameter_count-mapped_parameter_count | 
 |  4780   // We loop from right to left. | 
 |  4781   Label parameters_loop, parameters_test; | 
 |  4782  | 
 |  4783   // Load tagged parameter count into r9. | 
 |  4784   __ Integer32ToSmi(r9, rbx); | 
 |  4785   __ Move(r8, Smi::FromInt(Context::MIN_CONTEXT_SLOTS)); | 
 |  4786   __ addp(r8, rcx); | 
 |  4787   __ subp(r8, r9); | 
 |  4788   __ movp(rcx, rdi); | 
 |  4789   __ leap(rdi, Operand(rdi, rbx, times_pointer_size, kParameterMapHeaderSize)); | 
 |  4790   __ SmiToInteger64(r9, r9); | 
 |  4791   // r9 = loop variable (untagged) | 
 |  4792   // r8 = mapping index (tagged) | 
 |  4793   // rcx = address of parameter map (tagged) | 
 |  4794   // rdi = address of backing store (tagged) | 
 |  4795   __ jmp(¶meters_test, Label::kNear); | 
 |  4796  | 
 |  4797   __ bind(¶meters_loop); | 
 |  4798   __ subp(r9, Immediate(1)); | 
 |  4799   __ LoadRoot(kScratchRegister, Heap::kTheHoleValueRootIndex); | 
 |  4800   __ movp(FieldOperand(rcx, r9, times_pointer_size, kParameterMapHeaderSize), | 
 |  4801           r8); | 
 |  4802   __ movp(FieldOperand(rdi, r9, times_pointer_size, FixedArray::kHeaderSize), | 
 |  4803           kScratchRegister); | 
 |  4804   __ SmiAddConstant(r8, r8, Smi::FromInt(1)); | 
 |  4805   __ bind(¶meters_test); | 
 |  4806   __ testp(r9, r9); | 
 |  4807   __ j(not_zero, ¶meters_loop, Label::kNear); | 
 |  4808  | 
 |  4809   __ bind(&skip_parameter_map); | 
 |  4810  | 
 |  4811   // r11 = argument count (tagged) | 
 |  4812   // rdi = address of backing store (tagged) | 
 |  4813   // Copy arguments header and remaining slots (if there are any). | 
 |  4814   __ Move(FieldOperand(rdi, FixedArray::kMapOffset), | 
 |  4815           factory->fixed_array_map()); | 
 |  4816   __ movp(FieldOperand(rdi, FixedArray::kLengthOffset), r11); | 
 |  4817  | 
 |  4818   Label arguments_loop, arguments_test; | 
 |  4819   __ movp(r8, rbx); | 
 |  4820   // Untag r11 for the loop below. | 
 |  4821   __ SmiToInteger64(r11, r11); | 
 |  4822   __ leap(kScratchRegister, Operand(r8, times_pointer_size, 0)); | 
 |  4823   __ subp(rdx, kScratchRegister); | 
 |  4824   __ jmp(&arguments_test, Label::kNear); | 
 |  4825  | 
 |  4826   __ bind(&arguments_loop); | 
 |  4827   __ subp(rdx, Immediate(kPointerSize)); | 
 |  4828   __ movp(r9, Operand(rdx, 0)); | 
 |  4829   __ movp(FieldOperand(rdi, r8, | 
 |  4830                        times_pointer_size, | 
 |  4831                        FixedArray::kHeaderSize), | 
 |  4832           r9); | 
 |  4833   __ addp(r8, Immediate(1)); | 
 |  4834  | 
 |  4835   __ bind(&arguments_test); | 
 |  4836   __ cmpp(r8, r11); | 
 |  4837   __ j(less, &arguments_loop, Label::kNear); | 
 |  4838  | 
 |  4839   // Return. | 
 |  4840   __ ret(0); | 
 |  4841  | 
 |  4842   // Do the runtime call to allocate the arguments object. | 
 |  4843   // r11 = argument count (untagged) | 
 |  4844   __ bind(&runtime); | 
 |  4845   __ Integer32ToSmi(r11, r11); | 
 |  4846   __ PopReturnAddressTo(rax); | 
 |  4847   __ Push(rdi);  // Push function. | 
 |  4848   __ Push(rdx);  // Push parameters pointer. | 
 |  4849   __ Push(r11);  // Push parameter count. | 
 |  4850   __ PushReturnAddressFrom(rax); | 
 |  4851   __ TailCallRuntime(Runtime::kNewSloppyArguments); | 
 |  4852 } | 
 |  4853  | 
 |  4854  | 
|  4877 void FastNewStrictArgumentsStub::Generate(MacroAssembler* masm) { |  4855 void FastNewStrictArgumentsStub::Generate(MacroAssembler* masm) { | 
|  4878   // ----------- S t a t e ------------- |  4856   // ----------- S t a t e ------------- | 
|  4879   //  -- rdi    : function |  4857   //  -- rdi    : function | 
|  4880   //  -- rsi    : context |  4858   //  -- rsi    : context | 
|  4881   //  -- rbp    : frame pointer |  4859   //  -- rbp    : frame pointer | 
|  4882   //  -- rsp[0] : return address |  4860   //  -- rsp[0] : return address | 
|  4883   // ----------------------------------- |  4861   // ----------------------------------- | 
|  4884   __ AssertFunction(rdi); |  4862   __ AssertFunction(rdi); | 
|  4885  |  4863  | 
|  4886   // For Ignition we need to skip all possible handler/stub frames until |  4864   // For Ignition we need to skip all possible handler/stub frames until | 
| (...skipping 656 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  5543                            NULL); |  5521                            NULL); | 
|  5544 } |  5522 } | 
|  5545  |  5523  | 
|  5546  |  5524  | 
|  5547 #undef __ |  5525 #undef __ | 
|  5548  |  5526  | 
|  5549 }  // namespace internal |  5527 }  // namespace internal | 
|  5550 }  // namespace v8 |  5528 }  // namespace v8 | 
|  5551  |  5529  | 
|  5552 #endif  // V8_TARGET_ARCH_X64 |  5530 #endif  // V8_TARGET_ARCH_X64 | 
| OLD | NEW |