| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "vm/globals.h" | 5 #include "vm/globals.h" |
| 6 #if defined(TARGET_ARCH_X64) | 6 #if defined(TARGET_ARCH_X64) |
| 7 | 7 |
| 8 #include "vm/assembler.h" |
| 9 #include "vm/assembler_macros.h" |
| 8 #include "vm/code_generator.h" | 10 #include "vm/code_generator.h" |
| 9 #include "vm/compiler.h" | 11 #include "vm/compiler.h" |
| 10 #include "vm/object_store.h" | 12 #include "vm/object_store.h" |
| 11 #include "vm/pages.h" | 13 #include "vm/pages.h" |
| 12 #include "vm/resolver.h" | 14 #include "vm/resolver.h" |
| 13 #include "vm/scavenger.h" | 15 #include "vm/scavenger.h" |
| 14 #include "vm/stub_code.h" | 16 #include "vm/stub_code.h" |
| 15 | 17 |
| 16 | 18 |
| 17 #define __ assembler-> | 19 #define __ assembler-> |
| 18 | 20 |
| 19 namespace dart { | 21 namespace dart { |
| 20 | 22 |
| 21 DEFINE_FLAG(bool, inline_alloc, true, "Inline allocation of objects."); | 23 DEFINE_FLAG(bool, inline_alloc, true, "Inline allocation of objects."); |
| 22 DEFINE_FLAG(bool, use_slow_path, false, | 24 DEFINE_FLAG(bool, use_slow_path, false, |
| 23 "Set to true for debugging & verifying the slow paths."); | 25 "Set to true for debugging & verifying the slow paths."); |
| 24 DECLARE_FLAG(int, optimization_counter_threshold); | 26 DECLARE_FLAG(int, optimization_counter_threshold); |
| 25 | 27 |
| 28 |
| 26 // Input parameters: | 29 // Input parameters: |
| 27 // RSP : points to return address. | 30 // RSP : points to return address. |
| 28 // RSP + 8 : address of last argument in argument array. | 31 // RSP + 8 : address of last argument in argument array. |
| 29 // RSP + 8*R10 : address of first argument in argument array. | 32 // RSP + 8*R10 : address of first argument in argument array. |
| 30 // RSP + 8*R10 + 8 : address of return value. | 33 // RSP + 8*R10 + 8 : address of return value. |
| 31 // RBX : address of the runtime function to call. | 34 // RBX : address of the runtime function to call. |
| 32 // R10 : number of arguments to the call. | 35 // R10 : number of arguments to the call. |
| 33 // Must preserve callee saved registers R12 and R13. | 36 // Must preserve callee saved registers R12 and R13. |
| 34 void StubCode::GenerateCallToRuntimeStub(Assembler* assembler) { | 37 void StubCode::GenerateCallToRuntimeStub(Assembler* assembler) { |
| 35 ASSERT((R12 != CTX) && (R13 != CTX)); | 38 ASSERT((R12 != CTX) && (R13 != CTX)); |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 100 void StubCode::GeneratePrintStopMessageStub(Assembler* assembler) { | 103 void StubCode::GeneratePrintStopMessageStub(Assembler* assembler) { |
| 101 // Preserve caller-saved registers. | 104 // Preserve caller-saved registers. |
| 102 __ pushq(RAX); | 105 __ pushq(RAX); |
| 103 __ pushq(RCX); | 106 __ pushq(RCX); |
| 104 __ pushq(RDX); | 107 __ pushq(RDX); |
| 105 __ pushq(RSI); | 108 __ pushq(RSI); |
| 106 __ pushq(R8); | 109 __ pushq(R8); |
| 107 __ pushq(R9); | 110 __ pushq(R9); |
| 108 __ pushq(R10); | 111 __ pushq(R10); |
| 109 | 112 |
| 110 __ EnterFrame(0); | 113 AssemblerMacros::EnterStubFrame(assembler); |
| 111 | 114 |
| 112 // Align frame before entering C++ world. | 115 // Align frame before entering C++ world. |
| 113 if (OS::ActivationFrameAlignment() > 0) { | 116 if (OS::ActivationFrameAlignment() > 0) { |
| 114 __ andq(RSP, Immediate(~(OS::ActivationFrameAlignment() - 1))); | 117 __ andq(RSP, Immediate(~(OS::ActivationFrameAlignment() - 1))); |
| 115 } | 118 } |
| 116 | 119 |
| 117 // Stop message is already in RDI. | 120 // Stop message is already in RDI. |
| 118 __ movq(TMP, Immediate(reinterpret_cast<uword>(&PrintStopMessage))); | 121 __ movq(TMP, Immediate(reinterpret_cast<uword>(&PrintStopMessage))); |
| 119 __ call(TMP); | 122 __ call(TMP); |
| 120 | 123 |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 209 const Immediate raw_null = | 212 const Immediate raw_null = |
| 210 Immediate(reinterpret_cast<intptr_t>(Object::null())); | 213 Immediate(reinterpret_cast<intptr_t>(Object::null())); |
| 211 | 214 |
| 212 __ movq(RAX, FieldAddress(RBX, Function::code_offset())); | 215 __ movq(RAX, FieldAddress(RBX, Function::code_offset())); |
| 213 __ cmpq(RAX, raw_null); | 216 __ cmpq(RAX, raw_null); |
| 214 Label function_compiled; | 217 Label function_compiled; |
| 215 __ j(NOT_EQUAL, &function_compiled, Assembler::kNearJump); | 218 __ j(NOT_EQUAL, &function_compiled, Assembler::kNearJump); |
| 216 | 219 |
| 217 // Create a stub frame as we are pushing some objects on the stack before | 220 // Create a stub frame as we are pushing some objects on the stack before |
| 218 // calling into the runtime. | 221 // calling into the runtime. |
| 219 __ EnterFrame(0); | 222 AssemblerMacros::EnterStubFrame(assembler); |
| 220 | 223 |
| 221 __ pushq(R10); // Preserve arguments descriptor array. | 224 __ pushq(R10); // Preserve arguments descriptor array. |
| 222 __ pushq(RBX); | 225 __ pushq(RBX); |
| 223 __ CallRuntime(kCompileFunctionRuntimeEntry); | 226 __ CallRuntime(kCompileFunctionRuntimeEntry); |
| 224 __ popq(RBX); // Restore read-only function object argument in RBX. | 227 __ popq(RBX); // Restore read-only function object argument in RBX. |
| 225 __ popq(R10); // Restore arguments descriptor array. | 228 __ popq(R10); // Restore arguments descriptor array. |
| 226 // Restore RAX. | 229 // Restore RAX. |
| 227 __ movq(RAX, FieldAddress(RBX, Function::code_offset())); | 230 __ movq(RAX, FieldAddress(RBX, Function::code_offset())); |
| 228 | 231 |
| 229 // Remove the stub frame as we are about to jump to the dart function. | 232 // Remove the stub frame as we are about to jump to the dart function. |
| 230 __ LeaveFrame(); | 233 __ LeaveFrame(); |
| 231 | 234 |
| 232 __ Bind(&function_compiled); | 235 __ Bind(&function_compiled); |
| 233 // Patch caller. | 236 // Patch caller. |
| 234 __ EnterFrame(0); | 237 AssemblerMacros::EnterStubFrame(assembler); |
| 235 | 238 |
| 236 __ pushq(R10); // Preserve arguments descriptor array. | 239 __ pushq(R10); // Preserve arguments descriptor array. |
| 237 __ pushq(RBX); // Preserve function object. | 240 __ pushq(RBX); // Preserve function object. |
| 238 __ CallRuntime(kPatchStaticCallRuntimeEntry); | 241 __ CallRuntime(kPatchStaticCallRuntimeEntry); |
| 239 __ popq(RBX); // Restore function object argument in RBX. | 242 __ popq(RBX); // Restore function object argument in RBX. |
| 240 __ popq(R10); // Restore arguments descriptor array. | 243 __ popq(R10); // Restore arguments descriptor array. |
| 241 // Remove the stub frame as we are about to jump to the dart function. | 244 // Remove the stub frame as we are about to jump to the dart function. |
| 242 __ LeaveFrame(); | 245 __ LeaveFrame(); |
| 243 __ movq(RAX, FieldAddress(RBX, Function::code_offset())); | 246 __ movq(RAX, FieldAddress(RBX, Function::code_offset())); |
| 244 | 247 |
| 245 __ movq(RBX, FieldAddress(RAX, Code::instructions_offset())); | 248 __ movq(RBX, FieldAddress(RAX, Code::instructions_offset())); |
| 246 __ addq(RBX, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); | 249 __ addq(RBX, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); |
| 247 __ jmp(RBX); | 250 __ jmp(RBX); |
| 248 } | 251 } |
| 249 | 252 |
| 250 | 253 |
| 251 // Called from a static call only when an invalid code has been entered | 254 // Called from a static call only when an invalid code has been entered |
| 252 // (invalid because its function was optimized or deoptimized). | 255 // (invalid because its function was optimized or deoptimized). |
| 253 // RBX: function object. | 256 // RBX: function object. |
| 254 // R10: arguments descriptor array (num_args is first Smi element). | 257 // R10: arguments descriptor array (num_args is first Smi element). |
| 255 void StubCode::GenerateFixCallersTargetStub(Assembler* assembler) { | 258 void StubCode::GenerateFixCallersTargetStub(Assembler* assembler) { |
| 256 __ EnterFrame(0); | 259 AssemblerMacros::EnterStubFrame(assembler); |
| 257 __ pushq(R10); // Preserve arguments descriptor array. | 260 __ pushq(R10); // Preserve arguments descriptor array. |
| 258 __ pushq(RBX); // Preserve target function. | 261 __ pushq(RBX); // Preserve target function. |
| 259 __ pushq(RBX); // Target function. | 262 __ pushq(RBX); // Target function. |
| 260 __ CallRuntime(kFixCallersTargetRuntimeEntry); | 263 __ CallRuntime(kFixCallersTargetRuntimeEntry); |
| 261 __ popq(RAX); // discard argument. | 264 __ popq(RAX); // discard argument. |
| 262 __ popq(RAX); // Restore function. | 265 __ popq(RAX); // Restore function. |
| 263 __ popq(R10); // Restore arguments descriptor array. | 266 __ popq(R10); // Restore arguments descriptor array. |
| 264 __ movq(RAX, FieldAddress(RAX, Function::code_offset())); | 267 __ movq(RAX, FieldAddress(RAX, Function::code_offset())); |
| 265 __ movq(RAX, FieldAddress(RAX, Code::instructions_offset())); | 268 __ movq(RAX, FieldAddress(RAX, Code::instructions_offset())); |
| 266 __ addq(RAX, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); | 269 __ addq(RAX, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); |
| (...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 391 void StubCode::GenerateMegamorphicLookupStub(Assembler* assembler) { | 394 void StubCode::GenerateMegamorphicLookupStub(Assembler* assembler) { |
| 392 const Immediate raw_null = | 395 const Immediate raw_null = |
| 393 Immediate(reinterpret_cast<intptr_t>(Object::null())); | 396 Immediate(reinterpret_cast<intptr_t>(Object::null())); |
| 394 | 397 |
| 395 MegamorphicLookup(assembler); | 398 MegamorphicLookup(assembler); |
| 396 // Lookup in function_table_ failed, resolve, compile and enter function | 399 // Lookup in function_table_ failed, resolve, compile and enter function |
| 397 // into function_table_. | 400 // into function_table_. |
| 398 | 401 |
| 399 // Create a stub frame as we are pushing some objects on the stack before | 402 // Create a stub frame as we are pushing some objects on the stack before |
| 400 // calling into the runtime. | 403 // calling into the runtime. |
| 401 __ EnterFrame(0); | 404 AssemblerMacros::EnterStubFrame(assembler); |
| 402 | 405 |
| 403 // Preserve values across call to resolving. | 406 // Preserve values across call to resolving. |
| 404 // Stack at this point: | 407 // Stack at this point: |
| 405 // TOS + 0: Saved RBP of previous frame. <== RBP | 408 // TOS + 0: PC marker => RawInstruction object. |
| 406 // TOS + 1: Dart code return address | 409 // TOS + 1: Saved RBP of previous frame. <== RBP |
| 407 // TOS + 2: Last argument of caller. | 410 // TOS + 2: Dart code return address |
| 411 // TOS + 3: Last argument of caller. |
| 408 // .... | 412 // .... |
| 409 // Total number of args is the first Smi in args descriptor array (R10). | 413 // Total number of args is the first Smi in args descriptor array (R10). |
| 410 __ movq(RAX, FieldAddress(R10, Array::data_offset())); | 414 __ movq(RAX, FieldAddress(R10, Array::data_offset())); |
| 411 __ movq(RAX, Address(RSP, RAX, TIMES_4, kWordSize)); // Get receiver. | 415 __ movq(RAX, Address(RBP, RAX, TIMES_4, kWordSize)); // Get receiver. |
| 412 __ pushq(R10); // Preserve arguments descriptor array. | 416 __ pushq(R10); // Preserve arguments descriptor array. |
| 413 __ pushq(RAX); // Preserve receiver. | 417 __ pushq(RAX); // Preserve receiver. |
| 414 __ pushq(RBX); // Preserve ic-data. | 418 __ pushq(RBX); // Preserve ic-data. |
| 415 // First resolve the function to get the function object. | 419 // First resolve the function to get the function object. |
| 416 | 420 |
| 417 __ pushq(raw_null); // Setup space on stack for return value. | 421 __ pushq(raw_null); // Setup space on stack for return value. |
| 418 __ pushq(RAX); // Push receiver. | 422 __ pushq(RAX); // Push receiver. |
| 419 __ CallRuntime(kResolveCompileInstanceFunctionRuntimeEntry); | 423 __ CallRuntime(kResolveCompileInstanceFunctionRuntimeEntry); |
| 420 __ popq(RAX); // Remove receiver pushed earlier. | 424 __ popq(RAX); // Remove receiver pushed earlier. |
| 421 __ popq(RBX); // Pop returned code object into RBX. | 425 __ popq(RBX); // Pop returned code object into RBX. |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 502 __ j(EQUAL, &function_not_found); | 506 __ j(EQUAL, &function_not_found); |
| 503 | 507 |
| 504 // RBX: Closure object. | 508 // RBX: Closure object. |
| 505 // R13: Arguments descriptor array. | 509 // R13: Arguments descriptor array. |
| 506 __ pushq(raw_null); // Setup space on stack for result from invoking Closure. | 510 __ pushq(raw_null); // Setup space on stack for result from invoking Closure. |
| 507 __ pushq(RBX); // Closure object. | 511 __ pushq(RBX); // Closure object. |
| 508 __ pushq(R13); // Arguments descriptor. | 512 __ pushq(R13); // Arguments descriptor. |
| 509 __ movq(R13, FieldAddress(R13, Array::data_offset())); | 513 __ movq(R13, FieldAddress(R13, Array::data_offset())); |
| 510 __ SmiUntag(R13); | 514 __ SmiUntag(R13); |
| 511 __ subq(R13, Immediate(1)); // Arguments array length, minus the receiver. | 515 __ subq(R13, Immediate(1)); // Arguments array length, minus the receiver. |
| 512 PushArgumentsArray(assembler, (kWordSize * 5)); | 516 PushArgumentsArray(assembler, (kWordSize * 6)); |
| 513 // Stack layout explaining "(kWordSize * 5)" offset. | 517 // Stack layout explaining "(kWordSize * 6)" offset. |
| 514 // TOS + 0: Argument array. | 518 // TOS + 0: Argument array. |
| 515 // TOS + 1: Arguments descriptor array. | 519 // TOS + 1: Arguments descriptor array. |
| 516 // TOS + 2: Closure object. | 520 // TOS + 2: Closure object. |
| 517 // TOS + 3: Place for result from closure function. | 521 // TOS + 3: Place for result from closure function. |
| 518 // TOS + 4: Saved RBP of previous frame. <== RBP | 522 // TOS + 4: PC marker => RawInstruction object. |
| 519 // TOS + 5: Dart code return address | 523 // TOS + 5: Saved RBP of previous frame. <== RBP |
| 520 // TOS + 6: Last argument of caller. | 524 // TOS + 6: Dart code return address |
| 525 // TOS + 7: Last argument of caller. |
| 521 // .... | 526 // .... |
| 522 | 527 |
| 523 __ CallRuntime(kInvokeImplicitClosureFunctionRuntimeEntry); | 528 __ CallRuntime(kInvokeImplicitClosureFunctionRuntimeEntry); |
| 524 // Remove arguments. | 529 // Remove arguments. |
| 525 __ popq(RAX); | 530 __ popq(RAX); |
| 526 __ popq(RAX); | 531 __ popq(RAX); |
| 527 __ popq(RAX); | 532 __ popq(RAX); |
| 528 __ popq(RAX); // Get result into RAX. | 533 __ popq(RAX); // Get result into RAX. |
| 529 | 534 |
| 530 // Remove the stub frame as we are about to return. | 535 // Remove the stub frame as we are about to return. |
| 531 __ LeaveFrame(); | 536 __ LeaveFrame(); |
| 532 __ ret(); | 537 __ ret(); |
| 533 | 538 |
| 534 __ Bind(&function_not_found); | 539 __ Bind(&function_not_found); |
| 535 // The target function was not found, so invoke method | 540 // The target function was not found, so invoke method |
| 536 // "void noSuchMethod(function_name, args_array)". | 541 // "void noSuchMethod(function_name, args_array)". |
| 537 // RAX: receiver. | 542 // RAX: receiver. |
| 538 // R10: ic-data. | 543 // R10: ic-data. |
| 539 // RBX: raw_null. | 544 // RBX: raw_null. |
| 540 // R13: argument descriptor array. | 545 // R13: argument descriptor array. |
| 541 | 546 |
| 542 __ pushq(raw_null); // Setup space on stack for result from noSuchMethod. | 547 __ pushq(raw_null); // Setup space on stack for result from noSuchMethod. |
| 543 __ pushq(RAX); // Receiver. | 548 __ pushq(RAX); // Receiver. |
| 544 __ pushq(R10); // IC-data array. | 549 __ pushq(R10); // IC-data array. |
| 545 __ pushq(R13); // Argument descriptor array. | 550 __ pushq(R13); // Argument descriptor array. |
| 546 __ movq(R13, FieldAddress(R13, Array::data_offset())); | 551 __ movq(R13, FieldAddress(R13, Array::data_offset())); |
| 547 __ SmiUntag(R13); | 552 __ SmiUntag(R13); |
| 548 __ subq(R13, Immediate(1)); // Arguments array length, minus the receiver. | 553 __ subq(R13, Immediate(1)); // Arguments array length, minus the receiver. |
| 549 // See stack layout below explaining "wordSize * 6" offset. | 554 // See stack layout below explaining "wordSize * 7" offset. |
| 550 PushArgumentsArray(assembler, (kWordSize * 6)); | 555 PushArgumentsArray(assembler, (kWordSize * 7)); |
| 551 | 556 |
| 552 // Stack: | 557 // Stack: |
| 553 // TOS + 0: Argument array. | 558 // TOS + 0: Argument array. |
| 554 // TOS + 1: Argument descriptor array. | 559 // TOS + 1: Argument descriptor array. |
| 555 // TOS + 2: IC-data array. | 560 // TOS + 2: IC-data array. |
| 556 // TOS + 3: Receiver. | 561 // TOS + 3: Receiver. |
| 557 // TOS + 4: Place for result from noSuchMethod. | 562 // TOS + 4: Place for result from noSuchMethod. |
| 558 // TOS + 5: Saved RBP of previous frame. <== RBP | 563 // TOS + 5: PC marker => RawInstruction object. |
| 559 // TOS + 6: Dart code return address | 564 // TOS + 6: Saved RBP of previous frame. <== RBP |
| 560 // TOS + 7: Last argument of caller. | 565 // TOS + 7: Dart code return address |
| 566 // TOS + 8: Last argument of caller. |
| 561 // .... | 567 // .... |
| 562 | 568 |
| 563 __ CallRuntime(kInvokeNoSuchMethodFunctionRuntimeEntry); | 569 __ CallRuntime(kInvokeNoSuchMethodFunctionRuntimeEntry); |
| 564 // Remove arguments. | 570 // Remove arguments. |
| 565 __ popq(RAX); | 571 __ popq(RAX); |
| 566 __ popq(RAX); | 572 __ popq(RAX); |
| 567 __ popq(RAX); | 573 __ popq(RAX); |
| 568 __ popq(RAX); | 574 __ popq(RAX); |
| 569 __ popq(RAX); // Get result into RAX. | 575 __ popq(RAX); // Get result into RAX. |
| 570 | 576 |
| 571 // Remove the stub frame as we are about to return. | 577 // Remove the stub frame as we are about to return. |
| 572 __ LeaveFrame(); | 578 __ LeaveFrame(); |
| 573 __ ret(); | 579 __ ret(); |
| 574 } | 580 } |
| 575 | 581 |
| 576 | 582 |
| 577 void StubCode::GenerateDeoptimizeStub(Assembler* assembler) { | 583 void StubCode::GenerateDeoptimizeStub(Assembler* assembler) { |
| 578 __ Untested("Deoptimize stub"); | 584 __ Untested("Deoptimize stub"); |
| 579 __ EnterFrame(0); | 585 AssemblerMacros::EnterStubFrame(assembler); |
| 580 // RAX: deoptimization reason id. | 586 // RAX: deoptimization reason id. |
| 581 // Stack at this point: | 587 // Stack at this point: |
| 582 // TOS + 0: Saved EBP of function frame that will be deoptimized. <== EBP | 588 // TOS + 0: PC marker => RawInstruction object. |
| 583 // TOS + 1: Deoptimization point (return address), will be patched. | 589 // TOS + 1: Saved EBP of function frame that will be deoptimized. <== EBP |
| 584 // TOS + 2: top-of-stack at deoptimization point (all arguments on stack). | 590 // TOS + 2: Deoptimization point (return address), will be patched. |
| 591 // TOS + 3: top-of-stack at deoptimization point (all arguments on stack). |
| 585 __ pushq(RAX); | 592 __ pushq(RAX); |
| 586 __ CallRuntime(kDeoptimizeRuntimeEntry); | 593 __ CallRuntime(kDeoptimizeRuntimeEntry); |
| 587 __ popq(RAX); | 594 __ popq(RAX); |
| 588 __ LeaveFrame(); | 595 __ LeaveFrame(); |
| 589 __ ret(); | 596 __ ret(); |
| 590 } | 597 } |
| 591 | 598 |
| 592 | 599 |
| 593 // Called for inline allocation of arrays. | 600 // Called for inline allocation of arrays. |
| 594 // Input parameters: | 601 // Input parameters: |
| (...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 704 | 711 |
| 705 // Done allocating and initializing the array. | 712 // Done allocating and initializing the array. |
| 706 // RAX: new object. | 713 // RAX: new object. |
| 707 // R10: Array length as Smi (preserved for the caller.) | 714 // R10: Array length as Smi (preserved for the caller.) |
| 708 __ ret(); | 715 __ ret(); |
| 709 } | 716 } |
| 710 | 717 |
| 711 // Unable to allocate the array using the fast inline code, just call | 718 // Unable to allocate the array using the fast inline code, just call |
| 712 // into the runtime. | 719 // into the runtime. |
| 713 __ Bind(&slow_case); | 720 __ Bind(&slow_case); |
| 714 __ EnterFrame(0); | 721 AssemblerMacros::EnterStubFrame(assembler); |
| 715 __ pushq(raw_null); // Setup space on stack for return value. | 722 __ pushq(raw_null); // Setup space on stack for return value. |
| 716 __ pushq(R10); // Array length as Smi. | 723 __ pushq(R10); // Array length as Smi. |
| 717 __ pushq(RBX); // Element type. | 724 __ pushq(RBX); // Element type. |
| 718 __ CallRuntime(kAllocateArrayRuntimeEntry); | 725 __ CallRuntime(kAllocateArrayRuntimeEntry); |
| 719 __ popq(RAX); // Pop element type argument. | 726 __ popq(RAX); // Pop element type argument. |
| 720 __ popq(R10); // Pop array length argument. | 727 __ popq(R10); // Pop array length argument. |
| 721 __ popq(RAX); // Pop return value from return slot. | 728 __ popq(RAX); // Pop return value from return slot. |
| 722 __ LeaveFrame(); | 729 __ LeaveFrame(); |
| 723 __ ret(); | 730 __ ret(); |
| 724 } | 731 } |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 761 __ movq(CTX, FieldAddress(R13, Closure::context_offset())); | 768 __ movq(CTX, FieldAddress(R13, Closure::context_offset())); |
| 762 | 769 |
| 763 // Load closure function code in RAX. | 770 // Load closure function code in RAX. |
| 764 __ movq(RAX, FieldAddress(RBX, Function::code_offset())); | 771 __ movq(RAX, FieldAddress(RBX, Function::code_offset())); |
| 765 __ cmpq(RAX, raw_null); | 772 __ cmpq(RAX, raw_null); |
| 766 Label function_compiled; | 773 Label function_compiled; |
| 767 __ j(NOT_EQUAL, &function_compiled, Assembler::kNearJump); | 774 __ j(NOT_EQUAL, &function_compiled, Assembler::kNearJump); |
| 768 | 775 |
| 769 // Create a stub frame as we are pushing some objects on the stack before | 776 // Create a stub frame as we are pushing some objects on the stack before |
| 770 // calling into the runtime. | 777 // calling into the runtime. |
| 771 __ EnterFrame(0); | 778 AssemblerMacros::EnterStubFrame(assembler); |
| 772 | 779 |
| 773 __ pushq(R10); // Preserve arguments descriptor array. | 780 __ pushq(R10); // Preserve arguments descriptor array. |
| 774 __ pushq(RBX); // Preserve read-only function object argument. | 781 __ pushq(RBX); // Preserve read-only function object argument. |
| 775 __ CallRuntime(kCompileFunctionRuntimeEntry); | 782 __ CallRuntime(kCompileFunctionRuntimeEntry); |
| 776 __ popq(RBX); // Restore read-only function object argument in RBX. | 783 __ popq(RBX); // Restore read-only function object argument in RBX. |
| 777 __ popq(R10); // Restore arguments descriptor array. | 784 __ popq(R10); // Restore arguments descriptor array. |
| 778 // Restore RAX. | 785 // Restore RAX. |
| 779 __ movq(RAX, FieldAddress(RBX, Function::code_offset())); | 786 __ movq(RAX, FieldAddress(RBX, Function::code_offset())); |
| 780 | 787 |
| 781 // Remove the stub frame as we are about to jump to the closure function. | 788 // Remove the stub frame as we are about to jump to the closure function. |
| (...skipping 10 matching lines...) Expand all Loading... |
| 792 | 799 |
| 793 __ Bind(¬_closure); | 800 __ Bind(¬_closure); |
| 794 // Call runtime to report that a closure call was attempted on a non-closure | 801 // Call runtime to report that a closure call was attempted on a non-closure |
| 795 // object, passing the non-closure object and its arguments array. | 802 // object, passing the non-closure object and its arguments array. |
| 796 // R13: non-closure object. | 803 // R13: non-closure object. |
| 797 // R10: arguments descriptor array (num_args is first Smi element, closure | 804 // R10: arguments descriptor array (num_args is first Smi element, closure |
| 798 // object is not included in num_args). | 805 // object is not included in num_args). |
| 799 | 806 |
| 800 // Create a stub frame as we are pushing some objects on the stack before | 807 // Create a stub frame as we are pushing some objects on the stack before |
| 801 // calling into the runtime. | 808 // calling into the runtime. |
| 802 __ EnterFrame(0); | 809 AssemblerMacros::EnterStubFrame(assembler); |
| 803 | 810 |
| 804 __ pushq(raw_null); // Setup space on stack for result from error reporting. | 811 __ pushq(raw_null); // Setup space on stack for result from error reporting. |
| 805 __ pushq(R13); // Non-closure object. | 812 __ pushq(R13); // Non-closure object. |
| 806 // Total number of args is the first Smi in args descriptor array (R10). | 813 // Total number of args is the first Smi in args descriptor array (R10). |
| 807 __ movq(R13, FieldAddress(R10, Array::data_offset())); // Load num_args. | 814 __ movq(R13, FieldAddress(R10, Array::data_offset())); // Load num_args. |
| 808 __ SmiUntag(R13); | 815 __ SmiUntag(R13); |
| 809 // See stack layout below explaining "wordSize * 4" offset. | 816 // See stack layout below explaining "wordSize * 5" offset. |
| 810 PushArgumentsArray(assembler, (kWordSize * 4)); | 817 PushArgumentsArray(assembler, (kWordSize * 5)); |
| 811 | 818 |
| 812 // Stack: | 819 // Stack: |
| 813 // TOS + 0: Argument array. | 820 // TOS + 0: Argument array. |
| 814 // TOS + 1: Non-closure object. | 821 // TOS + 1: Non-closure object. |
| 815 // TOS + 2: Place for result from reporting the error. | 822 // TOS + 2: Place for result from reporting the error. |
| 816 // TOS + 3: Saved RBP of previous frame. <== RBP | 823 // TOS + 3: PC marker => RawInstruction object. |
| 817 // TOS + 4: Dart code return address | 824 // TOS + 4: Saved RBP of previous frame. <== RBP |
| 818 // TOS + 5: Last argument of caller. | 825 // TOS + 5: Dart code return address |
| 826 // TOS + 6: Last argument of caller. |
| 819 // .... | 827 // .... |
| 820 __ CallRuntime(kReportObjectNotClosureRuntimeEntry); | 828 __ CallRuntime(kReportObjectNotClosureRuntimeEntry); |
| 821 __ Stop("runtime call throws an exception"); | 829 __ Stop("runtime call throws an exception"); |
| 822 } | 830 } |
| 823 | 831 |
| 824 | 832 |
| 825 // Called when invoking Dart code from C++ (VM code). | 833 // Called when invoking Dart code from C++ (VM code). |
| 826 // Input parameters: | 834 // Input parameters: |
| 827 // RSP : points to return address. | 835 // RSP : points to return address. |
| 828 // RDI : entrypoint of the Dart function to call. | 836 // RDI : entrypoint of the Dart function to call. |
| (...skipping 221 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1050 __ j(NOT_EQUAL, &loop, Assembler::kNearJump); | 1058 __ j(NOT_EQUAL, &loop, Assembler::kNearJump); |
| 1051 } | 1059 } |
| 1052 | 1060 |
| 1053 // Done allocating and initializing the context. | 1061 // Done allocating and initializing the context. |
| 1054 // RAX: new object. | 1062 // RAX: new object. |
| 1055 __ ret(); | 1063 __ ret(); |
| 1056 | 1064 |
| 1057 __ Bind(&slow_case); | 1065 __ Bind(&slow_case); |
| 1058 } | 1066 } |
| 1059 // Create a stub frame. | 1067 // Create a stub frame. |
| 1060 __ EnterFrame(0); | 1068 AssemblerMacros::EnterStubFrame(assembler); |
| 1061 __ pushq(raw_null); // Setup space on stack for the return value. | 1069 __ pushq(raw_null); // Setup space on stack for the return value. |
| 1062 __ SmiTag(R10); | 1070 __ SmiTag(R10); |
| 1063 __ pushq(R10); // Push number of context variables. | 1071 __ pushq(R10); // Push number of context variables. |
| 1064 __ CallRuntime(kAllocateContextRuntimeEntry); // Allocate context. | 1072 __ CallRuntime(kAllocateContextRuntimeEntry); // Allocate context. |
| 1065 __ popq(RAX); // Pop number of context variables argument. | 1073 __ popq(RAX); // Pop number of context variables argument. |
| 1066 __ popq(RAX); // Pop the new context object. | 1074 __ popq(RAX); // Pop the new context object. |
| 1067 // RAX: new object | 1075 // RAX: new object |
| 1068 // Restore the frame pointer. | 1076 // Restore the frame pointer. |
| 1069 __ LeaveFrame(); | 1077 __ LeaveFrame(); |
| 1070 __ ret(); | 1078 __ ret(); |
| (...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1243 __ addq(RAX, Immediate(kHeapObjectTag)); | 1251 __ addq(RAX, Immediate(kHeapObjectTag)); |
| 1244 __ ret(); | 1252 __ ret(); |
| 1245 | 1253 |
| 1246 __ Bind(&slow_case); | 1254 __ Bind(&slow_case); |
| 1247 } | 1255 } |
| 1248 if (is_cls_parameterized) { | 1256 if (is_cls_parameterized) { |
| 1249 __ movq(RAX, Address(RSP, kObjectTypeArgumentsOffset)); | 1257 __ movq(RAX, Address(RSP, kObjectTypeArgumentsOffset)); |
| 1250 __ movq(RDX, Address(RSP, kInstantiatorTypeArgumentsOffset)); | 1258 __ movq(RDX, Address(RSP, kInstantiatorTypeArgumentsOffset)); |
| 1251 } | 1259 } |
| 1252 // Create a stub frame. | 1260 // Create a stub frame. |
| 1253 __ EnterFrame(0); | 1261 AssemblerMacros::EnterStubFrame(assembler); |
| 1254 __ pushq(raw_null); // Setup space on stack for return value. | 1262 __ pushq(raw_null); // Setup space on stack for return value. |
| 1255 __ PushObject(cls); // Push class of object to be allocated. | 1263 __ PushObject(cls); // Push class of object to be allocated. |
| 1256 if (is_cls_parameterized) { | 1264 if (is_cls_parameterized) { |
| 1257 __ pushq(RAX); // Push type arguments of object to be allocated. | 1265 __ pushq(RAX); // Push type arguments of object to be allocated. |
| 1258 __ pushq(RDX); // Push type arguments of instantiator. | 1266 __ pushq(RDX); // Push type arguments of instantiator. |
| 1259 } else { | 1267 } else { |
| 1260 __ pushq(raw_null); // Push null type arguments. | 1268 __ pushq(raw_null); // Push null type arguments. |
| 1261 __ pushq(Immediate(Smi::RawValue(StubCode::kNoInstantiator))); | 1269 __ pushq(Immediate(Smi::RawValue(StubCode::kNoInstantiator))); |
| 1262 } | 1270 } |
| 1263 __ CallRuntime(kAllocateObjectRuntimeEntry); // Allocate object. | 1271 __ CallRuntime(kAllocateObjectRuntimeEntry); // Allocate object. |
| (...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1402 | 1410 |
| 1403 __ Bind(&slow_case); | 1411 __ Bind(&slow_case); |
| 1404 } | 1412 } |
| 1405 if (has_type_arguments) { | 1413 if (has_type_arguments) { |
| 1406 __ movq(RCX, Address(RSP, kTypeArgumentsOffset)); | 1414 __ movq(RCX, Address(RSP, kTypeArgumentsOffset)); |
| 1407 } | 1415 } |
| 1408 if (is_implicit_instance_closure) { | 1416 if (is_implicit_instance_closure) { |
| 1409 __ movq(RAX, Address(RSP, kReceiverOffset)); | 1417 __ movq(RAX, Address(RSP, kReceiverOffset)); |
| 1410 } | 1418 } |
| 1411 // Create the stub frame. | 1419 // Create the stub frame. |
| 1412 __ EnterFrame(0); | 1420 AssemblerMacros::EnterStubFrame(assembler); |
| 1413 __ pushq(raw_null); // Setup space on stack for the return value. | 1421 __ pushq(raw_null); // Setup space on stack for the return value. |
| 1414 __ PushObject(func); | 1422 __ PushObject(func); |
| 1415 if (is_implicit_static_closure) { | 1423 if (is_implicit_static_closure) { |
| 1416 __ CallRuntime(kAllocateImplicitStaticClosureRuntimeEntry); | 1424 __ CallRuntime(kAllocateImplicitStaticClosureRuntimeEntry); |
| 1417 } else { | 1425 } else { |
| 1418 if (is_implicit_instance_closure) { | 1426 if (is_implicit_instance_closure) { |
| 1419 __ pushq(RAX); // Receiver. | 1427 __ pushq(RAX); // Receiver. |
| 1420 } | 1428 } |
| 1421 if (has_type_arguments) { | 1429 if (has_type_arguments) { |
| 1422 __ pushq(RCX); // Push type arguments of closure to be allocated. | 1430 __ pushq(RCX); // Push type arguments of closure to be allocated. |
| (...skipping 15 matching lines...) Expand all Loading... |
| 1438 // RAX: New closure object. | 1446 // RAX: New closure object. |
| 1439 // Restore the calling frame. | 1447 // Restore the calling frame. |
| 1440 __ LeaveFrame(); | 1448 __ LeaveFrame(); |
| 1441 __ ret(); | 1449 __ ret(); |
| 1442 } | 1450 } |
| 1443 | 1451 |
| 1444 | 1452 |
| 1445 // Called for invoking noSuchMethod function from the entry code of a dart | 1453 // Called for invoking noSuchMethod function from the entry code of a dart |
| 1446 // function after an error in passed named arguments is detected. | 1454 // function after an error in passed named arguments is detected. |
| 1447 // Input parameters: | 1455 // Input parameters: |
| 1456 // RBP - 8 : PC marker => RawInstruction object. |
| 1448 // RBP : points to previous frame pointer. | 1457 // RBP : points to previous frame pointer. |
| 1449 // RBP + 8 : points to return address. | 1458 // RBP + 8 : points to return address. |
| 1450 // RBP + 16 : address of last argument (arg n-1). | 1459 // RBP + 16 : address of last argument (arg n-1). |
| 1451 // RBP + 16 + 8*(n-1) : address of first argument (arg 0). | 1460 // RBP + 16 + 8*(n-1) : address of first argument (arg 0). |
| 1452 // RBX : ic-data. | 1461 // RBX : ic-data. |
| 1453 // R10 : arguments descriptor array. | 1462 // R10 : arguments descriptor array. |
| 1454 void StubCode::GenerateCallNoSuchMethodFunctionStub(Assembler* assembler) { | 1463 void StubCode::GenerateCallNoSuchMethodFunctionStub(Assembler* assembler) { |
| 1455 // The target function was not found, so invoke method | 1464 // The target function was not found, so invoke method |
| 1456 // "void noSuchMethod(function_name, Array arguments)". | 1465 // "void noSuchMethod(function_name, Array arguments)". |
| 1457 // TODO(regis): For now, we simply pass the actual arguments, both positional | 1466 // TODO(regis): For now, we simply pass the actual arguments, both positional |
| 1458 // and named, as the argument array. This is not correct if out-of-order | 1467 // and named, as the argument array. This is not correct if out-of-order |
| 1459 // named arguments were passed. | 1468 // named arguments were passed. |
| 1460 // The signature of the "noSuchMethod" method has to change from | 1469 // The signature of the "noSuchMethod" method has to change from |
| 1461 // noSuchMethod(String name, Array arguments) to something like | 1470 // noSuchMethod(String name, Array arguments) to something like |
| 1462 // noSuchMethod(InvocationMirror call). | 1471 // noSuchMethod(InvocationMirror call). |
| 1463 // Also, the class NoSuchMethodException has to be modified accordingly. | 1472 // Also, the class NoSuchMethodException has to be modified accordingly. |
| 1464 // Total number of args is the first Smi in args descriptor array (R10). | 1473 // Total number of args is the first Smi in args descriptor array (R10). |
| 1465 const Immediate raw_null = | 1474 const Immediate raw_null = |
| 1466 Immediate(reinterpret_cast<intptr_t>(Object::null())); | 1475 Immediate(reinterpret_cast<intptr_t>(Object::null())); |
| 1467 __ movq(R13, FieldAddress(R10, Array::data_offset())); | 1476 __ movq(R13, FieldAddress(R10, Array::data_offset())); |
| 1468 __ SmiUntag(R13); | 1477 __ SmiUntag(R13); |
| 1469 __ movq(RAX, Address(RBP, R13, TIMES_8, kWordSize)); // Get receiver. | 1478 __ movq(RAX, Address(RBP, R13, TIMES_8, kWordSize)); // Get receiver. |
| 1470 | 1479 |
| 1471 __ EnterFrame(0); | 1480 // Create a stub frame. |
| 1481 AssemblerMacros::EnterStubFrame(assembler); |
| 1482 |
| 1472 __ pushq(raw_null); // Setup space on stack for result from noSuchMethod. | 1483 __ pushq(raw_null); // Setup space on stack for result from noSuchMethod. |
| 1473 __ pushq(RAX); // Receiver. | 1484 __ pushq(RAX); // Receiver. |
| 1474 __ pushq(RBX); // IC data array. | 1485 __ pushq(RBX); // IC data array. |
| 1475 __ pushq(R10); // Arguments descriptor array. | 1486 __ pushq(R10); // Arguments descriptor array. |
| 1476 __ subq(R13, Immediate(1)); // Arguments array length, minus the receiver. | 1487 __ subq(R13, Immediate(1)); // Arguments array length, minus the receiver. |
| 1477 // See stack layout below explaining "wordSize * 8" offset. | 1488 // See stack layout below explaining "wordSize * 10" offset. |
| 1478 PushArgumentsArray(assembler, (kWordSize * 8)); | 1489 PushArgumentsArray(assembler, (kWordSize * 10)); |
| 1479 | 1490 |
| 1480 // Stack: | 1491 // Stack: |
| 1481 // TOS + 0: Argument array. | 1492 // TOS + 0: Argument array. |
| 1482 // TOS + 1: Arguments descriptor array. | 1493 // TOS + 1: Arguments descriptor array. |
| 1483 // TOS + 2: Ic-data array. | 1494 // TOS + 2: Ic-data array. |
| 1484 // TOS + 3: Receiver. | 1495 // TOS + 3: Receiver. |
| 1485 // TOS + 4: Place for result from noSuchMethod. | 1496 // TOS + 4: Place for result from noSuchMethod. |
| 1486 // TOS + 5: Saved RBP of previous frame. <== RBP | 1497 // TOS + 5: PC marker => RawInstruction object. |
| 1487 // TOS + 6: Dart callee (or stub) code return address | 1498 // TOS + 6: Saved RBP of previous frame. <== RBP |
| 1488 // TOS + 7: Saved RBP of dart caller frame. | 1499 // TOS + 7: Dart callee (or stub) code return address |
| 1489 // TOS + 8: Dart caller code return address | 1500 // TOS + 8: PC marker => RawInstruction object of dart caller frame. |
| 1490 // TOS + 9: Last argument of caller. | 1501 // TOS + 9: Saved RBP of dart caller frame. |
| 1502 // TOS + 10: Dart caller code return address |
| 1503 // TOS + 11: Last argument of caller. |
| 1491 // .... | 1504 // .... |
| 1492 __ CallRuntime(kInvokeNoSuchMethodFunctionRuntimeEntry); | 1505 __ CallRuntime(kInvokeNoSuchMethodFunctionRuntimeEntry); |
| 1493 // Remove arguments. | 1506 // Remove arguments. |
| 1494 __ popq(RAX); | 1507 __ popq(RAX); |
| 1495 __ popq(RAX); | 1508 __ popq(RAX); |
| 1496 __ popq(RAX); | 1509 __ popq(RAX); |
| 1497 __ popq(RAX); | 1510 __ popq(RAX); |
| 1498 __ popq(RAX); // Get result into RAX. | 1511 __ popq(RAX); // Get result into RAX. |
| 1499 | 1512 |
| 1500 // Remove the stub frame as we are about to return. | 1513 // Remove the stub frame as we are about to return. |
| (...skipping 16 matching lines...) Expand all Loading... |
| 1517 // - Match not found -> jump to IC miss. | 1530 // - Match not found -> jump to IC miss. |
| 1518 void StubCode::GenerateNArgsCheckInlineCacheStub(Assembler* assembler, | 1531 void StubCode::GenerateNArgsCheckInlineCacheStub(Assembler* assembler, |
| 1519 intptr_t num_args) { | 1532 intptr_t num_args) { |
| 1520 __ movq(RCX, FieldAddress(RBX, ICData::function_offset())); | 1533 __ movq(RCX, FieldAddress(RBX, ICData::function_offset())); |
| 1521 __ incq(FieldAddress(RCX, Function::usage_counter_offset())); | 1534 __ incq(FieldAddress(RCX, Function::usage_counter_offset())); |
| 1522 if (CodeGenerator::CanOptimize()) { | 1535 if (CodeGenerator::CanOptimize()) { |
| 1523 __ cmpq(FieldAddress(RCX, Function::usage_counter_offset()), | 1536 __ cmpq(FieldAddress(RCX, Function::usage_counter_offset()), |
| 1524 Immediate(FLAG_optimization_counter_threshold)); | 1537 Immediate(FLAG_optimization_counter_threshold)); |
| 1525 Label not_yet_hot; | 1538 Label not_yet_hot; |
| 1526 __ j(LESS_EQUAL, ¬_yet_hot, Assembler::kNearJump); | 1539 __ j(LESS_EQUAL, ¬_yet_hot, Assembler::kNearJump); |
| 1527 __ EnterFrame(0); | 1540 AssemblerMacros::EnterStubFrame(assembler); |
| 1528 __ pushq(RBX); // Preserve inline cache data object. | 1541 __ pushq(RBX); // Preserve inline cache data object. |
| 1529 __ pushq(R10); // Preserve arguments array. | 1542 __ pushq(R10); // Preserve arguments array. |
| 1530 __ pushq(RCX); // Argument for runtime: function object. | 1543 __ pushq(RCX); // Argument for runtime: function object. |
| 1531 __ CallRuntime(kOptimizeInvokedFunctionRuntimeEntry); | 1544 __ CallRuntime(kOptimizeInvokedFunctionRuntimeEntry); |
| 1532 __ popq(RCX); // Remove argument. | 1545 __ popq(RCX); // Remove argument. |
| 1533 __ popq(R10); // Restore arguments array. | 1546 __ popq(R10); // Restore arguments array. |
| 1534 __ popq(RBX); // Restore inline cache data object. | 1547 __ popq(RBX); // Restore inline cache data object. |
| 1535 __ LeaveFrame(); | 1548 __ LeaveFrame(); |
| 1536 __ Bind(¬_yet_hot); | 1549 __ Bind(¬_yet_hot); |
| 1537 } | 1550 } |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1598 __ addq(R12, Immediate(kWordSize * (1 + num_args))); // Next element. | 1611 __ addq(R12, Immediate(kWordSize * (1 + num_args))); // Next element. |
| 1599 __ cmpq(R13, raw_null); // Done? | 1612 __ cmpq(R13, raw_null); // Done? |
| 1600 __ j(NOT_EQUAL, &loop, Assembler::kNearJump); | 1613 __ j(NOT_EQUAL, &loop, Assembler::kNearJump); |
| 1601 } | 1614 } |
| 1602 | 1615 |
| 1603 __ Bind(&ic_miss); | 1616 __ Bind(&ic_miss); |
| 1604 // Compute address of arguments (first read number of arguments from argument | 1617 // Compute address of arguments (first read number of arguments from argument |
| 1605 // descriptor array and then compute address on the stack). | 1618 // descriptor array and then compute address on the stack). |
| 1606 __ movq(RAX, FieldAddress(R10, Array::data_offset())); | 1619 __ movq(RAX, FieldAddress(R10, Array::data_offset())); |
| 1607 __ leaq(RAX, Address(RSP, RAX, TIMES_4, 0)); // RAX is Smi. | 1620 __ leaq(RAX, Address(RSP, RAX, TIMES_4, 0)); // RAX is Smi. |
| 1608 __ EnterFrame(0); | 1621 AssemblerMacros::EnterStubFrame(assembler); |
| 1609 __ pushq(R10); // Preserve arguments array. | 1622 __ pushq(R10); // Preserve arguments array. |
| 1610 __ pushq(RBX); // Preserve IC data array | 1623 __ pushq(RBX); // Preserve IC data array |
| 1611 __ pushq(raw_null); // Setup space on stack for result (target code object). | 1624 __ pushq(raw_null); // Setup space on stack for result (target code object). |
| 1612 // Push call arguments. | 1625 // Push call arguments. |
| 1613 for (intptr_t i = 0; i < num_args; i++) { | 1626 for (intptr_t i = 0; i < num_args; i++) { |
| 1614 __ movq(R10, Address(RAX, -kWordSize * i)); | 1627 __ movq(R10, Address(RAX, -kWordSize * i)); |
| 1615 __ pushq(R10); | 1628 __ pushq(R10); |
| 1616 } | 1629 } |
| 1617 if (num_args == 1) { | 1630 if (num_args == 1) { |
| 1618 __ CallRuntime(kInlineCacheMissHandlerOneArgRuntimeEntry); | 1631 __ CallRuntime(kInlineCacheMissHandlerOneArgRuntimeEntry); |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1680 | 1693 |
| 1681 void StubCode::GenerateTwoArgsCheckInlineCacheStub(Assembler* assembler) { | 1694 void StubCode::GenerateTwoArgsCheckInlineCacheStub(Assembler* assembler) { |
| 1682 return GenerateNArgsCheckInlineCacheStub(assembler, 2); | 1695 return GenerateNArgsCheckInlineCacheStub(assembler, 2); |
| 1683 } | 1696 } |
| 1684 | 1697 |
| 1685 | 1698 |
| 1686 // RBX: Function object. | 1699 // RBX: Function object. |
| 1687 // R10: Arguments array. | 1700 // R10: Arguments array. |
| 1688 // TOS(0): return address (Dart code). | 1701 // TOS(0): return address (Dart code). |
| 1689 void StubCode::GenerateBreakpointStaticStub(Assembler* assembler) { | 1702 void StubCode::GenerateBreakpointStaticStub(Assembler* assembler) { |
| 1690 __ EnterFrame(0); | 1703 AssemblerMacros::EnterStubFrame(assembler); |
| 1691 __ pushq(R10); | 1704 __ pushq(R10); |
| 1692 __ pushq(RBX); | 1705 __ pushq(RBX); |
| 1693 __ CallRuntime(kBreakpointStaticHandlerRuntimeEntry); | 1706 __ CallRuntime(kBreakpointStaticHandlerRuntimeEntry); |
| 1694 __ popq(RBX); | 1707 __ popq(RBX); |
| 1695 __ popq(R10); | 1708 __ popq(R10); |
| 1696 __ LeaveFrame(); | 1709 __ LeaveFrame(); |
| 1697 | 1710 |
| 1698 // Now call the static function. The breakpoint handler function | 1711 // Now call the static function. The breakpoint handler function |
| 1699 // ensures that the call target is compiled. | 1712 // ensures that the call target is compiled. |
| 1700 __ movq(RAX, FieldAddress(RBX, Function::code_offset())); | 1713 __ movq(RAX, FieldAddress(RBX, Function::code_offset())); |
| 1701 __ movq(RBX, FieldAddress(RAX, Code::instructions_offset())); | 1714 __ movq(RBX, FieldAddress(RAX, Code::instructions_offset())); |
| 1702 __ addq(RBX, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); | 1715 __ addq(RBX, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); |
| 1703 __ jmp(RBX); | 1716 __ jmp(RBX); |
| 1704 } | 1717 } |
| 1705 | 1718 |
| 1706 | 1719 |
| 1707 // TOS(0): return address (Dart code). | 1720 // TOS(0): return address (Dart code). |
| 1708 void StubCode::GenerateBreakpointReturnStub(Assembler* assembler) { | 1721 void StubCode::GenerateBreakpointReturnStub(Assembler* assembler) { |
| 1709 __ EnterFrame(0); | 1722 AssemblerMacros::EnterStubFrame(assembler); |
| 1710 __ pushq(RAX); | 1723 __ pushq(RAX); |
| 1711 __ CallRuntime(kBreakpointReturnHandlerRuntimeEntry); | 1724 __ CallRuntime(kBreakpointReturnHandlerRuntimeEntry); |
| 1712 __ popq(RAX); | 1725 __ popq(RAX); |
| 1713 __ LeaveFrame(); | 1726 __ LeaveFrame(); |
| 1714 | 1727 |
| 1715 __ popq(R11); // discard return address of call to this stub. | 1728 __ popq(R11); // discard return address of call to this stub. |
| 1716 __ LeaveFrame(); | 1729 __ LeaveFrame(); |
| 1717 __ ret(); | 1730 __ ret(); |
| 1718 } | 1731 } |
| 1719 | 1732 |
| 1720 | 1733 |
| 1721 // RBX: Inline cache data array. | 1734 // RBX: Inline cache data array. |
| 1722 // R10: Arguments array. | 1735 // R10: Arguments array. |
| 1723 // TOS(0): return address (Dart code). | 1736 // TOS(0): return address (Dart code). |
| 1724 void StubCode::GenerateBreakpointDynamicStub(Assembler* assembler) { | 1737 void StubCode::GenerateBreakpointDynamicStub(Assembler* assembler) { |
| 1725 __ EnterFrame(0); | 1738 AssemblerMacros::EnterStubFrame(assembler); |
| 1726 __ pushq(RBX); | 1739 __ pushq(RBX); |
| 1727 __ pushq(R10); | 1740 __ pushq(R10); |
| 1728 __ CallRuntime(kBreakpointDynamicHandlerRuntimeEntry); | 1741 __ CallRuntime(kBreakpointDynamicHandlerRuntimeEntry); |
| 1729 __ popq(R10); | 1742 __ popq(R10); |
| 1730 __ popq(RBX); | 1743 __ popq(RBX); |
| 1731 __ LeaveFrame(); | 1744 __ LeaveFrame(); |
| 1732 | 1745 |
| 1733 // Find out which dispatch stub to call. | 1746 // Find out which dispatch stub to call. |
| 1734 Label ic_cache_one_arg; | 1747 Label ic_cache_one_arg; |
| 1735 __ movq(RCX, FieldAddress(RBX, ICData::num_args_tested_offset())); | 1748 __ movq(RCX, FieldAddress(RBX, ICData::num_args_tested_offset())); |
| 1736 __ cmpq(RCX, Immediate(1)); | 1749 __ cmpq(RCX, Immediate(1)); |
| 1737 __ j(EQUAL, &ic_cache_one_arg, Assembler::kNearJump); | 1750 __ j(EQUAL, &ic_cache_one_arg, Assembler::kNearJump); |
| 1738 __ jmp(&StubCode::TwoArgsCheckInlineCacheLabel()); | 1751 __ jmp(&StubCode::TwoArgsCheckInlineCacheLabel()); |
| 1739 __ Bind(&ic_cache_one_arg); | 1752 __ Bind(&ic_cache_one_arg); |
| 1740 __ jmp(&StubCode::OneArgCheckInlineCacheLabel()); | 1753 __ jmp(&StubCode::OneArgCheckInlineCacheLabel()); |
| 1741 } | 1754 } |
| 1742 | 1755 |
| 1743 | 1756 |
| 1744 void StubCode::GenerateSubtype1TestCacheStub(Assembler* assembler) { | 1757 void StubCode::GenerateSubtype1TestCacheStub(Assembler* assembler) { |
| 1745 __ Unimplemented("Subtype1TestCache Stub"); | 1758 __ Unimplemented("Subtype1TestCache Stub"); |
| 1746 } | 1759 } |
| 1747 | 1760 |
| 1761 |
| 1748 void StubCode::GenerateSubtype2TestCacheStub(Assembler* assembler) { | 1762 void StubCode::GenerateSubtype2TestCacheStub(Assembler* assembler) { |
| 1749 __ Unimplemented("Subtype2TestCache Stub"); | 1763 __ Unimplemented("Subtype2TestCache Stub"); |
| 1750 } | 1764 } |
| 1751 | 1765 |
| 1766 |
| 1752 void StubCode::GenerateSubtype3TestCacheStub(Assembler* assembler) { | 1767 void StubCode::GenerateSubtype3TestCacheStub(Assembler* assembler) { |
| 1753 __ Unimplemented("Subtype3TestCache Stub"); | 1768 __ Unimplemented("Subtype3TestCache Stub"); |
| 1754 } | 1769 } |
| 1755 | 1770 |
| 1756 } // namespace dart | 1771 } // namespace dart |
| 1757 | 1772 |
| 1758 #endif // defined TARGET_ARCH_X64 | 1773 #endif // defined TARGET_ARCH_X64 |
| OLD | NEW |