| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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/flow_graph_builder.h" | 5 #include "vm/flow_graph_builder.h" |
| 6 | 6 |
| 7 #include "vm/ast_printer.h" | 7 #include "vm/ast_printer.h" |
| 8 #include "vm/code_descriptors.h" | 8 #include "vm/code_descriptors.h" |
| 9 #include "vm/dart_entry.h" | 9 #include "vm/dart_entry.h" |
| 10 #include "vm/flags.h" | 10 #include "vm/flags.h" |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 51 } | 51 } |
| 52 | 52 |
| 53 | 53 |
| 54 void EffectGraphVisitor::Append(const EffectGraphVisitor& other_fragment) { | 54 void EffectGraphVisitor::Append(const EffectGraphVisitor& other_fragment) { |
| 55 ASSERT(is_open()); | 55 ASSERT(is_open()); |
| 56 if (other_fragment.is_empty()) return; | 56 if (other_fragment.is_empty()) return; |
| 57 if (is_empty()) { | 57 if (is_empty()) { |
| 58 entry_ = other_fragment.entry(); | 58 entry_ = other_fragment.entry(); |
| 59 exit_ = other_fragment.exit(); | 59 exit_ = other_fragment.exit(); |
| 60 } else { | 60 } else { |
| 61 exit()->set_next(other_fragment.entry()); | 61 exit()->LinkTo(other_fragment.entry()); |
| 62 exit_ = other_fragment.exit(); | 62 exit_ = other_fragment.exit(); |
| 63 } | 63 } |
| 64 temp_index_ = other_fragment.temp_index(); | 64 temp_index_ = other_fragment.temp_index(); |
| 65 } | 65 } |
| 66 | 66 |
| 67 | 67 |
| 68 Value* EffectGraphVisitor::Bind(Definition* definition) { | 68 Value* EffectGraphVisitor::Bind(Definition* definition) { |
| 69 ASSERT(is_open()); | 69 ASSERT(is_open()); |
| 70 DeallocateTempIndex(definition->InputCount()); | 70 DeallocateTempIndex(definition->InputCount()); |
| 71 definition->set_use_kind(Definition::kValue); | 71 definition->set_use_kind(Definition::kValue); |
| 72 definition->set_temp_index(AllocateTempIndex()); | 72 definition->set_temp_index(AllocateTempIndex()); |
| 73 if (is_empty()) { | 73 if (is_empty()) { |
| 74 entry_ = definition; | 74 entry_ = definition; |
| 75 } else { | 75 } else { |
| 76 exit()->set_next(definition); | 76 exit()->LinkTo(definition); |
| 77 } | 77 } |
| 78 exit_ = definition; | 78 exit_ = definition; |
| 79 return new Value(definition); | 79 return new Value(definition); |
| 80 } | 80 } |
| 81 | 81 |
| 82 | 82 |
| 83 void EffectGraphVisitor::Do(Definition* definition) { | 83 void EffectGraphVisitor::Do(Definition* definition) { |
| 84 ASSERT(is_open()); | 84 ASSERT(is_open()); |
| 85 DeallocateTempIndex(definition->InputCount()); | 85 DeallocateTempIndex(definition->InputCount()); |
| 86 definition->set_use_kind(Definition::kEffect); | 86 definition->set_use_kind(Definition::kEffect); |
| 87 if (is_empty()) { | 87 if (is_empty()) { |
| 88 entry_ = definition; | 88 entry_ = definition; |
| 89 } else { | 89 } else { |
| 90 exit()->set_next(definition); | 90 exit()->LinkTo(definition); |
| 91 } | 91 } |
| 92 exit_ = definition; | 92 exit_ = definition; |
| 93 } | 93 } |
| 94 | 94 |
| 95 | 95 |
| 96 void EffectGraphVisitor::AddInstruction(Instruction* instruction) { | 96 void EffectGraphVisitor::AddInstruction(Instruction* instruction) { |
| 97 ASSERT(is_open()); | 97 ASSERT(is_open()); |
| 98 ASSERT(instruction->IsPushArgument() || !instruction->IsDefinition()); | 98 ASSERT(instruction->IsPushArgument() || !instruction->IsDefinition()); |
| 99 ASSERT(!instruction->IsBlockEntry()); | 99 ASSERT(!instruction->IsBlockEntry()); |
| 100 DeallocateTempIndex(instruction->InputCount()); | 100 DeallocateTempIndex(instruction->InputCount()); |
| 101 if (is_empty()) { | 101 if (is_empty()) { |
| 102 entry_ = exit_ = instruction; | 102 entry_ = exit_ = instruction; |
| 103 } else { | 103 } else { |
| 104 exit()->set_next(instruction); | 104 exit()->LinkTo(instruction); |
| 105 exit_ = instruction; | 105 exit_ = instruction; |
| 106 } | 106 } |
| 107 } | 107 } |
| 108 | 108 |
| 109 | 109 |
| 110 void EffectGraphVisitor::Goto(JoinEntryInstr* join) { | 110 void EffectGraphVisitor::Goto(JoinEntryInstr* join) { |
| 111 ASSERT(is_open()); | 111 ASSERT(is_open()); |
| 112 if (is_empty()) { | 112 if (is_empty()) { |
| 113 entry_ = new GotoInstr(join); | 113 entry_ = new GotoInstr(join); |
| 114 } else { | 114 } else { |
| 115 exit()->Goto(join); | 115 exit()->Goto(join); |
| 116 } | 116 } |
| 117 exit_ = NULL; | 117 exit_ = NULL; |
| 118 } | 118 } |
| 119 | 119 |
| 120 | 120 |
| 121 // Appends a graph fragment to a block entry instruction. Returns the entry | 121 // Appends a graph fragment to a block entry instruction. Returns the entry |
| 122 // instruction if the fragment was empty or else the exit of the fragment if | 122 // instruction if the fragment was empty or else the exit of the fragment if |
| 123 // it was non-empty (so NULL if the fragment is closed). | 123 // it was non-empty (so NULL if the fragment is closed). |
| 124 // | 124 // |
| 125 // Note that the fragment is no longer a valid fragment after calling this | 125 // Note that the fragment is no longer a valid fragment after calling this |
| 126 // function -- the fragment is closed at its entry because the entry has a | 126 // function -- the fragment is closed at its entry because the entry has a |
| 127 // predecessor in the graph. | 127 // predecessor in the graph. |
| 128 static Instruction* AppendFragment(BlockEntryInstr* entry, | 128 static Instruction* AppendFragment(BlockEntryInstr* entry, |
| 129 const EffectGraphVisitor& fragment) { | 129 const EffectGraphVisitor& fragment) { |
| 130 if (fragment.is_empty()) return entry; | 130 if (fragment.is_empty()) return entry; |
| 131 entry->set_next(fragment.entry()); | 131 entry->LinkTo(fragment.entry()); |
| 132 return fragment.exit(); | 132 return fragment.exit(); |
| 133 } | 133 } |
| 134 | 134 |
| 135 | 135 |
| 136 void EffectGraphVisitor::Join(const TestGraphVisitor& test_fragment, | 136 void EffectGraphVisitor::Join(const TestGraphVisitor& test_fragment, |
| 137 const EffectGraphVisitor& true_fragment, | 137 const EffectGraphVisitor& true_fragment, |
| 138 const EffectGraphVisitor& false_fragment) { | 138 const EffectGraphVisitor& false_fragment) { |
| 139 // We have: a test graph fragment with zero, one, or two available exits; | 139 // We have: a test graph fragment with zero, one, or two available exits; |
| 140 // and a pair of effect graph fragments with zero or one available exits. | 140 // and a pair of effect graph fragments with zero or one available exits. |
| 141 // We want to append the branch and (if necessary) a join node to this | 141 // We want to append the branch and (if necessary) a join node to this |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 185 BlockEntryInstr* body_entry = test_fragment.CreateTrueSuccessor(); | 185 BlockEntryInstr* body_entry = test_fragment.CreateTrueSuccessor(); |
| 186 Instruction* body_exit = AppendFragment(body_entry, body_fragment); | 186 Instruction* body_exit = AppendFragment(body_entry, body_fragment); |
| 187 | 187 |
| 188 // 2. Connect the test to this graph, including the body if reachable and | 188 // 2. Connect the test to this graph, including the body if reachable and |
| 189 // using a fresh join node if the body is reachable and has an open exit. | 189 // using a fresh join node if the body is reachable and has an open exit. |
| 190 if (body_exit == NULL) { | 190 if (body_exit == NULL) { |
| 191 Append(test_fragment); | 191 Append(test_fragment); |
| 192 } else { | 192 } else { |
| 193 JoinEntryInstr* join = | 193 JoinEntryInstr* join = |
| 194 new JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index()); | 194 new JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index()); |
| 195 join->set_next(test_fragment.entry()); | 195 join->LinkTo(test_fragment.entry()); |
| 196 Goto(join); | 196 Goto(join); |
| 197 body_exit->Goto(join); | 197 body_exit->Goto(join); |
| 198 } | 198 } |
| 199 | 199 |
| 200 // 3. Set the exit to the graph to be the false successor of the test, a | 200 // 3. Set the exit to the graph to be the false successor of the test, a |
| 201 // fresh target node | 201 // fresh target node |
| 202 | 202 |
| 203 exit_ = test_fragment.CreateFalseSuccessor(); | 203 exit_ = test_fragment.CreateFalseSuccessor(); |
| 204 } | 204 } |
| 205 | 205 |
| (...skipping 1036 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1242 new JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index()); | 1242 new JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index()); |
| 1243 Goto(body_entry_join); | 1243 Goto(body_entry_join); |
| 1244 Instruction* body_exit = AppendFragment(body_entry_join, for_body); | 1244 Instruction* body_exit = AppendFragment(body_entry_join, for_body); |
| 1245 | 1245 |
| 1246 JoinEntryInstr* join = node->label()->join_for_continue(); | 1246 JoinEntryInstr* join = node->label()->join_for_continue(); |
| 1247 if ((body_exit != NULL) || (join != NULL)) { | 1247 if ((body_exit != NULL) || (join != NULL)) { |
| 1248 if (join == NULL) { | 1248 if (join == NULL) { |
| 1249 join = | 1249 join = |
| 1250 new JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index()); | 1250 new JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index()); |
| 1251 } | 1251 } |
| 1252 join->set_next(for_test.entry()); | 1252 join->LinkTo(for_test.entry()); |
| 1253 if (body_exit != NULL) { | 1253 if (body_exit != NULL) { |
| 1254 body_exit->Goto(join); | 1254 body_exit->Goto(join); |
| 1255 } | 1255 } |
| 1256 } | 1256 } |
| 1257 | 1257 |
| 1258 | 1258 |
| 1259 for_test.IfTrueGoto(body_entry_join); | 1259 for_test.IfTrueGoto(body_entry_join); |
| 1260 if (node->label()->join_for_break() == NULL) { | 1260 if (node->label()->join_for_break() == NULL) { |
| 1261 exit_ = for_test.CreateFalseSuccessor(); | 1261 exit_ = for_test.CreateFalseSuccessor(); |
| 1262 } else { | 1262 } else { |
| (...skipping 1380 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2643 intptr_t len = OS::SNPrint(NULL, 0, kFormat, function_name, reason) + 1; | 2643 intptr_t len = OS::SNPrint(NULL, 0, kFormat, function_name, reason) + 1; |
| 2644 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len); | 2644 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len); |
| 2645 OS::SNPrint(chars, len, kFormat, function_name, reason); | 2645 OS::SNPrint(chars, len, kFormat, function_name, reason); |
| 2646 const Error& error = Error::Handle( | 2646 const Error& error = Error::Handle( |
| 2647 LanguageError::New(String::Handle(String::New(chars)))); | 2647 LanguageError::New(String::Handle(String::New(chars)))); |
| 2648 Isolate::Current()->long_jump_base()->Jump(1, error); | 2648 Isolate::Current()->long_jump_base()->Jump(1, error); |
| 2649 } | 2649 } |
| 2650 | 2650 |
| 2651 | 2651 |
| 2652 } // namespace dart | 2652 } // namespace dart |
| OLD | NEW |