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 523 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
534 ReturnDefinition(new ConstantInstr(node->literal())); | 534 ReturnDefinition(new ConstantInstr(node->literal())); |
535 } | 535 } |
536 | 536 |
537 | 537 |
538 // Type nodes only occur as the right-hand side of instanceof comparisons, | 538 // Type nodes only occur as the right-hand side of instanceof comparisons, |
539 // and they are handled specially in that context. | 539 // and they are handled specially in that context. |
540 void EffectGraphVisitor::VisitTypeNode(TypeNode* node) { UNREACHABLE(); } | 540 void EffectGraphVisitor::VisitTypeNode(TypeNode* node) { UNREACHABLE(); } |
541 | 541 |
542 | 542 |
543 // Returns true if the type check can be skipped, for example, if the | 543 // Returns true if the type check can be skipped, for example, if the |
544 // destination type is Dynamic or if the compile type of the value is a subtype | 544 // destination type is dynamic or if the compile type of the value is a subtype |
545 // of the destination type. | 545 // of the destination type. |
546 bool EffectGraphVisitor::CanSkipTypeCheck(intptr_t token_pos, | 546 bool EffectGraphVisitor::CanSkipTypeCheck(intptr_t token_pos, |
547 Value* value, | 547 Value* value, |
548 const AbstractType& dst_type, | 548 const AbstractType& dst_type, |
549 const String& dst_name) { | 549 const String& dst_name) { |
550 ASSERT(!dst_type.IsNull()); | 550 ASSERT(!dst_type.IsNull()); |
551 ASSERT(dst_type.IsFinalized()); | 551 ASSERT(dst_type.IsFinalized()); |
552 | 552 |
553 // If the destination type is malformed, a dynamic type error must be thrown | 553 // If the destination type is malformed, a dynamic type error must be thrown |
554 // at run time. | 554 // at run time. |
555 if (dst_type.IsMalformed()) { | 555 if (dst_type.IsMalformed()) { |
556 return false; | 556 return false; |
557 } | 557 } |
558 | 558 |
559 // Any type is more specific than the Dynamic type and than the Object type. | 559 // Any type is more specific than the dynamic type and than the Object type. |
560 if (dst_type.IsDynamicType() || dst_type.IsObjectType()) { | 560 if (dst_type.IsDynamicType() || dst_type.IsObjectType()) { |
561 return true; | 561 return true; |
562 } | 562 } |
563 | 563 |
564 // Do not perform type check elimination if this optimization is turned off. | 564 // Do not perform type check elimination if this optimization is turned off. |
565 if (!FLAG_eliminate_type_checks) { | 565 if (!FLAG_eliminate_type_checks) { |
566 return false; | 566 return false; |
567 } | 567 } |
568 | 568 |
569 // If nothing is known about the value, as is the case for passed-in | 569 // If nothing is known about the value, as is the case for passed-in |
(...skipping 252 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
822 } | 822 } |
823 | 823 |
824 // Eliminate the test if it can be performed successfully at compile time. | 824 // Eliminate the test if it can be performed successfully at compile time. |
825 if ((node->left() != NULL) && | 825 if ((node->left() != NULL) && |
826 node->left()->IsLiteralNode() && | 826 node->left()->IsLiteralNode() && |
827 type.IsInstantiated()) { | 827 type.IsInstantiated()) { |
828 const Instance& literal_value = node->left()->AsLiteralNode()->literal(); | 828 const Instance& literal_value = node->left()->AsLiteralNode()->literal(); |
829 const Class& cls = Class::Handle(literal_value.clazz()); | 829 const Class& cls = Class::Handle(literal_value.clazz()); |
830 ConstantInstr* result = NULL; | 830 ConstantInstr* result = NULL; |
831 if (cls.IsNullClass()) { | 831 if (cls.IsNullClass()) { |
832 // A null object is only an instance of Object and Dynamic, which has | 832 // A null object is only an instance of Object and dynamic, which has |
833 // already been checked above (if the type is instantiated). So we can | 833 // already been checked above (if the type is instantiated). So we can |
834 // return false here if the instance is null (and if the type is | 834 // return false here if the instance is null (and if the type is |
835 // instantiated). | 835 // instantiated). |
836 result = new ConstantInstr(negate_result ? bool_true : bool_false); | 836 result = new ConstantInstr(negate_result ? bool_true : bool_false); |
837 } else { | 837 } else { |
838 if (literal_value.IsInstanceOf(type, TypeArguments::Handle(), NULL)) { | 838 if (literal_value.IsInstanceOf(type, TypeArguments::Handle(), NULL)) { |
839 result = new ConstantInstr(negate_result ? bool_false : bool_true); | 839 result = new ConstantInstr(negate_result ? bool_false : bool_true); |
840 } else { | 840 } else { |
841 result = new ConstantInstr(negate_result ? bool_true : bool_false); | 841 result = new ConstantInstr(negate_result ? bool_true : bool_false); |
842 } | 842 } |
(...skipping 1834 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2677 intptr_t len = OS::SNPrint(NULL, 0, kFormat, function_name, reason) + 1; | 2677 intptr_t len = OS::SNPrint(NULL, 0, kFormat, function_name, reason) + 1; |
2678 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len); | 2678 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len); |
2679 OS::SNPrint(chars, len, kFormat, function_name, reason); | 2679 OS::SNPrint(chars, len, kFormat, function_name, reason); |
2680 const Error& error = Error::Handle( | 2680 const Error& error = Error::Handle( |
2681 LanguageError::New(String::Handle(String::New(chars)))); | 2681 LanguageError::New(String::Handle(String::New(chars)))); |
2682 Isolate::Current()->long_jump_base()->Jump(1, error); | 2682 Isolate::Current()->long_jump_base()->Jump(1, error); |
2683 } | 2683 } |
2684 | 2684 |
2685 | 2685 |
2686 } // namespace dart | 2686 } // namespace dart |
OLD | NEW |