| 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::EmitTrySyncMove(Address dest, |
| 654 Location loc, |
| 655 bool* push_emitted) { |
| 656 if (loc.IsConstant()) { |
| 657 if (!*push_emitted) { |
| 658 __ pushq(RAX); |
| 659 *push_emitted = true; |
| 660 } |
| 661 __ LoadObject(RAX, loc.constant()); |
| 662 __ movq(dest, RAX); |
| 663 } else if (loc.IsRegister()) { |
| 664 if (*push_emitted && loc.reg() == RAX) { |
| 665 __ movq(RAX, Address(RSP, 0)); |
| 666 __ movq(dest, RAX); |
| 667 } else { |
| 668 __ movq(dest, loc.reg()); |
| 669 } |
| 670 } else { |
| 671 Address src = loc.ToStackSlotAddress(); |
| 672 if (!src.Equals(dest)) { |
| 673 if (!*push_emitted) { |
| 674 __ pushq(RAX); |
| 675 *push_emitted = true; |
| 676 } |
| 677 __ movq(RAX, src); |
| 678 __ movq(dest, RAX); |
| 679 } |
| 680 } |
| 681 } |
| 682 |
| 683 |
| 684 void FlowGraphCompiler::EmitTrySync(Instruction* instr, intptr_t try_index) { |
| 685 ASSERT(is_optimizing()); |
| 686 Environment* env = instr->env(); |
| 687 CatchBlockEntryInstr* catch_block = |
| 688 flow_graph().graph_entry()->GetCatchEntry(try_index); |
| 689 const GrowableArray<Definition*>* idefs = catch_block->initial_definitions(); |
| 690 // Parameters. |
| 691 intptr_t i = 0; |
| 692 bool push_emitted = false; |
| 693 const intptr_t num_non_copied_params = flow_graph().num_non_copied_params(); |
| 694 const intptr_t param_base = kParamEndSlotFromFp + num_non_copied_params; |
| 695 for (; i < num_non_copied_params; ++i) { |
| 696 if ((*idefs)[i]->IsConstant()) continue; // Common constants |
| 697 Location loc = env->LocationAt(i); |
| 698 Address dest(RBP, (param_base - i) * kWordSize); |
| 699 EmitTrySyncMove(dest, loc, &push_emitted); |
| 700 } |
| 701 |
| 702 // Process locals. Skip exception_var and stacktrace_var. |
| 703 CatchEntryInstr* catch_entry = catch_block->next()->AsCatchEntry(); |
| 704 intptr_t local_base = kFirstLocalSlotFromFp + num_non_copied_params; |
| 705 intptr_t ex_idx = local_base - catch_entry->exception_var().index(); |
| 706 intptr_t st_idx = local_base - catch_entry->stacktrace_var().index(); |
| 707 for (; i < flow_graph().variable_count(); ++i) { |
| 708 if (i == ex_idx || i == st_idx) continue; |
| 709 if ((*idefs)[i]->IsConstant()) continue; |
| 710 Location loc = env->LocationAt(i); |
| 711 Address dest(RBP, (local_base - i) * kWordSize); |
| 712 EmitTrySyncMove(dest, loc, &push_emitted); |
| 713 // Update safepoint bitmap to indicate that the target location |
| 714 // now contains a pointer. |
| 715 instr->locs()->stack_bitmap()->Set(i - num_non_copied_params, true); |
| 716 } |
| 717 if (push_emitted) { |
| 718 __ popq(RAX); |
| 645 } | 719 } |
| 646 } | 720 } |
| 647 | 721 |
| 648 | 722 |
| 649 void FlowGraphCompiler::EmitInstructionEpilogue(Instruction* instr) { | 723 void FlowGraphCompiler::EmitInstructionEpilogue(Instruction* instr) { |
| 650 if (is_optimizing()) return; | 724 if (is_optimizing()) return; |
| 651 Definition* defn = instr->AsDefinition(); | 725 Definition* defn = instr->AsDefinition(); |
| 652 if ((defn != NULL) && defn->is_used()) { | 726 if ((defn != NULL) && defn->is_used()) { |
| 653 __ pushq(defn->locs()->out().reg()); | 727 __ pushq(defn->locs()->out().reg()); |
| 654 } | 728 } |
| (...skipping 275 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 930 Immediate(FLAG_optimization_counter_threshold)); | 1004 Immediate(FLAG_optimization_counter_threshold)); |
| 931 ASSERT(function_reg == RDI); | 1005 ASSERT(function_reg == RDI); |
| 932 __ j(GREATER_EQUAL, &StubCode::OptimizeFunctionLabel()); | 1006 __ j(GREATER_EQUAL, &StubCode::OptimizeFunctionLabel()); |
| 933 } | 1007 } |
| 934 } else { | 1008 } else { |
| 935 AddCurrentDescriptor(PcDescriptors::kEntryPatch, | 1009 AddCurrentDescriptor(PcDescriptors::kEntryPatch, |
| 936 Isolate::kNoDeoptId, | 1010 Isolate::kNoDeoptId, |
| 937 0); // No token position. | 1011 0); // No token position. |
| 938 } | 1012 } |
| 939 __ Comment("Enter frame"); | 1013 __ Comment("Enter frame"); |
| 940 __ EnterDartFrame((StackSize() * kWordSize)); | 1014 __ EnterDartFrame(StackSize() * kWordSize); |
| 941 } | 1015 } |
| 942 | 1016 |
| 943 | 1017 |
| 944 void FlowGraphCompiler::CompileGraph() { | 1018 void FlowGraphCompiler::CompileGraph() { |
| 945 InitCompiler(); | 1019 InitCompiler(); |
| 946 if (TryIntrinsify()) { | 1020 if (TryIntrinsify()) { |
| 947 // Although this intrinsified code will never be patched, it must satisfy | 1021 // Although this intrinsified code will never be patched, it must satisfy |
| 948 // CodePatcher::CodeIsPatchable, which verifies that this code has a minimum | 1022 // CodePatcher::CodeIsPatchable, which verifies that this code has a minimum |
| 949 // code size, and nop(2) increases the minimum code size appropriately. | 1023 // code size, and nop(2) increases the minimum code size appropriately. |
| 950 __ nop(2); | 1024 __ nop(2); |
| (...skipping 815 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1766 __ movups(reg, Address(RSP, 0)); | 1840 __ movups(reg, Address(RSP, 0)); |
| 1767 __ addq(RSP, Immediate(kFpuRegisterSize)); | 1841 __ addq(RSP, Immediate(kFpuRegisterSize)); |
| 1768 } | 1842 } |
| 1769 | 1843 |
| 1770 | 1844 |
| 1771 #undef __ | 1845 #undef __ |
| 1772 | 1846 |
| 1773 } // namespace dart | 1847 } // namespace dart |
| 1774 | 1848 |
| 1775 #endif // defined TARGET_ARCH_X64 | 1849 #endif // defined TARGET_ARCH_X64 |
| OLD | NEW |