| 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 "lib/invocation_mirror.h" | 7 #include "lib/invocation_mirror.h" |
| 8 #include "vm/ast_printer.h" | 8 #include "vm/ast_printer.h" |
| 9 #include "vm/bit_vector.h" | 9 #include "vm/bit_vector.h" |
| 10 #include "vm/class_finalizer.h" | 10 #include "vm/class_finalizer.h" |
| (...skipping 955 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 966 // of the destination type. | 966 // of the destination type. |
| 967 bool EffectGraphVisitor::CanSkipTypeCheck(intptr_t token_pos, | 967 bool EffectGraphVisitor::CanSkipTypeCheck(intptr_t token_pos, |
| 968 Value* value, | 968 Value* value, |
| 969 const AbstractType& dst_type, | 969 const AbstractType& dst_type, |
| 970 const String& dst_name) { | 970 const String& dst_name) { |
| 971 ASSERT(!dst_type.IsNull()); | 971 ASSERT(!dst_type.IsNull()); |
| 972 ASSERT(dst_type.IsFinalized()); | 972 ASSERT(dst_type.IsFinalized()); |
| 973 | 973 |
| 974 // If the destination type is malformed or malbounded, a dynamic type error | 974 // If the destination type is malformed or malbounded, a dynamic type error |
| 975 // must be thrown at run time. | 975 // must be thrown at run time. |
| 976 if (dst_type.IsMalformed() || dst_type.IsMalbounded()) { | 976 if (dst_type.IsMalformedOrMalbounded()) { |
| 977 return false; | 977 return false; |
| 978 } | 978 } |
| 979 | 979 |
| 980 // Any type is more specific than the dynamic type and than the Object type. | 980 // Any type is more specific than the dynamic type and than the Object type. |
| 981 if (dst_type.IsDynamicType() || dst_type.IsObjectType()) { | 981 if (dst_type.IsDynamicType() || dst_type.IsObjectType()) { |
| 982 return true; | 982 return true; |
| 983 } | 983 } |
| 984 | 984 |
| 985 // Do not perform type check elimination if this optimization is turned off. | 985 // Do not perform type check elimination if this optimization is turned off. |
| 986 if (!FLAG_eliminate_type_checks) { | 986 if (!FLAG_eliminate_type_checks) { |
| (...skipping 314 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1301 ASSERT(Token::IsTypeTestOperator(node->kind())); | 1301 ASSERT(Token::IsTypeTestOperator(node->kind())); |
| 1302 EffectGraphVisitor for_left_value(owner()); | 1302 EffectGraphVisitor for_left_value(owner()); |
| 1303 node->left()->Visit(&for_left_value); | 1303 node->left()->Visit(&for_left_value); |
| 1304 Append(for_left_value); | 1304 Append(for_left_value); |
| 1305 } | 1305 } |
| 1306 | 1306 |
| 1307 | 1307 |
| 1308 void ValueGraphVisitor::BuildTypeTest(ComparisonNode* node) { | 1308 void ValueGraphVisitor::BuildTypeTest(ComparisonNode* node) { |
| 1309 ASSERT(Token::IsTypeTestOperator(node->kind())); | 1309 ASSERT(Token::IsTypeTestOperator(node->kind())); |
| 1310 const AbstractType& type = node->right()->AsTypeNode()->type(); | 1310 const AbstractType& type = node->right()->AsTypeNode()->type(); |
| 1311 ASSERT(type.IsFinalized() && !type.IsMalformed() && !type.IsMalbounded()); | 1311 ASSERT(type.IsFinalized() && !type.IsMalformedOrMalbounded()); |
| 1312 const bool negate_result = (node->kind() == Token::kISNOT); | 1312 const bool negate_result = (node->kind() == Token::kISNOT); |
| 1313 // All objects are instances of type T if Object type is a subtype of type T. | 1313 // All objects are instances of type T if Object type is a subtype of type T. |
| 1314 const Type& object_type = Type::Handle(Type::ObjectType()); | 1314 const Type& object_type = Type::Handle(Type::ObjectType()); |
| 1315 if (type.IsInstantiated() && object_type.IsSubtypeOf(type, NULL)) { | 1315 if (type.IsInstantiated() && object_type.IsSubtypeOf(type, NULL)) { |
| 1316 // Must evaluate left side. | 1316 // Must evaluate left side. |
| 1317 EffectGraphVisitor for_left_value(owner()); | 1317 EffectGraphVisitor for_left_value(owner()); |
| 1318 node->left()->Visit(&for_left_value); | 1318 node->left()->Visit(&for_left_value); |
| 1319 Append(for_left_value); | 1319 Append(for_left_value); |
| 1320 ReturnDefinition(new ConstantInstr(Bool::Get(!negate_result))); | 1320 ReturnDefinition(new ConstantInstr(Bool::Get(!negate_result))); |
| 1321 return; | 1321 return; |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1377 Object::null_array(), // No argument names. | 1377 Object::null_array(), // No argument names. |
| 1378 kNumArgsChecked, | 1378 kNumArgsChecked, |
| 1379 owner()->ic_data_array()); | 1379 owner()->ic_data_array()); |
| 1380 ReturnDefinition(call); | 1380 ReturnDefinition(call); |
| 1381 } | 1381 } |
| 1382 | 1382 |
| 1383 | 1383 |
| 1384 void EffectGraphVisitor::BuildTypeCast(ComparisonNode* node) { | 1384 void EffectGraphVisitor::BuildTypeCast(ComparisonNode* node) { |
| 1385 ASSERT(Token::IsTypeCastOperator(node->kind())); | 1385 ASSERT(Token::IsTypeCastOperator(node->kind())); |
| 1386 const AbstractType& type = node->right()->AsTypeNode()->type(); | 1386 const AbstractType& type = node->right()->AsTypeNode()->type(); |
| 1387 ASSERT(type.IsFinalized() && !type.IsMalformed() && !type.IsMalbounded()); | 1387 ASSERT(type.IsFinalized() && !type.IsMalformedOrMalbounded()); |
| 1388 ValueGraphVisitor for_value(owner()); | 1388 ValueGraphVisitor for_value(owner()); |
| 1389 node->left()->Visit(&for_value); | 1389 node->left()->Visit(&for_value); |
| 1390 Append(for_value); | 1390 Append(for_value); |
| 1391 const String& dst_name = String::ZoneHandle( | 1391 const String& dst_name = String::ZoneHandle( |
| 1392 Symbols::New(Exceptions::kCastErrorDstName)); | 1392 Symbols::New(Exceptions::kCastErrorDstName)); |
| 1393 if (CanSkipTypeCheck(node->token_pos(), for_value.value(), type, dst_name)) { | 1393 if (CanSkipTypeCheck(node->token_pos(), for_value.value(), type, dst_name)) { |
| 1394 // Drop the value and 0 additional temporaries. | 1394 // Drop the value and 0 additional temporaries. |
| 1395 Do(new DropTempsInstr(0, for_value.value())); | 1395 Do(new DropTempsInstr(0, for_value.value())); |
| 1396 } else { | 1396 } else { |
| 1397 Do(BuildAssertAssignable(node->token_pos(), | 1397 Do(BuildAssertAssignable(node->token_pos(), |
| (...skipping 1202 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2600 const Class& instantiator_class, | 2600 const Class& instantiator_class, |
| 2601 Value* instantiator) { | 2601 Value* instantiator) { |
| 2602 if (instantiator_class.NumTypeParameters() == 0) { | 2602 if (instantiator_class.NumTypeParameters() == 0) { |
| 2603 // The type arguments are compile time constants. | 2603 // The type arguments are compile time constants. |
| 2604 AbstractTypeArguments& type_arguments = AbstractTypeArguments::ZoneHandle(); | 2604 AbstractTypeArguments& type_arguments = AbstractTypeArguments::ZoneHandle(); |
| 2605 // Type is temporary. Only its type arguments are preserved. | 2605 // Type is temporary. Only its type arguments are preserved. |
| 2606 Type& type = Type::Handle( | 2606 Type& type = Type::Handle( |
| 2607 Type::New(instantiator_class, type_arguments, token_pos, Heap::kNew)); | 2607 Type::New(instantiator_class, type_arguments, token_pos, Heap::kNew)); |
| 2608 type ^= ClassFinalizer::FinalizeType( | 2608 type ^= ClassFinalizer::FinalizeType( |
| 2609 instantiator_class, type, ClassFinalizer::kFinalize); | 2609 instantiator_class, type, ClassFinalizer::kFinalize); |
| 2610 ASSERT(!type.IsMalformed() && !type.IsMalbounded()); | 2610 ASSERT(!type.IsMalformedOrMalbounded()); |
| 2611 type_arguments = type.arguments(); | 2611 type_arguments = type.arguments(); |
| 2612 type_arguments = type_arguments.Canonicalize(); | 2612 type_arguments = type_arguments.Canonicalize(); |
| 2613 return Bind(new ConstantInstr(type_arguments)); | 2613 return Bind(new ConstantInstr(type_arguments)); |
| 2614 } | 2614 } |
| 2615 Function& outer_function = | 2615 Function& outer_function = |
| 2616 Function::Handle(owner()->parsed_function()->function().raw()); | 2616 Function::Handle(owner()->parsed_function()->function().raw()); |
| 2617 while (outer_function.IsLocalFunction()) { | 2617 while (outer_function.IsLocalFunction()) { |
| 2618 outer_function = outer_function.parent_function(); | 2618 outer_function = outer_function.parent_function(); |
| 2619 } | 2619 } |
| 2620 if (outer_function.IsFactory()) { | 2620 if (outer_function.IsFactory()) { |
| (...skipping 1356 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3977 LanguageError::kError, | 3977 LanguageError::kError, |
| 3978 Heap::kNew, | 3978 Heap::kNew, |
| 3979 "FlowGraphBuilder Bailout: %s %s", | 3979 "FlowGraphBuilder Bailout: %s %s", |
| 3980 String::Handle(function.name()).ToCString(), | 3980 String::Handle(function.name()).ToCString(), |
| 3981 reason)); | 3981 reason)); |
| 3982 Isolate::Current()->long_jump_base()->Jump(1, error); | 3982 Isolate::Current()->long_jump_base()->Jump(1, error); |
| 3983 } | 3983 } |
| 3984 | 3984 |
| 3985 | 3985 |
| 3986 } // namespace dart | 3986 } // namespace dart |
| OLD | NEW |