30 #if defined(V8_TARGET_ARCH_X64)
40 #define __ ACCESS_MASM(masm)
43 void Builtins::Generate_Adaptor(MacroAssembler* masm,
59 int num_extra_args = 0;
71 __ addq(
rax, Immediate(num_extra_args + 1));
72 __ JumpToExternalReference(ExternalReference(
id, masm->isolate()), 1);
76 static void Generate_JSConstructStubHelper(MacroAssembler* masm,
78 bool count_constructions) {
85 ASSERT(!is_api_function || !count_constructions);
89 FrameScope scope(masm, StackFrame::CONSTRUCT);
100 Label rt_call, allocated;
101 if (FLAG_inline_new) {
102 Label undo_allocation;
104 #ifdef ENABLE_DEBUGGER_SUPPORT
105 ExternalReference debug_step_in_fp =
106 ExternalReference::debug_step_in_fp_address(masm->isolate());
118 __ JumpIfSmi(
rax, &rt_call);
132 if (count_constructions) {
145 __ CallRuntime(Runtime::kFinalizeInstanceSize, 1);
157 __ AllocateInNewSpace(
rdi,
168 __ LoadRoot(
rcx, Heap::kEmptyFixedArrayRootIndex);
176 __ LoadRoot(
rdx, Heap::kUndefinedValueRootIndex);
177 if (count_constructions) {
183 if (FLAG_debug_code) {
186 "Unexpected number of pre-allocated property fields.");
189 __ LoadRoot(
rdx, Heap::kOnePointerFillerMapRootIndex);
217 __ Assert(
positive,
"Property allocation count failed.");
238 __ LoadRoot(
rcx, Heap::kFixedArrayMapRootIndex);
249 __ LoadRoot(
rdx, Heap::kUndefinedValueRootIndex);
276 __ bind(&undo_allocation);
277 __ UndoAllocationInNewSpace(
rbx);
286 __ CallRuntime(Runtime::kNewObject, 1);
319 if (is_api_function) {
322 masm->isolate()->builtins()->HandleApiCallConstruct();
323 ParameterCount expected(0);
324 __ InvokeCode(code, expected, expected, RelocInfo::CODE_TARGET,
327 ParameterCount actual(
rax);
333 if (!is_api_function && !count_constructions) {
334 masm->isolate()->heap()->SetConstructStubDeoptPCOffset(masm->pc_offset());
343 Label use_receiver, exit;
345 __ JumpIfSmi(
rax, &use_receiver);
355 __ bind(&use_receiver);
370 Counters* counters = masm->isolate()->counters();
371 __ IncrementCounter(counters->constructed_objects(), 1);
376 void Builtins::Generate_JSConstructStubCountdown(MacroAssembler* masm) {
377 Generate_JSConstructStubHelper(masm,
false,
true);
381 void Builtins::Generate_JSConstructStubGeneric(MacroAssembler* masm) {
382 Generate_JSConstructStubHelper(masm,
false,
false);
386 void Builtins::Generate_JSConstructStubApi(MacroAssembler* masm) {
387 Generate_JSConstructStubHelper(masm,
true,
false);
391 static void Generate_JSEntryTrampolineHelper(MacroAssembler* masm,
480 __ addq(
rcx, Immediate(1));
491 ParameterCount actual(
rax);
506 void Builtins::Generate_JSEntryTrampoline(MacroAssembler* masm) {
507 Generate_JSEntryTrampolineHelper(masm,
false);
511 void Builtins::Generate_JSConstructEntryTrampoline(MacroAssembler* masm) {
512 Generate_JSEntryTrampolineHelper(masm,
true);
516 void Builtins::Generate_LazyCompile(MacroAssembler* masm) {
527 __ CallRuntime(Runtime::kLazyCompile, 1);
543 void Builtins::Generate_LazyRecompile(MacroAssembler* masm) {
554 __ CallRuntime(Runtime::kLazyRecompile, 1);
570 static void Generate_NotifyDeoptimizedHelper(MacroAssembler* masm,
579 __ CallRuntime(Runtime::kNotifyDeoptimized, 1);
587 Label not_no_registers, not_tos_rax;
592 __ bind(¬_no_registers);
598 __ bind(¬_tos_rax);
599 __ Abort(
"no cases left");
602 void Builtins::Generate_NotifyDeoptimized(MacroAssembler* masm) {
607 void Builtins::Generate_NotifyLazyDeoptimized(MacroAssembler* masm) {
612 void Builtins::Generate_NotifyOSR(MacroAssembler* masm) {
620 __ CallRuntime(Runtime::kNotifyOSR, 0);
627 void Builtins::Generate_FunctionCall(MacroAssembler* masm) {
643 __ Push(masm->isolate()->factory()->undefined_value());
651 Label slow, non_function;
654 __ JumpIfSmi(
rdi, &non_function);
659 Label shift_arguments;
661 { Label convert_to_object, use_global_receiver, patch_receiver;
679 __ JumpIfSmi(
rbx, &convert_to_object, Label::kNear);
681 __ CompareRoot(
rbx, Heap::kNullValueRootIndex);
682 __ j(
equal, &use_global_receiver);
683 __ CompareRoot(
rbx, Heap::kUndefinedValueRootIndex);
684 __ j(
equal, &use_global_receiver);
690 __ bind(&convert_to_object);
708 __ jmp(&patch_receiver, Label::kNear);
712 __ bind(&use_global_receiver);
713 const int kGlobalIndex =
720 __ bind(&patch_receiver);
723 __ jmp(&shift_arguments);
731 __ bind(&non_function);
743 __ bind(&shift_arguments);
757 { Label
function, non_proxy;
762 __ cmpq(
rdx, Immediate(1));
769 __ GetBuiltinEntry(
rdx, Builtins::CALL_FUNCTION_PROXY);
770 __ jmp(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(),
771 RelocInfo::CODE_TARGET);
774 __ GetBuiltinEntry(
rdx, Builtins::CALL_NON_FUNCTION);
775 __ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(),
776 RelocInfo::CODE_TARGET);
791 masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(),
792 RelocInfo::CODE_TARGET);
794 ParameterCount expected(0);
800 void Builtins::Generate_FunctionApply(MacroAssembler* masm) {
818 __ push(Operand(
rbp, kFunctionOffset));
819 __ push(Operand(
rbp, kArgumentsOffset));
839 __ push(Operand(
rbp, kFunctionOffset));
846 const int kLimitOffset =
848 const int kIndexOffset = kLimitOffset - 1 *
kPointerSize;
850 __ push(Immediate(0));
853 __ movq(
rbx, Operand(
rbp, kReceiverOffset));
857 __ movq(
rdi, Operand(
rbp, kFunctionOffset));
865 Label call_to_object, use_global_receiver;
877 __ JumpIfSmi(
rbx, &call_to_object, Label::kNear);
878 __ CompareRoot(
rbx, Heap::kNullValueRootIndex);
879 __ j(
equal, &use_global_receiver);
880 __ CompareRoot(
rbx, Heap::kUndefinedValueRootIndex);
881 __ j(
equal, &use_global_receiver);
890 __ bind(&call_to_object);
894 __ jmp(&push_receiver, Label::kNear);
897 __ bind(&use_global_receiver);
898 const int kGlobalOffset =
906 __ bind(&push_receiver);
911 __ movq(
rax, Operand(
rbp, kIndexOffset));
914 __ movq(
rdx, Operand(
rbp, kArgumentsOffset));
918 masm->isolate()->builtins()->KeyedLoadIC_Initialize();
919 __ Call(ic, RelocInfo::CODE_TARGET);
929 __ movq(
rax, Operand(
rbp, kIndexOffset));
931 __ movq(Operand(
rbp, kIndexOffset),
rax);
934 __ cmpq(
rax, Operand(
rbp, kLimitOffset));
939 ParameterCount actual(
rax);
941 __ movq(
rdi, Operand(
rbp, kFunctionOffset));
947 frame_scope.GenerateLeaveFrame();
948 __ ret(3 * kPointerSize);
951 __ bind(&call_proxy);
956 __ GetBuiltinEntry(
rdx, Builtins::CALL_FUNCTION_PROXY);
957 __ call(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(),
958 RelocInfo::CODE_TARGET);
962 __ ret(3 * kPointerSize);
970 static void AllocateEmptyJSArray(MacroAssembler* masm,
971 Register array_function,
976 Label* gc_required) {
980 __ LoadInitialArrayMap(array_function, scratch2, scratch1,
false);
985 if (initial_capacity > 0) {
988 __ AllocateInNewSpace(size,
1000 Factory* factory = masm->isolate()->factory();
1003 factory->empty_fixed_array());
1009 if (initial_capacity == 0) {
1011 factory->empty_fixed_array());
1028 factory->fixed_array_map());
1034 static const int kLoopUnfoldLimit = 4;
1035 __ LoadRoot(scratch3, Heap::kTheHoleValueRootIndex);
1036 if (initial_capacity <= kLoopUnfoldLimit) {
1039 for (
int i = 0; i < initial_capacity; i++) {
1046 __ movq(scratch2, Immediate(initial_capacity));
1070 static void AllocateJSArray(MacroAssembler* masm,
1071 Register array_function,
1072 Register array_size,
1074 Register elements_array,
1075 Register elements_array_end,
1077 bool fill_with_hole,
1078 Label* gc_required) {
1079 __ LoadInitialArrayMap(array_function, scratch,
1080 elements_array, fill_with_hole);
1082 if (FLAG_debug_code) {
1083 __ testq(array_size, array_size);
1084 __ Assert(
not_zero,
"array size is unexpectedly 0");
1106 Factory* factory = masm->isolate()->factory();
1108 __ Move(elements_array, factory->empty_fixed_array());
1127 factory->fixed_array_map());
1136 if (fill_with_hole) {
1138 __ LoadRoot(scratch, Heap::kTheHoleValueRootIndex);
1139 __ lea(elements_array, Operand(elements_array,
1143 __ movq(Operand(elements_array, 0), scratch);
1144 __ addq(elements_array, Immediate(kPointerSize));
1146 __ cmpq(elements_array, elements_array_end);
1166 static void ArrayNativeCode(MacroAssembler* masm,
1167 Label* call_generic_code) {
1168 Label argc_one_or_more, argc_two_or_more, empty_array, not_empty_array,
1169 has_non_smi_element, finish, cant_transition_map, not_double;
1175 __ bind(&empty_array);
1177 AllocateEmptyJSArray(masm,
1184 Counters* counters = masm->isolate()->counters();
1185 __ IncrementCounter(counters->array_function_native(), 1);
1187 __ ret(kPointerSize);
1191 __ bind(&argc_one_or_more);
1192 __ cmpq(
rax, Immediate(1));
1194 __ movq(
rdx, Operand(
rsp, kPointerSize));
1201 __ movq(
rax, Immediate(0));
1202 __ jmp(&empty_array);
1204 __ bind(¬_empty_array);
1205 __ JumpUnlessNonNegativeSmi(
rdx, call_generic_code);
1217 AllocateJSArray(masm,
1226 __ IncrementCounter(counters->array_function_native(), 1);
1228 __ ret(2 * kPointerSize);
1231 __ bind(&argc_two_or_more);
1239 AllocateJSArray(masm,
1248 __ IncrementCounter(counters->array_function_native(), 1);
1258 __ lea(
r9, Operand(
rsp, kPointerSize));
1275 if (FLAG_smi_only_arrays) {
1276 __ JumpIfNotSmi(
r8, &has_non_smi_element);
1279 __ addq(
rdx, Immediate(kPointerSize));
1296 __ bind(&has_non_smi_element);
1299 masm->isolate()->factory()->heap_number_map(),
1302 __ bind(&cant_transition_map);
1303 __ UndoAllocationInNewSpace(
rbx);
1304 __ jmp(call_generic_code);
1306 __ bind(¬_double);
1314 &cant_transition_map);
1325 __ addq(
rdx, Immediate(kPointerSize));
1332 void Builtins::Generate_InternalArrayCode(MacroAssembler* masm) {
1338 Label generic_array_code;
1343 if (FLAG_debug_code) {
1349 __ Check(not_smi,
"Unexpected initial map for InternalArray function");
1351 __ Check(
equal,
"Unexpected initial map for InternalArray function");
1356 ArrayNativeCode(masm, &generic_array_code);
1360 __ bind(&generic_array_code);
1361 Handle<Code> array_code =
1362 masm->isolate()->builtins()->InternalArrayCodeGeneric();
1363 __ Jump(array_code, RelocInfo::CODE_TARGET);
1367 void Builtins::Generate_ArrayCode(MacroAssembler* masm) {
1373 Label generic_array_code;
1378 if (FLAG_debug_code) {
1384 __ Check(not_smi,
"Unexpected initial map for Array function");
1386 __ Check(
equal,
"Unexpected initial map for Array function");
1390 ArrayNativeCode(masm, &generic_array_code);
1394 __ bind(&generic_array_code);
1395 Handle<Code> array_code =
1396 masm->isolate()->builtins()->ArrayCodeGeneric();
1397 __ Jump(array_code, RelocInfo::CODE_TARGET);
1401 void Builtins::Generate_ArrayConstructCode(MacroAssembler* masm) {
1408 Label generic_constructor;
1410 if (FLAG_debug_code) {
1418 __ Check(not_smi,
"Unexpected initial map for Array function");
1420 __ Check(
equal,
"Unexpected initial map for Array function");
1424 ArrayNativeCode(masm, &generic_constructor);
1428 __ bind(&generic_constructor);
1429 Handle<Code> generic_construct_stub =
1430 masm->isolate()->builtins()->JSConstructStubGeneric();
1431 __ Jump(generic_construct_stub, RelocInfo::CODE_TARGET);
1435 void Builtins::Generate_StringConstructCode(MacroAssembler* masm) {
1443 Counters* counters = masm->isolate()->counters();
1444 __ IncrementCounter(counters->string_ctor_calls(), 1);
1446 if (FLAG_debug_code) {
1449 __ Assert(
equal,
"Unexpected String function");
1456 __ j(
zero, &no_arguments);
1464 Label not_cached, argument_is_string;
1473 __ IncrementCounter(counters->string_ctor_cached_number(), 1);
1474 __ bind(&argument_is_string);
1492 __ LoadGlobalFunctionInitialMap(
rdi,
rcx);
1493 if (FLAG_debug_code) {
1496 __ Assert(
equal,
"Unexpected string wrapper instance size");
1498 __ Assert(
equal,
"Unexpected unused properties of string wrapper");
1503 __ LoadRoot(
rcx, Heap::kEmptyFixedArrayRootIndex);
1518 Label convert_argument;
1519 __ bind(¬_cached);
1521 __ JumpIfSmi(
rax, &convert_argument);
1525 __ IncrementCounter(counters->string_ctor_string_value(), 1);
1526 __ jmp(&argument_is_string);
1529 __ bind(&convert_argument);
1530 __ IncrementCounter(counters->string_ctor_conversions(), 1);
1539 __ jmp(&argument_is_string);
1543 __ bind(&no_arguments);
1544 __ LoadRoot(
rbx, Heap::kEmptyStringRootIndex);
1546 __ lea(
rsp, Operand(
rsp, kPointerSize));
1548 __ jmp(&argument_is_string);
1552 __ bind(&gc_required);
1553 __ IncrementCounter(counters->string_ctor_gc_required(), 1);
1557 __ CallRuntime(Runtime::kNewStringWrapper, 1);
1563 static void EnterArgumentsAdaptorFrame(MacroAssembler* masm) {
1581 static void LeaveArgumentsAdaptorFrame(MacroAssembler* masm) {
1592 __ lea(
rsp, Operand(
rsp, index.reg, index.scale, 1 * kPointerSize));
1597 void Builtins::Generate_ArgumentsAdaptorTrampoline(MacroAssembler* masm) {
1605 Label invoke, dont_adapt_arguments;
1606 Counters* counters = masm->isolate()->counters();
1607 __ IncrementCounter(counters->arguments_adaptors(), 1);
1609 Label enough, too_few;
1613 __ j(
equal, &dont_adapt_arguments);
1617 EnterArgumentsAdaptorFrame(masm);
1627 __ push(Operand(
rax, 0));
1628 __ subq(
rax, Immediate(kPointerSize));
1636 EnterArgumentsAdaptorFrame(masm);
1646 __ push(Operand(
rdi, 0));
1647 __ subq(
rdi, Immediate(kPointerSize));
1669 masm->isolate()->heap()->SetArgumentsAdaptorDeoptPCOffset(masm->pc_offset());
1672 LeaveArgumentsAdaptorFrame(masm);
1678 __ bind(&dont_adapt_arguments);
1683 void Builtins::Generate_OnStackReplacement(MacroAssembler* masm) {
1705 __ CallRuntime(Runtime::kCompileForOnStackReplacement, 1);
1717 __ bind(&stack_check);
1719 __ CompareRoot(
rsp, Heap::kStackLimitRootIndex);
1722 StackCheckStub stub;
1723 __ TailCallStub(&stub);
1724 if (FLAG_debug_code) {
1725 __ Abort(
"Unreachable code: returned from tail call.");
1738 generator.Generate();
1746 #endif // V8_TARGET_ARCH_X64
static const int kLengthOffset
static const int kCodeOffset
static const int kCodeEntryOffset
static const int kPrototypeOrInitialMapOffset
static const int kAllowOSRAtLoopNestingLevelOffset
static Smi * FromInt(int value)
static const int kGlobalReceiverOffset
static const int kConstructionCountOffset
static const int kNativeByteOffset
static const int kStrictModeBitWithinByte
static const int kCallerSPOffset
#define ASSERT(condition)
const int kPointerSizeLog2
static const int kInstanceSizeOffset
static const int kUnusedPropertyFieldsOffset
static const int kGlobalContextOffset
static const int kContextOffset
STATIC_ASSERT((FixedDoubleArray::kHeaderSize &kDoubleAlignmentMask)==0)
static const int kDontAdaptArgumentsSentinel
Operand FieldOperand(Register object, int offset)
static const int kExpressionsOffset
static const int kPropertiesOffset
static const int kInObjectPropertiesOffset
static const int kElementsOffset
static const int kNativeBitWithinByte
static const int kLengthOffset
static int SizeFor(int length)
static const int kHeaderSize
static const int kMapOffset
static const int kLengthOffset
const Register kScratchRegister
static const int kContextOffset
static const int kFunctionOffset
static const int kFormalParameterCountOffset
static const int kStrictModeByteOffset
static const int kHeaderSize
Condition NegateCondition(Condition cond)
static const int kArgvOffset
static const int kHeaderSize
static void GenerateLookupNumberStringCache(MacroAssembler *masm, Register object, Register result, Register scratch1, Register scratch2, Register scratch3, bool object_is_smi, Label *not_found)
static const int kPreallocatedArrayElements
static const int kValueOffset
static const int kSharedFunctionInfoOffset
static const int kInitialMaxFastElementArray
static const int kPreAllocatedPropertyFieldsOffset