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