OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 #if V8_TARGET_ARCH_X64 | 5 #if V8_TARGET_ARCH_X64 |
6 | 6 |
7 #include "src/code-factory.h" | 7 #include "src/code-factory.h" |
8 #include "src/codegen.h" | 8 #include "src/codegen.h" |
9 #include "src/deoptimizer.h" | 9 #include "src/deoptimizer.h" |
10 #include "src/full-codegen/full-codegen.h" | 10 #include "src/full-codegen/full-codegen.h" |
11 | 11 |
12 namespace v8 { | 12 namespace v8 { |
13 namespace internal { | 13 namespace internal { |
14 | 14 |
15 | |
16 #define __ ACCESS_MASM(masm) | 15 #define __ ACCESS_MASM(masm) |
17 | 16 |
18 void Builtins::Generate_Adaptor(MacroAssembler* masm, CFunctionId id, | 17 void Builtins::Generate_Adaptor(MacroAssembler* masm, CFunctionId id, |
19 ExitFrameType exit_frame_type) { | 18 ExitFrameType exit_frame_type) { |
20 // ----------- S t a t e ------------- | 19 // ----------- S t a t e ------------- |
21 // -- rax : number of arguments excluding receiver | 20 // -- rax : number of arguments excluding receiver |
22 // -- rdi : target | 21 // -- rdi : target |
23 // -- rdx : new.target | 22 // -- rdx : new.target |
24 // -- rsp[0] : return address | 23 // -- rsp[0] : return address |
25 // -- rsp[8] : last argument | 24 // -- rsp[8] : last argument |
(...skipping 21 matching lines...) Expand all Loading... |
47 __ Push(rax); | 46 __ Push(rax); |
48 __ SmiToInteger32(rax, rax); | 47 __ SmiToInteger32(rax, rax); |
49 __ Push(rdi); | 48 __ Push(rdi); |
50 __ Push(rdx); | 49 __ Push(rdx); |
51 __ PushReturnAddressFrom(kScratchRegister); | 50 __ PushReturnAddressFrom(kScratchRegister); |
52 | 51 |
53 __ JumpToExternalReference(ExternalReference(id, masm->isolate()), | 52 __ JumpToExternalReference(ExternalReference(id, masm->isolate()), |
54 exit_frame_type == BUILTIN_EXIT); | 53 exit_frame_type == BUILTIN_EXIT); |
55 } | 54 } |
56 | 55 |
57 | |
58 static void GenerateTailCallToSharedCode(MacroAssembler* masm) { | 56 static void GenerateTailCallToSharedCode(MacroAssembler* masm) { |
59 __ movp(kScratchRegister, | 57 __ movp(kScratchRegister, |
60 FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset)); | 58 FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset)); |
61 __ movp(kScratchRegister, | 59 __ movp(kScratchRegister, |
62 FieldOperand(kScratchRegister, SharedFunctionInfo::kCodeOffset)); | 60 FieldOperand(kScratchRegister, SharedFunctionInfo::kCodeOffset)); |
63 __ leap(kScratchRegister, FieldOperand(kScratchRegister, Code::kHeaderSize)); | 61 __ leap(kScratchRegister, FieldOperand(kScratchRegister, Code::kHeaderSize)); |
64 __ jmp(kScratchRegister); | 62 __ jmp(kScratchRegister); |
65 } | 63 } |
66 | 64 |
67 static void GenerateTailCallToReturnedCode(MacroAssembler* masm, | 65 static void GenerateTailCallToReturnedCode(MacroAssembler* masm, |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
104 Label ok; | 102 Label ok; |
105 __ CompareRoot(rsp, Heap::kStackLimitRootIndex); | 103 __ CompareRoot(rsp, Heap::kStackLimitRootIndex); |
106 __ j(above_equal, &ok); | 104 __ j(above_equal, &ok); |
107 | 105 |
108 GenerateTailCallToReturnedCode(masm, Runtime::kTryInstallOptimizedCode); | 106 GenerateTailCallToReturnedCode(masm, Runtime::kTryInstallOptimizedCode); |
109 | 107 |
110 __ bind(&ok); | 108 __ bind(&ok); |
111 GenerateTailCallToSharedCode(masm); | 109 GenerateTailCallToSharedCode(masm); |
112 } | 110 } |
113 | 111 |
114 | |
115 static void Generate_JSConstructStubHelper(MacroAssembler* masm, | 112 static void Generate_JSConstructStubHelper(MacroAssembler* masm, |
116 bool is_api_function, | 113 bool is_api_function, |
117 bool create_implicit_receiver, | 114 bool create_implicit_receiver, |
118 bool check_derived_construct) { | 115 bool check_derived_construct) { |
119 // ----------- S t a t e ------------- | 116 // ----------- S t a t e ------------- |
120 // -- rax: number of arguments | 117 // -- rax: number of arguments |
121 // -- rsi: context | 118 // -- rsi: context |
122 // -- rdi: constructor function | 119 // -- rdi: constructor function |
123 // -- rbx: allocation site or undefined | 120 // -- rbx: allocation site or undefined |
124 // -- rdx: new target | 121 // -- rdx: new target |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
239 SmiIndex index = masm->SmiToIndex(rbx, rbx, kPointerSizeLog2); | 236 SmiIndex index = masm->SmiToIndex(rbx, rbx, kPointerSizeLog2); |
240 __ leap(rsp, Operand(rsp, index.reg, index.scale, 1 * kPointerSize)); | 237 __ leap(rsp, Operand(rsp, index.reg, index.scale, 1 * kPointerSize)); |
241 __ PushReturnAddressFrom(rcx); | 238 __ PushReturnAddressFrom(rcx); |
242 if (create_implicit_receiver) { | 239 if (create_implicit_receiver) { |
243 Counters* counters = masm->isolate()->counters(); | 240 Counters* counters = masm->isolate()->counters(); |
244 __ IncrementCounter(counters->constructed_objects(), 1); | 241 __ IncrementCounter(counters->constructed_objects(), 1); |
245 } | 242 } |
246 __ ret(0); | 243 __ ret(0); |
247 } | 244 } |
248 | 245 |
249 | |
250 void Builtins::Generate_JSConstructStubGeneric(MacroAssembler* masm) { | 246 void Builtins::Generate_JSConstructStubGeneric(MacroAssembler* masm) { |
251 Generate_JSConstructStubHelper(masm, false, true, false); | 247 Generate_JSConstructStubHelper(masm, false, true, false); |
252 } | 248 } |
253 | 249 |
254 | |
255 void Builtins::Generate_JSConstructStubApi(MacroAssembler* masm) { | 250 void Builtins::Generate_JSConstructStubApi(MacroAssembler* masm) { |
256 Generate_JSConstructStubHelper(masm, true, false, false); | 251 Generate_JSConstructStubHelper(masm, true, false, false); |
257 } | 252 } |
258 | 253 |
259 | |
260 void Builtins::Generate_JSBuiltinsConstructStub(MacroAssembler* masm) { | 254 void Builtins::Generate_JSBuiltinsConstructStub(MacroAssembler* masm) { |
261 Generate_JSConstructStubHelper(masm, false, false, false); | 255 Generate_JSConstructStubHelper(masm, false, false, false); |
262 } | 256 } |
263 | 257 |
264 | |
265 void Builtins::Generate_JSBuiltinsConstructStubForDerived( | 258 void Builtins::Generate_JSBuiltinsConstructStubForDerived( |
266 MacroAssembler* masm) { | 259 MacroAssembler* masm) { |
267 Generate_JSConstructStubHelper(masm, false, false, true); | 260 Generate_JSConstructStubHelper(masm, false, false, true); |
268 } | 261 } |
269 | 262 |
270 | |
271 void Builtins::Generate_ConstructedNonConstructable(MacroAssembler* masm) { | 263 void Builtins::Generate_ConstructedNonConstructable(MacroAssembler* masm) { |
272 FrameScope scope(masm, StackFrame::INTERNAL); | 264 FrameScope scope(masm, StackFrame::INTERNAL); |
273 __ Push(rdi); | 265 __ Push(rdi); |
274 __ CallRuntime(Runtime::kThrowConstructedNonConstructable); | 266 __ CallRuntime(Runtime::kThrowConstructedNonConstructable); |
275 } | 267 } |
276 | 268 |
277 | |
278 enum IsTagged { kRaxIsSmiTagged, kRaxIsUntaggedInt }; | 269 enum IsTagged { kRaxIsSmiTagged, kRaxIsUntaggedInt }; |
279 | 270 |
280 | |
281 // Clobbers rcx, r11, kScratchRegister; preserves all other registers. | 271 // Clobbers rcx, r11, kScratchRegister; preserves all other registers. |
282 static void Generate_CheckStackOverflow(MacroAssembler* masm, | 272 static void Generate_CheckStackOverflow(MacroAssembler* masm, |
283 IsTagged rax_is_tagged) { | 273 IsTagged rax_is_tagged) { |
284 // rax : the number of items to be pushed to the stack | 274 // rax : the number of items to be pushed to the stack |
285 // | 275 // |
286 // Check the stack for overflow. We are not trying to catch | 276 // Check the stack for overflow. We are not trying to catch |
287 // interruptions (e.g. debug break and preemption) here, so the "real stack | 277 // interruptions (e.g. debug break and preemption) here, so the "real stack |
288 // limit" is checked. | 278 // limit" is checked. |
289 Label okay; | 279 Label okay; |
290 __ LoadRoot(kScratchRegister, Heap::kRealStackLimitRootIndex); | 280 __ LoadRoot(kScratchRegister, Heap::kRealStackLimitRootIndex); |
(...skipping 13 matching lines...) Expand all Loading... |
304 // Check if the arguments will overflow the stack. | 294 // Check if the arguments will overflow the stack. |
305 __ cmpp(rcx, r11); | 295 __ cmpp(rcx, r11); |
306 __ j(greater, &okay); // Signed comparison. | 296 __ j(greater, &okay); // Signed comparison. |
307 | 297 |
308 // Out of stack space. | 298 // Out of stack space. |
309 __ CallRuntime(Runtime::kThrowStackOverflow); | 299 __ CallRuntime(Runtime::kThrowStackOverflow); |
310 | 300 |
311 __ bind(&okay); | 301 __ bind(&okay); |
312 } | 302 } |
313 | 303 |
314 | |
315 static void Generate_JSEntryTrampolineHelper(MacroAssembler* masm, | 304 static void Generate_JSEntryTrampolineHelper(MacroAssembler* masm, |
316 bool is_construct) { | 305 bool is_construct) { |
317 ProfileEntryHookStub::MaybeCallEntryHook(masm); | 306 ProfileEntryHookStub::MaybeCallEntryHook(masm); |
318 | 307 |
319 // Expects five C++ function parameters. | 308 // Expects five C++ function parameters. |
320 // - Object* new_target | 309 // - Object* new_target |
321 // - JSFunction* function | 310 // - JSFunction* function |
322 // - Object* receiver | 311 // - Object* receiver |
323 // - int argc | 312 // - int argc |
324 // - Object*** argv | 313 // - Object*** argv |
325 // (see Handle::Invoke in execution.cc). | 314 // (see Handle::Invoke in execution.cc). |
326 | 315 |
327 // Open a C++ scope for the FrameScope. | 316 // Open a C++ scope for the FrameScope. |
328 { | 317 { |
329 // Platform specific argument handling. After this, the stack contains | 318 // Platform specific argument handling. After this, the stack contains |
330 // an internal frame and the pushed function and receiver, and | 319 // an internal frame and the pushed function and receiver, and |
331 // register rax and rbx holds the argument count and argument array, | 320 // register rax and rbx holds the argument count and argument array, |
332 // while rdi holds the function pointer, rsi the context, and rdx the | 321 // while rdi holds the function pointer, rsi the context, and rdx the |
333 // new.target. | 322 // new.target. |
334 | 323 |
335 #ifdef _WIN64 | 324 #ifdef _WIN64 |
336 // MSVC parameters in: | 325 // MSVC parameters in: |
337 // rcx : new_target | 326 // rcx : new_target |
338 // rdx : function | 327 // rdx : function |
339 // r8 : receiver | 328 // r8 : receiver |
340 // r9 : argc | 329 // r9 : argc |
341 // [rsp+0x20] : argv | 330 // [rsp+0x20] : argv |
342 | 331 |
343 // Enter an internal frame. | 332 // Enter an internal frame. |
(...skipping 10 matching lines...) Expand all Loading... |
354 | 343 |
355 // Load the number of arguments and setup pointer to the arguments. | 344 // Load the number of arguments and setup pointer to the arguments. |
356 __ movp(rax, r9); | 345 __ movp(rax, r9); |
357 // Load the previous frame pointer to access C argument on stack | 346 // Load the previous frame pointer to access C argument on stack |
358 __ movp(kScratchRegister, Operand(rbp, 0)); | 347 __ movp(kScratchRegister, Operand(rbp, 0)); |
359 __ movp(rbx, Operand(kScratchRegister, EntryFrameConstants::kArgvOffset)); | 348 __ movp(rbx, Operand(kScratchRegister, EntryFrameConstants::kArgvOffset)); |
360 // Load the function pointer into rdi. | 349 // Load the function pointer into rdi. |
361 __ movp(rdi, rdx); | 350 __ movp(rdi, rdx); |
362 // Load the new.target into rdx. | 351 // Load the new.target into rdx. |
363 __ movp(rdx, rcx); | 352 __ movp(rdx, rcx); |
364 #else // _WIN64 | 353 #else // _WIN64 |
365 // GCC parameters in: | 354 // GCC parameters in: |
366 // rdi : new_target | 355 // rdi : new_target |
367 // rsi : function | 356 // rsi : function |
368 // rdx : receiver | 357 // rdx : receiver |
369 // rcx : argc | 358 // rcx : argc |
370 // r8 : argv | 359 // r8 : argv |
371 | 360 |
372 __ movp(r11, rdi); | 361 __ movp(r11, rdi); |
373 __ movp(rdi, rsi); | 362 __ movp(rdi, rsi); |
374 // rdi : function | 363 // rdi : function |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
434 | 423 |
435 // Exit the internal frame. Notice that this also removes the empty | 424 // Exit the internal frame. Notice that this also removes the empty |
436 // context and the function left on the stack by the code | 425 // context and the function left on the stack by the code |
437 // invocation. | 426 // invocation. |
438 } | 427 } |
439 | 428 |
440 // TODO(X64): Is argument correct? Is there a receiver to remove? | 429 // TODO(X64): Is argument correct? Is there a receiver to remove? |
441 __ ret(1 * kPointerSize); // Remove receiver. | 430 __ ret(1 * kPointerSize); // Remove receiver. |
442 } | 431 } |
443 | 432 |
444 | |
445 void Builtins::Generate_JSEntryTrampoline(MacroAssembler* masm) { | 433 void Builtins::Generate_JSEntryTrampoline(MacroAssembler* masm) { |
446 Generate_JSEntryTrampolineHelper(masm, false); | 434 Generate_JSEntryTrampolineHelper(masm, false); |
447 } | 435 } |
448 | 436 |
449 | |
450 void Builtins::Generate_JSConstructEntryTrampoline(MacroAssembler* masm) { | 437 void Builtins::Generate_JSConstructEntryTrampoline(MacroAssembler* masm) { |
451 Generate_JSEntryTrampolineHelper(masm, true); | 438 Generate_JSEntryTrampolineHelper(masm, true); |
452 } | 439 } |
453 | 440 |
454 // static | 441 // static |
455 void Builtins::Generate_ResumeGeneratorTrampoline(MacroAssembler* masm) { | 442 void Builtins::Generate_ResumeGeneratorTrampoline(MacroAssembler* masm) { |
456 // ----------- S t a t e ------------- | 443 // ----------- S t a t e ------------- |
457 // -- rax : the value to pass to the generator | 444 // -- rax : the value to pass to the generator |
458 // -- rbx : the JSGeneratorObject to resume | 445 // -- rbx : the JSGeneratorObject to resume |
459 // -- rdx : the resume mode (tagged) | 446 // -- rdx : the resume mode (tagged) |
(...skipping 612 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1072 | 1059 |
1073 void Builtins::Generate_CompileBaseline(MacroAssembler* masm) { | 1060 void Builtins::Generate_CompileBaseline(MacroAssembler* masm) { |
1074 GenerateTailCallToReturnedCode(masm, Runtime::kCompileBaseline); | 1061 GenerateTailCallToReturnedCode(masm, Runtime::kCompileBaseline); |
1075 } | 1062 } |
1076 | 1063 |
1077 void Builtins::Generate_CompileOptimized(MacroAssembler* masm) { | 1064 void Builtins::Generate_CompileOptimized(MacroAssembler* masm) { |
1078 GenerateTailCallToReturnedCode(masm, | 1065 GenerateTailCallToReturnedCode(masm, |
1079 Runtime::kCompileOptimized_NotConcurrent); | 1066 Runtime::kCompileOptimized_NotConcurrent); |
1080 } | 1067 } |
1081 | 1068 |
1082 | |
1083 void Builtins::Generate_CompileOptimizedConcurrent(MacroAssembler* masm) { | 1069 void Builtins::Generate_CompileOptimizedConcurrent(MacroAssembler* masm) { |
1084 GenerateTailCallToReturnedCode(masm, Runtime::kCompileOptimized_Concurrent); | 1070 GenerateTailCallToReturnedCode(masm, Runtime::kCompileOptimized_Concurrent); |
1085 } | 1071 } |
1086 | 1072 |
1087 void Builtins::Generate_InstantiateAsmJs(MacroAssembler* masm) { | 1073 void Builtins::Generate_InstantiateAsmJs(MacroAssembler* masm) { |
1088 // ----------- S t a t e ------------- | 1074 // ----------- S t a t e ------------- |
1089 // -- rax : argument count (preserved for callee) | 1075 // -- rax : argument count (preserved for callee) |
1090 // -- rdx : new target (preserved for callee) | 1076 // -- rdx : new target (preserved for callee) |
1091 // -- rdi : target function (preserved for callee) | 1077 // -- rdi : target function (preserved for callee) |
1092 // ----------------------------------- | 1078 // ----------------------------------- |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1141 { // NOLINT | 1127 { // NOLINT |
1142 FrameScope scope(masm, StackFrame::MANUAL); | 1128 FrameScope scope(masm, StackFrame::MANUAL); |
1143 __ PrepareCallCFunction(2); | 1129 __ PrepareCallCFunction(2); |
1144 __ CallCFunction( | 1130 __ CallCFunction( |
1145 ExternalReference::get_make_code_young_function(masm->isolate()), 2); | 1131 ExternalReference::get_make_code_young_function(masm->isolate()), 2); |
1146 } | 1132 } |
1147 __ Popad(); | 1133 __ Popad(); |
1148 __ ret(0); | 1134 __ ret(0); |
1149 } | 1135 } |
1150 | 1136 |
1151 | 1137 #define DEFINE_CODE_AGE_BUILTIN_GENERATOR(C) \ |
1152 #define DEFINE_CODE_AGE_BUILTIN_GENERATOR(C) \ | 1138 void Builtins::Generate_Make##C##CodeYoungAgainEvenMarking( \ |
1153 void Builtins::Generate_Make##C##CodeYoungAgainEvenMarking( \ | 1139 MacroAssembler* masm) { \ |
1154 MacroAssembler* masm) { \ | 1140 GenerateMakeCodeYoungAgainCommon(masm); \ |
1155 GenerateMakeCodeYoungAgainCommon(masm); \ | 1141 } \ |
1156 } \ | 1142 void Builtins::Generate_Make##C##CodeYoungAgainOddMarking( \ |
1157 void Builtins::Generate_Make##C##CodeYoungAgainOddMarking( \ | 1143 MacroAssembler* masm) { \ |
1158 MacroAssembler* masm) { \ | 1144 GenerateMakeCodeYoungAgainCommon(masm); \ |
1159 GenerateMakeCodeYoungAgainCommon(masm); \ | 1145 } |
1160 } | |
1161 CODE_AGE_LIST(DEFINE_CODE_AGE_BUILTIN_GENERATOR) | 1146 CODE_AGE_LIST(DEFINE_CODE_AGE_BUILTIN_GENERATOR) |
1162 #undef DEFINE_CODE_AGE_BUILTIN_GENERATOR | 1147 #undef DEFINE_CODE_AGE_BUILTIN_GENERATOR |
1163 | 1148 |
1164 | |
1165 void Builtins::Generate_MarkCodeAsExecutedOnce(MacroAssembler* masm) { | 1149 void Builtins::Generate_MarkCodeAsExecutedOnce(MacroAssembler* masm) { |
1166 // For now, as in GenerateMakeCodeYoungAgainCommon, we are relying on the fact | 1150 // For now, as in GenerateMakeCodeYoungAgainCommon, we are relying on the fact |
1167 // that make_code_young doesn't do any garbage collection which allows us to | 1151 // that make_code_young doesn't do any garbage collection which allows us to |
1168 // save/restore the registers without worrying about which of them contain | 1152 // save/restore the registers without worrying about which of them contain |
1169 // pointers. | 1153 // pointers. |
1170 __ Pushad(); | 1154 __ Pushad(); |
1171 __ Move(arg_reg_2, ExternalReference::isolate_address(masm->isolate())); | 1155 __ Move(arg_reg_2, ExternalReference::isolate_address(masm->isolate())); |
1172 __ movp(arg_reg_1, Operand(rsp, kNumSafepointRegisters * kPointerSize)); | 1156 __ movp(arg_reg_1, Operand(rsp, kNumSafepointRegisters * kPointerSize)); |
1173 __ subp(arg_reg_1, Immediate(Assembler::kShortCallInstructionLength)); | 1157 __ subp(arg_reg_1, Immediate(Assembler::kShortCallInstructionLength)); |
1174 { // NOLINT | 1158 { // NOLINT |
(...skipping 10 matching lines...) Expand all Loading... |
1185 __ pushq(rbp); // Caller's frame pointer. | 1169 __ pushq(rbp); // Caller's frame pointer. |
1186 __ movp(rbp, rsp); | 1170 __ movp(rbp, rsp); |
1187 __ Push(rsi); // Callee's context. | 1171 __ Push(rsi); // Callee's context. |
1188 __ Push(rdi); // Callee's JS Function. | 1172 __ Push(rdi); // Callee's JS Function. |
1189 __ PushReturnAddressFrom(kScratchRegister); | 1173 __ PushReturnAddressFrom(kScratchRegister); |
1190 | 1174 |
1191 // Jump to point after the code-age stub. | 1175 // Jump to point after the code-age stub. |
1192 __ ret(0); | 1176 __ ret(0); |
1193 } | 1177 } |
1194 | 1178 |
1195 | |
1196 void Builtins::Generate_MarkCodeAsExecutedTwice(MacroAssembler* masm) { | 1179 void Builtins::Generate_MarkCodeAsExecutedTwice(MacroAssembler* masm) { |
1197 GenerateMakeCodeYoungAgainCommon(masm); | 1180 GenerateMakeCodeYoungAgainCommon(masm); |
1198 } | 1181 } |
1199 | 1182 |
1200 | |
1201 void Builtins::Generate_MarkCodeAsToBeExecutedOnce(MacroAssembler* masm) { | 1183 void Builtins::Generate_MarkCodeAsToBeExecutedOnce(MacroAssembler* masm) { |
1202 Generate_MarkCodeAsExecutedOnce(masm); | 1184 Generate_MarkCodeAsExecutedOnce(masm); |
1203 } | 1185 } |
1204 | 1186 |
1205 | |
1206 static void Generate_NotifyStubFailureHelper(MacroAssembler* masm, | 1187 static void Generate_NotifyStubFailureHelper(MacroAssembler* masm, |
1207 SaveFPRegsMode save_doubles) { | 1188 SaveFPRegsMode save_doubles) { |
1208 // Enter an internal frame. | 1189 // Enter an internal frame. |
1209 { | 1190 { |
1210 FrameScope scope(masm, StackFrame::INTERNAL); | 1191 FrameScope scope(masm, StackFrame::INTERNAL); |
1211 | 1192 |
1212 // Preserve registers across notification, this is important for compiled | 1193 // Preserve registers across notification, this is important for compiled |
1213 // stubs that tail call the runtime on deopts passing their parameters in | 1194 // stubs that tail call the runtime on deopts passing their parameters in |
1214 // registers. | 1195 // registers. |
1215 __ Pushad(); | 1196 __ Pushad(); |
1216 __ CallRuntime(Runtime::kNotifyStubFailure, save_doubles); | 1197 __ CallRuntime(Runtime::kNotifyStubFailure, save_doubles); |
1217 __ Popad(); | 1198 __ Popad(); |
1218 // Tear down internal frame. | 1199 // Tear down internal frame. |
1219 } | 1200 } |
1220 | 1201 |
1221 __ DropUnderReturnAddress(1); // Ignore state offset | 1202 __ DropUnderReturnAddress(1); // Ignore state offset |
1222 __ ret(0); // Return to IC Miss stub, continuation still on stack. | 1203 __ ret(0); // Return to IC Miss stub, continuation still on stack. |
1223 } | 1204 } |
1224 | 1205 |
1225 | |
1226 void Builtins::Generate_NotifyStubFailure(MacroAssembler* masm) { | 1206 void Builtins::Generate_NotifyStubFailure(MacroAssembler* masm) { |
1227 Generate_NotifyStubFailureHelper(masm, kDontSaveFPRegs); | 1207 Generate_NotifyStubFailureHelper(masm, kDontSaveFPRegs); |
1228 } | 1208 } |
1229 | 1209 |
1230 | |
1231 void Builtins::Generate_NotifyStubFailureSaveDoubles(MacroAssembler* masm) { | 1210 void Builtins::Generate_NotifyStubFailureSaveDoubles(MacroAssembler* masm) { |
1232 Generate_NotifyStubFailureHelper(masm, kSaveFPRegs); | 1211 Generate_NotifyStubFailureHelper(masm, kSaveFPRegs); |
1233 } | 1212 } |
1234 | 1213 |
1235 | |
1236 static void Generate_NotifyDeoptimizedHelper(MacroAssembler* masm, | 1214 static void Generate_NotifyDeoptimizedHelper(MacroAssembler* masm, |
1237 Deoptimizer::BailoutType type) { | 1215 Deoptimizer::BailoutType type) { |
1238 // Enter an internal frame. | 1216 // Enter an internal frame. |
1239 { | 1217 { |
1240 FrameScope scope(masm, StackFrame::INTERNAL); | 1218 FrameScope scope(masm, StackFrame::INTERNAL); |
1241 | 1219 |
1242 // Pass the deoptimization type to the runtime system. | 1220 // Pass the deoptimization type to the runtime system. |
1243 __ Push(Smi::FromInt(static_cast<int>(type))); | 1221 __ Push(Smi::FromInt(static_cast<int>(type))); |
1244 | 1222 |
1245 __ CallRuntime(Runtime::kNotifyDeoptimized); | 1223 __ CallRuntime(Runtime::kNotifyDeoptimized); |
(...skipping 15 matching lines...) Expand all Loading... |
1261 __ movp(rax, Operand(rsp, kPCOnStackSize + kPointerSize)); | 1239 __ movp(rax, Operand(rsp, kPCOnStackSize + kPointerSize)); |
1262 __ cmpp(kScratchRegister, | 1240 __ cmpp(kScratchRegister, |
1263 Immediate(static_cast<int>(Deoptimizer::BailoutState::TOS_REGISTER))); | 1241 Immediate(static_cast<int>(Deoptimizer::BailoutState::TOS_REGISTER))); |
1264 __ j(not_equal, ¬_tos_rax, Label::kNear); | 1242 __ j(not_equal, ¬_tos_rax, Label::kNear); |
1265 __ ret(2 * kPointerSize); // Remove state, rax. | 1243 __ ret(2 * kPointerSize); // Remove state, rax. |
1266 | 1244 |
1267 __ bind(¬_tos_rax); | 1245 __ bind(¬_tos_rax); |
1268 __ Abort(kNoCasesLeft); | 1246 __ Abort(kNoCasesLeft); |
1269 } | 1247 } |
1270 | 1248 |
1271 | |
1272 void Builtins::Generate_NotifyDeoptimized(MacroAssembler* masm) { | 1249 void Builtins::Generate_NotifyDeoptimized(MacroAssembler* masm) { |
1273 Generate_NotifyDeoptimizedHelper(masm, Deoptimizer::EAGER); | 1250 Generate_NotifyDeoptimizedHelper(masm, Deoptimizer::EAGER); |
1274 } | 1251 } |
1275 | 1252 |
1276 | |
1277 void Builtins::Generate_NotifySoftDeoptimized(MacroAssembler* masm) { | 1253 void Builtins::Generate_NotifySoftDeoptimized(MacroAssembler* masm) { |
1278 Generate_NotifyDeoptimizedHelper(masm, Deoptimizer::SOFT); | 1254 Generate_NotifyDeoptimizedHelper(masm, Deoptimizer::SOFT); |
1279 } | 1255 } |
1280 | 1256 |
1281 | |
1282 void Builtins::Generate_NotifyLazyDeoptimized(MacroAssembler* masm) { | 1257 void Builtins::Generate_NotifyLazyDeoptimized(MacroAssembler* masm) { |
1283 Generate_NotifyDeoptimizedHelper(masm, Deoptimizer::LAZY); | 1258 Generate_NotifyDeoptimizedHelper(masm, Deoptimizer::LAZY); |
1284 } | 1259 } |
1285 | 1260 |
1286 | |
1287 // static | 1261 // static |
1288 void Builtins::Generate_DatePrototype_GetField(MacroAssembler* masm, | 1262 void Builtins::Generate_DatePrototype_GetField(MacroAssembler* masm, |
1289 int field_index) { | 1263 int field_index) { |
1290 // ----------- S t a t e ------------- | 1264 // ----------- S t a t e ------------- |
1291 // -- rax : number of arguments | 1265 // -- rax : number of arguments |
1292 // -- rdi : function | 1266 // -- rdi : function |
1293 // -- rsi : context | 1267 // -- rsi : context |
1294 // -- rsp[0] : return address | 1268 // -- rsp[0] : return address |
1295 // -- rsp[8] : receiver | 1269 // -- rsp[8] : receiver |
1296 // ----------------------------------- | 1270 // ----------------------------------- |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1411 | 1385 |
1412 // 4c. The receiver is not callable, throw an appropriate TypeError. | 1386 // 4c. The receiver is not callable, throw an appropriate TypeError. |
1413 __ bind(&receiver_not_callable); | 1387 __ bind(&receiver_not_callable); |
1414 { | 1388 { |
1415 StackArgumentsAccessor args(rsp, 0); | 1389 StackArgumentsAccessor args(rsp, 0); |
1416 __ movp(args.GetReceiverOperand(), rdi); | 1390 __ movp(args.GetReceiverOperand(), rdi); |
1417 __ TailCallRuntime(Runtime::kThrowApplyNonFunction); | 1391 __ TailCallRuntime(Runtime::kThrowApplyNonFunction); |
1418 } | 1392 } |
1419 } | 1393 } |
1420 | 1394 |
1421 | |
1422 // static | 1395 // static |
1423 void Builtins::Generate_FunctionPrototypeCall(MacroAssembler* masm) { | 1396 void Builtins::Generate_FunctionPrototypeCall(MacroAssembler* masm) { |
1424 // Stack Layout: | 1397 // Stack Layout: |
1425 // rsp[0] : Return address | 1398 // rsp[0] : Return address |
1426 // rsp[8] : Argument n | 1399 // rsp[8] : Argument n |
1427 // rsp[16] : Argument n-1 | 1400 // rsp[16] : Argument n-1 |
1428 // ... | 1401 // ... |
1429 // rsp[8 * n] : Argument 1 | 1402 // rsp[8 * n] : Argument 1 |
1430 // rsp[8 * (n + 1)] : Receiver (callable to call) | 1403 // rsp[8 * (n + 1)] : Receiver (callable to call) |
1431 // | 1404 // |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1464 __ DropUnderReturnAddress(1, rbx); // Drop one slot under return address. | 1437 __ DropUnderReturnAddress(1, rbx); // Drop one slot under return address. |
1465 __ decp(rax); // One fewer argument (first argument is new receiver). | 1438 __ decp(rax); // One fewer argument (first argument is new receiver). |
1466 } | 1439 } |
1467 | 1440 |
1468 // 4. Call the callable. | 1441 // 4. Call the callable. |
1469 // Since we did not create a frame for Function.prototype.call() yet, | 1442 // Since we did not create a frame for Function.prototype.call() yet, |
1470 // we use a normal Call builtin here. | 1443 // we use a normal Call builtin here. |
1471 __ Jump(masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET); | 1444 __ Jump(masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET); |
1472 } | 1445 } |
1473 | 1446 |
1474 | |
1475 void Builtins::Generate_ReflectApply(MacroAssembler* masm) { | 1447 void Builtins::Generate_ReflectApply(MacroAssembler* masm) { |
1476 // ----------- S t a t e ------------- | 1448 // ----------- S t a t e ------------- |
1477 // -- rax : argc | 1449 // -- rax : argc |
1478 // -- rsp[0] : return address | 1450 // -- rsp[0] : return address |
1479 // -- rsp[8] : argumentsList | 1451 // -- rsp[8] : argumentsList |
1480 // -- rsp[16] : thisArgument | 1452 // -- rsp[16] : thisArgument |
1481 // -- rsp[24] : target | 1453 // -- rsp[24] : target |
1482 // -- rsp[32] : receiver | 1454 // -- rsp[32] : receiver |
1483 // ----------------------------------- | 1455 // ----------------------------------- |
1484 | 1456 |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1529 | 1501 |
1530 // 3b. The target is not callable, throw an appropriate TypeError. | 1502 // 3b. The target is not callable, throw an appropriate TypeError. |
1531 __ bind(&target_not_callable); | 1503 __ bind(&target_not_callable); |
1532 { | 1504 { |
1533 StackArgumentsAccessor args(rsp, 0); | 1505 StackArgumentsAccessor args(rsp, 0); |
1534 __ movp(args.GetReceiverOperand(), rdi); | 1506 __ movp(args.GetReceiverOperand(), rdi); |
1535 __ TailCallRuntime(Runtime::kThrowApplyNonFunction); | 1507 __ TailCallRuntime(Runtime::kThrowApplyNonFunction); |
1536 } | 1508 } |
1537 } | 1509 } |
1538 | 1510 |
1539 | |
1540 void Builtins::Generate_ReflectConstruct(MacroAssembler* masm) { | 1511 void Builtins::Generate_ReflectConstruct(MacroAssembler* masm) { |
1541 // ----------- S t a t e ------------- | 1512 // ----------- S t a t e ------------- |
1542 // -- rax : argc | 1513 // -- rax : argc |
1543 // -- rsp[0] : return address | 1514 // -- rsp[0] : return address |
1544 // -- rsp[8] : new.target (optional) | 1515 // -- rsp[8] : new.target (optional) |
1545 // -- rsp[16] : argumentsList | 1516 // -- rsp[16] : argumentsList |
1546 // -- rsp[24] : target | 1517 // -- rsp[24] : target |
1547 // -- rsp[32] : receiver | 1518 // -- rsp[32] : receiver |
1548 // ----------------------------------- | 1519 // ----------------------------------- |
1549 | 1520 |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1611 | 1582 |
1612 // 4c. The new.target is not a constructor, throw an appropriate TypeError. | 1583 // 4c. The new.target is not a constructor, throw an appropriate TypeError. |
1613 __ bind(&new_target_not_constructor); | 1584 __ bind(&new_target_not_constructor); |
1614 { | 1585 { |
1615 StackArgumentsAccessor args(rsp, 0); | 1586 StackArgumentsAccessor args(rsp, 0); |
1616 __ movp(args.GetReceiverOperand(), rdx); | 1587 __ movp(args.GetReceiverOperand(), rdx); |
1617 __ TailCallRuntime(Runtime::kThrowCalledNonCallable); | 1588 __ TailCallRuntime(Runtime::kThrowCalledNonCallable); |
1618 } | 1589 } |
1619 } | 1590 } |
1620 | 1591 |
1621 | |
1622 void Builtins::Generate_InternalArrayCode(MacroAssembler* masm) { | 1592 void Builtins::Generate_InternalArrayCode(MacroAssembler* masm) { |
1623 // ----------- S t a t e ------------- | 1593 // ----------- S t a t e ------------- |
1624 // -- rax : argc | 1594 // -- rax : argc |
1625 // -- rsp[0] : return address | 1595 // -- rsp[0] : return address |
1626 // -- rsp[8] : last argument | 1596 // -- rsp[8] : last argument |
1627 // ----------------------------------- | 1597 // ----------------------------------- |
1628 Label generic_array_code; | 1598 Label generic_array_code; |
1629 | 1599 |
1630 // Get the InternalArray function. | 1600 // Get the InternalArray function. |
1631 __ LoadNativeContextSlot(Context::INTERNAL_ARRAY_FUNCTION_INDEX, rdi); | 1601 __ LoadNativeContextSlot(Context::INTERNAL_ARRAY_FUNCTION_INDEX, rdi); |
1632 | 1602 |
1633 if (FLAG_debug_code) { | 1603 if (FLAG_debug_code) { |
1634 // Initial map for the builtin InternalArray functions should be maps. | 1604 // Initial map for the builtin InternalArray functions should be maps. |
1635 __ movp(rbx, FieldOperand(rdi, JSFunction::kPrototypeOrInitialMapOffset)); | 1605 __ movp(rbx, FieldOperand(rdi, JSFunction::kPrototypeOrInitialMapOffset)); |
1636 // Will both indicate a NULL and a Smi. | 1606 // Will both indicate a NULL and a Smi. |
1637 STATIC_ASSERT(kSmiTag == 0); | 1607 STATIC_ASSERT(kSmiTag == 0); |
1638 Condition not_smi = NegateCondition(masm->CheckSmi(rbx)); | 1608 Condition not_smi = NegateCondition(masm->CheckSmi(rbx)); |
1639 __ Check(not_smi, kUnexpectedInitialMapForInternalArrayFunction); | 1609 __ Check(not_smi, kUnexpectedInitialMapForInternalArrayFunction); |
1640 __ CmpObjectType(rbx, MAP_TYPE, rcx); | 1610 __ CmpObjectType(rbx, MAP_TYPE, rcx); |
1641 __ Check(equal, kUnexpectedInitialMapForInternalArrayFunction); | 1611 __ Check(equal, kUnexpectedInitialMapForInternalArrayFunction); |
1642 } | 1612 } |
1643 | 1613 |
1644 // Run the native code for the InternalArray function called as a normal | 1614 // Run the native code for the InternalArray function called as a normal |
1645 // function. | 1615 // function. |
1646 // tail call a stub | 1616 // tail call a stub |
1647 InternalArrayConstructorStub stub(masm->isolate()); | 1617 InternalArrayConstructorStub stub(masm->isolate()); |
1648 __ TailCallStub(&stub); | 1618 __ TailCallStub(&stub); |
1649 } | 1619 } |
1650 | 1620 |
1651 | |
1652 void Builtins::Generate_ArrayCode(MacroAssembler* masm) { | 1621 void Builtins::Generate_ArrayCode(MacroAssembler* masm) { |
1653 // ----------- S t a t e ------------- | 1622 // ----------- S t a t e ------------- |
1654 // -- rax : argc | 1623 // -- rax : argc |
1655 // -- rsp[0] : return address | 1624 // -- rsp[0] : return address |
1656 // -- rsp[8] : last argument | 1625 // -- rsp[8] : last argument |
1657 // ----------------------------------- | 1626 // ----------------------------------- |
1658 Label generic_array_code; | 1627 Label generic_array_code; |
1659 | 1628 |
1660 // Get the Array function. | 1629 // Get the Array function. |
1661 __ LoadNativeContextSlot(Context::ARRAY_FUNCTION_INDEX, rdi); | 1630 __ LoadNativeContextSlot(Context::ARRAY_FUNCTION_INDEX, rdi); |
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1829 __ leap(rsp, Operand(rsp, rbx, times_pointer_size, kPointerSize)); | 1798 __ leap(rsp, Operand(rsp, rbx, times_pointer_size, kPointerSize)); |
1830 __ PushReturnAddressFrom(rcx); | 1799 __ PushReturnAddressFrom(rcx); |
1831 __ Ret(); | 1800 __ Ret(); |
1832 } | 1801 } |
1833 | 1802 |
1834 // 2b. No arguments, return +0 (already in rax). | 1803 // 2b. No arguments, return +0 (already in rax). |
1835 __ bind(&no_arguments); | 1804 __ bind(&no_arguments); |
1836 __ ret(1 * kPointerSize); | 1805 __ ret(1 * kPointerSize); |
1837 } | 1806 } |
1838 | 1807 |
1839 | |
1840 // static | 1808 // static |
1841 void Builtins::Generate_NumberConstructor_ConstructStub(MacroAssembler* masm) { | 1809 void Builtins::Generate_NumberConstructor_ConstructStub(MacroAssembler* masm) { |
1842 // ----------- S t a t e ------------- | 1810 // ----------- S t a t e ------------- |
1843 // -- rax : number of arguments | 1811 // -- rax : number of arguments |
1844 // -- rdi : constructor function | 1812 // -- rdi : constructor function |
1845 // -- rdx : new target | 1813 // -- rdx : new target |
1846 // -- rsi : context | 1814 // -- rsi : context |
1847 // -- rsp[0] : return address | 1815 // -- rsp[0] : return address |
1848 // -- rsp[(argc - n) * 8] : arg[n] (zero-based) | 1816 // -- rsp[(argc - n) * 8] : arg[n] (zero-based) |
1849 // -- rsp[(argc + 1) * 8] : receiver | 1817 // -- rsp[(argc + 1) * 8] : receiver |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1913 { | 1881 { |
1914 // Drop all arguments including the receiver. | 1882 // Drop all arguments including the receiver. |
1915 __ PopReturnAddressTo(rcx); | 1883 __ PopReturnAddressTo(rcx); |
1916 __ SmiToInteger32(r8, r8); | 1884 __ SmiToInteger32(r8, r8); |
1917 __ leap(rsp, Operand(rsp, r8, times_pointer_size, kPointerSize)); | 1885 __ leap(rsp, Operand(rsp, r8, times_pointer_size, kPointerSize)); |
1918 __ PushReturnAddressFrom(rcx); | 1886 __ PushReturnAddressFrom(rcx); |
1919 __ Ret(); | 1887 __ Ret(); |
1920 } | 1888 } |
1921 } | 1889 } |
1922 | 1890 |
1923 | |
1924 // static | 1891 // static |
1925 void Builtins::Generate_StringConstructor(MacroAssembler* masm) { | 1892 void Builtins::Generate_StringConstructor(MacroAssembler* masm) { |
1926 // ----------- S t a t e ------------- | 1893 // ----------- S t a t e ------------- |
1927 // -- rax : number of arguments | 1894 // -- rax : number of arguments |
1928 // -- rdi : constructor function | 1895 // -- rdi : constructor function |
1929 // -- rsi : context | 1896 // -- rsi : context |
1930 // -- rsp[0] : return address | 1897 // -- rsp[0] : return address |
1931 // -- rsp[(argc - n) * 8] : arg[n] (zero-based) | 1898 // -- rsp[(argc - n) * 8] : arg[n] (zero-based) |
1932 // -- rsp[(argc + 1) * 8] : receiver | 1899 // -- rsp[(argc + 1) * 8] : receiver |
1933 // ----------------------------------- | 1900 // ----------------------------------- |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1987 { | 1954 { |
1988 // Drop all arguments including the receiver. | 1955 // Drop all arguments including the receiver. |
1989 __ PopReturnAddressTo(rcx); | 1956 __ PopReturnAddressTo(rcx); |
1990 __ SmiToInteger32(r8, r8); | 1957 __ SmiToInteger32(r8, r8); |
1991 __ leap(rsp, Operand(rsp, r8, times_pointer_size, kPointerSize)); | 1958 __ leap(rsp, Operand(rsp, r8, times_pointer_size, kPointerSize)); |
1992 __ PushReturnAddressFrom(rcx); | 1959 __ PushReturnAddressFrom(rcx); |
1993 __ Ret(); | 1960 __ Ret(); |
1994 } | 1961 } |
1995 } | 1962 } |
1996 | 1963 |
1997 | |
1998 // static | 1964 // static |
1999 void Builtins::Generate_StringConstructor_ConstructStub(MacroAssembler* masm) { | 1965 void Builtins::Generate_StringConstructor_ConstructStub(MacroAssembler* masm) { |
2000 // ----------- S t a t e ------------- | 1966 // ----------- S t a t e ------------- |
2001 // -- rax : number of arguments | 1967 // -- rax : number of arguments |
2002 // -- rdi : constructor function | 1968 // -- rdi : constructor function |
2003 // -- rdx : new target | 1969 // -- rdx : new target |
2004 // -- rsi : context | 1970 // -- rsi : context |
2005 // -- rsp[0] : return address | 1971 // -- rsp[0] : return address |
2006 // -- rsp[(argc - n) * 8] : arg[n] (zero-based) | 1972 // -- rsp[(argc - n) * 8] : arg[n] (zero-based) |
2007 // -- rsp[(argc + 1) * 8] : receiver | 1973 // -- rsp[(argc + 1) * 8] : receiver |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2072 { | 2038 { |
2073 // Drop all arguments including the receiver. | 2039 // Drop all arguments including the receiver. |
2074 __ PopReturnAddressTo(rcx); | 2040 __ PopReturnAddressTo(rcx); |
2075 __ SmiToInteger32(r8, r8); | 2041 __ SmiToInteger32(r8, r8); |
2076 __ leap(rsp, Operand(rsp, r8, times_pointer_size, kPointerSize)); | 2042 __ leap(rsp, Operand(rsp, r8, times_pointer_size, kPointerSize)); |
2077 __ PushReturnAddressFrom(rcx); | 2043 __ PushReturnAddressFrom(rcx); |
2078 __ Ret(); | 2044 __ Ret(); |
2079 } | 2045 } |
2080 } | 2046 } |
2081 | 2047 |
2082 | |
2083 static void ArgumentsAdaptorStackCheck(MacroAssembler* masm, | 2048 static void ArgumentsAdaptorStackCheck(MacroAssembler* masm, |
2084 Label* stack_overflow) { | 2049 Label* stack_overflow) { |
2085 // ----------- S t a t e ------------- | 2050 // ----------- S t a t e ------------- |
2086 // -- rax : actual number of arguments | 2051 // -- rax : actual number of arguments |
2087 // -- rbx : expected number of arguments | 2052 // -- rbx : expected number of arguments |
2088 // -- rdx : new target (passed through to callee) | 2053 // -- rdx : new target (passed through to callee) |
2089 // -- rdi : function (passed through to callee) | 2054 // -- rdi : function (passed through to callee) |
2090 // ----------------------------------- | 2055 // ----------------------------------- |
2091 // Check the stack for overflow. We are not trying to catch | 2056 // Check the stack for overflow. We are not trying to catch |
2092 // interruptions (e.g. debug break and preemption) here, so the "real stack | 2057 // interruptions (e.g. debug break and preemption) here, so the "real stack |
2093 // limit" is checked. | 2058 // limit" is checked. |
2094 Label okay; | 2059 Label okay; |
2095 __ LoadRoot(r8, Heap::kRealStackLimitRootIndex); | 2060 __ LoadRoot(r8, Heap::kRealStackLimitRootIndex); |
2096 __ movp(rcx, rsp); | 2061 __ movp(rcx, rsp); |
2097 // Make rcx the space we have left. The stack might already be overflowed | 2062 // Make rcx the space we have left. The stack might already be overflowed |
2098 // here which will cause rcx to become negative. | 2063 // here which will cause rcx to become negative. |
2099 __ subp(rcx, r8); | 2064 __ subp(rcx, r8); |
2100 // Make r8 the space we need for the array when it is unrolled onto the | 2065 // Make r8 the space we need for the array when it is unrolled onto the |
2101 // stack. | 2066 // stack. |
2102 __ movp(r8, rbx); | 2067 __ movp(r8, rbx); |
2103 __ shlp(r8, Immediate(kPointerSizeLog2)); | 2068 __ shlp(r8, Immediate(kPointerSizeLog2)); |
2104 // Check if the arguments will overflow the stack. | 2069 // Check if the arguments will overflow the stack. |
2105 __ cmpp(rcx, r8); | 2070 __ cmpp(rcx, r8); |
2106 __ j(less_equal, stack_overflow); // Signed comparison. | 2071 __ j(less_equal, stack_overflow); // Signed comparison. |
2107 } | 2072 } |
2108 | 2073 |
2109 | |
2110 static void EnterArgumentsAdaptorFrame(MacroAssembler* masm) { | 2074 static void EnterArgumentsAdaptorFrame(MacroAssembler* masm) { |
2111 __ pushq(rbp); | 2075 __ pushq(rbp); |
2112 __ movp(rbp, rsp); | 2076 __ movp(rbp, rsp); |
2113 | 2077 |
2114 // Store the arguments adaptor context sentinel. | 2078 // Store the arguments adaptor context sentinel. |
2115 __ Push(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)); | 2079 __ Push(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)); |
2116 | 2080 |
2117 // Push the function on the stack. | 2081 // Push the function on the stack. |
2118 __ Push(rdi); | 2082 __ Push(rdi); |
2119 | 2083 |
2120 // Preserve the number of arguments on the stack. Must preserve rax, | 2084 // Preserve the number of arguments on the stack. Must preserve rax, |
2121 // rbx and rcx because these registers are used when copying the | 2085 // rbx and rcx because these registers are used when copying the |
2122 // arguments and the receiver. | 2086 // arguments and the receiver. |
2123 __ Integer32ToSmi(r8, rax); | 2087 __ Integer32ToSmi(r8, rax); |
2124 __ Push(r8); | 2088 __ Push(r8); |
2125 } | 2089 } |
2126 | 2090 |
2127 | |
2128 static void LeaveArgumentsAdaptorFrame(MacroAssembler* masm) { | 2091 static void LeaveArgumentsAdaptorFrame(MacroAssembler* masm) { |
2129 // Retrieve the number of arguments from the stack. Number is a Smi. | 2092 // Retrieve the number of arguments from the stack. Number is a Smi. |
2130 __ movp(rbx, Operand(rbp, ArgumentsAdaptorFrameConstants::kLengthOffset)); | 2093 __ movp(rbx, Operand(rbp, ArgumentsAdaptorFrameConstants::kLengthOffset)); |
2131 | 2094 |
2132 // Leave the frame. | 2095 // Leave the frame. |
2133 __ movp(rsp, rbp); | 2096 __ movp(rsp, rbp); |
2134 __ popq(rbp); | 2097 __ popq(rbp); |
2135 | 2098 |
2136 // Remove caller arguments from the stack. | 2099 // Remove caller arguments from the stack. |
2137 __ PopReturnAddressTo(rcx); | 2100 __ PopReturnAddressTo(rcx); |
(...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2338 __ jmp(rcx); | 2301 __ jmp(rcx); |
2339 | 2302 |
2340 __ bind(&stack_overflow); | 2303 __ bind(&stack_overflow); |
2341 { | 2304 { |
2342 FrameScope frame(masm, StackFrame::MANUAL); | 2305 FrameScope frame(masm, StackFrame::MANUAL); |
2343 __ CallRuntime(Runtime::kThrowStackOverflow); | 2306 __ CallRuntime(Runtime::kThrowStackOverflow); |
2344 __ int3(); | 2307 __ int3(); |
2345 } | 2308 } |
2346 } | 2309 } |
2347 | 2310 |
2348 | |
2349 // static | 2311 // static |
2350 void Builtins::Generate_Apply(MacroAssembler* masm) { | 2312 void Builtins::Generate_Apply(MacroAssembler* masm) { |
2351 // ----------- S t a t e ------------- | 2313 // ----------- S t a t e ------------- |
2352 // -- rax : argumentsList | 2314 // -- rax : argumentsList |
2353 // -- rdi : target | 2315 // -- rdi : target |
2354 // -- rdx : new.target (checked to be constructor or undefined) | 2316 // -- rdx : new.target (checked to be constructor or undefined) |
2355 // -- rsp[0] : return address. | 2317 // -- rsp[0] : return address. |
2356 // -- rsp[8] : thisArgument | 2318 // -- rsp[8] : thisArgument |
2357 // ----------------------------------- | 2319 // ----------------------------------- |
2358 | 2320 |
(...skipping 312 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2671 | 2633 |
2672 // The function is a "classConstructor", need to raise an exception. | 2634 // The function is a "classConstructor", need to raise an exception. |
2673 __ bind(&class_constructor); | 2635 __ bind(&class_constructor); |
2674 { | 2636 { |
2675 FrameScope frame(masm, StackFrame::INTERNAL); | 2637 FrameScope frame(masm, StackFrame::INTERNAL); |
2676 __ Push(rdi); | 2638 __ Push(rdi); |
2677 __ CallRuntime(Runtime::kThrowConstructorNonCallableError); | 2639 __ CallRuntime(Runtime::kThrowConstructorNonCallableError); |
2678 } | 2640 } |
2679 } | 2641 } |
2680 | 2642 |
2681 | |
2682 namespace { | 2643 namespace { |
2683 | 2644 |
2684 void Generate_PushBoundArguments(MacroAssembler* masm) { | 2645 void Generate_PushBoundArguments(MacroAssembler* masm) { |
2685 // ----------- S t a t e ------------- | 2646 // ----------- S t a t e ------------- |
2686 // -- rax : the number of arguments (not including the receiver) | 2647 // -- rax : the number of arguments (not including the receiver) |
2687 // -- rdx : new.target (only in case of [[Construct]]) | 2648 // -- rdx : new.target (only in case of [[Construct]]) |
2688 // -- rdi : target (checked to be a JSBoundFunction) | 2649 // -- rdi : target (checked to be a JSBoundFunction) |
2689 // ----------------------------------- | 2650 // ----------------------------------- |
2690 | 2651 |
2691 // Load [[BoundArguments]] into rcx and length of that into rbx. | 2652 // Load [[BoundArguments]] into rcx and length of that into rbx. |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2756 // Adjust effective number of arguments (rax contains the number of | 2717 // Adjust effective number of arguments (rax contains the number of |
2757 // arguments from the call plus return address plus the number of | 2718 // arguments from the call plus return address plus the number of |
2758 // [[BoundArguments]]), so we need to subtract one for the return address. | 2719 // [[BoundArguments]]), so we need to subtract one for the return address. |
2759 __ decl(rax); | 2720 __ decl(rax); |
2760 } | 2721 } |
2761 __ bind(&no_bound_arguments); | 2722 __ bind(&no_bound_arguments); |
2762 } | 2723 } |
2763 | 2724 |
2764 } // namespace | 2725 } // namespace |
2765 | 2726 |
2766 | |
2767 // static | 2727 // static |
2768 void Builtins::Generate_CallBoundFunctionImpl(MacroAssembler* masm, | 2728 void Builtins::Generate_CallBoundFunctionImpl(MacroAssembler* masm, |
2769 TailCallMode tail_call_mode) { | 2729 TailCallMode tail_call_mode) { |
2770 // ----------- S t a t e ------------- | 2730 // ----------- S t a t e ------------- |
2771 // -- rax : the number of arguments (not including the receiver) | 2731 // -- rax : the number of arguments (not including the receiver) |
2772 // -- rdi : the function to call (checked to be a JSBoundFunction) | 2732 // -- rdi : the function to call (checked to be a JSBoundFunction) |
2773 // ----------------------------------- | 2733 // ----------------------------------- |
2774 __ AssertBoundFunction(rdi); | 2734 __ AssertBoundFunction(rdi); |
2775 | 2735 |
2776 if (tail_call_mode == TailCallMode::kAllow) { | 2736 if (tail_call_mode == TailCallMode::kAllow) { |
2777 PrepareForTailCall(masm, rax, rbx, rcx, r8); | 2737 PrepareForTailCall(masm, rax, rbx, rcx, r8); |
2778 } | 2738 } |
2779 | 2739 |
2780 // Patch the receiver to [[BoundThis]]. | 2740 // Patch the receiver to [[BoundThis]]. |
2781 StackArgumentsAccessor args(rsp, rax); | 2741 StackArgumentsAccessor args(rsp, rax); |
2782 __ movp(rbx, FieldOperand(rdi, JSBoundFunction::kBoundThisOffset)); | 2742 __ movp(rbx, FieldOperand(rdi, JSBoundFunction::kBoundThisOffset)); |
2783 __ movp(args.GetReceiverOperand(), rbx); | 2743 __ movp(args.GetReceiverOperand(), rbx); |
2784 | 2744 |
2785 // Push the [[BoundArguments]] onto the stack. | 2745 // Push the [[BoundArguments]] onto the stack. |
2786 Generate_PushBoundArguments(masm); | 2746 Generate_PushBoundArguments(masm); |
2787 | 2747 |
2788 // Call the [[BoundTargetFunction]] via the Call builtin. | 2748 // Call the [[BoundTargetFunction]] via the Call builtin. |
2789 __ movp(rdi, FieldOperand(rdi, JSBoundFunction::kBoundTargetFunctionOffset)); | 2749 __ movp(rdi, FieldOperand(rdi, JSBoundFunction::kBoundTargetFunctionOffset)); |
2790 __ Load(rcx, | 2750 __ Load(rcx, |
2791 ExternalReference(Builtins::kCall_ReceiverIsAny, masm->isolate())); | 2751 ExternalReference(Builtins::kCall_ReceiverIsAny, masm->isolate())); |
2792 __ leap(rcx, FieldOperand(rcx, Code::kHeaderSize)); | 2752 __ leap(rcx, FieldOperand(rcx, Code::kHeaderSize)); |
2793 __ jmp(rcx); | 2753 __ jmp(rcx); |
2794 } | 2754 } |
2795 | 2755 |
2796 | |
2797 // static | 2756 // static |
2798 void Builtins::Generate_Call(MacroAssembler* masm, ConvertReceiverMode mode, | 2757 void Builtins::Generate_Call(MacroAssembler* masm, ConvertReceiverMode mode, |
2799 TailCallMode tail_call_mode) { | 2758 TailCallMode tail_call_mode) { |
2800 // ----------- S t a t e ------------- | 2759 // ----------- S t a t e ------------- |
2801 // -- rax : the number of arguments (not including the receiver) | 2760 // -- rax : the number of arguments (not including the receiver) |
2802 // -- rdi : the target to call (can be any Object) | 2761 // -- rdi : the target to call (can be any Object) |
2803 // ----------------------------------- | 2762 // ----------------------------------- |
2804 StackArgumentsAccessor args(rsp, rax); | 2763 StackArgumentsAccessor args(rsp, rax); |
2805 | 2764 |
2806 Label non_callable, non_function, non_smi; | 2765 Label non_callable, non_function, non_smi; |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2850 | 2809 |
2851 // 3. Call to something that is not callable. | 2810 // 3. Call to something that is not callable. |
2852 __ bind(&non_callable); | 2811 __ bind(&non_callable); |
2853 { | 2812 { |
2854 FrameScope scope(masm, StackFrame::INTERNAL); | 2813 FrameScope scope(masm, StackFrame::INTERNAL); |
2855 __ Push(rdi); | 2814 __ Push(rdi); |
2856 __ CallRuntime(Runtime::kThrowCalledNonCallable); | 2815 __ CallRuntime(Runtime::kThrowCalledNonCallable); |
2857 } | 2816 } |
2858 } | 2817 } |
2859 | 2818 |
2860 | |
2861 // static | 2819 // static |
2862 void Builtins::Generate_ConstructFunction(MacroAssembler* masm) { | 2820 void Builtins::Generate_ConstructFunction(MacroAssembler* masm) { |
2863 // ----------- S t a t e ------------- | 2821 // ----------- S t a t e ------------- |
2864 // -- rax : the number of arguments (not including the receiver) | 2822 // -- rax : the number of arguments (not including the receiver) |
2865 // -- rdx : the new target (checked to be a constructor) | 2823 // -- rdx : the new target (checked to be a constructor) |
2866 // -- rdi : the constructor to call (checked to be a JSFunction) | 2824 // -- rdi : the constructor to call (checked to be a JSFunction) |
2867 // ----------------------------------- | 2825 // ----------------------------------- |
2868 __ AssertFunction(rdi); | 2826 __ AssertFunction(rdi); |
2869 | 2827 |
2870 // Calling convention for function specific ConstructStubs require | 2828 // Calling convention for function specific ConstructStubs require |
2871 // rbx to contain either an AllocationSite or undefined. | 2829 // rbx to contain either an AllocationSite or undefined. |
2872 __ LoadRoot(rbx, Heap::kUndefinedValueRootIndex); | 2830 __ LoadRoot(rbx, Heap::kUndefinedValueRootIndex); |
2873 | 2831 |
2874 // Tail call to the function-specific construct stub (still in the caller | 2832 // Tail call to the function-specific construct stub (still in the caller |
2875 // context at this point). | 2833 // context at this point). |
2876 __ movp(rcx, FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset)); | 2834 __ movp(rcx, FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset)); |
2877 __ movp(rcx, FieldOperand(rcx, SharedFunctionInfo::kConstructStubOffset)); | 2835 __ movp(rcx, FieldOperand(rcx, SharedFunctionInfo::kConstructStubOffset)); |
2878 __ leap(rcx, FieldOperand(rcx, Code::kHeaderSize)); | 2836 __ leap(rcx, FieldOperand(rcx, Code::kHeaderSize)); |
2879 __ jmp(rcx); | 2837 __ jmp(rcx); |
2880 } | 2838 } |
2881 | 2839 |
2882 | |
2883 // static | 2840 // static |
2884 void Builtins::Generate_ConstructBoundFunction(MacroAssembler* masm) { | 2841 void Builtins::Generate_ConstructBoundFunction(MacroAssembler* masm) { |
2885 // ----------- S t a t e ------------- | 2842 // ----------- S t a t e ------------- |
2886 // -- rax : the number of arguments (not including the receiver) | 2843 // -- rax : the number of arguments (not including the receiver) |
2887 // -- rdx : the new target (checked to be a constructor) | 2844 // -- rdx : the new target (checked to be a constructor) |
2888 // -- rdi : the constructor to call (checked to be a JSBoundFunction) | 2845 // -- rdi : the constructor to call (checked to be a JSBoundFunction) |
2889 // ----------------------------------- | 2846 // ----------------------------------- |
2890 __ AssertBoundFunction(rdi); | 2847 __ AssertBoundFunction(rdi); |
2891 | 2848 |
2892 // Push the [[BoundArguments]] onto the stack. | 2849 // Push the [[BoundArguments]] onto the stack. |
2893 Generate_PushBoundArguments(masm); | 2850 Generate_PushBoundArguments(masm); |
2894 | 2851 |
2895 // Patch new.target to [[BoundTargetFunction]] if new.target equals target. | 2852 // Patch new.target to [[BoundTargetFunction]] if new.target equals target. |
2896 { | 2853 { |
2897 Label done; | 2854 Label done; |
2898 __ cmpp(rdi, rdx); | 2855 __ cmpp(rdi, rdx); |
2899 __ j(not_equal, &done, Label::kNear); | 2856 __ j(not_equal, &done, Label::kNear); |
2900 __ movp(rdx, | 2857 __ movp(rdx, |
2901 FieldOperand(rdi, JSBoundFunction::kBoundTargetFunctionOffset)); | 2858 FieldOperand(rdi, JSBoundFunction::kBoundTargetFunctionOffset)); |
2902 __ bind(&done); | 2859 __ bind(&done); |
2903 } | 2860 } |
2904 | 2861 |
2905 // Construct the [[BoundTargetFunction]] via the Construct builtin. | 2862 // Construct the [[BoundTargetFunction]] via the Construct builtin. |
2906 __ movp(rdi, FieldOperand(rdi, JSBoundFunction::kBoundTargetFunctionOffset)); | 2863 __ movp(rdi, FieldOperand(rdi, JSBoundFunction::kBoundTargetFunctionOffset)); |
2907 __ Load(rcx, ExternalReference(Builtins::kConstruct, masm->isolate())); | 2864 __ Load(rcx, ExternalReference(Builtins::kConstruct, masm->isolate())); |
2908 __ leap(rcx, FieldOperand(rcx, Code::kHeaderSize)); | 2865 __ leap(rcx, FieldOperand(rcx, Code::kHeaderSize)); |
2909 __ jmp(rcx); | 2866 __ jmp(rcx); |
2910 } | 2867 } |
2911 | 2868 |
2912 | |
2913 // static | 2869 // static |
2914 void Builtins::Generate_ConstructProxy(MacroAssembler* masm) { | 2870 void Builtins::Generate_ConstructProxy(MacroAssembler* masm) { |
2915 // ----------- S t a t e ------------- | 2871 // ----------- S t a t e ------------- |
2916 // -- rax : the number of arguments (not including the receiver) | 2872 // -- rax : the number of arguments (not including the receiver) |
2917 // -- rdi : the constructor to call (checked to be a JSProxy) | 2873 // -- rdi : the constructor to call (checked to be a JSProxy) |
2918 // -- rdx : the new target (either the same as the constructor or | 2874 // -- rdx : the new target (either the same as the constructor or |
2919 // the JSFunction on which new was invoked initially) | 2875 // the JSFunction on which new was invoked initially) |
2920 // ----------------------------------- | 2876 // ----------------------------------- |
2921 | 2877 |
2922 // Call into the Runtime for Proxy [[Construct]]. | 2878 // Call into the Runtime for Proxy [[Construct]]. |
2923 __ PopReturnAddressTo(kScratchRegister); | 2879 __ PopReturnAddressTo(kScratchRegister); |
2924 __ Push(rdi); | 2880 __ Push(rdi); |
2925 __ Push(rdx); | 2881 __ Push(rdx); |
2926 __ PushReturnAddressFrom(kScratchRegister); | 2882 __ PushReturnAddressFrom(kScratchRegister); |
2927 // Include the pushed new_target, constructor and the receiver. | 2883 // Include the pushed new_target, constructor and the receiver. |
2928 __ addp(rax, Immediate(3)); | 2884 __ addp(rax, Immediate(3)); |
2929 __ JumpToExternalReference( | 2885 __ JumpToExternalReference( |
2930 ExternalReference(Runtime::kJSProxyConstruct, masm->isolate())); | 2886 ExternalReference(Runtime::kJSProxyConstruct, masm->isolate())); |
2931 } | 2887 } |
2932 | 2888 |
2933 | |
2934 // static | 2889 // static |
2935 void Builtins::Generate_Construct(MacroAssembler* masm) { | 2890 void Builtins::Generate_Construct(MacroAssembler* masm) { |
2936 // ----------- S t a t e ------------- | 2891 // ----------- S t a t e ------------- |
2937 // -- rax : the number of arguments (not including the receiver) | 2892 // -- rax : the number of arguments (not including the receiver) |
2938 // -- rdx : the new target (either the same as the constructor or | 2893 // -- rdx : the new target (either the same as the constructor or |
2939 // the JSFunction on which new was invoked initially) | 2894 // the JSFunction on which new was invoked initially) |
2940 // -- rdi : the constructor to call (can be any Object) | 2895 // -- rdi : the constructor to call (can be any Object) |
2941 // ----------------------------------- | 2896 // ----------------------------------- |
2942 StackArgumentsAccessor args(rsp, rax); | 2897 StackArgumentsAccessor args(rsp, rax); |
2943 | 2898 |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2976 RelocInfo::CODE_TARGET); | 2931 RelocInfo::CODE_TARGET); |
2977 } | 2932 } |
2978 | 2933 |
2979 // Called Construct on an Object that doesn't have a [[Construct]] internal | 2934 // Called Construct on an Object that doesn't have a [[Construct]] internal |
2980 // method. | 2935 // method. |
2981 __ bind(&non_constructor); | 2936 __ bind(&non_constructor); |
2982 __ Jump(masm->isolate()->builtins()->ConstructedNonConstructable(), | 2937 __ Jump(masm->isolate()->builtins()->ConstructedNonConstructable(), |
2983 RelocInfo::CODE_TARGET); | 2938 RelocInfo::CODE_TARGET); |
2984 } | 2939 } |
2985 | 2940 |
2986 | |
2987 static void CompatibleReceiverCheck(MacroAssembler* masm, Register receiver, | 2941 static void CompatibleReceiverCheck(MacroAssembler* masm, Register receiver, |
2988 Register function_template_info, | 2942 Register function_template_info, |
2989 Register scratch0, Register scratch1, | 2943 Register scratch0, Register scratch1, |
2990 Register scratch2, | 2944 Register scratch2, |
2991 Label* receiver_check_failed) { | 2945 Label* receiver_check_failed) { |
2992 Register signature = scratch0; | 2946 Register signature = scratch0; |
2993 Register map = scratch1; | 2947 Register map = scratch1; |
2994 Register constructor = scratch2; | 2948 Register constructor = scratch2; |
2995 | 2949 |
2996 // If there is no signature, return the holder. | 2950 // If there is no signature, return the holder. |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3042 Immediate(Map::HasHiddenPrototype::kMask)); | 2996 Immediate(Map::HasHiddenPrototype::kMask)); |
3043 __ j(zero, receiver_check_failed); | 2997 __ j(zero, receiver_check_failed); |
3044 __ movp(receiver, FieldOperand(map, Map::kPrototypeOffset)); | 2998 __ movp(receiver, FieldOperand(map, Map::kPrototypeOffset)); |
3045 __ movp(map, FieldOperand(receiver, HeapObject::kMapOffset)); | 2999 __ movp(map, FieldOperand(receiver, HeapObject::kMapOffset)); |
3046 // Iterate. | 3000 // Iterate. |
3047 __ jmp(&prototype_loop_start, Label::kNear); | 3001 __ jmp(&prototype_loop_start, Label::kNear); |
3048 | 3002 |
3049 __ bind(&receiver_check_passed); | 3003 __ bind(&receiver_check_passed); |
3050 } | 3004 } |
3051 | 3005 |
3052 | |
3053 void Builtins::Generate_HandleFastApiCall(MacroAssembler* masm) { | 3006 void Builtins::Generate_HandleFastApiCall(MacroAssembler* masm) { |
3054 // ----------- S t a t e ------------- | 3007 // ----------- S t a t e ------------- |
3055 // -- rax : number of arguments (not including the receiver) | 3008 // -- rax : number of arguments (not including the receiver) |
3056 // -- rdi : callee | 3009 // -- rdi : callee |
3057 // -- rsi : context | 3010 // -- rsi : context |
3058 // -- rsp[0] : return address | 3011 // -- rsp[0] : return address |
3059 // -- rsp[8] : last argument | 3012 // -- rsp[8] : last argument |
3060 // -- ... | 3013 // -- ... |
3061 // -- rsp[rax * 8] : first argument | 3014 // -- rsp[rax * 8] : first argument |
3062 // -- rsp[(rax + 1) * 8] : receiver | 3015 // -- rsp[(rax + 1) * 8] : receiver |
(...skipping 23 matching lines...) Expand all Loading... |
3086 __ PopReturnAddressTo(rbx); | 3039 __ PopReturnAddressTo(rbx); |
3087 __ leap(rax, Operand(rax, times_pointer_size, 1 * kPointerSize)); | 3040 __ leap(rax, Operand(rax, times_pointer_size, 1 * kPointerSize)); |
3088 __ addp(rsp, rax); | 3041 __ addp(rsp, rax); |
3089 __ PushReturnAddressFrom(rbx); | 3042 __ PushReturnAddressFrom(rbx); |
3090 { | 3043 { |
3091 FrameScope scope(masm, StackFrame::INTERNAL); | 3044 FrameScope scope(masm, StackFrame::INTERNAL); |
3092 __ TailCallRuntime(Runtime::kThrowIllegalInvocation); | 3045 __ TailCallRuntime(Runtime::kThrowIllegalInvocation); |
3093 } | 3046 } |
3094 } | 3047 } |
3095 | 3048 |
3096 | |
3097 void Builtins::Generate_OnStackReplacement(MacroAssembler* masm) { | 3049 void Builtins::Generate_OnStackReplacement(MacroAssembler* masm) { |
3098 // Lookup the function in the JavaScript frame. | 3050 // Lookup the function in the JavaScript frame. |
3099 __ movp(rax, Operand(rbp, JavaScriptFrameConstants::kFunctionOffset)); | 3051 __ movp(rax, Operand(rbp, JavaScriptFrameConstants::kFunctionOffset)); |
3100 { | 3052 { |
3101 FrameScope scope(masm, StackFrame::INTERNAL); | 3053 FrameScope scope(masm, StackFrame::INTERNAL); |
3102 // Pass function as argument. | 3054 // Pass function as argument. |
3103 __ Push(rax); | 3055 __ Push(rax); |
3104 __ CallRuntime(Runtime::kCompileForOnStackReplacement); | 3056 __ CallRuntime(Runtime::kCompileForOnStackReplacement); |
3105 } | 3057 } |
3106 | 3058 |
3107 Label skip; | 3059 Label skip; |
3108 // If the code object is null, just return to the unoptimized code. | 3060 // If the code object is null, just return to the unoptimized code. |
3109 __ cmpp(rax, Immediate(0)); | 3061 __ cmpp(rax, Immediate(0)); |
3110 __ j(not_equal, &skip, Label::kNear); | 3062 __ j(not_equal, &skip, Label::kNear); |
3111 __ ret(0); | 3063 __ ret(0); |
3112 | 3064 |
3113 __ bind(&skip); | 3065 __ bind(&skip); |
3114 | 3066 |
3115 // Load deoptimization data from the code object. | 3067 // Load deoptimization data from the code object. |
3116 __ movp(rbx, Operand(rax, Code::kDeoptimizationDataOffset - kHeapObjectTag)); | 3068 __ movp(rbx, Operand(rax, Code::kDeoptimizationDataOffset - kHeapObjectTag)); |
3117 | 3069 |
3118 // Load the OSR entrypoint offset from the deoptimization data. | 3070 // Load the OSR entrypoint offset from the deoptimization data. |
3119 __ SmiToInteger32(rbx, Operand(rbx, FixedArray::OffsetOfElementAt( | 3071 __ SmiToInteger32( |
3120 DeoptimizationInputData::kOsrPcOffsetIndex) - kHeapObjectTag)); | 3072 rbx, Operand(rbx, FixedArray::OffsetOfElementAt( |
| 3073 DeoptimizationInputData::kOsrPcOffsetIndex) - |
| 3074 kHeapObjectTag)); |
3121 | 3075 |
3122 // Compute the target address = code_obj + header_size + osr_offset | 3076 // Compute the target address = code_obj + header_size + osr_offset |
3123 __ leap(rax, Operand(rax, rbx, times_1, Code::kHeaderSize - kHeapObjectTag)); | 3077 __ leap(rax, Operand(rax, rbx, times_1, Code::kHeaderSize - kHeapObjectTag)); |
3124 | 3078 |
3125 // Overwrite the return address on the stack. | 3079 // Overwrite the return address on the stack. |
3126 __ movq(StackOperandForReturnAddress(0), rax); | 3080 __ movq(StackOperandForReturnAddress(0), rax); |
3127 | 3081 |
3128 // And "return" to the OSR entry point of the function. | 3082 // And "return" to the OSR entry point of the function. |
3129 __ ret(0); | 3083 __ ret(0); |
3130 } | 3084 } |
3131 | 3085 |
3132 | |
3133 #undef __ | 3086 #undef __ |
3134 | 3087 |
3135 } // namespace internal | 3088 } // namespace internal |
3136 } // namespace v8 | 3089 } // namespace v8 |
3137 | 3090 |
3138 #endif // V8_TARGET_ARCH_X64 | 3091 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |