| 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_ARM. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_ARM. |
| 6 #if defined(TARGET_ARCH_ARM) | 6 #if defined(TARGET_ARCH_ARM) |
| 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 704 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 715 AddCurrentDescriptor(PcDescriptors::kDeopt, | 715 AddCurrentDescriptor(PcDescriptors::kDeopt, |
| 716 assert->deopt_id(), | 716 assert->deopt_id(), |
| 717 assert->token_pos()); | 717 assert->token_pos()); |
| 718 } else if (instr->IsGuardField() || | 718 } else if (instr->IsGuardField() || |
| 719 instr->CanBecomeDeoptimizationTarget()) { | 719 instr->CanBecomeDeoptimizationTarget()) { |
| 720 AddCurrentDescriptor(PcDescriptors::kDeopt, | 720 AddCurrentDescriptor(PcDescriptors::kDeopt, |
| 721 instr->deopt_id(), | 721 instr->deopt_id(), |
| 722 Scanner::kDummyTokenIndex); | 722 Scanner::kDummyTokenIndex); |
| 723 } | 723 } |
| 724 AllocateRegistersLocally(instr); | 724 AllocateRegistersLocally(instr); |
| 725 } else if (instr->MayThrow() && |
| 726 (CurrentTryIndex() != CatchClauseNode::kInvalidTryIndex)) { |
| 727 // Optimized try-block: Sync locals to fixed stack locations. |
| 728 EmitTrySync(instr, CurrentTryIndex()); |
| 729 } |
| 730 } |
| 731 |
| 732 |
| 733 // TODO(regis): Pass an offset instead of an Address to avoid addressing |
| 734 // mode restrictions and remove Operand::Equals() on IA32/X64 and |
| 735 // Address::Equals() on ARM/MIPS. |
| 736 void FlowGraphCompiler::EmitTrySyncMove(Address dest, |
| 737 Location loc, |
| 738 bool* push_emitted) { |
| 739 if (loc.IsConstant()) { |
| 740 if (!*push_emitted) { |
| 741 __ Push(R0); |
| 742 *push_emitted = true; |
| 743 } |
| 744 __ LoadObject(R0, loc.constant()); |
| 745 __ str(R0, dest); |
| 746 } else if (loc.IsRegister()) { |
| 747 if (*push_emitted && (loc.reg() == R0)) { |
| 748 __ ldr(R0, Address(SP, 0)); |
| 749 __ str(R0, dest); |
| 750 } else { |
| 751 __ str(loc.reg(), dest); |
| 752 } |
| 753 } else { |
| 754 Address src = loc.ToStackSlotAddress(); |
| 755 if (!src.Equals(dest)) { |
| 756 if (!*push_emitted) { |
| 757 __ Push(R0); |
| 758 *push_emitted = true; |
| 759 } |
| 760 __ ldr(R0, src); |
| 761 __ str(R0, dest); |
| 762 } |
| 763 } |
| 764 } |
| 765 |
| 766 |
| 767 void FlowGraphCompiler::EmitTrySync(Instruction* instr, intptr_t try_index) { |
| 768 ASSERT(is_optimizing()); |
| 769 Environment* env = instr->env(); |
| 770 CatchBlockEntryInstr* catch_block = |
| 771 flow_graph().graph_entry()->GetCatchEntry(try_index); |
| 772 const GrowableArray<Definition*>* idefs = catch_block->initial_definitions(); |
| 773 // Parameters. |
| 774 intptr_t i = 0; |
| 775 bool push_emitted = false; |
| 776 const intptr_t num_non_copied_params = flow_graph().num_non_copied_params(); |
| 777 const intptr_t param_base = |
| 778 kParamEndSlotFromFp + num_non_copied_params; |
| 779 for (; i < num_non_copied_params; ++i) { |
| 780 if ((*idefs)[i]->IsConstant()) continue; // Common constants |
| 781 Location loc = env->LocationAt(i); |
| 782 Address dest(FP, (param_base - i) * kWordSize); |
| 783 EmitTrySyncMove(dest, loc, &push_emitted); |
| 784 } |
| 785 |
| 786 // Process locals. Skip exception_var and stacktrace_var. |
| 787 CatchEntryInstr* catch_entry = catch_block->next()->AsCatchEntry(); |
| 788 intptr_t local_base = kFirstLocalSlotFromFp + num_non_copied_params; |
| 789 intptr_t ex_idx = local_base - catch_entry->exception_var().index(); |
| 790 intptr_t st_idx = local_base - catch_entry->stacktrace_var().index(); |
| 791 for (; i < flow_graph().variable_count(); ++i) { |
| 792 if (i == ex_idx || i == st_idx) continue; |
| 793 if ((*idefs)[i]->IsConstant()) continue; |
| 794 Location loc = env->LocationAt(i); |
| 795 Address dest(FP, (local_base - i) * kWordSize); |
| 796 EmitTrySyncMove(dest, loc, &push_emitted); |
| 797 // Update safepoint bitmap to indicate that the target location |
| 798 // now contains a pointer. |
| 799 instr->locs()->stack_bitmap()->Set(i - num_non_copied_params, true); |
| 800 } |
| 801 if (push_emitted) { |
| 802 __ Pop(R0); |
| 725 } | 803 } |
| 726 } | 804 } |
| 727 | 805 |
| 728 | 806 |
| 729 void FlowGraphCompiler::EmitInstructionEpilogue(Instruction* instr) { | 807 void FlowGraphCompiler::EmitInstructionEpilogue(Instruction* instr) { |
| 730 if (is_optimizing()) return; | 808 if (is_optimizing()) return; |
| 731 Definition* defn = instr->AsDefinition(); | 809 Definition* defn = instr->AsDefinition(); |
| 732 if ((defn != NULL) && defn->is_used()) { | 810 if ((defn != NULL) && defn->is_used()) { |
| 733 __ Push(defn->locs()->out().reg()); | 811 __ Push(defn->locs()->out().reg()); |
| 734 } | 812 } |
| (...skipping 266 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1001 __ CompareImmediate(R7, FLAG_optimization_counter_threshold); | 1079 __ CompareImmediate(R7, FLAG_optimization_counter_threshold); |
| 1002 ASSERT(function_reg == R6); | 1080 ASSERT(function_reg == R6); |
| 1003 __ Branch(&StubCode::OptimizeFunctionLabel(), GE); | 1081 __ Branch(&StubCode::OptimizeFunctionLabel(), GE); |
| 1004 } | 1082 } |
| 1005 } else { | 1083 } else { |
| 1006 AddCurrentDescriptor(PcDescriptors::kEntryPatch, | 1084 AddCurrentDescriptor(PcDescriptors::kEntryPatch, |
| 1007 Isolate::kNoDeoptId, | 1085 Isolate::kNoDeoptId, |
| 1008 0); // No token position. | 1086 0); // No token position. |
| 1009 } | 1087 } |
| 1010 __ Comment("Enter frame"); | 1088 __ Comment("Enter frame"); |
| 1011 __ EnterDartFrame((StackSize() * kWordSize)); | 1089 __ EnterDartFrame(StackSize() * kWordSize); |
| 1012 } | 1090 } |
| 1013 | 1091 |
| 1014 | 1092 |
| 1015 // Input parameters: | 1093 // Input parameters: |
| 1016 // LR: return address. | 1094 // LR: return address. |
| 1017 // SP: address of last argument. | 1095 // SP: address of last argument. |
| 1018 // FP: caller's frame pointer. | 1096 // FP: caller's frame pointer. |
| 1019 // PP: caller's pool pointer. | 1097 // PP: caller's pool pointer. |
| 1020 // R5: ic-data. | 1098 // R5: ic-data. |
| 1021 // R4: arguments descriptor array. | 1099 // R4: arguments descriptor array. |
| (...skipping 739 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1761 void ParallelMoveResolver::RestoreFpuScratch(FpuRegister reg) { | 1839 void ParallelMoveResolver::RestoreFpuScratch(FpuRegister reg) { |
| 1762 __ vldrd(reg, Address(SP, kDoubleSize, Address::PostIndex)); | 1840 __ vldrd(reg, Address(SP, kDoubleSize, Address::PostIndex)); |
| 1763 } | 1841 } |
| 1764 | 1842 |
| 1765 | 1843 |
| 1766 #undef __ | 1844 #undef __ |
| 1767 | 1845 |
| 1768 } // namespace dart | 1846 } // namespace dart |
| 1769 | 1847 |
| 1770 #endif // defined TARGET_ARCH_ARM | 1848 #endif // defined TARGET_ARCH_ARM |
| OLD | NEW |