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 |