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" // Needed here to get TARGET_ARCH_X64. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_X64. |
| 6 #if defined(TARGET_ARCH_X64) | 6 #if defined(TARGET_ARCH_X64) |
| 7 | 7 |
| 8 #include "vm/flow_graph_compiler.h" | 8 #include "vm/flow_graph_compiler.h" |
| 9 | 9 |
| 10 #include "lib/error.h" | 10 #include "lib/error.h" |
| (...skipping 624 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 635 GuardFieldInstr* guard = instr->AsGuardField(); | 635 GuardFieldInstr* guard = instr->AsGuardField(); |
| 636 AddCurrentDescriptor(PcDescriptors::kDeopt, | 636 AddCurrentDescriptor(PcDescriptors::kDeopt, |
| 637 guard->deopt_id(), | 637 guard->deopt_id(), |
| 638 Scanner::kDummyTokenIndex); | 638 Scanner::kDummyTokenIndex); |
| 639 } else if (instr->CanBeDeoptimizationTarget()) { | 639 } else if (instr->CanBeDeoptimizationTarget()) { |
| 640 AddCurrentDescriptor(PcDescriptors::kDeopt, | 640 AddCurrentDescriptor(PcDescriptors::kDeopt, |
| 641 instr->deopt_id(), | 641 instr->deopt_id(), |
| 642 Scanner::kDummyTokenIndex); | 642 Scanner::kDummyTokenIndex); |
| 643 } | 643 } |
| 644 AllocateRegistersLocally(instr); | 644 AllocateRegistersLocally(instr); |
| 645 } else if (instr->MayThrow() && | |
| 646 (CurrentTryIndex() != CatchClauseNode::kInvalidTryIndex)) { | |
| 647 // Optimized try-block: Sync locals to fixed stack locations. | |
| 648 EmitTrySync(instr, CurrentTryIndex()); | |
| 649 } | |
| 650 } | |
| 651 | |
| 652 | |
| 653 void FlowGraphCompiler::EmitTrySync(Instruction* instr, intptr_t try_index) { | |
|
Kevin Millikin (Google)
2013/05/08 11:42:00
Same comments as IA32.
Florian Schneider
2013/05/08 17:10:55
Done.
| |
| 654 ASSERT(is_optimizing()); | |
| 655 Environment* env = instr->env(); | |
| 656 CatchBlockEntryInstr* catch_block = | |
| 657 flow_graph().graph_entry()->GetCatchEntry(try_index); | |
| 658 const GrowableArray<Definition*>* idefs = catch_block->initial_definitions(); | |
| 659 // Parameters. | |
| 660 intptr_t i = 0; | |
| 661 bool push_emitted = false; | |
| 662 for (; i < flow_graph().num_non_copied_params(); ++i) { | |
| 663 if ((*idefs)[i]->IsConstant()) continue; // common constants | |
| 664 Location loc = env->LocationAt(i); | |
| 665 const intptr_t index = flow_graph().num_non_copied_params() - i; | |
| 666 Address dest(RBP, (kLastParamSlotIndex + index - 1) * kWordSize); | |
| 667 if (loc.IsConstant()) { | |
| 668 if (!push_emitted) { | |
| 669 __ pushq(RAX); | |
| 670 push_emitted = true; | |
| 671 } | |
| 672 __ LoadObject(RAX, loc.constant()); | |
| 673 __ movq(dest, RAX); | |
| 674 } else if (loc.IsRegister()) { | |
| 675 __ movq(dest, loc.reg()); | |
| 676 } else { | |
| 677 Address src = loc.ToStackSlotAddress(); | |
| 678 if (!src.Equals(dest)) { | |
| 679 if (!push_emitted) { | |
| 680 __ pushq(RAX); | |
| 681 push_emitted = true; | |
| 682 } | |
| 683 __ movq(RAX, src); | |
| 684 __ movq(dest, RAX); | |
| 685 } | |
| 686 } | |
| 687 } | |
| 688 // Process locals. Skip exception_var and stacktrace_var. | |
| 689 CatchEntryInstr* catch_entry = catch_block->next()->AsCatchEntry(); | |
| 690 intptr_t nncp = flow_graph_.num_non_copied_params(); | |
| 691 intptr_t ex_idx = | |
| 692 kFirstLocalSlotIndex - catch_entry->exception_var().index() + nncp; | |
| 693 intptr_t st_idx = | |
| 694 kFirstLocalSlotIndex - catch_entry->stacktrace_var().index() + nncp; | |
| 695 for (; i < flow_graph().variable_count(); ++i) { | |
| 696 if (i == ex_idx || i == st_idx) continue; | |
| 697 if ((*idefs)[i]->IsConstant()) continue; | |
| 698 Location loc = env->LocationAt(i); | |
| 699 const intptr_t index = i - flow_graph().num_non_copied_params(); | |
| 700 Address dest(RBP, (kFirstLocalSlotIndex - index) * kWordSize); | |
| 701 if (loc.IsConstant()) { | |
| 702 if (!push_emitted) { | |
| 703 __ pushq(RAX); | |
| 704 push_emitted = true; | |
| 705 } | |
| 706 __ LoadObject(RAX, loc.constant()); | |
| 707 __ movq(dest, RAX); | |
| 708 } else if (loc.IsRegister()) { | |
| 709 __ movq(dest, loc.reg()); | |
| 710 } else { | |
| 711 Address src = loc.ToStackSlotAddress(); | |
| 712 if (!src.Equals(dest)) { | |
| 713 if (!push_emitted) { | |
| 714 __ pushq(RAX); | |
| 715 push_emitted = true; | |
| 716 } | |
| 717 __ movq(RAX, src); | |
| 718 __ movq(dest, RAX); | |
| 719 } | |
| 720 } | |
| 721 // Update safepoint bitmap to indicate that the target location | |
| 722 // now contains a pointer. | |
| 723 instr->locs()->stack_bitmap()->Set(index, true); | |
| 724 } | |
| 725 if (push_emitted) { | |
| 726 __ popq(RAX); | |
| 645 } | 727 } |
| 646 } | 728 } |
| 647 | 729 |
| 648 | 730 |
| 649 void FlowGraphCompiler::EmitInstructionEpilogue(Instruction* instr) { | 731 void FlowGraphCompiler::EmitInstructionEpilogue(Instruction* instr) { |
| 650 if (is_optimizing()) return; | 732 if (is_optimizing()) return; |
| 651 Definition* defn = instr->AsDefinition(); | 733 Definition* defn = instr->AsDefinition(); |
| 652 if ((defn != NULL) && defn->is_used()) { | 734 if ((defn != NULL) && defn->is_used()) { |
| 653 __ pushq(defn->locs()->out().reg()); | 735 __ pushq(defn->locs()->out().reg()); |
| 654 } | 736 } |
| (...skipping 274 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 929 Immediate(FLAG_optimization_counter_threshold)); | 1011 Immediate(FLAG_optimization_counter_threshold)); |
| 930 ASSERT(function_reg == RDI); | 1012 ASSERT(function_reg == RDI); |
| 931 __ j(GREATER_EQUAL, &StubCode::OptimizeFunctionLabel()); | 1013 __ j(GREATER_EQUAL, &StubCode::OptimizeFunctionLabel()); |
| 932 } | 1014 } |
| 933 } else { | 1015 } else { |
| 934 AddCurrentDescriptor(PcDescriptors::kEntryPatch, | 1016 AddCurrentDescriptor(PcDescriptors::kEntryPatch, |
| 935 Isolate::kNoDeoptId, | 1017 Isolate::kNoDeoptId, |
| 936 0); // No token position. | 1018 0); // No token position. |
| 937 } | 1019 } |
| 938 __ Comment("Enter frame"); | 1020 __ Comment("Enter frame"); |
| 939 __ EnterDartFrame((StackSize() * kWordSize)); | 1021 __ EnterDartFrame(StackSize() * kWordSize); |
| 940 } | 1022 } |
| 941 | 1023 |
| 942 | 1024 |
| 943 void FlowGraphCompiler::CompileGraph() { | 1025 void FlowGraphCompiler::CompileGraph() { |
| 944 InitCompiler(); | 1026 InitCompiler(); |
| 945 if (TryIntrinsify()) { | 1027 if (TryIntrinsify()) { |
| 946 // Although this intrinsified code will never be patched, it must satisfy | 1028 // Although this intrinsified code will never be patched, it must satisfy |
| 947 // CodePatcher::CodeIsPatchable, which verifies that this code has a minimum | 1029 // CodePatcher::CodeIsPatchable, which verifies that this code has a minimum |
| 948 // code size, and nop(2) increases the minimum code size appropriately. | 1030 // code size, and nop(2) increases the minimum code size appropriately. |
| 949 __ nop(2); | 1031 __ nop(2); |
| (...skipping 815 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1765 __ movups(reg, Address(RSP, 0)); | 1847 __ movups(reg, Address(RSP, 0)); |
| 1766 __ addq(RSP, Immediate(kFpuRegisterSize)); | 1848 __ addq(RSP, Immediate(kFpuRegisterSize)); |
| 1767 } | 1849 } |
| 1768 | 1850 |
| 1769 | 1851 |
| 1770 #undef __ | 1852 #undef __ |
| 1771 | 1853 |
| 1772 } // namespace dart | 1854 } // namespace dart |
| 1773 | 1855 |
| 1774 #endif // defined TARGET_ARCH_X64 | 1856 #endif // defined TARGET_ARCH_X64 |
| OLD | NEW |