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_XXX. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_XXX. |
6 | 6 |
7 #include "vm/flow_graph_compiler.h" | 7 #include "vm/flow_graph_compiler.h" |
8 | 8 |
9 #include "vm/cha.h" | 9 #include "vm/cha.h" |
10 #include "vm/dart_entry.h" | 10 #include "vm/dart_entry.h" |
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
124 } | 124 } |
125 // In optimized code, ICData is always set in the instructions. | 125 // In optimized code, ICData is always set in the instructions. |
126 const ICData* ic_data = NULL; | 126 const ICData* ic_data = NULL; |
127 if (current->IsInstanceCall()) { | 127 if (current->IsInstanceCall()) { |
128 ic_data = current->AsInstanceCall()->ic_data(); | 128 ic_data = current->AsInstanceCall()->ic_data(); |
129 ASSERT(ic_data != NULL); | 129 ASSERT(ic_data != NULL); |
130 } | 130 } |
131 if ((ic_data != NULL) && (ic_data->NumberOfChecks() == 0)) { | 131 if ((ic_data != NULL) && (ic_data->NumberOfChecks() == 0)) { |
132 may_reoptimize_ = true; | 132 may_reoptimize_ = true; |
133 } | 133 } |
134 if (is_leaf && !current->IsCheckStackOverflow()) { | 134 if (is_leaf && |
| 135 !current->IsCheckStackOverflow() && |
| 136 !current->IsParallelMove()) { |
135 // Note that we do not care if the code contains instructions that | 137 // Note that we do not care if the code contains instructions that |
136 // can deoptimize. | 138 // can deoptimize. |
137 LocationSummary* locs = current->locs(); | 139 LocationSummary* locs = current->locs(); |
138 if ((locs != NULL) && locs->can_call()) { | 140 if ((locs != NULL) && locs->can_call()) { |
139 is_leaf = false; | 141 is_leaf = false; |
140 } | 142 } |
141 } | 143 } |
142 } | 144 } |
143 } | 145 } |
144 } | 146 } |
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
260 } | 262 } |
261 | 263 |
262 entry->EmitNativeCode(this); | 264 entry->EmitNativeCode(this); |
263 // Compile all successors until an exit, branch, or a block entry. | 265 // Compile all successors until an exit, branch, or a block entry. |
264 for (ForwardInstructionIterator it(entry); !it.Done(); it.Advance()) { | 266 for (ForwardInstructionIterator it(entry); !it.Done(); it.Advance()) { |
265 Instruction* instr = it.Current(); | 267 Instruction* instr = it.Current(); |
266 if (FLAG_code_comments) EmitComment(instr); | 268 if (FLAG_code_comments) EmitComment(instr); |
267 if (instr->IsParallelMove()) { | 269 if (instr->IsParallelMove()) { |
268 parallel_move_resolver_.EmitNativeCode(instr->AsParallelMove()); | 270 parallel_move_resolver_.EmitNativeCode(instr->AsParallelMove()); |
269 } else { | 271 } else { |
270 ASSERT(instr->locs() != NULL); | |
271 EmitInstructionPrologue(instr); | 272 EmitInstructionPrologue(instr); |
272 ASSERT(pending_deoptimization_env_ == NULL); | 273 ASSERT(pending_deoptimization_env_ == NULL); |
273 pending_deoptimization_env_ = instr->env(); | 274 pending_deoptimization_env_ = instr->env(); |
274 instr->EmitNativeCode(this); | 275 instr->EmitNativeCode(this); |
275 pending_deoptimization_env_ = NULL; | 276 pending_deoptimization_env_ = NULL; |
276 EmitInstructionEpilogue(instr); | 277 EmitInstructionEpilogue(instr); |
277 } | 278 } |
278 } | 279 } |
279 } | 280 } |
280 set_current_block(NULL); | 281 set_current_block(NULL); |
(...skipping 348 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
629 if (FLAG_intrinsify && !FLAG_enable_type_checks) { | 630 if (FLAG_intrinsify && !FLAG_enable_type_checks) { |
630 if (parsed_function().function().kind() == RawFunction::kImplicitGetter) { | 631 if (parsed_function().function().kind() == RawFunction::kImplicitGetter) { |
631 // An implicit getter must have a specific AST structure. | 632 // An implicit getter must have a specific AST structure. |
632 const SequenceNode& sequence_node = *parsed_function().node_sequence(); | 633 const SequenceNode& sequence_node = *parsed_function().node_sequence(); |
633 ASSERT(sequence_node.length() == 1); | 634 ASSERT(sequence_node.length() == 1); |
634 ASSERT(sequence_node.NodeAt(0)->IsReturnNode()); | 635 ASSERT(sequence_node.NodeAt(0)->IsReturnNode()); |
635 const ReturnNode& return_node = *sequence_node.NodeAt(0)->AsReturnNode(); | 636 const ReturnNode& return_node = *sequence_node.NodeAt(0)->AsReturnNode(); |
636 ASSERT(return_node.value()->IsLoadInstanceFieldNode()); | 637 ASSERT(return_node.value()->IsLoadInstanceFieldNode()); |
637 const LoadInstanceFieldNode& load_node = | 638 const LoadInstanceFieldNode& load_node = |
638 *return_node.value()->AsLoadInstanceFieldNode(); | 639 *return_node.value()->AsLoadInstanceFieldNode(); |
639 GenerateInlinedGetter(load_node.field().Offset()); | 640 // Only intrinsify getter if the field cannot contain a mutable double. |
| 641 // Reading from a mutable double box requires allocating a fresh double. |
| 642 if (load_node.field().guarded_cid() == kDynamicCid) { |
| 643 GenerateInlinedGetter(load_node.field().Offset()); |
| 644 } |
640 return; | 645 return; |
641 } | 646 } |
642 if (parsed_function().function().kind() == RawFunction::kImplicitSetter) { | 647 if (parsed_function().function().kind() == RawFunction::kImplicitSetter) { |
643 // An implicit setter must have a specific AST structure. | 648 // An implicit setter must have a specific AST structure. |
644 // Sequence node has one store node and one return NULL node. | 649 // Sequence node has one store node and one return NULL node. |
645 const SequenceNode& sequence_node = *parsed_function().node_sequence(); | 650 const SequenceNode& sequence_node = *parsed_function().node_sequence(); |
646 ASSERT(sequence_node.length() == 2); | 651 ASSERT(sequence_node.length() == 2); |
647 ASSERT(sequence_node.NodeAt(0)->IsStoreInstanceFieldNode()); | 652 ASSERT(sequence_node.NodeAt(0)->IsStoreInstanceFieldNode()); |
648 ASSERT(sequence_node.NodeAt(1)->IsReturnNode()); | 653 ASSERT(sequence_node.NodeAt(1)->IsReturnNode()); |
649 const StoreInstanceFieldNode& store_node = | 654 const StoreInstanceFieldNode& store_node = |
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
812 } | 817 } |
813 } | 818 } |
814 UNREACHABLE(); | 819 UNREACHABLE(); |
815 return kNoRegister; | 820 return kNoRegister; |
816 } | 821 } |
817 | 822 |
818 | 823 |
819 void FlowGraphCompiler::AllocateRegistersLocally(Instruction* instr) { | 824 void FlowGraphCompiler::AllocateRegistersLocally(Instruction* instr) { |
820 ASSERT(!is_optimizing()); | 825 ASSERT(!is_optimizing()); |
821 | 826 |
| 827 instr->InitializeLocationSummary(false); // Not optimizing. |
822 LocationSummary* locs = instr->locs(); | 828 LocationSummary* locs = instr->locs(); |
823 | 829 |
824 bool blocked_registers[kNumberOfCpuRegisters]; | 830 bool blocked_registers[kNumberOfCpuRegisters]; |
825 | 831 |
826 // Mark all available registers free. | 832 // Mark all available registers free. |
827 for (intptr_t i = 0; i < kNumberOfCpuRegisters; i++) { | 833 for (intptr_t i = 0; i < kNumberOfCpuRegisters; i++) { |
828 blocked_registers[i] = false; | 834 blocked_registers[i] = false; |
829 } | 835 } |
830 | 836 |
831 // Mark all fixed input, temp and output registers as used. | 837 // Mark all fixed input, temp and output registers as used. |
(...skipping 387 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1219 | 1225 |
1220 for (int i = 0; i < len; i++) { | 1226 for (int i = 0; i < len; i++) { |
1221 sorted->Add(CidTarget(ic_data.GetReceiverClassIdAt(i), | 1227 sorted->Add(CidTarget(ic_data.GetReceiverClassIdAt(i), |
1222 &Function::ZoneHandle(ic_data.GetTargetAt(i)), | 1228 &Function::ZoneHandle(ic_data.GetTargetAt(i)), |
1223 ic_data.GetCountAt(i))); | 1229 ic_data.GetCountAt(i))); |
1224 } | 1230 } |
1225 sorted->Sort(HighestCountFirst); | 1231 sorted->Sort(HighestCountFirst); |
1226 } | 1232 } |
1227 | 1233 |
1228 } // namespace dart | 1234 } // namespace dart |
OLD | NEW |