Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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" | 8 #include "vm/assembler.h" |
| 9 #include "vm/compiler.h" | 9 #include "vm/compiler.h" |
| 10 #include "vm/dart_entry.h" | 10 #include "vm/dart_entry.h" |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 21 #define __ assembler-> | 21 #define __ assembler-> |
| 22 | 22 |
| 23 namespace dart { | 23 namespace dart { |
| 24 | 24 |
| 25 DEFINE_FLAG(bool, inline_alloc, true, "Inline allocation of objects."); | 25 DEFINE_FLAG(bool, inline_alloc, true, "Inline allocation of objects."); |
| 26 DEFINE_FLAG(bool, use_slow_path, false, | 26 DEFINE_FLAG(bool, use_slow_path, false, |
| 27 "Set to true for debugging & verifying the slow paths."); | 27 "Set to true for debugging & verifying the slow paths."); |
| 28 DECLARE_FLAG(bool, trace_optimized_ic_calls); | 28 DECLARE_FLAG(bool, trace_optimized_ic_calls); |
| 29 DECLARE_FLAG(int, optimization_counter_threshold); | 29 DECLARE_FLAG(int, optimization_counter_threshold); |
| 30 DECLARE_FLAG(bool, support_debugger); | 30 DECLARE_FLAG(bool, support_debugger); |
| 31 DECLARE_FLAG(bool, lazy_dispatchers); | |
| 31 | 32 |
| 32 // Input parameters: | 33 // Input parameters: |
| 33 // RSP : points to return address. | 34 // RSP : points to return address. |
| 34 // RSP + 8 : address of last argument in argument array. | 35 // RSP + 8 : address of last argument in argument array. |
| 35 // RSP + 8*R10 : address of first argument in argument array. | 36 // RSP + 8*R10 : address of first argument in argument array. |
| 36 // RSP + 8*R10 + 8 : address of return value. | 37 // RSP + 8*R10 + 8 : address of return value. |
| 37 // RBX : address of the runtime function to call. | 38 // RBX : address of the runtime function to call. |
| 38 // R10 : number of arguments to the call. | 39 // R10 : number of arguments to the call. |
| 39 // Must preserve callee saved registers R12 and R13. | 40 // Must preserve callee saved registers R12 and R13. |
| 40 void StubCode::GenerateCallToRuntimeStub(Assembler* assembler) { | 41 void StubCode::GenerateCallToRuntimeStub(Assembler* assembler) { |
| (...skipping 479 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 520 __ pushq(RBX); | 521 __ pushq(RBX); |
| 521 GenerateDeoptimizationSequence(assembler, true); // Preserve RAX. | 522 GenerateDeoptimizationSequence(assembler, true); // Preserve RAX. |
| 522 } | 523 } |
| 523 | 524 |
| 524 | 525 |
| 525 void StubCode::GenerateDeoptimizeStub(Assembler* assembler) { | 526 void StubCode::GenerateDeoptimizeStub(Assembler* assembler) { |
| 526 GenerateDeoptimizationSequence(assembler, false); // Don't preserve RAX. | 527 GenerateDeoptimizationSequence(assembler, false); // Don't preserve RAX. |
| 527 } | 528 } |
| 528 | 529 |
| 529 | 530 |
| 531 static void GenerateDispatcherCode(Assembler* assembler, | |
| 532 Label* call_target_function) { | |
| 533 __ Comment("NoSuchMethodDispatch"); | |
| 534 // When lazily generated invocation dispatchers are disabled, the | |
| 535 // miss-handler may return null. | |
| 536 const Immediate& raw_null = | |
| 537 Immediate(reinterpret_cast<intptr_t>(Object::null())); | |
| 538 __ cmpq(RAX, raw_null); | |
| 539 __ j(NOT_EQUAL, call_target_function); | |
| 540 __ EnterStubFrame(); | |
| 541 // Load the receiver. | |
| 542 __ movq(RDI, FieldAddress(R10, ArgumentsDescriptor::count_offset())); | |
| 543 __ movq(RAX, Address( | |
| 544 RBP, RDI, TIMES_HALF_WORD_SIZE, kParamEndSlotFromFp * kWordSize)); | |
| 545 __ pushq(raw_null); // Setup space on stack for result. | |
| 546 __ pushq(RAX); // Receiver. | |
| 547 __ pushq(RBX); | |
| 548 __ pushq(R10); // Arguments descriptor array. | |
| 549 __ movq(R10, RDI); | |
| 550 // EDX: Smi-tagged arguments array length. | |
| 551 PushArgumentsArray(assembler); | |
| 552 const intptr_t kNumArgs = 4; | |
| 553 __ CallRuntime(kInvokeNoSuchMethodDispatcherRuntimeEntry, kNumArgs); | |
| 554 __ popq(RAX); | |
|
Florian Schneider
2015/06/17 08:01:34
__ Drop(4);
__ popq(RAX);
rmacnak
2015/06/17 17:42:20
Done.
| |
| 555 __ popq(RAX); | |
| 556 __ popq(RAX); | |
| 557 __ popq(RAX); | |
| 558 __ popq(RAX); // Return value. | |
| 559 __ LeaveStubFrame(); | |
| 560 __ ret(); | |
| 561 } | |
| 562 | |
| 563 | |
| 530 void StubCode::GenerateMegamorphicMissStub(Assembler* assembler) { | 564 void StubCode::GenerateMegamorphicMissStub(Assembler* assembler) { |
| 531 __ EnterStubFrame(); | 565 __ EnterStubFrame(); |
| 532 // Load the receiver into RAX. The argument count in the arguments | 566 // Load the receiver into RAX. The argument count in the arguments |
| 533 // descriptor in R10 is a smi. | 567 // descriptor in R10 is a smi. |
| 534 __ movq(RAX, FieldAddress(R10, ArgumentsDescriptor::count_offset())); | 568 __ movq(RAX, FieldAddress(R10, ArgumentsDescriptor::count_offset())); |
| 535 // Three words (saved pp, saved fp, stub's pc marker) | 569 // Three words (saved pp, saved fp, stub's pc marker) |
| 536 // in the stack above the return address. | 570 // in the stack above the return address. |
| 537 __ movq(RAX, Address(RSP, RAX, TIMES_4, | 571 __ movq(RAX, Address(RSP, RAX, TIMES_4, |
| 538 kSavedAboveReturnAddress * kWordSize)); | 572 kSavedAboveReturnAddress * kWordSize)); |
| 539 // Preserve IC data and arguments descriptor. | 573 // Preserve IC data and arguments descriptor. |
| 540 __ pushq(RBX); | 574 __ pushq(RBX); |
| 541 __ pushq(R10); | 575 __ pushq(R10); |
| 542 | 576 |
| 543 // Space for the result of the runtime call. | 577 // Space for the result of the runtime call. |
| 544 __ PushObject(Object::null_object(), PP); | 578 __ PushObject(Object::null_object(), PP); |
| 545 __ pushq(RAX); // Receiver. | 579 __ pushq(RAX); // Receiver. |
| 546 __ pushq(RBX); // IC data. | 580 __ pushq(RBX); // IC data. |
| 547 __ pushq(R10); // Arguments descriptor. | 581 __ pushq(R10); // Arguments descriptor. |
| 548 __ CallRuntime(kMegamorphicCacheMissHandlerRuntimeEntry, 3); | 582 __ CallRuntime(kMegamorphicCacheMissHandlerRuntimeEntry, 3); |
| 549 // Discard arguments. | 583 // Discard arguments. |
| 550 __ popq(RAX); | 584 __ popq(RAX); |
| 551 __ popq(RAX); | 585 __ popq(RAX); |
| 552 __ popq(RAX); | 586 __ popq(RAX); |
| 553 __ popq(RAX); // Return value from the runtime call (function). | 587 __ popq(RAX); // Return value from the runtime call (function). |
| 554 __ popq(R10); // Restore arguments descriptor. | 588 __ popq(R10); // Restore arguments descriptor. |
| 555 __ popq(RBX); // Restore IC data. | 589 __ popq(RBX); // Restore IC data. |
| 556 __ LeaveStubFrame(); | 590 __ LeaveStubFrame(); |
| 557 | 591 |
| 592 if (!FLAG_lazy_dispatchers) { | |
| 593 Label call_target_function; | |
| 594 GenerateDispatcherCode(assembler, &call_target_function); | |
| 595 __ Bind(&call_target_function); | |
| 596 } | |
| 597 | |
| 558 __ movq(RCX, FieldAddress(RAX, Function::instructions_offset())); | 598 __ movq(RCX, FieldAddress(RAX, Function::instructions_offset())); |
| 559 __ addq(RCX, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); | 599 __ addq(RCX, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); |
| 560 __ jmp(RCX); | 600 __ jmp(RCX); |
| 561 } | 601 } |
| 562 | 602 |
| 563 | 603 |
| 564 // Called for inline allocation of arrays. | 604 // Called for inline allocation of arrays. |
| 565 // Input parameters: | 605 // Input parameters: |
| 566 // R10 : Array length as Smi. | 606 // R10 : Array length as Smi. |
| 567 // RBX : array element type (either NULL or an instantiated type). | 607 // RBX : array element type (either NULL or an instantiated type). |
| (...skipping 884 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1452 __ CallRuntime(handle_ic_miss, num_args + 1); | 1492 __ CallRuntime(handle_ic_miss, num_args + 1); |
| 1453 // Remove the call arguments pushed earlier, including the IC data object. | 1493 // Remove the call arguments pushed earlier, including the IC data object. |
| 1454 for (intptr_t i = 0; i < num_args + 1; i++) { | 1494 for (intptr_t i = 0; i < num_args + 1; i++) { |
| 1455 __ popq(RAX); | 1495 __ popq(RAX); |
| 1456 } | 1496 } |
| 1457 __ popq(RAX); // Pop returned function object into RAX. | 1497 __ popq(RAX); // Pop returned function object into RAX. |
| 1458 __ popq(RBX); // Restore IC data array. | 1498 __ popq(RBX); // Restore IC data array. |
| 1459 __ popq(R10); // Restore arguments descriptor array. | 1499 __ popq(R10); // Restore arguments descriptor array. |
| 1460 __ LeaveStubFrame(); | 1500 __ LeaveStubFrame(); |
| 1461 Label call_target_function; | 1501 Label call_target_function; |
| 1462 __ jmp(&call_target_function); | 1502 if (!FLAG_lazy_dispatchers) { |
| 1503 GenerateDispatcherCode(assembler, &call_target_function); | |
| 1504 } else { | |
| 1505 __ jmp(&call_target_function); | |
| 1506 } | |
| 1463 | 1507 |
| 1464 __ Bind(&found); | 1508 __ Bind(&found); |
| 1465 // R12: Pointer to an IC data check group. | 1509 // R12: Pointer to an IC data check group. |
| 1466 const intptr_t target_offset = ICData::TargetIndexFor(num_args) * kWordSize; | 1510 const intptr_t target_offset = ICData::TargetIndexFor(num_args) * kWordSize; |
| 1467 const intptr_t count_offset = ICData::CountIndexFor(num_args) * kWordSize; | 1511 const intptr_t count_offset = ICData::CountIndexFor(num_args) * kWordSize; |
| 1468 __ movq(RAX, Address(R12, target_offset)); | 1512 __ movq(RAX, Address(R12, target_offset)); |
| 1469 | 1513 |
| 1470 if (FLAG_optimization_counter_threshold >= 0) { | 1514 if (FLAG_optimization_counter_threshold >= 0) { |
| 1471 // Update counter. | 1515 // Update counter. |
| 1472 __ Comment("Update caller's counter"); | 1516 __ Comment("Update caller's counter"); |
| (...skipping 662 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2135 // Result: | 2179 // Result: |
| 2136 // RCX: entry point. | 2180 // RCX: entry point. |
| 2137 void StubCode::GenerateMegamorphicLookupStub(Assembler* assembler) { | 2181 void StubCode::GenerateMegamorphicLookupStub(Assembler* assembler) { |
| 2138 EmitMegamorphicLookup(assembler, RDI, RBX, RCX); | 2182 EmitMegamorphicLookup(assembler, RDI, RBX, RCX); |
| 2139 __ ret(); | 2183 __ ret(); |
| 2140 } | 2184 } |
| 2141 | 2185 |
| 2142 } // namespace dart | 2186 } // namespace dart |
| 2143 | 2187 |
| 2144 #endif // defined TARGET_ARCH_X64 | 2188 #endif // defined TARGET_ARCH_X64 |
| OLD | NEW |