Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(72)

Side by Side Diff: runtime/vm/class_finalizer.cc

Issue 8437028: Perform type canonicalization as part of type finalization. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 9 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « runtime/vm/class_finalizer.h ('k') | runtime/vm/object.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2011, 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/class_finalizer.h" 5 #include "vm/class_finalizer.h"
6 6
7 #include "vm/flags.h" 7 #include "vm/flags.h"
8 #include "vm/heap.h" 8 #include "vm/heap.h"
9 #include "vm/isolate.h" 9 #include "vm/isolate.h"
10 #include "vm/longjump.h" 10 #include "vm/longjump.h"
(...skipping 433 matching lines...) Expand 10 before | Expand all | Expand 10 after
444 ReportError("type argument '%s' does not extend type '%s'\n", 444 ReportError("type argument '%s' does not extend type '%s'\n",
445 type_name.ToCString(), 445 type_name.ToCString(),
446 extends_name.ToCString()); 446 extends_name.ToCString());
447 } 447 }
448 } 448 }
449 } 449 }
450 } 450 }
451 } 451 }
452 Type& super_type = Type::Handle(cls.super_type()); 452 Type& super_type = Type::Handle(cls.super_type());
453 if (!super_type.IsNull()) { 453 if (!super_type.IsNull()) {
454 FinalizeType(super_type); 454 super_type = FinalizeType(super_type);
455 super_type = super_type.Canonicalize();
456 cls.set_super_type(super_type); 455 cls.set_super_type(super_type);
457 const Class& super_class = Class::Handle(super_type.type_class()); 456 const Class& super_class = Class::Handle(super_type.type_class());
458 const TypeArguments& super_type_args = 457 const TypeArguments& super_type_args =
459 TypeArguments::Handle(super_type.arguments()); 458 TypeArguments::Handle(super_type.arguments());
460 const intptr_t num_super_type_params = super_class.NumTypeParameters(); 459 const intptr_t num_super_type_params = super_class.NumTypeParameters();
461 const intptr_t offset = super_class.NumTypeArguments(); 460 const intptr_t offset = super_class.NumTypeArguments();
462 const intptr_t super_offset = offset - num_super_type_params; 461 const intptr_t super_offset = offset - num_super_type_params;
463 ASSERT(offset == (cls.NumTypeArguments() - cls.NumTypeParameters())); 462 ASSERT(offset == (cls.NumTypeArguments() - cls.NumTypeParameters()));
464 Type& super_type_arg = Type::Handle(); 463 Type& super_type_arg = Type::Handle();
465 for (intptr_t i = 0; i < num_super_type_params; i++) { 464 for (intptr_t i = 0; i < num_super_type_params; i++) {
466 super_type_arg = super_type_args.TypeAt(super_offset + i); 465 super_type_arg = super_type_args.TypeAt(super_offset + i);
467 if (!super_type_arg.IsInstantiated()) { 466 if (!super_type_arg.IsInstantiated()) {
468 super_type_arg = super_type_arg.InstantiateFrom(arguments, offset); 467 super_type_arg = super_type_arg.InstantiateFrom(arguments, offset);
469 } 468 }
470 super_type_arg = super_type_arg.Canonicalize(); 469 super_type_arg = super_type_arg.Canonicalize();
471 arguments.SetTypeAt(super_offset + i, super_type_arg); 470 arguments.SetTypeAt(super_offset + i, super_type_arg);
472 } 471 }
473 FinalizeTypeArguments(super_class, arguments); 472 FinalizeTypeArguments(super_class, arguments);
474 } 473 }
475 } 474 }
476 475
477 476
478 void ClassFinalizer::FinalizeType(const Type& type) { 477 RawType* ClassFinalizer::FinalizeType(const Type& type) {
479 ASSERT(type.IsResolved()); 478 ASSERT(type.IsResolved());
480 if (type.IsFinalized()) { 479 if (type.IsFinalized()) {
481 return; 480 return type.raw();
482 } 481 }
483 482
484 // At this point, we can only have a parameterized_type. 483 // At this point, we can only have a parameterized_type.
485 ParameterizedType& parameterized_type = ParameterizedType::Handle(); 484 ParameterizedType& parameterized_type = ParameterizedType::Handle();
486 parameterized_type ^= type.raw(); 485 parameterized_type ^= type.raw();
487 486
488 if (parameterized_type.IsBeingFinalized()) { 487 if (parameterized_type.IsBeingFinalized()) {
489 ReportError("type '%s' illegally refers to itself\n", 488 ReportError("type '%s' illegally refers to itself\n",
490 String::Handle(parameterized_type.Name()).ToCString()); 489 String::Handle(parameterized_type.Name()).ToCString());
491 } 490 }
492 491
493 // Mark type as being finalized in order to detect illegal self reference. 492 // Mark type as being finalized in order to detect illegal self reference.
494 parameterized_type.set_is_being_finalized(); 493 parameterized_type.set_is_being_finalized();
495 494
496 // Finalize the current type arguments of the type, which are still the 495 // Finalize the current type arguments of the type, which are still the
497 // parsed type arguments. 496 // parsed type arguments.
498 TypeArguments& arguments = 497 TypeArguments& arguments =
499 TypeArguments::Handle(parameterized_type.arguments()); 498 TypeArguments::Handle(parameterized_type.arguments());
500 if (!arguments.IsNull()) { 499 if (!arguments.IsNull()) {
501 intptr_t num_arguments = arguments.Length(); 500 intptr_t num_arguments = arguments.Length();
502 for (intptr_t i = 0; i < num_arguments; i++) { 501 for (intptr_t i = 0; i < num_arguments; i++) {
503 Type& type_argument = Type::Handle(arguments.TypeAt(i)); 502 Type& type_argument = Type::Handle(arguments.TypeAt(i));
504 FinalizeType(type_argument); 503 type_argument = FinalizeType(type_argument);
505 type_argument = type_argument.Canonicalize();
506 arguments.SetTypeAt(i, type_argument); 504 arguments.SetTypeAt(i, type_argument);
507 } 505 }
508 } 506 }
509 507
510 // The type class does not need to be finalized in order to finalize the type, 508 // The type class does not need to be finalized in order to finalize the type,
511 // however, it must at least be resolved. This was done as part of resolving 509 // however, it must at least be resolved. This was done as part of resolving
512 // the type itself. 510 // the type itself.
513 Class& type_class = Class::Handle(parameterized_type.type_class()); 511 Class& type_class = Class::Handle(parameterized_type.type_class());
514 512
515 // The finalized type argument vector needs num_type_arguments types. 513 // The finalized type argument vector needs num_type_arguments types.
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
548 parameterized_type.set_arguments(full_arguments); 546 parameterized_type.set_arguments(full_arguments);
549 } 547 }
550 548
551 // If the type is a function type, finalize the result and parameter types. 549 // If the type is a function type, finalize the result and parameter types.
552 if (type_class.IsSignatureClass()) { 550 if (type_class.IsSignatureClass()) {
553 ResolveAndFinalizeSignature( 551 ResolveAndFinalizeSignature(
554 type_class, Function::Handle(type_class.signature_function())); 552 type_class, Function::Handle(type_class.signature_function()));
555 } 553 }
556 554
557 parameterized_type.set_is_finalized(); 555 parameterized_type.set_is_finalized();
556 return parameterized_type.Canonicalize();
558 } 557 }
559 558
560 559
561 RawType* ClassFinalizer::FinalizeAndCanonicalizeType(const Type& type, 560 RawType* ClassFinalizer::FinalizeAndCanonicalizeType(const Type& type,
562 String* errmsg) { 561 String* errmsg) {
563 Isolate* isolate = Isolate::Current(); 562 Isolate* isolate = Isolate::Current();
564 ASSERT(isolate != NULL); 563 ASSERT(isolate != NULL);
565 LongJump* base = isolate->long_jump_base(); 564 LongJump* base = isolate->long_jump_base();
566 LongJump jump; 565 LongJump jump;
567 isolate->set_long_jump_base(&jump); 566 isolate->set_long_jump_base(&jump);
568 if (setjmp(*jump.Set()) == 0) { 567 if (setjmp(*jump.Set()) == 0) {
569 FinalizeType(type); 568 const Type& canonical_type = Type::Handle(FinalizeType(type));
570 isolate->set_long_jump_base(base); 569 isolate->set_long_jump_base(base);
571 *errmsg = String::null(); 570 *errmsg = String::null();
572 return type.Canonicalize(); 571 return canonical_type.raw();
573 } else { 572 } else {
574 // Error occured: Get the error message. 573 // Error occured: Get the error message.
575 isolate->set_long_jump_base(base); 574 isolate->set_long_jump_base(base);
576 *errmsg = isolate->object_store()->sticky_error(); 575 *errmsg = isolate->object_store()->sticky_error();
577 return type.raw(); 576 return type.raw();
578 } 577 }
579 UNREACHABLE(); 578 UNREACHABLE();
580 return Type::null(); 579 return Type::null();
581 } 580 }
582 581
583 582
584 // Top level function signatures are canonicalized, added to the library class 583 // Top level function signatures are canonicalized, added to the library class
585 // dictionary, and finalized with other library classes and interfaces. 584 // dictionary, and finalized with other library classes and interfaces.
586 // Function signatures used as type of a local variable or of a local function 585 // Function signatures used as type of a local variable or of a local function
587 // are canonicalized and finalized upon creation, since all the types they 586 // are canonicalized and finalized upon creation, since all the types they
588 // reference are already resolved. 587 // reference are already resolved.
589 void ClassFinalizer::ResolveAndFinalizeSignature(const Class& cls, 588 void ClassFinalizer::ResolveAndFinalizeSignature(const Class& cls,
590 const Function& function) { 589 const Function& function) {
591 // Resolve result type. 590 // Resolve result type.
592 Type& type = Type::Handle(function.result_type()); 591 Type& type = Type::Handle(function.result_type());
593 type = ResolveType(cls, type); 592 type = ResolveType(cls, type);
594 function.set_result_type(type); 593 function.set_result_type(type);
595 FinalizeType(type); 594 type = FinalizeType(type);
596 type = type.Canonicalize();
597 function.set_result_type(type); 595 function.set_result_type(type);
598 // Resolve formal parameter types. 596 // Resolve formal parameter types.
599 const intptr_t num_parameters = function.NumberOfParameters(); 597 const intptr_t num_parameters = function.NumberOfParameters();
600 for (intptr_t i = 0; i < num_parameters; i++) { 598 for (intptr_t i = 0; i < num_parameters; i++) {
601 type = function.ParameterTypeAt(i); 599 type = function.ParameterTypeAt(i);
602 type = ResolveType(cls, type); 600 type = ResolveType(cls, type);
603 function.SetParameterTypeAt(i, type); 601 function.SetParameterTypeAt(i, type);
604 FinalizeType(type); 602 type = FinalizeType(type);
605 type = type.Canonicalize();
606 function.SetParameterTypeAt(i, type); 603 function.SetParameterTypeAt(i, type);
607 } 604 }
608 } 605 }
609 606
610 607
611 static RawClass* FindSuperOwnerOfInstanceMember(const Class& cls, 608 static RawClass* FindSuperOwnerOfInstanceMember(const Class& cls,
612 const String& name) { 609 const String& name) {
613 Class& super_class = Class::Handle(); 610 Class& super_class = Class::Handle();
614 Function& function = Function::Handle(); 611 Function& function = Function::Handle();
615 Field& field = Field::Handle(); 612 Field& field = Field::Handle();
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
664 Field& field = Field::Handle(); 661 Field& field = Field::Handle();
665 Type& type = Type::Handle(); 662 Type& type = Type::Handle();
666 String& name = String::Handle(); 663 String& name = String::Handle();
667 Class& super_class = Class::Handle(); 664 Class& super_class = Class::Handle();
668 intptr_t num_fields = array.Length(); 665 intptr_t num_fields = array.Length();
669 for (intptr_t i = 0; i < num_fields; i++) { 666 for (intptr_t i = 0; i < num_fields; i++) {
670 field ^= array.At(i); 667 field ^= array.At(i);
671 type = field.type(); 668 type = field.type();
672 type = ResolveType(cls, type); 669 type = ResolveType(cls, type);
673 field.set_type(type); 670 field.set_type(type);
674 FinalizeType(type); 671 type = FinalizeType(type);
675 type = type.Canonicalize();
676 field.set_type(type); 672 field.set_type(type);
677 name = field.name(); 673 name = field.name();
678 super_class = FindSuperOwnerOfInstanceMember(cls, name); 674 super_class = FindSuperOwnerOfInstanceMember(cls, name);
679 if (!super_class.IsNull()) { 675 if (!super_class.IsNull()) {
680 const String& class_name = String::Handle(cls.Name()); 676 const String& class_name = String::Handle(cls.Name());
681 const String& super_class_name = String::Handle(super_class.Name()); 677 const String& super_class_name = String::Handle(super_class.Name());
682 ReportError("field '%s' of class '%s' conflicts with instance " 678 ReportError("field '%s' of class '%s' conflicts with instance "
683 "member '%s' of super class '%s'.\n", 679 "member '%s' of super class '%s'.\n",
684 name.ToCString(), 680 name.ToCString(),
685 class_name.ToCString(), 681 class_name.ToCString(),
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
776 "setter '%s' of super class '%s'.\n", 772 "setter '%s' of super class '%s'.\n",
777 function_name.ToCString(), 773 function_name.ToCString(),
778 class_name.ToCString(), 774 class_name.ToCString(),
779 function_name.ToCString(), 775 function_name.ToCString(),
780 super_class_name.ToCString()); 776 super_class_name.ToCString());
781 } 777 }
782 } 778 }
783 } 779 }
784 // Resolve the signature type if this class is a signature class. 780 // Resolve the signature type if this class is a signature class.
785 if (cls.IsSignatureClass()) { 781 if (cls.IsSignatureClass()) {
786 const Type& signature_type = Type::Handle(cls.SignatureType()); 782 Type& signature_type = Type::Handle(cls.SignatureType());
787 FinalizeType(signature_type); 783 signature_type = FinalizeType(signature_type);
788 // Signature types are canonicalized by default. 784 // Signature types are canonicalized by default.
785 ASSERT(signature_type.raw() == cls.SignatureType());
789 } 786 }
790 } 787 }
791 788
792 789
793 void ClassFinalizer::FinalizeClass(const Class& cls) { 790 void ClassFinalizer::FinalizeClass(const Class& cls) {
794 if (cls.is_finalized()) { 791 if (cls.is_finalized()) {
795 return; 792 return;
796 } 793 }
797 if (FLAG_trace_class_finalization) { 794 if (FLAG_trace_class_finalization) {
798 OS::Print("Finalize %s\n", cls.ToCString()); 795 OS::Print("Finalize %s\n", cls.ToCString());
799 } 796 }
800 if (!IsSuperCycleFree(cls)) { 797 if (!IsSuperCycleFree(cls)) {
801 const String& name = String::Handle(cls.Name()); 798 const String& name = String::Handle(cls.Name());
802 ReportError("class '%s' has a cycle in its superclass relationship.\n", 799 ReportError("class '%s' has a cycle in its superclass relationship.\n",
803 name.ToCString()); 800 name.ToCString());
804 } 801 }
805 GrowableArray<const Class*> visited; 802 GrowableArray<const Class*> visited;
806 ResolveInterfaces(cls, &visited); 803 ResolveInterfaces(cls, &visited);
807 Type& super_type = Type::Handle(cls.super_type()); 804 Type& super_type = Type::Handle(cls.super_type());
808 if (!super_type.IsNull()) { 805 if (!super_type.IsNull()) {
809 const Class& super_class = Class::Handle(super_type.type_class()); 806 const Class& super_class = Class::Handle(super_type.type_class());
810 // Finalize super class and super type. 807 // Finalize super class and super type.
811 FinalizeClass(super_class); 808 FinalizeClass(super_class);
812 FinalizeType(super_type); 809 super_type = FinalizeType(super_type);
813 super_type = super_type.Canonicalize();
814 cls.set_super_type(super_type); 810 cls.set_super_type(super_type);
815 } 811 }
816 if (cls.is_interface()) { 812 if (cls.is_interface()) {
817 Type& factory_type = Type::Handle(cls.factory_type()); 813 Type& factory_type = Type::Handle(cls.factory_type());
818 if (!factory_type.IsNull()) { 814 if (!factory_type.IsNull()) {
819 const Class& factory_class = Class::Handle(factory_type.type_class()); 815 const Class& factory_class = Class::Handle(factory_type.type_class());
820 // Finalize factory class and factory type. 816 // Finalize factory class and factory type.
821 if (!factory_class.is_finalized()) { 817 if (!factory_class.is_finalized()) {
822 FinalizeClass(factory_class); 818 FinalizeClass(factory_class);
823 // Finalizing the factory class may indirectly finalize this interface. 819 // Finalizing the factory class may indirectly finalize this interface.
824 if (cls.is_finalized()) { 820 if (cls.is_finalized()) {
825 return; 821 return;
826 } 822 }
827 } 823 }
828 FinalizeType(factory_type); 824 factory_type = FinalizeType(factory_type);
829 factory_type = factory_type.Canonicalize();
830 cls.set_factory_type(factory_type); 825 cls.set_factory_type(factory_type);
831 } 826 }
832 } 827 }
833 // Finalize interface types (but not necessarily interface classes). 828 // Finalize interface types (but not necessarily interface classes).
834 Array& interface_types = Array::Handle(cls.interfaces()); 829 Array& interface_types = Array::Handle(cls.interfaces());
835 Type& interface_type = Type::Handle(); 830 Type& interface_type = Type::Handle();
836 for (intptr_t i = 0; i < interface_types.Length(); i++) { 831 for (intptr_t i = 0; i < interface_types.Length(); i++) {
837 interface_type ^= interface_types.At(i); 832 interface_type ^= interface_types.At(i);
838 FinalizeType(interface_type); 833 interface_type = FinalizeType(interface_type);
839 interface_type = interface_type.Canonicalize();
840 interface_types.SetAt(i, interface_type); 834 interface_types.SetAt(i, interface_type);
841 } 835 }
842 // Mark as finalized before resolving member types in order to break cycles. 836 // Mark as finalized before resolving member types in order to break cycles.
843 cls.Finalize(); 837 cls.Finalize();
844 ResolveAndFinalizeMemberTypes(cls); 838 ResolveAndFinalizeMemberTypes(cls);
845 // Run additional checks after all types are finalized. 839 // Run additional checks after all types are finalized.
846 if (cls.is_const()) { 840 if (cls.is_const()) {
847 CheckForLegalConstClass(cls); 841 CheckForLegalConstClass(cls);
848 } 842 }
849 } 843 }
(...skipping 240 matching lines...) Expand 10 before | Expand all | Expand 10 after
1090 ASSERT(msg_buffer != NULL); 1084 ASSERT(msg_buffer != NULL);
1091 va_list args; 1085 va_list args;
1092 va_start(args, format); 1086 va_start(args, format);
1093 OS::VSNPrint(msg_buffer, kBufferLength, format, args); 1087 OS::VSNPrint(msg_buffer, kBufferLength, format, args);
1094 va_end(args); 1088 va_end(args);
1095 isolate->long_jump_base()->Jump(1, msg_buffer); 1089 isolate->long_jump_base()->Jump(1, msg_buffer);
1096 UNREACHABLE(); 1090 UNREACHABLE();
1097 } 1091 }
1098 1092
1099 } // namespace dart 1093 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/class_finalizer.h ('k') | runtime/vm/object.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698