| 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_IA32. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_IA32. |
| 6 #if defined(TARGET_ARCH_IA32) | 6 #if defined(TARGET_ARCH_IA32) |
| 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 628 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 639 GuardFieldInstr* guard = instr->AsGuardField(); | 639 GuardFieldInstr* guard = instr->AsGuardField(); |
| 640 AddCurrentDescriptor(PcDescriptors::kDeopt, | 640 AddCurrentDescriptor(PcDescriptors::kDeopt, |
| 641 guard->deopt_id(), | 641 guard->deopt_id(), |
| 642 Scanner::kDummyTokenIndex); | 642 Scanner::kDummyTokenIndex); |
| 643 } else if (instr->CanBeDeoptimizationTarget()) { | 643 } else if (instr->CanBeDeoptimizationTarget()) { |
| 644 AddCurrentDescriptor(PcDescriptors::kDeopt, | 644 AddCurrentDescriptor(PcDescriptors::kDeopt, |
| 645 instr->deopt_id(), | 645 instr->deopt_id(), |
| 646 Scanner::kDummyTokenIndex); | 646 Scanner::kDummyTokenIndex); |
| 647 } | 647 } |
| 648 AllocateRegistersLocally(instr); | 648 AllocateRegistersLocally(instr); |
| 649 } else if (instr->MayThrow() && |
| 650 (CurrentTryIndex() != CatchClauseNode::kInvalidTryIndex)) { |
| 651 // Optimized try-block: Sync locals to fixed stack locations. |
| 652 EmitTrySync(instr, CurrentTryIndex()); |
| 653 } |
| 654 } |
| 655 |
| 656 |
| 657 void FlowGraphCompiler::EmitTrySync(Instruction* instr, intptr_t try_index) { |
| 658 ASSERT(is_optimizing()); |
| 659 Environment* env = instr->env(); |
| 660 CatchBlockEntryInstr* catch_block = |
| 661 flow_graph().graph_entry()->GetCatchEntry(try_index); |
| 662 const GrowableArray<Definition*>* idefs = catch_block->initial_definitions(); |
| 663 // Parameters. |
| 664 intptr_t i = 0; |
| 665 bool push_emitted = false; |
| 666 for (; i < flow_graph().num_non_copied_params(); ++i) { |
| 667 if ((*idefs)[i]->IsConstant()) continue; // common constants |
| 668 Location loc = env->LocationAt(i); |
| 669 const intptr_t index = flow_graph().num_non_copied_params() - i; |
| 670 Address dest(EBP, (kLastParamSlotIndex + index - 1) * kWordSize); |
| 671 if (loc.IsConstant()) { |
| 672 if (!push_emitted) { |
| 673 __ pushl(EAX); |
| 674 push_emitted = true; |
| 675 } |
| 676 __ LoadObject(EAX, loc.constant()); |
| 677 __ movl(dest, EAX); |
| 678 } else if (loc.IsRegister()) { |
| 679 __ movl(dest, loc.reg()); |
| 680 } else { |
| 681 Address src = loc.ToStackSlotAddress(); |
| 682 if (!src.Equals(dest)) { |
| 683 if (!push_emitted) { |
| 684 __ pushl(EAX); |
| 685 push_emitted = true; |
| 686 } |
| 687 __ movl(EAX, src); |
| 688 __ movl(dest, EAX); |
| 689 } |
| 690 } |
| 691 } |
| 692 // Process locals. Skip exception_var and stacktrace_var. |
| 693 CatchEntryInstr* catch_entry = catch_block->next()->AsCatchEntry(); |
| 694 intptr_t nncp = flow_graph_.num_non_copied_params(); |
| 695 intptr_t ex_idx = |
| 696 kFirstLocalSlotIndex - catch_entry->exception_var().index() + nncp; |
| 697 intptr_t st_idx = |
| 698 kFirstLocalSlotIndex - catch_entry->stacktrace_var().index() + nncp; |
| 699 for (; i < flow_graph().variable_count(); ++i) { |
| 700 if (i == ex_idx || i == st_idx) continue; |
| 701 if ((*idefs)[i]->IsConstant()) continue; |
| 702 Location loc = env->LocationAt(i); |
| 703 const intptr_t index = i - flow_graph().num_non_copied_params(); |
| 704 Address dest(EBP, (kFirstLocalSlotIndex - index) * kWordSize); |
| 705 if (loc.IsConstant()) { |
| 706 if (!push_emitted) { |
| 707 __ pushl(EAX); |
| 708 push_emitted = true; |
| 709 } |
| 710 __ LoadObject(EAX, loc.constant()); |
| 711 __ movl(dest, EAX); |
| 712 } else if (loc.IsRegister()) { |
| 713 __ movl(dest, loc.reg()); |
| 714 } else { |
| 715 Address src = loc.ToStackSlotAddress(); |
| 716 if (!src.Equals(dest)) { |
| 717 if (!push_emitted) { |
| 718 __ pushl(EAX); |
| 719 push_emitted = true; |
| 720 } |
| 721 __ movl(EAX, src); |
| 722 __ movl(dest, EAX); |
| 723 } |
| 724 } |
| 725 // Update safepoint bitmap to indicate that the target location |
| 726 // now contains a pointer. |
| 727 instr->locs()->stack_bitmap()->Set(index, true); |
| 728 } |
| 729 if (push_emitted) { |
| 730 __ popl(EAX); |
| 649 } | 731 } |
| 650 } | 732 } |
| 651 | 733 |
| 652 | 734 |
| 653 void FlowGraphCompiler::EmitInstructionEpilogue(Instruction* instr) { | 735 void FlowGraphCompiler::EmitInstructionEpilogue(Instruction* instr) { |
| 654 if (is_optimizing()) return; | 736 if (is_optimizing()) return; |
| 655 Definition* defn = instr->AsDefinition(); | 737 Definition* defn = instr->AsDefinition(); |
| 656 if ((defn != NULL) && defn->is_used()) { | 738 if ((defn != NULL) && defn->is_used()) { |
| 657 __ pushl(defn->locs()->out().reg()); | 739 __ pushl(defn->locs()->out().reg()); |
| 658 } | 740 } |
| (...skipping 272 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 931 Immediate(FLAG_optimization_counter_threshold)); | 1013 Immediate(FLAG_optimization_counter_threshold)); |
| 932 ASSERT(function_reg == EDI); | 1014 ASSERT(function_reg == EDI); |
| 933 __ j(GREATER_EQUAL, &StubCode::OptimizeFunctionLabel()); | 1015 __ j(GREATER_EQUAL, &StubCode::OptimizeFunctionLabel()); |
| 934 } | 1016 } |
| 935 } else { | 1017 } else { |
| 936 AddCurrentDescriptor(PcDescriptors::kEntryPatch, | 1018 AddCurrentDescriptor(PcDescriptors::kEntryPatch, |
| 937 Isolate::kNoDeoptId, | 1019 Isolate::kNoDeoptId, |
| 938 0); // No token position. | 1020 0); // No token position. |
| 939 } | 1021 } |
| 940 __ Comment("Enter frame"); | 1022 __ Comment("Enter frame"); |
| 941 __ EnterDartFrame((StackSize() * kWordSize)); | 1023 __ EnterDartFrame(StackSize() * kWordSize); |
| 942 } | 1024 } |
| 943 | 1025 |
| 944 | 1026 |
| 945 void FlowGraphCompiler::CompileGraph() { | 1027 void FlowGraphCompiler::CompileGraph() { |
| 946 InitCompiler(); | 1028 InitCompiler(); |
| 947 if (TryIntrinsify()) { | 1029 if (TryIntrinsify()) { |
| 948 // Although this intrinsified code will never be patched, it must satisfy | 1030 // Although this intrinsified code will never be patched, it must satisfy |
| 949 // CodePatcher::CodeIsPatchable, which verifies that this code has a minimum | 1031 // CodePatcher::CodeIsPatchable, which verifies that this code has a minimum |
| 950 // code size. | 1032 // code size. |
| 951 __ int3(); | 1033 __ int3(); |
| (...skipping 829 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1781 __ movups(reg, Address(ESP, 0)); | 1863 __ movups(reg, Address(ESP, 0)); |
| 1782 __ addl(ESP, Immediate(kFpuRegisterSize)); | 1864 __ addl(ESP, Immediate(kFpuRegisterSize)); |
| 1783 } | 1865 } |
| 1784 | 1866 |
| 1785 | 1867 |
| 1786 #undef __ | 1868 #undef __ |
| 1787 | 1869 |
| 1788 } // namespace dart | 1870 } // namespace dart |
| 1789 | 1871 |
| 1790 #endif // defined TARGET_ARCH_IA32 | 1872 #endif // defined TARGET_ARCH_IA32 |
| OLD | NEW |