| 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 |