7 #include "src/api-arguments-inl.h" 8 #include "src/assembler-inl.h" 9 #include "src/base/bits.h" 10 #include "src/bootstrapper.h" 11 #include "src/code-stubs.h" 12 #include "src/counters.h" 13 #include "src/double.h" 14 #include "src/frame-constants.h" 15 #include "src/frames.h" 16 #include "src/ic/ic.h" 17 #include "src/ic/stub-cache.h" 18 #include "src/isolate.h" 19 #include "src/macro-assembler.h" 20 #include "src/objects/api-callbacks.h" 21 #include "src/objects/regexp-match-info.h" 22 #include "src/regexp/jsregexp.h" 23 #include "src/regexp/regexp-macro-assembler.h" 24 #include "src/runtime/runtime.h" 26 #include "src/arm/code-stubs-arm.h" 31 #define __ ACCESS_MASM(masm) 33 void JSEntryStub::Generate(MacroAssembler* masm) {
40 Label invoke, handler_entry, exit;
43 NoRootArrayScope no_root_array(masm);
48 __ stm(db_w, sp, kCalleeSaved | lr.bit());
51 __ vstm(db_w, sp, kFirstCalleeSavedDoubleReg, kLastCalleeSavedDoubleReg);
53 __ vmov(kDoubleRegZero, Double(0.0));
55 __ InitializeRootRegister();
65 int offset_to_argv = (kNumCalleeSaved + 1) * kPointerSize;
66 offset_to_argv += kNumDoubleCalleeSaved * kDoubleSize;
67 __ ldr(r4, MemOperand(sp, offset_to_argv));
75 StackFrame::Type marker = type();
76 __ mov(r7, Operand(StackFrame::TypeToMarker(marker)));
77 __ mov(r6, Operand(StackFrame::TypeToMarker(marker)));
78 __ mov(r5, Operand(ExternalReference::Create(
79 IsolateAddressId::kCEntryFPAddress, isolate())));
80 __ ldr(r5, MemOperand(r5));
82 UseScratchRegisterScope temps(masm);
83 Register scratch = temps.Acquire();
86 __ mov(scratch, Operand(-1));
87 __ stm(db_w, sp, r5.bit() | r6.bit() | r7.bit() | scratch.bit());
90 Register scratch = r6;
93 __ add(fp, sp, Operand(-EntryFrameConstants::kCallerFPOffset));
96 Label non_outermost_js;
97 ExternalReference js_entry_sp =
98 ExternalReference::Create(IsolateAddressId::kJSEntrySPAddress, isolate());
99 __ mov(r5, Operand(ExternalReference(js_entry_sp)));
100 __ ldr(scratch, MemOperand(r5));
101 __ cmp(scratch, Operand::Zero());
102 __ b(ne, &non_outermost_js);
103 __ str(fp, MemOperand(r5));
104 __ mov(scratch, Operand(StackFrame::OUTERMOST_JSENTRY_FRAME));
107 __ bind(&non_outermost_js);
108 __ mov(scratch, Operand(StackFrame::INNER_JSENTRY_FRAME));
120 Assembler::BlockConstPoolScope block_const_pool(masm);
121 __ bind(&handler_entry);
122 handler_offset_ = handler_entry.pos();
128 Operand(ExternalReference::Create(
129 IsolateAddressId::kPendingExceptionAddress, isolate())));
131 __ str(r0, MemOperand(scratch));
132 __ LoadRoot(r0, RootIndex::kException);
138 __ PushStackHandler();
154 __ Call(EntryTrampoline(), RelocInfo::CODE_TARGET);
157 __ PopStackHandler();
161 Label non_outermost_js_2;
163 __ cmp(r5, Operand(StackFrame::OUTERMOST_JSENTRY_FRAME));
164 __ b(ne, &non_outermost_js_2);
165 __ mov(r6, Operand::Zero());
166 __ mov(r5, Operand(ExternalReference(js_entry_sp)));
167 __ str(r6, MemOperand(r5));
168 __ bind(&non_outermost_js_2);
172 __ mov(scratch, Operand(ExternalReference::Create(
173 IsolateAddressId::kCEntryFPAddress, isolate())));
174 __ str(r3, MemOperand(scratch));
177 __ add(sp, sp, Operand(-EntryFrameConstants::kCallerFPOffset));
181 if (FLAG_debug_code) {
182 __ mov(lr, Operand(pc));
187 __ vldm(ia_w, sp, kFirstCalleeSavedDoubleReg, kLastCalleeSavedDoubleReg);
189 __ ldm(ia_w, sp, kCalleeSaved | pc.bit());
192 void DirectCEntryStub::Generate(MacroAssembler* masm) {
195 __ str(lr, MemOperand(sp, 0));
197 __ ldr(pc, MemOperand(sp, 0));
201 void DirectCEntryStub::GenerateCall(MacroAssembler* masm,
203 if (FLAG_embedded_builtins) {
204 if (masm->root_array_available() &&
205 isolate()->ShouldLoadConstantsFromRootList()) {
209 __ IndirectLoadConstant(lr, GetCode());
210 __ add(lr, lr, Operand(Code::kHeaderSize - kHeapObjectTag));
216 reinterpret_cast<intptr_t
>(GetCode().location());
218 __ mov(lr, Operand(code, RelocInfo::CODE_TARGET));
223 static int AddressOffset(ExternalReference ref0, ExternalReference ref1) {
224 return ref0.address() - ref1.address();
232 static void CallApiFunctionAndReturn(MacroAssembler* masm,
233 Register function_address,
234 ExternalReference thunk_ref,
236 MemOperand* stack_space_operand,
237 MemOperand return_value_operand) {
238 Isolate* isolate = masm->isolate();
239 ExternalReference next_address =
240 ExternalReference::handle_scope_next_address(isolate);
241 const int kNextOffset = 0;
242 const int kLimitOffset = AddressOffset(
243 ExternalReference::handle_scope_limit_address(isolate), next_address);
244 const int kLevelOffset = AddressOffset(
245 ExternalReference::handle_scope_level_address(isolate), next_address);
247 DCHECK(function_address == r1 || function_address == r2);
249 Label profiler_disabled;
250 Label end_profiler_check;
251 __ Move(r9, ExternalReference::is_profiling_address(isolate));
252 __ ldrb(r9, MemOperand(r9, 0));
253 __ cmp(r9, Operand(0));
254 __ b(eq, &profiler_disabled);
257 __ Move(r3, thunk_ref);
258 __ jmp(&end_profiler_check);
260 __ bind(&profiler_disabled);
261 __ Move(r3, function_address);
262 __ bind(&end_profiler_check);
265 __ Move(r9, next_address);
266 __ ldr(r4, MemOperand(r9, kNextOffset));
267 __ ldr(r5, MemOperand(r9, kLimitOffset));
268 __ ldr(r6, MemOperand(r9, kLevelOffset));
269 __ add(r6, r6, Operand(1));
270 __ str(r6, MemOperand(r9, kLevelOffset));
272 if (FLAG_log_timer_events) {
273 FrameScope frame(masm, StackFrame::MANUAL);
274 __ PushSafepointRegisters();
275 __ PrepareCallCFunction(1);
276 __ Move(r0, ExternalReference::isolate_address(isolate));
277 __ CallCFunction(ExternalReference::log_enter_external_function(), 1);
278 __ PopSafepointRegisters();
284 DirectCEntryStub stub(isolate);
285 stub.GenerateCall(masm, r3);
287 if (FLAG_log_timer_events) {
288 FrameScope frame(masm, StackFrame::MANUAL);
289 __ PushSafepointRegisters();
290 __ PrepareCallCFunction(1);
291 __ Move(r0, ExternalReference::isolate_address(isolate));
292 __ CallCFunction(ExternalReference::log_leave_external_function(), 1);
293 __ PopSafepointRegisters();
296 Label promote_scheduled_exception;
297 Label delete_allocated_handles;
298 Label leave_exit_frame;
299 Label return_value_loaded;
302 __ ldr(r0, return_value_operand);
303 __ bind(&return_value_loaded);
306 __ str(r4, MemOperand(r9, kNextOffset));
307 if (__ emit_debug_code()) {
308 __ ldr(r1, MemOperand(r9, kLevelOffset));
310 __ Check(eq, AbortReason::kUnexpectedLevelAfterReturnFromApiCall);
312 __ sub(r6, r6, Operand(1));
313 __ str(r6, MemOperand(r9, kLevelOffset));
314 __ ldr(r6, MemOperand(r9, kLimitOffset));
316 __ b(ne, &delete_allocated_handles);
319 __ bind(&leave_exit_frame);
321 if (stack_space_operand !=
nullptr) {
322 __ ldr(r4, *stack_space_operand);
324 __ mov(r4, Operand(stack_space));
326 __ LeaveExitFrame(
false, r4, stack_space_operand !=
nullptr);
329 __ LoadRoot(r4, RootIndex::kTheHoleValue);
330 __ Move(r6, ExternalReference::scheduled_exception_address(isolate));
331 __ ldr(r5, MemOperand(r6));
333 __ b(ne, &promote_scheduled_exception);
338 __ bind(&promote_scheduled_exception);
339 __ TailCallRuntime(Runtime::kPromoteScheduledException);
342 __ bind(&delete_allocated_handles);
343 __ str(r5, MemOperand(r9, kLimitOffset));
345 __ PrepareCallCFunction(1);
346 __ Move(r0, ExternalReference::isolate_address(isolate));
347 __ CallCFunction(ExternalReference::delete_handle_scope_extensions(), 1);
349 __ jmp(&leave_exit_frame);
352 void CallApiCallbackStub::Generate(MacroAssembler* masm) {
365 Register call_data = r4;
366 Register holder = r2;
367 Register api_function_address = r1;
369 typedef FunctionCallbackArguments FCA;
371 STATIC_ASSERT(FCA::kArgsLength == 6);
372 STATIC_ASSERT(FCA::kNewTargetIndex == 5);
373 STATIC_ASSERT(FCA::kDataIndex == 4);
374 STATIC_ASSERT(FCA::kReturnValueOffset == 3);
375 STATIC_ASSERT(FCA::kReturnValueDefaultValueIndex == 2);
376 STATIC_ASSERT(FCA::kIsolateIndex == 1);
377 STATIC_ASSERT(FCA::kHolderIndex == 0);
380 __ PushRoot(RootIndex::kUndefinedValue);
385 Register scratch0 = call_data;
386 Register scratch1 = r5;
387 __ LoadRoot(scratch0, RootIndex::kUndefinedValue);
393 __ Move(scratch1, ExternalReference::isolate_address(masm->isolate()));
399 __ mov(scratch0, sp);
403 const int kApiStackSpace = 3;
405 FrameScope frame_scope(masm, StackFrame::MANUAL);
406 __ EnterExitFrame(
false, kApiStackSpace);
408 DCHECK(api_function_address != r0 && scratch0 != r0);
411 __ add(r0, sp, Operand(1 * kPointerSize));
413 __ str(scratch0, MemOperand(r0, 0 * kPointerSize));
415 __ add(scratch1, scratch0,
416 Operand((FCA::kArgsLength - 1 + argc()) * kPointerSize));
417 __ str(scratch1, MemOperand(r0, 1 * kPointerSize));
419 __ mov(scratch0, Operand(argc()));
420 __ str(scratch0, MemOperand(r0, 2 * kPointerSize));
422 ExternalReference thunk_ref = ExternalReference::invoke_function_callback();
424 AllowExternalCallThatCantCauseGC scope(masm);
426 int return_value_offset = 2 + FCA::kReturnValueOffset;
427 MemOperand return_value_operand(fp, return_value_offset * kPointerSize);
428 const int stack_space = argc() + FCA::kArgsLength + 1;
429 MemOperand* stack_space_operand =
nullptr;
431 CallApiFunctionAndReturn(masm, api_function_address, thunk_ref, stack_space,
432 stack_space_operand, return_value_operand);
436 void CallApiGetterStub::Generate(MacroAssembler* masm) {
439 STATIC_ASSERT(PropertyCallbackArguments::kShouldThrowOnErrorIndex == 0);
440 STATIC_ASSERT(PropertyCallbackArguments::kHolderIndex == 1);
441 STATIC_ASSERT(PropertyCallbackArguments::kIsolateIndex == 2);
442 STATIC_ASSERT(PropertyCallbackArguments::kReturnValueDefaultValueIndex == 3);
443 STATIC_ASSERT(PropertyCallbackArguments::kReturnValueOffset == 4);
444 STATIC_ASSERT(PropertyCallbackArguments::kDataIndex == 5);
445 STATIC_ASSERT(PropertyCallbackArguments::kThisIndex == 6);
446 STATIC_ASSERT(PropertyCallbackArguments::kArgsLength == 7);
448 Register receiver = ApiGetterDescriptor::ReceiverRegister();
449 Register holder = ApiGetterDescriptor::HolderRegister();
450 Register callback = ApiGetterDescriptor::CallbackRegister();
451 Register scratch = r4;
452 DCHECK(!AreAliased(receiver, holder, callback, scratch));
454 Register api_function_address = r2;
458 __ ldr(scratch, FieldMemOperand(callback, AccessorInfo::kDataOffset));
460 __ LoadRoot(scratch, RootIndex::kUndefinedValue);
461 __ Push(scratch, scratch);
462 __ Move(scratch, ExternalReference::isolate_address(isolate()));
463 __ Push(scratch, holder);
464 __ Push(Smi::zero());
465 __ ldr(scratch, FieldMemOperand(callback, AccessorInfo::kNameOffset));
468 const int kStackUnwindSpace = PropertyCallbackArguments::kArgsLength + 1;
472 __ add(r1, r0, Operand(1 * kPointerSize));
474 const int kApiStackSpace = 1;
475 FrameScope frame_scope(masm, StackFrame::MANUAL);
476 __ EnterExitFrame(
false, kApiStackSpace);
480 __ str(r1, MemOperand(sp, 1 * kPointerSize));
481 __ add(r1, sp, Operand(1 * kPointerSize));
483 ExternalReference thunk_ref =
484 ExternalReference::invoke_accessor_getter_callback();
486 __ ldr(scratch, FieldMemOperand(callback, AccessorInfo::kJsGetterOffset));
487 __ ldr(api_function_address,
488 FieldMemOperand(scratch, Foreign::kForeignAddressOffset));
491 MemOperand return_value_operand(
492 fp, (PropertyCallbackArguments::kReturnValueOffset + 3) * kPointerSize);
493 CallApiFunctionAndReturn(masm, api_function_address, thunk_ref,
494 kStackUnwindSpace,
nullptr, return_value_operand);
502 #endif // V8_TARGET_ARCH_ARM