| 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/bit_vector.h" | 8 #include "vm/bit_vector.h" |
| 9 #include "vm/code_descriptors.h" | 9 #include "vm/code_descriptors.h" |
| 10 #include "vm/dart_entry.h" | 10 #include "vm/dart_entry.h" |
| (...skipping 240 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 251 } | 251 } |
| 252 | 252 |
| 253 | 253 |
| 254 // Loads context saved in 'context_variable' into the current context. | 254 // Loads context saved in 'context_variable' into the current context. |
| 255 void EffectGraphVisitor::BuildLoadContext(const LocalVariable& variable) { | 255 void EffectGraphVisitor::BuildLoadContext(const LocalVariable& variable) { |
| 256 Value* load_saved_context = Bind(BuildLoadLocal(variable)); | 256 Value* load_saved_context = Bind(BuildLoadLocal(variable)); |
| 257 Do(new StoreContextComp(load_saved_context)); | 257 Do(new StoreContextComp(load_saved_context)); |
| 258 } | 258 } |
| 259 | 259 |
| 260 | 260 |
| 261 // TODO(srdjan): This code is clumsy. Try to skip allocation of ComparisonComp | |
| 262 // and generate the right BranchInstr directly. | |
| 263 // Replaces instruction patterns: | |
| 264 // t0 <- Comparison(kind, t0, t1) | |
| 265 // t1 <- #true | |
| 266 // Branch if t0 === t1 goto (true, false) | |
| 267 // With: | |
| 268 // Branch if t0 kind t1 goto (true, false) | |
| 269 // Returns false if fusing is not possible, e.g: | |
| 270 // t0 <- LoadLocal | |
| 271 // t1 <- #true | |
| 272 // Branch if t0 === t1 goto (true, false) | |
| 273 static bool TryFuseBranchInstr(BranchInstr* branch) { | |
| 274 UseVal* use = branch->left()->AsUse(); | |
| 275 if (use == NULL) return false; | |
| 276 BindInstr* compare_instr = use->definition()->AsBind(); | |
| 277 if (compare_instr == NULL) return false; | |
| 278 ComparisonComp* compare = compare_instr->computation()->AsComparison(); | |
| 279 Token::Kind kind; | |
| 280 if (compare == NULL) { | |
| 281 // Check if there is a BooleanNegate in between Comparison and Branch. | |
| 282 BooleanNegateComp* neg = compare_instr->computation()->AsBooleanNegate(); | |
| 283 if (neg == NULL) return false; | |
| 284 if (compare_instr->previous() == NULL) return false; | |
| 285 compare_instr = compare_instr->previous()->AsBind(); | |
| 286 ASSERT(compare_instr != NULL); | |
| 287 compare = compare_instr->computation()->AsComparison(); | |
| 288 if (compare == NULL) return false; | |
| 289 // Negation can be handled only in connection with EqualityCompare. | |
| 290 if (!compare->IsEqualityCompare()) return false; | |
| 291 kind = Token::kNE; | |
| 292 } else { | |
| 293 kind = compare->kind(); | |
| 294 } | |
| 295 branch->set_kind(kind); | |
| 296 branch->SetInputAt(0, compare->InputAt(0)); | |
| 297 branch->SetInputAt(1, compare->InputAt(1)); | |
| 298 // Remove elminated nodes. | |
| 299 branch->set_previous(compare_instr->previous()); | |
| 300 compare_instr->previous()->set_next(branch); | |
| 301 return true; | |
| 302 } | |
| 303 | |
| 304 | |
| 305 void TestGraphVisitor::ReturnValue(Value* value) { | 261 void TestGraphVisitor::ReturnValue(Value* value) { |
| 306 if (FLAG_enable_type_checks) { | 262 if (FLAG_enable_type_checks) { |
| 307 value = Bind(new AssertBooleanComp(condition_token_pos(), | 263 value = Bind(new AssertBooleanComp(condition_token_pos(), |
| 308 owner()->try_index(), | 264 owner()->try_index(), |
| 309 value)); | 265 value)); |
| 310 } | 266 } |
| 311 const Bool& bool_true = Bool::ZoneHandle(Bool::True()); | 267 const Bool& bool_true = Bool::ZoneHandle(Bool::True()); |
| 312 Value* constant_true = Bind(new ConstantVal(bool_true)); | 268 Value* constant_true = Bind(new ConstantVal(bool_true)); |
| 313 BranchInstr* branch = new BranchInstr(condition_token_pos(), | 269 BranchInstr* branch = new BranchInstr(condition_token_pos(), |
| 314 owner()->try_index(), | 270 owner()->try_index(), |
| 315 value, | 271 value, |
| 316 constant_true, | 272 constant_true, |
| 317 Token::kEQ_STRICT); | 273 Token::kEQ_STRICT); |
| 318 AddInstruction(branch); | 274 AddInstruction(branch); |
| 319 CloseFragment(); | 275 CloseFragment(); |
| 320 true_successor_address_ = branch->true_successor_address(); | 276 true_successor_address_ = branch->true_successor_address(); |
| 321 false_successor_address_ = branch->false_successor_address(); | 277 false_successor_address_ = branch->false_successor_address(); |
| 322 TryFuseBranchInstr(branch); | 278 } |
| 279 |
| 280 |
| 281 void TestGraphVisitor::MergeBranchWithComparison(ComparisonComp* comp) { |
| 282 ASSERT(!FLAG_enable_type_checks); |
| 283 BranchInstr* branch = new BranchInstr(condition_token_pos(), |
| 284 owner()->try_index(), |
| 285 comp->left(), |
| 286 comp->right(), |
| 287 comp->kind()); |
| 288 AddInstruction(branch); |
| 289 CloseFragment(); |
| 290 true_successor_address_ = branch->true_successor_address(); |
| 291 false_successor_address_ = branch->false_successor_address(); |
| 292 } |
| 293 |
| 294 |
| 295 void TestGraphVisitor::MergeBranchWithNegate(BooleanNegateComp* comp) { |
| 296 ASSERT(!FLAG_enable_type_checks); |
| 297 const Bool& bool_true = Bool::ZoneHandle(Bool::True()); |
| 298 Value* constant_true = Bind(new ConstantVal(bool_true)); |
| 299 BranchInstr* branch = new BranchInstr(condition_token_pos(), |
| 300 owner()->try_index(), |
| 301 comp->value(), |
| 302 constant_true, |
| 303 Token::kNE_STRICT); |
| 304 AddInstruction(branch); |
| 305 CloseFragment(); |
| 306 true_successor_address_ = branch->true_successor_address(); |
| 307 false_successor_address_ = branch->false_successor_address(); |
| 308 } |
| 309 |
| 310 |
| 311 void TestGraphVisitor::ReturnComputation(Computation* computation) { |
| 312 if (!FLAG_enable_type_checks) { |
| 313 if (computation->AsComparison() != NULL) { |
| 314 MergeBranchWithComparison(computation->AsComparison()); |
| 315 return; |
| 316 } |
| 317 if (computation->IsBooleanNegate()) { |
| 318 MergeBranchWithNegate(computation->AsBooleanNegate()); |
| 319 return; |
| 320 } |
| 321 } |
| 322 ReturnValue(Bind(computation)); |
| 323 } | 323 } |
| 324 | 324 |
| 325 | 325 |
| 326 void EffectGraphVisitor::Bailout(const char* reason) { | 326 void EffectGraphVisitor::Bailout(const char* reason) { |
| 327 owner()->Bailout(reason); | 327 owner()->Bailout(reason); |
| 328 } | 328 } |
| 329 | 329 |
| 330 | 330 |
| 331 // <Statement> ::= Return { value: <Expression> | 331 // <Statement> ::= Return { value: <Expression> |
| 332 // inlined_finally_list: <InlinedFinally>* } | 332 // inlined_finally_list: <InlinedFinally>* } |
| (...skipping 513 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 846 return; | 846 return; |
| 847 } | 847 } |
| 848 | 848 |
| 849 if ((node->kind() == Token::kEQ) || (node->kind() == Token::kNE)) { | 849 if ((node->kind() == Token::kEQ) || (node->kind() == Token::kNE)) { |
| 850 ValueGraphVisitor for_left_value(owner(), temp_index()); | 850 ValueGraphVisitor for_left_value(owner(), temp_index()); |
| 851 node->left()->Visit(&for_left_value); | 851 node->left()->Visit(&for_left_value); |
| 852 Append(for_left_value); | 852 Append(for_left_value); |
| 853 ValueGraphVisitor for_right_value(owner(), temp_index()); | 853 ValueGraphVisitor for_right_value(owner(), temp_index()); |
| 854 node->right()->Visit(&for_right_value); | 854 node->right()->Visit(&for_right_value); |
| 855 Append(for_right_value); | 855 Append(for_right_value); |
| 856 EqualityCompareComp* comp = new EqualityCompareComp( | 856 if (FLAG_enable_type_checks) { |
| 857 node->token_pos(), owner()->try_index(), | 857 EqualityCompareComp* comp = new EqualityCompareComp( |
| 858 for_left_value.value(), for_right_value.value()); | 858 node->token_pos(), owner()->try_index(), |
| 859 if (node->kind() == Token::kEQ) { | 859 Token::kEQ, for_left_value.value(), for_right_value.value()); |
| 860 if (node->kind() == Token::kEQ) { |
| 861 ReturnComputation(comp); |
| 862 } else { |
| 863 Value* eq_result = Bind(comp); |
| 864 eq_result = Bind(new AssertBooleanComp(node->token_pos(), |
| 865 owner()->try_index(), |
| 866 eq_result)); |
| 867 ReturnComputation(new BooleanNegateComp(eq_result)); |
| 868 } |
| 869 } else { |
| 870 EqualityCompareComp* comp = new EqualityCompareComp( |
| 871 node->token_pos(), owner()->try_index(), |
| 872 node->kind(), for_left_value.value(), for_right_value.value()); |
| 860 ReturnComputation(comp); | 873 ReturnComputation(comp); |
| 861 } else { | |
| 862 Value* eq_result = Bind(comp); | |
| 863 if (FLAG_enable_type_checks) { | |
| 864 eq_result = | |
| 865 Bind(new AssertBooleanComp(node->token_pos(), | |
| 866 owner()->try_index(), | |
| 867 eq_result)); | |
| 868 } | |
| 869 ReturnComputation(new BooleanNegateComp(eq_result)); | |
| 870 } | 874 } |
| 871 return; | 875 return; |
| 872 } | 876 } |
| 873 | 877 |
| 874 ValueGraphVisitor for_left_value(owner(), temp_index()); | 878 ValueGraphVisitor for_left_value(owner(), temp_index()); |
| 875 node->left()->Visit(&for_left_value); | 879 node->left()->Visit(&for_left_value); |
| 876 Append(for_left_value); | 880 Append(for_left_value); |
| 877 ValueGraphVisitor for_right_value(owner(), temp_index()); | 881 ValueGraphVisitor for_right_value(owner(), temp_index()); |
| 878 node->right()->Visit(&for_right_value); | 882 node->right()->Visit(&for_right_value); |
| 879 Append(for_right_value); | 883 Append(for_right_value); |
| (...skipping 1824 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2704 char* chars = reinterpret_cast<char*>( | 2708 char* chars = reinterpret_cast<char*>( |
| 2705 Isolate::Current()->current_zone()->Allocate(len)); | 2709 Isolate::Current()->current_zone()->Allocate(len)); |
| 2706 OS::SNPrint(chars, len, kFormat, function_name, reason); | 2710 OS::SNPrint(chars, len, kFormat, function_name, reason); |
| 2707 const Error& error = Error::Handle( | 2711 const Error& error = Error::Handle( |
| 2708 LanguageError::New(String::Handle(String::New(chars)))); | 2712 LanguageError::New(String::Handle(String::New(chars)))); |
| 2709 Isolate::Current()->long_jump_base()->Jump(1, error); | 2713 Isolate::Current()->long_jump_base()->Jump(1, error); |
| 2710 } | 2714 } |
| 2711 | 2715 |
| 2712 | 2716 |
| 2713 } // namespace dart | 2717 } // namespace dart |
| OLD | NEW |