OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
179 Isolate* isolate, | 179 Isolate* isolate, |
180 CodeStubInterfaceDescriptor* descriptor) { | 180 CodeStubInterfaceDescriptor* descriptor) { |
181 // x1: receiver | 181 // x1: receiver |
182 static Register registers[] = { x1 }; | 182 static Register registers[] = { x1 }; |
183 descriptor->register_param_count_ = sizeof(registers) / sizeof(registers[0]); | 183 descriptor->register_param_count_ = sizeof(registers) / sizeof(registers[0]); |
184 descriptor->register_params_ = registers; | 184 descriptor->register_params_ = registers; |
185 descriptor->deoptimization_handler_ = NULL; | 185 descriptor->deoptimization_handler_ = NULL; |
186 } | 186 } |
187 | 187 |
188 | 188 |
189 void KeyedArrayCallStub::InitializeInterfaceDescriptor( | |
190 Isolate* isolate, | |
191 CodeStubInterfaceDescriptor* descriptor) { | |
192 // x2: receiver | |
193 static Register registers[] = { x2 }; | |
194 descriptor->register_param_count_ = sizeof(registers) / sizeof(registers[0]); | |
195 descriptor->register_params_ = registers; | |
196 descriptor->continuation_type_ = TAIL_CALL_CONTINUATION; | |
197 descriptor->handler_arguments_mode_ = PASS_ARGUMENTS; | |
198 descriptor->deoptimization_handler_ = | |
199 FUNCTION_ADDR(KeyedCallIC_MissFromStubFailure); | |
200 } | |
201 | |
202 | |
203 void KeyedStoreFastElementStub::InitializeInterfaceDescriptor( | 189 void KeyedStoreFastElementStub::InitializeInterfaceDescriptor( |
204 Isolate* isolate, | 190 Isolate* isolate, |
205 CodeStubInterfaceDescriptor* descriptor) { | 191 CodeStubInterfaceDescriptor* descriptor) { |
206 // x2: receiver | 192 // x2: receiver |
207 // x1: key | 193 // x1: key |
208 // x0: value | 194 // x0: value |
209 static Register registers[] = { x2, x1, x0 }; | 195 static Register registers[] = { x2, x1, x0 }; |
210 descriptor->register_param_count_ = sizeof(registers) / sizeof(registers[0]); | 196 descriptor->register_param_count_ = sizeof(registers) / sizeof(registers[0]); |
211 descriptor->register_params_ = registers; | 197 descriptor->register_params_ = registers; |
212 descriptor->deoptimization_handler_ = | 198 descriptor->deoptimization_handler_ = |
(...skipping 277 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
490 }; | 476 }; |
491 static Representation representations[] = { | 477 static Representation representations[] = { |
492 Representation::Tagged(), // context | 478 Representation::Tagged(), // context |
493 Representation::Tagged(), // receiver | 479 Representation::Tagged(), // receiver |
494 }; | 480 }; |
495 descriptor->register_param_count_ = 2; | 481 descriptor->register_param_count_ = 2; |
496 descriptor->register_params_ = registers; | 482 descriptor->register_params_ = registers; |
497 descriptor->param_representations_ = representations; | 483 descriptor->param_representations_ = representations; |
498 descriptor->platform_specific_descriptor_ = &default_descriptor; | 484 descriptor->platform_specific_descriptor_ = &default_descriptor; |
499 } | 485 } |
| 486 { |
| 487 CallInterfaceDescriptor* descriptor = |
| 488 isolate->call_descriptor(Isolate::ApiFunctionCall); |
| 489 static Register registers[] = { x0, // callee |
| 490 x4, // call_data |
| 491 x2, // holder |
| 492 x1, // api_function_address |
| 493 cp, // context |
| 494 }; |
| 495 static Representation representations[] = { |
| 496 Representation::Tagged(), // callee |
| 497 Representation::Tagged(), // call_data |
| 498 Representation::Tagged(), // holder |
| 499 Representation::External(), // api_function_address |
| 500 Representation::Tagged(), // context |
| 501 }; |
| 502 descriptor->register_param_count_ = 5; |
| 503 descriptor->register_params_ = registers; |
| 504 descriptor->param_representations_ = representations; |
| 505 descriptor->platform_specific_descriptor_ = &default_descriptor; |
| 506 } |
500 } | 507 } |
501 | 508 |
502 | 509 |
503 #define __ ACCESS_MASM(masm) | 510 #define __ ACCESS_MASM(masm) |
504 | 511 |
505 | 512 |
506 void HydrogenCodeStub::GenerateLightweightMiss(MacroAssembler* masm) { | 513 void HydrogenCodeStub::GenerateLightweightMiss(MacroAssembler* masm) { |
507 // Update the static counter each time a new code stub is generated. | 514 // Update the static counter each time a new code stub is generated. |
508 Isolate* isolate = masm->isolate(); | 515 Isolate* isolate = masm->isolate(); |
509 isolate->counters()->code_stubs()->Increment(); | 516 isolate->counters()->code_stubs()->Increment(); |
(...skipping 2738 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3248 | 3255 |
3249 __ Bind(&done); | 3256 __ Bind(&done); |
3250 } | 3257 } |
3251 | 3258 |
3252 | 3259 |
3253 void CallFunctionStub::Generate(MacroAssembler* masm) { | 3260 void CallFunctionStub::Generate(MacroAssembler* masm) { |
3254 ASM_LOCATION("CallFunctionStub::Generate"); | 3261 ASM_LOCATION("CallFunctionStub::Generate"); |
3255 // x1 function the function to call | 3262 // x1 function the function to call |
3256 // x2 cache_cell cache cell for call target | 3263 // x2 cache_cell cache cell for call target |
3257 Register function = x1; | 3264 Register function = x1; |
3258 Register cache_cell = x2; | 3265 Register type = x4; |
3259 Label slow, non_function; | 3266 Label slow, non_function, wrap, cont; |
3260 | 3267 |
3261 // Check that the function is really a JavaScript function. | 3268 // TODO(jbramley): x2 is clobbered in a number of cases. Is it ever used? |
3262 __ JumpIfSmi(function, &non_function); | |
3263 | 3269 |
3264 // Goto slow case if we do not have a function. | 3270 // TODO(jbramley): This function has a lot of unnamed registers. Name them, |
3265 __ JumpIfNotObjectType(function, x10, x10, JS_FUNCTION_TYPE, &slow); | 3271 // and tidy things up a bit. |
3266 | 3272 |
3267 if (RecordCallTarget()) { | 3273 if (NeedsChecks()) { |
3268 GenerateRecordCallTarget(masm); | 3274 // Check that the function is really a JavaScript function. |
| 3275 __ JumpIfSmi(function, &non_function); |
| 3276 |
| 3277 // Goto slow case if we do not have a function. |
| 3278 __ JumpIfNotObjectType(function, x10, x10, JS_FUNCTION_TYPE, &slow); |
| 3279 |
| 3280 if (RecordCallTarget()) { |
| 3281 GenerateRecordCallTarget(masm); |
| 3282 } |
3269 } | 3283 } |
3270 | 3284 |
3271 // Fast-case: Invoke the function now. | 3285 // Fast-case: Invoke the function now. |
3272 // x1 function pushed function | 3286 // x1 function pushed function |
3273 ParameterCount actual(argc_); | 3287 ParameterCount actual(argc_); |
3274 | 3288 |
| 3289 if (CallAsMethod()) { |
| 3290 if (NeedsChecks()) { |
| 3291 // Do not transform the receiver for strict mode functions. |
| 3292 __ Ldr(x2, FieldMemOperand(x1, JSFunction::kSharedFunctionInfoOffset)); |
| 3293 __ Ldr(w3, FieldMemOperand(x2, SharedFunctionInfo::kCompilerHintsOffset)); |
| 3294 __ Tbnz(w3, SharedFunctionInfo::kStrictModeFunction, &cont); |
| 3295 |
| 3296 // Do not transform the receiver for native (Compilerhints already in x3). |
| 3297 __ Tbnz(w3, SharedFunctionInfo::kNative, &cont); |
| 3298 } |
| 3299 |
| 3300 // Compute the receiver in non-strict mode. |
| 3301 __ Peek(x2, argc_ * kPointerSize); |
| 3302 |
| 3303 if (NeedsChecks()) { |
| 3304 // x0: actual number of arguments |
| 3305 // x1: function |
| 3306 // x2: first argument |
| 3307 __ JumpIfSmi(x2, &wrap); |
| 3308 __ JumpIfObjectType(x2, x10, type, FIRST_SPEC_OBJECT_TYPE, &wrap, lt); |
| 3309 } else { |
| 3310 __ B(&wrap); |
| 3311 } |
| 3312 |
| 3313 __ Bind(&cont); |
| 3314 } |
3275 __ InvokeFunction(function, | 3315 __ InvokeFunction(function, |
3276 actual, | 3316 actual, |
3277 JUMP_FUNCTION, | 3317 JUMP_FUNCTION, |
3278 NullCallWrapper()); | 3318 NullCallWrapper()); |
3279 | 3319 |
3280 // Slow-case: Non-function called. | 3320 if (NeedsChecks()) { |
3281 __ Bind(&slow); | 3321 // Slow-case: Non-function called. |
3282 if (RecordCallTarget()) { | 3322 __ Bind(&slow); |
3283 // If there is a call target cache, mark it megamorphic in the | 3323 if (RecordCallTarget()) { |
3284 // non-function case. MegamorphicSentinel is an immortal immovable object | 3324 // If there is a call target cache, mark it megamorphic in the |
3285 // (undefined) so no write barrier is needed. | 3325 // non-function case. MegamorphicSentinel is an immortal immovable object |
3286 ASSERT_EQ(*TypeFeedbackCells::MegamorphicSentinel(masm->isolate()), | 3326 // (undefined) so no write barrier is needed. |
3287 masm->isolate()->heap()->undefined_value()); | 3327 ASSERT_EQ(*TypeFeedbackCells::MegamorphicSentinel(masm->isolate()), |
3288 __ LoadRoot(x11, Heap::kUndefinedValueRootIndex); | 3328 masm->isolate()->heap()->undefined_value()); |
3289 __ Str(x11, FieldMemOperand(cache_cell, Cell::kValueOffset)); | 3329 __ LoadRoot(x11, Heap::kUndefinedValueRootIndex); |
3290 } | 3330 __ Str(x11, FieldMemOperand(x2, Cell::kValueOffset)); |
3291 // Check for function proxy. | 3331 } |
3292 // x10 : function type. | 3332 // Check for function proxy. |
3293 __ Cmp(x10, JS_FUNCTION_PROXY_TYPE); | 3333 // x10 : function type. |
3294 __ B(ne, &non_function); | 3334 __ CompareAndBranch(type, JS_FUNCTION_PROXY_TYPE, ne, &non_function); |
3295 __ Push(function); // put proxy as additional argument | 3335 __ Push(function); // put proxy as additional argument |
3296 __ Mov(x0, argc_ + 1); | 3336 __ Mov(x0, argc_ + 1); |
3297 __ Mov(x2, 0); | 3337 __ Mov(x2, 0); |
3298 __ GetBuiltinFunction(x1, Builtins::CALL_FUNCTION_PROXY); | 3338 __ GetBuiltinFunction(x1, Builtins::CALL_FUNCTION_PROXY); |
3299 { | 3339 { |
3300 Handle<Code> adaptor = | 3340 Handle<Code> adaptor = |
3301 masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(); | 3341 masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(); |
3302 __ Jump(adaptor, RelocInfo::CODE_TARGET); | 3342 __ Jump(adaptor, RelocInfo::CODE_TARGET); |
| 3343 } |
| 3344 |
| 3345 // CALL_NON_FUNCTION expects the non-function callee as receiver (instead |
| 3346 // of the original receiver from the call site). |
| 3347 __ Bind(&non_function); |
| 3348 __ Poke(function, argc_ * kXRegSizeInBytes); |
| 3349 __ Mov(x0, argc_); // Set up the number of arguments. |
| 3350 __ Mov(x2, 0); |
| 3351 __ GetBuiltinFunction(function, Builtins::CALL_NON_FUNCTION); |
| 3352 __ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(), |
| 3353 RelocInfo::CODE_TARGET); |
3303 } | 3354 } |
3304 | 3355 |
3305 // CALL_NON_FUNCTION expects the non-function callee as receiver (instead | 3356 if (CallAsMethod()) { |
3306 // of the original receiver from the call site). | 3357 __ Bind(&wrap); |
3307 __ Bind(&non_function); | 3358 // Wrap the receiver and patch it back onto the stack. |
3308 __ Poke(function, argc_ * kXRegSizeInBytes); | 3359 { FrameScope frame_scope(masm, StackFrame::INTERNAL); |
3309 __ Mov(x0, argc_); // Set up the number of arguments. | 3360 __ Push(x1, x2); |
3310 __ Mov(x2, 0); | 3361 __ InvokeBuiltin(Builtins::TO_OBJECT, CALL_FUNCTION); |
3311 __ GetBuiltinFunction(function, Builtins::CALL_NON_FUNCTION); | 3362 __ Pop(x1); |
3312 __ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(), | 3363 } |
3313 RelocInfo::CODE_TARGET); | 3364 __ Poke(x0, argc_ * kPointerSize); |
| 3365 __ B(&cont); |
| 3366 } |
3314 } | 3367 } |
3315 | 3368 |
3316 | 3369 |
3317 void CallConstructStub::Generate(MacroAssembler* masm) { | 3370 void CallConstructStub::Generate(MacroAssembler* masm) { |
3318 ASM_LOCATION("CallConstructStub::Generate"); | 3371 ASM_LOCATION("CallConstructStub::Generate"); |
3319 // x0 : number of arguments | 3372 // x0 : number of arguments |
3320 // x1 : the function to call | 3373 // x1 : the function to call |
3321 // x2 : cache cell for call target | 3374 // x2 : cache cell for call target |
3322 Register function = x1; | 3375 Register function = x1; |
3323 Label slow, non_function_call; | 3376 Label slow, non_function_call; |
(...skipping 1466 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4790 if (function_mode_ == JS_FUNCTION_STUB_MODE) { | 4843 if (function_mode_ == JS_FUNCTION_STUB_MODE) { |
4791 __ Add(x1, x1, 1); | 4844 __ Add(x1, x1, 1); |
4792 } | 4845 } |
4793 masm->LeaveFrame(StackFrame::STUB_FAILURE_TRAMPOLINE); | 4846 masm->LeaveFrame(StackFrame::STUB_FAILURE_TRAMPOLINE); |
4794 __ Drop(x1); | 4847 __ Drop(x1); |
4795 // Return to IC Miss stub, continuation still on stack. | 4848 // Return to IC Miss stub, continuation still on stack. |
4796 __ Ret(); | 4849 __ Ret(); |
4797 } | 4850 } |
4798 | 4851 |
4799 | 4852 |
4800 void StubFailureTailCallTrampolineStub::Generate(MacroAssembler* masm) { | |
4801 CEntryStub ces(1, fp_registers_ ? kSaveFPRegs : kDontSaveFPRegs); | |
4802 __ Call(ces.GetCode(masm->isolate()), RelocInfo::CODE_TARGET); | |
4803 __ Mov(x1, x0); | |
4804 int parameter_count_offset = | |
4805 StubFailureTrampolineFrame::kCallerStackParameterCountFrameOffset; | |
4806 __ Ldr(x0, MemOperand(fp, parameter_count_offset)); | |
4807 // The parameter count above includes the receiver for the arguments passed to | |
4808 // the deoptimization handler. Subtract the receiver for the parameter count | |
4809 // for the call. | |
4810 __ Sub(x0, x0, 1); | |
4811 masm->LeaveFrame(StackFrame::STUB_FAILURE_TRAMPOLINE); | |
4812 ParameterCount argument_count(x0); | |
4813 __ InvokeFunction(x1, argument_count, JUMP_FUNCTION, NullCallWrapper()); | |
4814 } | |
4815 | |
4816 | |
4817 void ProfileEntryHookStub::MaybeCallEntryHook(MacroAssembler* masm) { | 4853 void ProfileEntryHookStub::MaybeCallEntryHook(MacroAssembler* masm) { |
4818 if (masm->isolate()->function_entry_hook() != NULL) { | 4854 if (masm->isolate()->function_entry_hook() != NULL) { |
4819 // TODO(all): This needs to be reliably consistent with | 4855 // TODO(all): This needs to be reliably consistent with |
4820 // kReturnAddressDistanceFromFunctionStart in ::Generate. | 4856 // kReturnAddressDistanceFromFunctionStart in ::Generate. |
4821 Assembler::BlockConstPoolScope no_const_pools(masm); | 4857 Assembler::BlockConstPoolScope no_const_pools(masm); |
4822 ProfileEntryHookStub stub; | 4858 ProfileEntryHookStub stub; |
4823 __ Push(lr); | 4859 __ Push(lr); |
4824 __ CallStub(&stub); | 4860 __ CallStub(&stub); |
4825 __ Pop(lr); | 4861 __ Pop(lr); |
4826 } | 4862 } |
(...skipping 665 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5492 GenerateCase(masm, FAST_HOLEY_ELEMENTS); | 5528 GenerateCase(masm, FAST_HOLEY_ELEMENTS); |
5493 | 5529 |
5494 __ Bind(&fast_elements_case); | 5530 __ Bind(&fast_elements_case); |
5495 GenerateCase(masm, FAST_ELEMENTS); | 5531 GenerateCase(masm, FAST_ELEMENTS); |
5496 } | 5532 } |
5497 | 5533 |
5498 | 5534 |
5499 void CallApiFunctionStub::Generate(MacroAssembler* masm) { | 5535 void CallApiFunctionStub::Generate(MacroAssembler* masm) { |
5500 // ----------- S t a t e ------------- | 5536 // ----------- S t a t e ------------- |
5501 // -- x0 : callee | 5537 // -- x0 : callee |
5502 // -- x1 : thunk_arg | 5538 // -- x4 : call_data |
5503 // -- x2 : holder | 5539 // -- x2 : holder |
5504 // -- x3 : api_function_address | 5540 // -- x1 : api_function_address |
5505 // -- x4 : call_data | |
5506 // -- cp : context | 5541 // -- cp : context |
5507 // -- | 5542 // -- |
5508 // -- sp[0] : last argument | 5543 // -- sp[0] : last argument |
5509 // -- ... | 5544 // -- ... |
5510 // -- sp[(argc - 1) * 8] : first argument | 5545 // -- sp[(argc - 1) * 8] : first argument |
5511 // -- sp[argc * 8] : receiver | 5546 // -- sp[argc * 8] : receiver |
5512 // ----------------------------------- | 5547 // ----------------------------------- |
5513 | 5548 |
5514 Register callee = x0; | 5549 Register callee = x0; |
5515 Register thunk_arg = x1; | 5550 Register call_data = x4; |
5516 Register holder = x2; | 5551 Register holder = x2; |
5517 Register api_function_address = x3; | 5552 Register api_function_address = x1; |
5518 Register call_data = x4; | |
5519 Register context = cp; | 5553 Register context = cp; |
5520 | 5554 |
5521 int argc = ArgumentBits::decode(bit_field_); | 5555 int argc = ArgumentBits::decode(bit_field_); |
5522 bool restore_context = RestoreContextBits::decode(bit_field_); | 5556 bool restore_context = RestoreContextBits::decode(bit_field_); |
5523 bool call_data_undefined = CallDataUndefinedBits::decode(bit_field_); | 5557 bool call_data_undefined = CallDataUndefinedBits::decode(bit_field_); |
5524 | 5558 |
5525 typedef FunctionCallbackArguments FCA; | 5559 typedef FunctionCallbackArguments FCA; |
5526 | 5560 |
5527 STATIC_ASSERT(FCA::kContextSaveIndex == 6); | 5561 STATIC_ASSERT(FCA::kContextSaveIndex == 6); |
5528 STATIC_ASSERT(FCA::kCalleeIndex == 5); | 5562 STATIC_ASSERT(FCA::kCalleeIndex == 5); |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5560 const int kApiStackSpace = 4; | 5594 const int kApiStackSpace = 4; |
5561 | 5595 |
5562 // Allocate space for CallApiFunctionAndReturn can store some scratch | 5596 // Allocate space for CallApiFunctionAndReturn can store some scratch |
5563 // registeres on the stack. | 5597 // registeres on the stack. |
5564 const int kCallApiFunctionSpillSpace = 4; | 5598 const int kCallApiFunctionSpillSpace = 4; |
5565 | 5599 |
5566 FrameScope frame_scope(masm, StackFrame::MANUAL); | 5600 FrameScope frame_scope(masm, StackFrame::MANUAL); |
5567 __ EnterExitFrame(false, x10, kApiStackSpace + kCallApiFunctionSpillSpace); | 5601 __ EnterExitFrame(false, x10, kApiStackSpace + kCallApiFunctionSpillSpace); |
5568 | 5602 |
5569 // TODO(all): Optimize this with stp and suchlike. | 5603 // TODO(all): Optimize this with stp and suchlike. |
5570 ASSERT(!AreAliased(x0, thunk_arg, api_function_address)); | 5604 ASSERT(!AreAliased(x0, api_function_address)); |
5571 // x0 = FunctionCallbackInfo& | 5605 // x0 = FunctionCallbackInfo& |
5572 // Arguments is after the return address. | 5606 // Arguments is after the return address. |
5573 __ Add(x0, masm->StackPointer(), 1 * kPointerSize); | 5607 __ Add(x0, masm->StackPointer(), 1 * kPointerSize); |
5574 // FunctionCallbackInfo::implicit_args_ | 5608 // FunctionCallbackInfo::implicit_args_ |
5575 __ Str(args, MemOperand(x0, 0 * kPointerSize)); | 5609 __ Str(args, MemOperand(x0, 0 * kPointerSize)); |
5576 // FunctionCallbackInfo::values_ | 5610 // FunctionCallbackInfo::values_ |
5577 __ Add(x10, args, Operand((FCA::kArgsLength - 1 + argc) * kPointerSize)); | 5611 __ Add(x10, args, Operand((FCA::kArgsLength - 1 + argc) * kPointerSize)); |
5578 __ Str(x10, MemOperand(x0, 1 * kPointerSize)); | 5612 __ Str(x10, MemOperand(x0, 1 * kPointerSize)); |
5579 // FunctionCallbackInfo::length_ = argc | 5613 // FunctionCallbackInfo::length_ = argc |
5580 __ Mov(x10, argc); | 5614 __ Mov(x10, argc); |
(...skipping 10 matching lines...) Expand all Loading... |
5591 | 5625 |
5592 AllowExternalCallThatCantCauseGC scope(masm); | 5626 AllowExternalCallThatCantCauseGC scope(masm); |
5593 MemOperand context_restore_operand( | 5627 MemOperand context_restore_operand( |
5594 fp, (2 + FCA::kContextSaveIndex) * kPointerSize); | 5628 fp, (2 + FCA::kContextSaveIndex) * kPointerSize); |
5595 MemOperand return_value_operand(fp, | 5629 MemOperand return_value_operand(fp, |
5596 (2 + FCA::kReturnValueOffset) * kPointerSize); | 5630 (2 + FCA::kReturnValueOffset) * kPointerSize); |
5597 | 5631 |
5598 const int spill_offset = 1 + kApiStackSpace; | 5632 const int spill_offset = 1 + kApiStackSpace; |
5599 __ CallApiFunctionAndReturn(api_function_address, | 5633 __ CallApiFunctionAndReturn(api_function_address, |
5600 thunk_ref, | 5634 thunk_ref, |
5601 thunk_arg, | |
5602 kStackUnwindSpace, | 5635 kStackUnwindSpace, |
5603 spill_offset, | 5636 spill_offset, |
5604 return_value_operand, | 5637 return_value_operand, |
5605 restore_context ? | 5638 restore_context ? |
5606 &context_restore_operand : NULL); | 5639 &context_restore_operand : NULL); |
5607 } | 5640 } |
5608 | 5641 |
5609 | 5642 |
| 5643 void CallApiGetterStub::Generate(MacroAssembler* masm) { |
| 5644 // ----------- S t a t e ------------- |
| 5645 // -- sp[0] : name |
| 5646 // -- sp[8 - kArgsLength*8] : PropertyCallbackArguments object |
| 5647 // -- ... |
| 5648 // -- x2 : api_function_address |
| 5649 // ----------------------------------- |
| 5650 |
| 5651 Register api_function_address = x2; |
| 5652 |
| 5653 __ Mov(x0, masm->StackPointer()); // x0 = Handle<Name> |
| 5654 __ Add(x1, x0, 1 * kPointerSize); // x1 = PCA |
| 5655 |
| 5656 const int kApiStackSpace = 1; |
| 5657 |
| 5658 // Allocate space for CallApiFunctionAndReturn can store some scratch |
| 5659 // registeres on the stack. |
| 5660 const int kCallApiFunctionSpillSpace = 4; |
| 5661 |
| 5662 FrameScope frame_scope(masm, StackFrame::MANUAL); |
| 5663 __ EnterExitFrame(false, x10, kApiStackSpace + kCallApiFunctionSpillSpace); |
| 5664 |
| 5665 // Create PropertyAccessorInfo instance on the stack above the exit frame with |
| 5666 // x1 (internal::Object** args_) as the data. |
| 5667 __ Poke(x1, 1 * kPointerSize); |
| 5668 __ Add(x1, masm->StackPointer(), 1 * kPointerSize); // x1 = AccessorInfo& |
| 5669 |
| 5670 const int kStackUnwindSpace = PropertyCallbackArguments::kArgsLength + 1; |
| 5671 |
| 5672 Address thunk_address = FUNCTION_ADDR(&InvokeAccessorGetterCallback); |
| 5673 ExternalReference::Type thunk_type = |
| 5674 ExternalReference::PROFILING_GETTER_CALL; |
| 5675 ApiFunction thunk_fun(thunk_address); |
| 5676 ExternalReference thunk_ref = ExternalReference(&thunk_fun, thunk_type, |
| 5677 masm->isolate()); |
| 5678 |
| 5679 const int spill_offset = 1 + kApiStackSpace; |
| 5680 __ CallApiFunctionAndReturn(api_function_address, |
| 5681 thunk_ref, |
| 5682 kStackUnwindSpace, |
| 5683 spill_offset, |
| 5684 MemOperand(fp, 6 * kPointerSize), |
| 5685 NULL); |
| 5686 } |
| 5687 |
| 5688 |
5610 #undef __ | 5689 #undef __ |
5611 | 5690 |
5612 } } // namespace v8::internal | 5691 } } // namespace v8::internal |
5613 | 5692 |
5614 #endif // V8_TARGET_ARCH_A64 | 5693 #endif // V8_TARGET_ARCH_A64 |
OLD | NEW |