7 #if V8_TARGET_ARCH_ARM64
19 #define __ ACCESS_MASM(masm)
23 static void GenerateLoadArrayFunction(MacroAssembler* masm, Register result) {
36 static void GenerateLoadInternalArrayFunction(MacroAssembler* masm,
63 int num_extra_args = 0;
73 __ Add(x0, x0, num_extra_args + 1);
74 __ JumpToExternalReference(ExternalReference(
id, masm->isolate()));
85 Label generic_array_code;
88 GenerateLoadInternalArrayFunction(masm, x1);
90 if (FLAG_debug_code) {
94 __ Assert(
ne, kUnexpectedInitialMapForInternalArrayFunction);
96 __ Assert(
eq, kUnexpectedInitialMapForInternalArrayFunction);
101 InternalArrayConstructorStub stub(masm->isolate());
102 __ TailCallStub(&stub);
113 Label generic_array_code, one_or_more_arguments, two_or_more_arguments;
116 GenerateLoadArrayFunction(masm, x1);
118 if (FLAG_debug_code) {
122 __ Assert(
ne, kUnexpectedInitialMapForArrayFunction);
123 __ CompareObjectType(x10, x11, x12,
MAP_TYPE);
124 __ Assert(
eq, kUnexpectedInitialMapForArrayFunction);
128 __ LoadRoot(x2, Heap::kUndefinedValueRootIndex);
129 ArrayConstructorStub stub(masm->isolate());
130 __ TailCallStub(&stub);
143 Counters* counters = masm->isolate()->counters();
144 __ IncrementCounter(counters->string_ctor_calls(), 1, x10, x11);
147 Register
function = x1;
148 if (FLAG_debug_code) {
150 __ Cmp(
function, x10);
151 __ Assert(
eq, kUnexpectedStringFunction);
156 __ Cbz(argc, &no_arguments);
158 __ Sub(argc, argc, 1);
165 Register argument = x2;
166 Label not_cached, argument_is_string;
167 __ LookupNumberStringCache(arg,
173 __ IncrementCounter(counters->string_ctor_cached_number(), 1, x10, x11);
174 __ Bind(&argument_is_string);
183 Register new_obj = x0;
188 __ LoadGlobalFunctionInitialMap(
function,
map, x10);
189 if (FLAG_debug_code) {
192 __ Assert(
eq, kUnexpectedStringWrapperInstanceSize);
195 __ Assert(
eq, kUnexpectedUnusedPropertiesOfStringWrapper);
200 __ LoadRoot(empty, Heap::kEmptyFixedArrayRootIndex);
213 Label convert_argument;
214 __ Bind(¬_cached);
215 __ JumpIfSmi(arg, &convert_argument);
221 __ Mov(argument, arg);
222 __ IncrementCounter(counters->string_ctor_string_value(), 1, x10, x11);
223 __ B(&argument_is_string);
226 __ Bind(&convert_argument);
228 __ IncrementCounter(counters->string_ctor_conversions(), 1, x10, x11);
235 __ Mov(argument, x0);
236 __ B(&argument_is_string);
240 __ Bind(&no_arguments);
241 __ LoadRoot(argument, Heap::kempty_stringRootIndex);
243 __ B(&argument_is_string);
247 __ Bind(&gc_required);
248 __ IncrementCounter(counters->string_ctor_gc_required(), 1, x10, x11);
252 __ CallRuntime(Runtime::kNewStringWrapper, 1);
258 static void CallRuntimePassFunction(MacroAssembler* masm,
265 __ CallRuntime(function_id, 1);
272 static void GenerateTailCallToSharedCode(MacroAssembler* masm) {
280 static void GenerateTailCallToReturnedCode(MacroAssembler* masm) {
293 __ CompareRoot(masm->StackPointer(), Heap::kStackLimitRootIndex);
296 CallRuntimePassFunction(masm, Runtime::kTryInstallOptimizedCode);
297 GenerateTailCallToReturnedCode(masm);
300 GenerateTailCallToSharedCode(masm);
304 static void Generate_JSConstructStubHelper(MacroAssembler* masm,
305 bool is_api_function,
306 bool create_memento) {
315 ASM_LOCATION(
"Builtins::Generate_JSConstructStubHelper");
317 DCHECK(!is_api_function || !create_memento);
319 Isolate* isolate = masm->isolate();
323 FrameScope scope(masm, StackFrame::CONSTRUCT);
326 if (create_memento) {
327 __ AssertUndefinedOrAllocationSite(x2, x10);
332 Register constructor = x1;
335 __ Push(argc, constructor);
341 Label rt_call, allocated;
342 if (FLAG_inline_new) {
343 Label undo_allocation;
344 ExternalReference debug_step_in_fp =
345 ExternalReference::debug_step_in_fp_address(isolate);
346 __ Mov(x2, Operand(debug_step_in_fp));
348 __ Cbnz(x2, &rt_call);
350 Register init_map = x2;
354 __ JumpIfSmi(init_map, &rt_call);
355 __ JumpIfNotObjectType(init_map, x10, x11,
MAP_TYPE, &rt_call);
363 Register constructon_count = x14;
364 if (!is_api_function) {
369 __ Ldr(x4, bit_field3);
370 __ DecodeField<Map::ConstructionCount>(constructon_count, x4);
375 __ Str(x4, bit_field3);
381 __ Push(constructor, init_map, constructor);
382 __ CallRuntime(Runtime::kFinalizeInstanceSize, 1);
383 __ Pop(init_map, constructor);
389 Register obj_size = x3;
390 Register new_obj = x4;
392 if (create_memento) {
404 __ LoadRoot(empty, Heap::kEmptyFixedArrayRootIndex);
410 Register first_prop = x5;
414 Register filler = x7;
415 __ LoadRoot(filler, Heap::kUndefinedValueRootIndex);
419 Register prealloc_fields = x10;
420 Register inobject_props = x11;
421 Register inst_sizes = x11;
423 __ Ubfx(prealloc_fields, inst_sizes,
426 __ Ubfx(inobject_props, inst_sizes,
430 Register prop_fields = x6;
433 if (!is_api_function) {
434 Label no_inobject_slack_tracking;
438 __ B(
eq, &no_inobject_slack_tracking);
439 constructon_count = NoReg;
442 __ FillFields(first_prop, prealloc_fields, filler);
446 __ Add(first_prop, first_prop,
449 if (FLAG_debug_code) {
450 Register obj_end = x14;
452 __ Cmp(first_prop, obj_end);
453 __ Assert(
le, kUnexpectedNumberOfPreAllocatedPropertyFields);
457 __ LoadRoot(filler, Heap::kOnePointerFillerMapRootIndex);
458 __ Sub(prop_fields, prop_fields, prealloc_fields);
460 __ bind(&no_inobject_slack_tracking);
462 if (create_memento) {
464 __ FillFields(first_prop, prop_fields, filler);
466 __ LoadRoot(x14, Heap::kAllocationMementoMapRootIndex);
476 __ FillFields(first_prop, prop_fields, filler);
489 Register element_count = x3;
490 __ Ldrb(element_count,
494 __ Add(element_count, element_count, prealloc_fields);
495 __ Subs(element_count, element_count, inobject_props);
498 __ B(
eq, &allocated);
499 __ Assert(
pl, kPropertyAllocationCountFailed);
503 Register new_array = x5;
504 Register array_size = x6;
506 __ Allocate(array_size, new_array, x11, x12, &undo_allocation,
510 Register array_map = x10;
511 __ LoadRoot(array_map, Heap::kFixedArrayMapRootIndex);
513 __ SmiTag(x0, element_count);
517 Register elements = x10;
519 __ FillFields(elements, element_count, filler);
532 __ Bind(&undo_allocation);
533 __ UndoAllocationInNewSpace(new_obj, x14);
538 Label count_incremented;
539 if (create_memento) {
544 __ CallRuntime(Runtime::kNewObjectWithAllocationSite, 2);
549 __ jmp(&count_incremented);
552 __ CallRuntime(Runtime::kNewObject, 1);
560 if (create_memento) {
562 __ JumpIfRoot(x10, Heap::kUndefinedValueRootIndex, &count_incremented);
570 __ bind(&count_incremented);
599 Label loop, entry, done_copying_arguments;
609 __ B(
eq, &done_copying_arguments);
611 __ Bind(&done_copying_arguments);
616 if (is_api_function) {
619 masm->isolate()->builtins()->HandleApiCallConstruct();
622 ParameterCount actual(argc);
623 __ InvokeFunction(constructor, actual,
CALL_FUNCTION, NullCallWrapper());
627 if (!is_api_function) {
628 masm->isolate()->heap()->SetConstructStubDeoptPCOffset(masm->pc_offset());
641 Label use_receiver, exit;
648 __ JumpIfSmi(x0, &use_receiver);
656 __ Bind(&use_receiver);
673 __ IncrementCounter(isolate->counters()->constructed_objects(), 1, x1, x2);
679 Generate_JSConstructStubHelper(masm,
false, FLAG_pretenuring_call_new);
684 Generate_JSConstructStubHelper(masm,
true,
false);
696 static void Generate_JSEntryTrampolineHelper(MacroAssembler* masm,
699 Register
function = x1;
700 Register receiver = x2;
716 __ InitializeRootRegister();
719 __ Push(
function, receiver);
740 __ LoadRoot(x19, Heap::kUndefinedValueRootIndex);
756 __ LoadRoot(x2, Heap::kUndefinedValueRootIndex);
761 ParameterCount actual(x0);
774 Generate_JSEntryTrampolineHelper(masm,
false);
779 Generate_JSEntryTrampolineHelper(masm,
true);
784 CallRuntimePassFunction(masm, Runtime::kCompileLazy);
785 GenerateTailCallToReturnedCode(masm);
789 static void CallCompileOptimized(MacroAssembler* masm,
bool concurrent) {
791 Register
function = x1;
795 __ LoadObject(x10, masm->isolate()->factory()->ToBoolean(concurrent));
796 __ Push(
function,
function, x10);
798 __ CallRuntime(Runtime::kCompileOptimized, 2);
806 CallCompileOptimized(masm,
false);
807 GenerateTailCallToReturnedCode(masm);
812 CallCompileOptimized(masm,
true);
813 GenerateTailCallToReturnedCode(masm);
817 static void GenerateMakeCodeYoungAgainCommon(MacroAssembler* masm) {
832 FrameScope scope(masm, StackFrame::MANUAL);
834 __ Mov(x1, ExternalReference::isolate_address(masm->isolate()));
836 ExternalReference::get_make_code_young_function(masm->isolate()), 2);
845 #define DEFINE_CODE_AGE_BUILTIN_GENERATOR(C) \
846 void Builtins::Generate_Make##C##CodeYoungAgainEvenMarking( \
847 MacroAssembler* masm) { \
848 GenerateMakeCodeYoungAgainCommon(masm); \
850 void Builtins::Generate_Make##C##CodeYoungAgainOddMarking( \
851 MacroAssembler* masm) { \
852 GenerateMakeCodeYoungAgainCommon(masm); \
855 #undef DEFINE_CODE_AGE_BUILTIN_GENERATOR
872 FrameScope scope(masm, StackFrame::MANUAL);
874 __ Mov(x1, ExternalReference::isolate_address(masm->isolate()));
876 ExternalReference::get_mark_code_as_executed_function(
877 masm->isolate()), 2);
881 __ EmitFrameSetupForCodeAgePatching(masm);
891 GenerateMakeCodeYoungAgainCommon(masm);
895 static void Generate_NotifyStubFailureHelper(MacroAssembler* masm,
908 __ CallRuntime(Runtime::kNotifyStubFailure, 0, save_doubles);
927 Generate_NotifyStubFailureHelper(masm,
kSaveFPRegs);
931 static void Generate_NotifyDeoptimizedHelper(MacroAssembler* masm,
938 __ CallRuntime(Runtime::kNotifyDeoptimized, 1);
947 Label with_tos_register, unknown_state;
953 __ Bind(&with_tos_register);
960 __ Bind(&unknown_state);
961 __ Abort(kInvalidFullCodegenState);
987 __ CallRuntime(Runtime::kCompileForOnStackReplacement, 1);
1019 __ CompareRoot(jssp, Heap::kStackLimitRootIndex);
1023 __ CallRuntime(Runtime::kStackGuard, 0);
1025 __ Jump(masm->isolate()->builtins()->OnStackReplacement(),
1035 call_type_JS_func = 0,
1036 call_type_func_proxy = 1,
1037 call_type_non_func = 2
1040 Register
function = x1;
1041 Register call_type = x4;
1042 Register scratch1 = x10;
1043 Register scratch2 = x11;
1044 Register receiver_type = x13;
1049 __ Cbnz(argc, &done);
1050 __ LoadRoot(scratch1, Heap::kUndefinedValueRootIndex);
1058 Label slow, non_function;
1060 __ JumpIfSmi(
function, &non_function);
1061 __ JumpIfNotObjectType(
function, scratch1, receiver_type,
1065 Label shift_arguments;
1066 __ Mov(call_type,
static_cast<int>(call_type_JS_func));
1067 { Label convert_to_object, use_global_proxy, patch_receiver;
1076 __ Ldr(scratch2.W(),
1078 __ TestAndBranchIfAnySet(
1085 Register receiver = x2;
1086 __ Sub(scratch1, argc, 1);
1088 __ JumpIfSmi(receiver, &convert_to_object);
1090 __ JumpIfRoot(receiver, Heap::kUndefinedValueRootIndex,
1092 __ JumpIfRoot(receiver, Heap::kNullValueRootIndex, &use_global_proxy);
1095 __ JumpIfObjectType(receiver, scratch1, scratch2,
1098 __ Bind(&convert_to_object);
1107 __ Mov(receiver, x0);
1117 __ Mov(call_type,
static_cast<int>(call_type_JS_func));
1118 __ B(&patch_receiver);
1120 __ Bind(&use_global_proxy);
1126 __ Bind(&patch_receiver);
1127 __ Sub(scratch1, argc, 1);
1130 __ B(&shift_arguments);
1135 __ Mov(call_type,
static_cast<int>(call_type_func_proxy));
1137 __ B(
eq, &shift_arguments);
1138 __ Bind(&non_function);
1139 __ Mov(call_type,
static_cast<int>(call_type_non_func));
1146 __ Sub(scratch1, argc, 1);
1153 __ Bind(&shift_arguments);
1162 __ Cmp(scratch1, jssp);
1166 __ Sub(argc, argc, 1);
1173 { Label js_function, non_proxy;
1174 __ Cbz(call_type, &js_function);
1177 __ Cmp(call_type,
static_cast<int>(call_type_func_proxy));
1178 __ B(
ne, &non_proxy);
1181 __ Add(argc, argc, 1);
1182 __ GetBuiltinFunction(
function, Builtins::CALL_FUNCTION_PROXY);
1183 __ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(),
1186 __ Bind(&non_proxy);
1187 __ GetBuiltinFunction(
function, Builtins::CALL_NON_FUNCTION);
1188 __ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(),
1190 __ Bind(&js_function);
1200 Label dont_adapt_args;
1202 __ B(
eq, &dont_adapt_args);
1203 __ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(),
1205 __ Bind(&dont_adapt_args);
1208 ParameterCount expected(0);
1209 __ InvokeCode(x3, expected, expected,
JUMP_FUNCTION, NullCallWrapper());
1215 const int kIndexOffset =
1217 const int kLimitOffset =
1226 Register args = x12;
1227 Register receiver = x14;
1228 Register
function = x15;
1240 Label enough_stack_space;
1241 __ LoadRoot(x10, Heap::kRealStackLimitRootIndex);
1246 __ Sub(x10, jssp, x10);
1249 __ B(
gt, &enough_stack_space);
1255 if (
__ emit_debug_code()) {
1259 __ Bind(&enough_stack_space);
1264 Label push_receiver;
1280 Label convert_receiver_to_object, use_global_proxy;
1287 __ JumpIfSmi(receiver, &convert_receiver_to_object);
1288 __ JumpIfRoot(receiver, Heap::kNullValueRootIndex, &use_global_proxy);
1289 __ JumpIfRoot(receiver, Heap::kUndefinedValueRootIndex,
1295 &push_receiver,
ge);
1298 __ Bind(&convert_receiver_to_object);
1301 __ Mov(receiver, x0);
1302 __ B(&push_receiver);
1304 __ Bind(&use_global_proxy);
1309 __ Bind(&push_receiver);
1314 Register current = x0;
1326 __ CallRuntime(Runtime::kGetProperty, 2);
1338 __ Cmp(current, x1);
1349 ParameterCount actual(current);
1350 __ SmiUntag(current);
1352 __ InvokeFunction(
function, actual,
CALL_FUNCTION, NullCallWrapper());
1353 frame_scope.GenerateLeaveFrame();
1358 __ Bind(&call_proxy);
1364 __ GetBuiltinFunction(x1, Builtins::CALL_FUNCTION_PROXY);
1365 __ Call(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(),
1373 static void ArgumentAdaptorStackCheck(MacroAssembler* masm,
1374 Label* stack_overflow) {
1383 Label enough_stack_space;
1384 __ LoadRoot(x10, Heap::kRealStackLimitRootIndex);
1387 __ Sub(x10, jssp, x10);
1390 __ B(
le, stack_overflow);
1394 static void EnterArgumentsAdaptorFrame(MacroAssembler* masm) {
1404 static void LeaveArgumentsAdaptorFrame(MacroAssembler* masm) {
1420 ASM_LOCATION(
"Builtins::Generate_ArgumentsAdaptorTrampoline");
1427 Label stack_overflow;
1428 ArgumentAdaptorStackCheck(masm, &stack_overflow);
1430 Register argc_actual = x0;
1431 Register argc_expected = x2;
1432 Register
function = x1;
1433 Register code_entry = x3;
1435 Label invoke, dont_adapt_arguments;
1437 Label enough, too_few;
1439 __ Cmp(argc_actual, argc_expected);
1442 __ B(
eq, &dont_adapt_arguments);
1445 EnterArgumentsAdaptorFrame(masm);
1447 Register copy_start = x10;
1448 Register copy_end = x11;
1449 Register copy_to = x12;
1450 Register scratch1 = x13, scratch2 = x14;
1457 __ Sub(copy_end, copy_start, argc_expected);
1459 __ Mov(copy_to, jssp);
1465 __ Claim(scratch1, 1);
1469 __ Bind(©_2_by_2);
1470 __ Ldp(scratch1, scratch2,
1472 __ Stp(scratch1, scratch2,
1474 __ Cmp(copy_start, copy_end);
1475 __ B(
hi, ©_2_by_2);
1485 EnterArgumentsAdaptorFrame(masm);
1487 Register copy_from = x10;
1488 Register copy_end = x11;
1489 Register copy_to = x12;
1490 Register scratch1 = x13, scratch2 = x14;
1497 __ Add(copy_from, copy_from, argc_actual);
1498 __ Mov(copy_to, jssp);
1500 __ Sub(copy_end, copy_end, argc_actual);
1506 __ Claim(scratch1, 1);
1510 __ Bind(©_2_by_2);
1511 __ Ldp(scratch1, scratch2,
1513 __ Stp(scratch1, scratch2,
1515 __ Cmp(copy_to, copy_end);
1516 __ B(
hi, ©_2_by_2);
1518 __ Mov(copy_to, copy_end);
1521 __ LoadRoot(scratch1, Heap::kUndefinedValueRootIndex);
1526 __ Stp(scratch1, scratch1,
1528 __ Cmp(copy_to, copy_end);
1537 __ Call(code_entry);
1540 masm->isolate()->heap()->SetArgumentsAdaptorDeoptPCOffset(masm->pc_offset());
1543 LeaveArgumentsAdaptorFrame(masm);
1547 __ Bind(&dont_adapt_arguments);
1548 __ Jump(code_entry);
1550 __ Bind(&stack_overflow);
1552 FrameScope frame(masm, StackFrame::MANUAL);
1553 EnterArgumentsAdaptorFrame(masm);
static const int kAllocationSiteOffset
static const int kPretenureCreateCountOffset
static void Generate_InternalArrayCode(MacroAssembler *masm)
static void Generate_FunctionApply(MacroAssembler *masm)
static void Generate_Adaptor(MacroAssembler *masm, CFunctionId id, BuiltinExtraArguments extra_args)
static void Generate_NotifyDeoptimized(MacroAssembler *masm)
static void Generate_JSConstructEntryTrampoline(MacroAssembler *masm)
static void Generate_CompileLazy(MacroAssembler *masm)
static void Generate_JSEntryTrampoline(MacroAssembler *masm)
static void Generate_OnStackReplacement(MacroAssembler *masm)
static void Generate_MarkCodeAsExecutedTwice(MacroAssembler *masm)
static void Generate_NotifyLazyDeoptimized(MacroAssembler *masm)
static void Generate_ArgumentsAdaptorTrampoline(MacroAssembler *masm)
static void Generate_JSConstructStubApi(MacroAssembler *masm)
static void Generate_FunctionCall(MacroAssembler *masm)
static void Generate_MarkCodeAsExecutedOnce(MacroAssembler *masm)
static void Generate_NotifyStubFailureSaveDoubles(MacroAssembler *masm)
static void Generate_NotifySoftDeoptimized(MacroAssembler *masm)
static void Generate_ArrayCode(MacroAssembler *masm)
static void Generate_StringConstructCode(MacroAssembler *masm)
static void Generate_NotifyStubFailure(MacroAssembler *masm)
static void Generate_CompileOptimized(MacroAssembler *masm)
static void Generate_OsrAfterStackCheck(MacroAssembler *masm)
static void Generate_InOptimizationQueue(MacroAssembler *masm)
static void Generate_CompileOptimizedConcurrent(MacroAssembler *masm)
static void Generate_JSConstructStubGeneric(MacroAssembler *masm)
static const int kHeaderSize
static const int kDeoptimizationDataOffset
@ INTERNAL_ARRAY_FUNCTION_INDEX
static int SlotOffset(int index)
static const int kLengthOffset
static const int kHeaderSize
static int OffsetOfElementAt(int index)
static const int kNativeContextOffset
static const int kGlobalProxyOffset
static const int kMapOffset
static const int kSharedFunctionInfoOffset
static const int kNoSlackTracking
static const int kContextOffset
static const int kFinishSlackTracking
static const int kCodeEntryOffset
static const int kPrototypeOrInitialMapOffset
static const int kHeaderSize
static const int kPropertiesOffset
static const int kElementsOffset
static const int kValueOffset
static const int kFunctionOffset
static const int kInObjectPropertiesByte
static const int kBitField3Offset
static const int kInstanceTypeOffset
static const int kPreAllocatedPropertyFieldsByte
static const int kInstanceSizesOffset
static const int kInstanceSizeOffset
static const int kUnusedPropertyFieldsOffset
static Operand UntagSmiAndScale(Register smi, int scale)
static void MaybeCallEntryHook(MacroAssembler *masm)
static const int kFormalParameterCountOffset
static const int kDontAdaptArgumentsSentinel
static const int kCompilerHintsOffset
static const int kCodeOffset
static Smi * FromInt(int value)
static const int kFixedFrameSizeFromFp
static const int kContextOffset
static const int kExpressionsOffset
static const int kCallerSPOffset
enable harmony numeric enable harmony object literal extensions Optimize object Array DOM strings and string trace pretenuring decisions of HAllocate instructions Enables optimizations which favor memory size over execution speed maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining trace the tracking of allocation sites deoptimize every n garbage collections perform array bounds checks elimination analyze liveness of environment slots and zap dead values flushes the cache of optimized code for closures on every GC allow uint32 values on optimize frames if they are used only in safe operations track concurrent recompilation artificial compilation delay in ms do not emit check maps for constant values that have a leaf map
#define DCHECK(condition)
#define DCHECK_EQ(v1, v2)
#define ASM_LOCATION(message)
static int Push(SpecialRPOStackFrame *stack, int depth, BasicBlock *child, int unvisited)
int MaskToBit(uint64_t mask)
MemOperand GlobalObjectMemOperand()
const int kPointerSizeLog2
MemOperand ContextMemOperand(Register context, int index)
MemOperand FieldMemOperand(Register object, int offset)
const unsigned kXRegSizeLog2
MemOperand UntagSmiFieldMemOperand(Register object, int offset)
STATIC_ASSERT(sizeof(CPURegister)==sizeof(Register))
const intptr_t kSmiTagMask
@ NO_CALL_CONSTRUCTOR_FLAGS
static const int kNoCodeAgeSequenceLength
const uint32_t kIsNotStringMask
const RegList kSafepointSavedRegisters
Debugger support for the V8 JavaScript engine.