| 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::EmitTrySyncMove(Address dest, |
| 658 Location loc, |
| 659 bool* push_emitted) { |
| 660 if (loc.IsConstant()) { |
| 661 if (!*push_emitted) { |
| 662 __ pushl(EAX); |
| 663 *push_emitted = true; |
| 664 } |
| 665 __ LoadObject(EAX, loc.constant()); |
| 666 __ movl(dest, EAX); |
| 667 } else if (loc.IsRegister()) { |
| 668 if (*push_emitted && loc.reg() == EAX) { |
| 669 __ movl(EAX, Address(ESP, 0)); |
| 670 __ movl(dest, EAX); |
| 671 } else { |
| 672 __ movl(dest, loc.reg()); |
| 673 } |
| 674 } else { |
| 675 Address src = loc.ToStackSlotAddress(); |
| 676 if (!src.Equals(dest)) { |
| 677 if (!*push_emitted) { |
| 678 __ pushl(EAX); |
| 679 *push_emitted = true; |
| 680 } |
| 681 __ movl(EAX, src); |
| 682 __ movl(dest, EAX); |
| 683 } |
| 684 } |
| 685 } |
| 686 |
| 687 |
| 688 void FlowGraphCompiler::EmitTrySync(Instruction* instr, intptr_t try_index) { |
| 689 ASSERT(is_optimizing()); |
| 690 Environment* env = instr->env(); |
| 691 CatchBlockEntryInstr* catch_block = |
| 692 flow_graph().graph_entry()->GetCatchEntry(try_index); |
| 693 const GrowableArray<Definition*>* idefs = catch_block->initial_definitions(); |
| 694 // Parameters. |
| 695 intptr_t i = 0; |
| 696 bool push_emitted = false; |
| 697 const intptr_t num_non_copied_params = flow_graph().num_non_copied_params(); |
| 698 const intptr_t param_base = |
| 699 kParamEndSlotFromFp + num_non_copied_params; |
| 700 for (; i < num_non_copied_params; ++i) { |
| 701 if ((*idefs)[i]->IsConstant()) continue; // Common constants |
| 702 Location loc = env->LocationAt(i); |
| 703 Address dest(EBP, (param_base - i) * kWordSize); |
| 704 EmitTrySyncMove(dest, loc, &push_emitted); |
| 705 } |
| 706 |
| 707 // Process locals. Skip exception_var and stacktrace_var. |
| 708 CatchEntryInstr* catch_entry = catch_block->next()->AsCatchEntry(); |
| 709 intptr_t local_base = kFirstLocalSlotFromFp + num_non_copied_params; |
| 710 intptr_t ex_idx = local_base - catch_entry->exception_var().index(); |
| 711 intptr_t st_idx = local_base - catch_entry->stacktrace_var().index(); |
| 712 for (; i < flow_graph().variable_count(); ++i) { |
| 713 if (i == ex_idx || i == st_idx) continue; |
| 714 if ((*idefs)[i]->IsConstant()) continue; |
| 715 Location loc = env->LocationAt(i); |
| 716 Address dest(EBP, (local_base - i) * kWordSize); |
| 717 EmitTrySyncMove(dest, loc, &push_emitted); |
| 718 // Update safepoint bitmap to indicate that the target location |
| 719 // now contains a pointer. |
| 720 instr->locs()->stack_bitmap()->Set(i - num_non_copied_params, true); |
| 721 } |
| 722 if (push_emitted) { |
| 723 __ popl(EAX); |
| 649 } | 724 } |
| 650 } | 725 } |
| 651 | 726 |
| 652 | 727 |
| 653 void FlowGraphCompiler::EmitInstructionEpilogue(Instruction* instr) { | 728 void FlowGraphCompiler::EmitInstructionEpilogue(Instruction* instr) { |
| 654 if (is_optimizing()) return; | 729 if (is_optimizing()) return; |
| 655 Definition* defn = instr->AsDefinition(); | 730 Definition* defn = instr->AsDefinition(); |
| 656 if ((defn != NULL) && defn->is_used()) { | 731 if ((defn != NULL) && defn->is_used()) { |
| 657 __ pushl(defn->locs()->out().reg()); | 732 __ pushl(defn->locs()->out().reg()); |
| 658 } | 733 } |
| (...skipping 273 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 932 Immediate(FLAG_optimization_counter_threshold)); | 1007 Immediate(FLAG_optimization_counter_threshold)); |
| 933 ASSERT(function_reg == EDI); | 1008 ASSERT(function_reg == EDI); |
| 934 __ j(GREATER_EQUAL, &StubCode::OptimizeFunctionLabel()); | 1009 __ j(GREATER_EQUAL, &StubCode::OptimizeFunctionLabel()); |
| 935 } | 1010 } |
| 936 } else { | 1011 } else { |
| 937 AddCurrentDescriptor(PcDescriptors::kEntryPatch, | 1012 AddCurrentDescriptor(PcDescriptors::kEntryPatch, |
| 938 Isolate::kNoDeoptId, | 1013 Isolate::kNoDeoptId, |
| 939 0); // No token position. | 1014 0); // No token position. |
| 940 } | 1015 } |
| 941 __ Comment("Enter frame"); | 1016 __ Comment("Enter frame"); |
| 942 __ EnterDartFrame((StackSize() * kWordSize)); | 1017 __ EnterDartFrame(StackSize() * kWordSize); |
| 943 } | 1018 } |
| 944 | 1019 |
| 945 | 1020 |
| 946 void FlowGraphCompiler::CompileGraph() { | 1021 void FlowGraphCompiler::CompileGraph() { |
| 947 InitCompiler(); | 1022 InitCompiler(); |
| 948 if (TryIntrinsify()) { | 1023 if (TryIntrinsify()) { |
| 949 // Although this intrinsified code will never be patched, it must satisfy | 1024 // Although this intrinsified code will never be patched, it must satisfy |
| 950 // CodePatcher::CodeIsPatchable, which verifies that this code has a minimum | 1025 // CodePatcher::CodeIsPatchable, which verifies that this code has a minimum |
| 951 // code size. | 1026 // code size. |
| 952 __ int3(); | 1027 __ int3(); |
| (...skipping 829 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1782 __ movups(reg, Address(ESP, 0)); | 1857 __ movups(reg, Address(ESP, 0)); |
| 1783 __ addl(ESP, Immediate(kFpuRegisterSize)); | 1858 __ addl(ESP, Immediate(kFpuRegisterSize)); |
| 1784 } | 1859 } |
| 1785 | 1860 |
| 1786 | 1861 |
| 1787 #undef __ | 1862 #undef __ |
| 1788 | 1863 |
| 1789 } // namespace dart | 1864 } // namespace dart |
| 1790 | 1865 |
| 1791 #endif // defined TARGET_ARCH_IA32 | 1866 #endif // defined TARGET_ARCH_IA32 |
| OLD | NEW |