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

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

Issue 860013002: move CallApiFunctionAndReturn to code-stubs-* (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 11 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/arm/macro-assembler-arm.cc ('k') | src/arm64/macro-assembler-arm64.h » ('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 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 #include "src/v8.h" 5 #include "src/v8.h"
6 6
7 #if V8_TARGET_ARCH_ARM64 7 #if V8_TARGET_ARCH_ARM64
8 8
9 #include "src/bootstrapper.h" 9 #include "src/bootstrapper.h"
10 #include "src/code-stubs.h" 10 #include "src/code-stubs.h"
(...skipping 5025 matching lines...) Expand 10 before | Expand all | Expand 10 after
5036 5036
5037 Label fast_elements_case; 5037 Label fast_elements_case;
5038 __ CompareAndBranch(kind, FAST_ELEMENTS, eq, &fast_elements_case); 5038 __ CompareAndBranch(kind, FAST_ELEMENTS, eq, &fast_elements_case);
5039 GenerateCase(masm, FAST_HOLEY_ELEMENTS); 5039 GenerateCase(masm, FAST_HOLEY_ELEMENTS);
5040 5040
5041 __ Bind(&fast_elements_case); 5041 __ Bind(&fast_elements_case);
5042 GenerateCase(masm, FAST_ELEMENTS); 5042 GenerateCase(masm, FAST_ELEMENTS);
5043 } 5043 }
5044 5044
5045 5045
5046 // The number of register that CallApiFunctionAndReturn will need to save on
5047 // the stack. The space for these registers need to be allocated in the
5048 // ExitFrame before calling CallApiFunctionAndReturn.
5049 static const int kCallApiFunctionSpillSpace = 4;
5050
5051
5052 static int AddressOffset(ExternalReference ref0, ExternalReference ref1) {
5053 return ref0.address() - ref1.address();
5054 }
5055
5056
5057 // Calls an API function. Allocates HandleScope, extracts returned value
5058 // from handle and propagates exceptions.
5059 // 'stack_space' is the space to be unwound on exit (includes the call JS
5060 // arguments space and the additional space allocated for the fast call).
5061 // 'spill_offset' is the offset from the stack pointer where
5062 // CallApiFunctionAndReturn can spill registers.
5063 static void CallApiFunctionAndReturn(
5064 MacroAssembler* masm, Register function_address,
5065 ExternalReference thunk_ref, int stack_space,
5066 MemOperand* stack_space_operand, int spill_offset,
5067 MemOperand return_value_operand, MemOperand* context_restore_operand) {
5068 ASM_LOCATION("CallApiFunctionAndReturn");
5069 Isolate* isolate = masm->isolate();
5070 ExternalReference next_address =
5071 ExternalReference::handle_scope_next_address(isolate);
5072 const int kNextOffset = 0;
5073 const int kLimitOffset = AddressOffset(
5074 ExternalReference::handle_scope_limit_address(isolate), next_address);
5075 const int kLevelOffset = AddressOffset(
5076 ExternalReference::handle_scope_level_address(isolate), next_address);
5077
5078 DCHECK(function_address.is(x1) || function_address.is(x2));
5079
5080 Label profiler_disabled;
5081 Label end_profiler_check;
5082 __ Mov(x10, ExternalReference::is_profiling_address(isolate));
5083 __ Ldrb(w10, MemOperand(x10));
5084 __ Cbz(w10, &profiler_disabled);
5085 __ Mov(x3, thunk_ref);
5086 __ B(&end_profiler_check);
5087
5088 __ Bind(&profiler_disabled);
5089 __ Mov(x3, function_address);
5090 __ Bind(&end_profiler_check);
5091
5092 // Save the callee-save registers we are going to use.
5093 // TODO(all): Is this necessary? ARM doesn't do it.
5094 STATIC_ASSERT(kCallApiFunctionSpillSpace == 4);
5095 __ Poke(x19, (spill_offset + 0) * kXRegSize);
5096 __ Poke(x20, (spill_offset + 1) * kXRegSize);
5097 __ Poke(x21, (spill_offset + 2) * kXRegSize);
5098 __ Poke(x22, (spill_offset + 3) * kXRegSize);
5099
5100 // Allocate HandleScope in callee-save registers.
5101 // We will need to restore the HandleScope after the call to the API function,
5102 // by allocating it in callee-save registers they will be preserved by C code.
5103 Register handle_scope_base = x22;
5104 Register next_address_reg = x19;
5105 Register limit_reg = x20;
5106 Register level_reg = w21;
5107
5108 __ Mov(handle_scope_base, next_address);
5109 __ Ldr(next_address_reg, MemOperand(handle_scope_base, kNextOffset));
5110 __ Ldr(limit_reg, MemOperand(handle_scope_base, kLimitOffset));
5111 __ Ldr(level_reg, MemOperand(handle_scope_base, kLevelOffset));
5112 __ Add(level_reg, level_reg, 1);
5113 __ Str(level_reg, MemOperand(handle_scope_base, kLevelOffset));
5114
5115 if (FLAG_log_timer_events) {
5116 FrameScope frame(masm, StackFrame::MANUAL);
5117 __ PushSafepointRegisters();
5118 __ Mov(x0, ExternalReference::isolate_address(isolate));
5119 __ CallCFunction(ExternalReference::log_enter_external_function(isolate),
5120 1);
5121 __ PopSafepointRegisters();
5122 }
5123
5124 // Native call returns to the DirectCEntry stub which redirects to the
5125 // return address pushed on stack (could have moved after GC).
5126 // DirectCEntry stub itself is generated early and never moves.
5127 DirectCEntryStub stub(isolate);
5128 stub.GenerateCall(masm, x3);
5129
5130 if (FLAG_log_timer_events) {
5131 FrameScope frame(masm, StackFrame::MANUAL);
5132 __ PushSafepointRegisters();
5133 __ Mov(x0, ExternalReference::isolate_address(isolate));
5134 __ CallCFunction(ExternalReference::log_leave_external_function(isolate),
5135 1);
5136 __ PopSafepointRegisters();
5137 }
5138
5139 Label promote_scheduled_exception;
5140 Label exception_handled;
5141 Label delete_allocated_handles;
5142 Label leave_exit_frame;
5143 Label return_value_loaded;
5144
5145 // Load value from ReturnValue.
5146 __ Ldr(x0, return_value_operand);
5147 __ Bind(&return_value_loaded);
5148 // No more valid handles (the result handle was the last one). Restore
5149 // previous handle scope.
5150 __ Str(next_address_reg, MemOperand(handle_scope_base, kNextOffset));
5151 if (__ emit_debug_code()) {
5152 __ Ldr(w1, MemOperand(handle_scope_base, kLevelOffset));
5153 __ Cmp(w1, level_reg);
5154 __ Check(eq, kUnexpectedLevelAfterReturnFromApiCall);
5155 }
5156 __ Sub(level_reg, level_reg, 1);
5157 __ Str(level_reg, MemOperand(handle_scope_base, kLevelOffset));
5158 __ Ldr(x1, MemOperand(handle_scope_base, kLimitOffset));
5159 __ Cmp(limit_reg, x1);
5160 __ B(ne, &delete_allocated_handles);
5161
5162 __ Bind(&leave_exit_frame);
5163 // Restore callee-saved registers.
5164 __ Peek(x19, (spill_offset + 0) * kXRegSize);
5165 __ Peek(x20, (spill_offset + 1) * kXRegSize);
5166 __ Peek(x21, (spill_offset + 2) * kXRegSize);
5167 __ Peek(x22, (spill_offset + 3) * kXRegSize);
5168
5169 // Check if the function scheduled an exception.
5170 __ Mov(x5, ExternalReference::scheduled_exception_address(isolate));
5171 __ Ldr(x5, MemOperand(x5));
5172 __ JumpIfNotRoot(x5, Heap::kTheHoleValueRootIndex,
5173 &promote_scheduled_exception);
5174 __ Bind(&exception_handled);
5175
5176 bool restore_context = context_restore_operand != NULL;
5177 if (restore_context) {
5178 __ Ldr(cp, *context_restore_operand);
5179 }
5180
5181 if (stack_space_operand != NULL) {
5182 __ Ldr(w2, *stack_space_operand);
5183 }
5184
5185 __ LeaveExitFrame(false, x1, !restore_context);
5186 if (stack_space_operand != NULL) {
5187 __ Drop(x2, 1);
5188 } else {
5189 __ Drop(stack_space);
5190 }
5191 __ Ret();
5192
5193 __ Bind(&promote_scheduled_exception);
5194 {
5195 FrameScope frame(masm, StackFrame::INTERNAL);
5196 __ CallExternalReference(
5197 ExternalReference(Runtime::kPromoteScheduledException, isolate), 0);
5198 }
5199 __ B(&exception_handled);
5200
5201 // HandleScope limit has changed. Delete allocated extensions.
5202 __ Bind(&delete_allocated_handles);
5203 __ Str(limit_reg, MemOperand(handle_scope_base, kLimitOffset));
5204 // Save the return value in a callee-save register.
5205 Register saved_result = x19;
5206 __ Mov(saved_result, x0);
5207 __ Mov(x0, ExternalReference::isolate_address(isolate));
5208 __ CallCFunction(ExternalReference::delete_handle_scope_extensions(isolate),
5209 1);
5210 __ Mov(x0, saved_result);
5211 __ B(&leave_exit_frame);
5212 }
5213
5214
5046 static void CallApiFunctionStubHelper(MacroAssembler* masm, 5215 static void CallApiFunctionStubHelper(MacroAssembler* masm,
5047 const ParameterCount& argc, 5216 const ParameterCount& argc,
5048 bool return_first_arg, 5217 bool return_first_arg,
5049 bool call_data_undefined) { 5218 bool call_data_undefined) {
5050 // ----------- S t a t e ------------- 5219 // ----------- S t a t e -------------
5051 // -- x0 : callee 5220 // -- x0 : callee
5052 // -- x4 : call_data 5221 // -- x4 : call_data
5053 // -- x2 : holder 5222 // -- x2 : holder
5054 // -- x1 : api_function_address 5223 // -- x1 : api_function_address
5055 // -- x3 : number of arguments if argc is a register 5224 // -- x3 : number of arguments if argc is a register
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
5153 int stack_space = 0; 5322 int stack_space = 0;
5154 MemOperand is_construct_call_operand = 5323 MemOperand is_construct_call_operand =
5155 MemOperand(masm->StackPointer(), 4 * kPointerSize); 5324 MemOperand(masm->StackPointer(), 4 * kPointerSize);
5156 MemOperand* stack_space_operand = &is_construct_call_operand; 5325 MemOperand* stack_space_operand = &is_construct_call_operand;
5157 if (argc.is_immediate()) { 5326 if (argc.is_immediate()) {
5158 stack_space = argc.immediate() + FCA::kArgsLength + 1; 5327 stack_space = argc.immediate() + FCA::kArgsLength + 1;
5159 stack_space_operand = NULL; 5328 stack_space_operand = NULL;
5160 } 5329 }
5161 5330
5162 const int spill_offset = 1 + kApiStackSpace; 5331 const int spill_offset = 1 + kApiStackSpace;
5163 __ CallApiFunctionAndReturn(api_function_address, thunk_ref, stack_space, 5332 CallApiFunctionAndReturn(masm, api_function_address, thunk_ref, stack_space,
5164 stack_space_operand, spill_offset, 5333 stack_space_operand, spill_offset,
5165 return_value_operand, &context_restore_operand); 5334 return_value_operand, &context_restore_operand);
5166 } 5335 }
5167 5336
5168 5337
5169 void CallApiFunctionStub::Generate(MacroAssembler* masm) { 5338 void CallApiFunctionStub::Generate(MacroAssembler* masm) {
5170 bool call_data_undefined = this->call_data_undefined(); 5339 bool call_data_undefined = this->call_data_undefined();
5171 CallApiFunctionStubHelper(masm, ParameterCount(x3), false, 5340 CallApiFunctionStubHelper(masm, ParameterCount(x3), false,
5172 call_data_undefined); 5341 call_data_undefined);
5173 } 5342 }
5174 5343
5175 5344
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
5209 // x1 (internal::Object** args_) as the data. 5378 // x1 (internal::Object** args_) as the data.
5210 __ Poke(x1, 1 * kPointerSize); 5379 __ Poke(x1, 1 * kPointerSize);
5211 __ Add(x1, masm->StackPointer(), 1 * kPointerSize); // x1 = AccessorInfo& 5380 __ Add(x1, masm->StackPointer(), 1 * kPointerSize); // x1 = AccessorInfo&
5212 5381
5213 const int kStackUnwindSpace = PropertyCallbackArguments::kArgsLength + 1; 5382 const int kStackUnwindSpace = PropertyCallbackArguments::kArgsLength + 1;
5214 5383
5215 ExternalReference thunk_ref = 5384 ExternalReference thunk_ref =
5216 ExternalReference::invoke_accessor_getter_callback(isolate()); 5385 ExternalReference::invoke_accessor_getter_callback(isolate());
5217 5386
5218 const int spill_offset = 1 + kApiStackSpace; 5387 const int spill_offset = 1 + kApiStackSpace;
5219 __ CallApiFunctionAndReturn(api_function_address, thunk_ref, 5388 CallApiFunctionAndReturn(masm, api_function_address, thunk_ref,
5220 kStackUnwindSpace, NULL, spill_offset, 5389 kStackUnwindSpace, NULL, spill_offset,
5221 MemOperand(fp, 6 * kPointerSize), NULL); 5390 MemOperand(fp, 6 * kPointerSize), NULL);
5222 } 5391 }
5223 5392
5224 5393
5225 #undef __ 5394 #undef __
5226 5395
5227 } } // namespace v8::internal 5396 } } // namespace v8::internal
5228 5397
5229 #endif // V8_TARGET_ARCH_ARM64 5398 #endif // V8_TARGET_ARCH_ARM64
OLDNEW
« no previous file with comments | « src/arm/macro-assembler-arm.cc ('k') | src/arm64/macro-assembler-arm64.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698