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

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

Issue 8372041: Canonicalize types. (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
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 431 matching lines...) Expand 10 before | Expand all | Expand 10 after
442 const String& type_name = String::Handle(type.Name()); 442 const String& type_name = String::Handle(type.Name());
443 const String& extends_name = String::Handle(type_extends.Name()); 443 const String& extends_name = String::Handle(type_extends.Name());
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 const 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 FinalizeType(super_type);
455 super_type = super_type.Canonicalize();
srdjan 2011/11/01 20:51:43 Do you need to finalize the super_type that you ma
regis 2011/11/01 21:54:50 The finalized and canonicalized super type is writ
srdjan 2011/11/01 22:05:14 As I understand it the canonical super_type could
regis 2011/11/01 22:28:53 If the super_type was already finalized, the call
456 cls.set_super_type(super_type);
455 const Class& super_class = Class::Handle(super_type.type_class()); 457 const Class& super_class = Class::Handle(super_type.type_class());
456 const TypeArguments& super_type_args = 458 const TypeArguments& super_type_args =
457 TypeArguments::Handle(super_type.arguments()); 459 TypeArguments::Handle(super_type.arguments());
458 const intptr_t num_super_type_params = super_class.NumTypeParameters(); 460 const intptr_t num_super_type_params = super_class.NumTypeParameters();
459 const intptr_t offset = super_class.NumTypeArguments(); 461 const intptr_t offset = super_class.NumTypeArguments();
460 const intptr_t super_offset = offset - num_super_type_params; 462 const intptr_t super_offset = offset - num_super_type_params;
461 ASSERT(offset == (cls.NumTypeArguments() - cls.NumTypeParameters())); 463 ASSERT(offset == (cls.NumTypeArguments() - cls.NumTypeParameters()));
462 Type& super_type_arg = Type::Handle(); 464 Type& super_type_arg = Type::Handle();
463 for (intptr_t i = 0; i < num_super_type_params; i++) { 465 for (intptr_t i = 0; i < num_super_type_params; i++) {
464 super_type_arg = super_type_args.TypeAt(super_offset + i); 466 super_type_arg = super_type_args.TypeAt(super_offset + i);
465 if (!super_type_arg.IsInstantiated()) { 467 if (!super_type_arg.IsInstantiated()) {
466 super_type_arg = super_type_arg.InstantiateFrom(arguments, offset); 468 super_type_arg = super_type_arg.InstantiateFrom(arguments, offset);
467 } 469 }
470 super_type_arg = super_type_arg.Canonicalize();
srdjan 2011/11/01 20:51:43 I assume you cannot ask for proper canonical versi
regis 2011/11/01 21:54:50 Correct. We want to canonicalize the finalized out
468 arguments.SetTypeAt(super_offset + i, super_type_arg); 471 arguments.SetTypeAt(super_offset + i, super_type_arg);
469 } 472 }
470 FinalizeTypeArguments(super_class, arguments); 473 FinalizeTypeArguments(super_class, arguments);
471 } 474 }
472 } 475 }
473 476
474 477
475 void ClassFinalizer::FinalizeType(const Type& type) { 478 void ClassFinalizer::FinalizeType(const Type& type) {
476 ASSERT(type.IsResolved()); 479 ASSERT(type.IsResolved());
477 if (type.IsFinalized()) { 480 if (type.IsFinalized()) {
(...skipping 14 matching lines...) Expand all
492 495
493 // Finalize the current type arguments of the type, which are still the 496 // Finalize the current type arguments of the type, which are still the
494 // parsed type arguments. 497 // parsed type arguments.
495 TypeArguments& arguments = 498 TypeArguments& arguments =
496 TypeArguments::Handle(parameterized_type.arguments()); 499 TypeArguments::Handle(parameterized_type.arguments());
497 if (!arguments.IsNull()) { 500 if (!arguments.IsNull()) {
498 intptr_t num_arguments = arguments.Length(); 501 intptr_t num_arguments = arguments.Length();
499 for (intptr_t i = 0; i < num_arguments; i++) { 502 for (intptr_t i = 0; i < num_arguments; i++) {
500 Type& type_argument = Type::Handle(arguments.TypeAt(i)); 503 Type& type_argument = Type::Handle(arguments.TypeAt(i));
501 FinalizeType(type_argument); 504 FinalizeType(type_argument);
505 type_argument = type_argument.Canonicalize();
srdjan 2011/11/01 20:51:43 Ditto here, Finalize after Canonicalize or is ther
regis 2011/11/01 21:54:50 Finalization may instantiate type arguments, so it
506 arguments.SetTypeAt(i, type_argument);
502 } 507 }
503 } 508 }
504 509
505 // The type class does not need to be finalized in order to finalize the type, 510 // The type class does not need to be finalized in order to finalize the type,
506 // however, it must at least be resolved. This was done as part of resolving 511 // however, it must at least be resolved. This was done as part of resolving
507 // the type itself. 512 // the type itself.
508 Class& type_class = Class::Handle(parameterized_type.type_class()); 513 Class& type_class = Class::Handle(parameterized_type.type_class());
509 514
510 // The finalized type argument vector needs num_type_arguments types. 515 // The finalized type argument vector needs num_type_arguments types.
511 const intptr_t num_type_arguments = type_class.NumTypeArguments(); 516 const intptr_t num_type_arguments = type_class.NumTypeArguments();
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
546 // If the type is a function type, finalize the result and parameter types. 551 // If the type is a function type, finalize the result and parameter types.
547 if (type_class.IsSignatureClass()) { 552 if (type_class.IsSignatureClass()) {
548 ResolveAndFinalizeSignature( 553 ResolveAndFinalizeSignature(
549 type_class, Function::Handle(type_class.signature_function())); 554 type_class, Function::Handle(type_class.signature_function()));
550 } 555 }
551 556
552 parameterized_type.set_is_finalized(); 557 parameterized_type.set_is_finalized();
553 } 558 }
554 559
555 560
556 RawString* ClassFinalizer::FinalizeTypeWhileParsing(const Type& type) { 561 RawType* ClassFinalizer::FinalizeAndCanonicalizeType(const Type& type,
562 String& errmsg) {
557 Isolate* isolate = Isolate::Current(); 563 Isolate* isolate = Isolate::Current();
558 ASSERT(isolate != NULL); 564 ASSERT(isolate != NULL);
559 LongJump* base = isolate->long_jump_base(); 565 LongJump* base = isolate->long_jump_base();
560 LongJump jump; 566 LongJump jump;
561 isolate->set_long_jump_base(&jump); 567 isolate->set_long_jump_base(&jump);
562 if (setjmp(*jump.Set()) == 0) { 568 if (setjmp(*jump.Set()) == 0) {
563 FinalizeType(type); 569 FinalizeType(type);
564 isolate->set_long_jump_base(base); 570 isolate->set_long_jump_base(base);
565 return String::null(); 571 errmsg = String::null();
572 return type.Canonicalize();
566 } else { 573 } else {
567 // Error occured: Get the error message. 574 // Error occured: Get the error message.
568 isolate->set_long_jump_base(base); 575 isolate->set_long_jump_base(base);
569 return isolate->object_store()->sticky_error(); 576 errmsg = isolate->object_store()->sticky_error();
577 return type.raw();
570 } 578 }
571 UNREACHABLE(); 579 UNREACHABLE();
572 return String::null(); 580 return Type::null();
573 } 581 }
574 582
575 583
576 // Top level function signatures are canonicalized, added to the library class 584 // Top level function signatures are canonicalized, added to the library class
577 // dictionary, and finalized with other library classes and interfaces. 585 // dictionary, and finalized with other library classes and interfaces.
578 // Function signatures used as type of a local variable or of a local function 586 // Function signatures used as type of a local variable or of a local function
579 // are canonicalized and finalized upon creation, since all the types they 587 // are canonicalized and finalized upon creation, since all the types they
580 // reference are already resolved. 588 // reference are already resolved.
581 void ClassFinalizer::ResolveAndFinalizeSignature(const Class& cls, 589 void ClassFinalizer::ResolveAndFinalizeSignature(const Class& cls,
582 const Function& function) { 590 const Function& function) {
583 // Resolve result type. 591 // Resolve result type.
584 Type& type = Type::Handle(function.result_type()); 592 Type& type = Type::Handle(function.result_type());
585 type = ResolveType(cls, type); 593 type = ResolveType(cls, type);
586 function.set_result_type(type); 594 function.set_result_type(type);
587 FinalizeType(type); 595 FinalizeType(type);
596 type = type.Canonicalize();
597 function.set_result_type(type);
588 // Resolve formal parameter types. 598 // Resolve formal parameter types.
589 const intptr_t num_parameters = function.NumberOfParameters(); 599 const intptr_t num_parameters = function.NumberOfParameters();
590 for (intptr_t i = 0; i < num_parameters; i++) { 600 for (intptr_t i = 0; i < num_parameters; i++) {
591 type = function.ParameterTypeAt(i); 601 type = function.ParameterTypeAt(i);
592 type = ResolveType(cls, type); 602 type = ResolveType(cls, type);
593 function.SetParameterTypeAt(i, type); 603 function.SetParameterTypeAt(i, type);
594 FinalizeType(type); 604 FinalizeType(type);
605 type = type.Canonicalize();
606 function.SetParameterTypeAt(i, type);
595 } 607 }
596 } 608 }
597 609
598 610
599 static RawClass* FindSuperOwnerOfInstanceMember(const Class& cls, 611 static RawClass* FindSuperOwnerOfInstanceMember(const Class& cls,
600 const String& name) { 612 const String& name) {
601 Class& super_class = Class::Handle(); 613 Class& super_class = Class::Handle();
602 Function& function = Function::Handle(); 614 Function& function = Function::Handle();
603 Field& field = Field::Handle(); 615 Field& field = Field::Handle();
604 super_class = cls.SuperClass(); 616 super_class = cls.SuperClass();
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
653 Type& type = Type::Handle(); 665 Type& type = Type::Handle();
654 String& name = String::Handle(); 666 String& name = String::Handle();
655 Class& super_class = Class::Handle(); 667 Class& super_class = Class::Handle();
656 intptr_t num_fields = array.Length(); 668 intptr_t num_fields = array.Length();
657 for (intptr_t i = 0; i < num_fields; i++) { 669 for (intptr_t i = 0; i < num_fields; i++) {
658 field ^= array.At(i); 670 field ^= array.At(i);
659 type = field.type(); 671 type = field.type();
660 type = ResolveType(cls, type); 672 type = ResolveType(cls, type);
661 field.set_type(type); 673 field.set_type(type);
662 FinalizeType(type); 674 FinalizeType(type);
675 type = type.Canonicalize();
676 field.set_type(type);
663 name = field.name(); 677 name = field.name();
664 super_class = FindSuperOwnerOfInstanceMember(cls, name); 678 super_class = FindSuperOwnerOfInstanceMember(cls, name);
665 if (!super_class.IsNull()) { 679 if (!super_class.IsNull()) {
666 const String& class_name = String::Handle(cls.Name()); 680 const String& class_name = String::Handle(cls.Name());
667 const String& super_class_name = String::Handle(super_class.Name()); 681 const String& super_class_name = String::Handle(super_class.Name());
668 ReportError("field '%s' of class '%s' conflicts with instance " 682 ReportError("field '%s' of class '%s' conflicts with instance "
669 "member '%s' of super class '%s'.\n", 683 "member '%s' of super class '%s'.\n",
670 name.ToCString(), 684 name.ToCString(),
671 class_name.ToCString(), 685 class_name.ToCString(),
672 name.ToCString(), 686 name.ToCString(),
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
764 class_name.ToCString(), 778 class_name.ToCString(),
765 function_name.ToCString(), 779 function_name.ToCString(),
766 super_class_name.ToCString()); 780 super_class_name.ToCString());
767 } 781 }
768 } 782 }
769 } 783 }
770 // Resolve the signature type if this class is a signature class. 784 // Resolve the signature type if this class is a signature class.
771 if (cls.IsSignatureClass()) { 785 if (cls.IsSignatureClass()) {
772 const Type& signature_type = Type::Handle(cls.SignatureType()); 786 const Type& signature_type = Type::Handle(cls.SignatureType());
773 FinalizeType(signature_type); 787 FinalizeType(signature_type);
788 // Signature types are canonicalized by default.
774 } 789 }
775 } 790 }
776 791
777 792
778 void ClassFinalizer::FinalizeClass(const Class& cls) { 793 void ClassFinalizer::FinalizeClass(const Class& cls) {
779 if (cls.is_finalized()) { 794 if (cls.is_finalized()) {
780 return; 795 return;
781 } 796 }
782 if (FLAG_trace_class_finalization) { 797 if (FLAG_trace_class_finalization) {
783 OS::Print("Finalize %s\n", cls.ToCString()); 798 OS::Print("Finalize %s\n", cls.ToCString());
784 } 799 }
785 if (!IsSuperCycleFree(cls)) { 800 if (!IsSuperCycleFree(cls)) {
786 const String& name = String::Handle(cls.Name()); 801 const String& name = String::Handle(cls.Name());
787 ReportError("class '%s' has a cycle in its superclass relationship.\n", 802 ReportError("class '%s' has a cycle in its superclass relationship.\n",
788 name.ToCString()); 803 name.ToCString());
789 } 804 }
790 GrowableArray<const Class*> visited; 805 GrowableArray<const Class*> visited;
791 ResolveInterfaces(cls, &visited); 806 ResolveInterfaces(cls, &visited);
792 const Type& super_type = Type::Handle(cls.super_type()); 807 Type& super_type = Type::Handle(cls.super_type());
793 if (!super_type.IsNull()) { 808 if (!super_type.IsNull()) {
794 const Class& super_class = Class::Handle(super_type.type_class()); 809 const Class& super_class = Class::Handle(super_type.type_class());
795 // Finalize super class and super type. 810 // Finalize super class and super type.
796 FinalizeClass(super_class); 811 FinalizeClass(super_class);
797 FinalizeType(super_type); 812 FinalizeType(super_type);
813 super_type = super_type.Canonicalize();
814 cls.set_super_type(super_type);
798 } 815 }
799 if (cls.is_interface()) { 816 if (cls.is_interface()) {
800 const Type& factory_type = Type::Handle(cls.factory_type()); 817 Type& factory_type = Type::Handle(cls.factory_type());
801 if (!factory_type.IsNull()) { 818 if (!factory_type.IsNull()) {
802 const Class& factory_class = Class::Handle(factory_type.type_class()); 819 const Class& factory_class = Class::Handle(factory_type.type_class());
803 // Finalize factory class and factory type. 820 // Finalize factory class and factory type.
804 if (!factory_class.is_finalized()) { 821 if (!factory_class.is_finalized()) {
805 FinalizeClass(factory_class); 822 FinalizeClass(factory_class);
806 // Finalizing the factory class may indirectly finalize this interface. 823 // Finalizing the factory class may indirectly finalize this interface.
807 if (cls.is_finalized()) { 824 if (cls.is_finalized()) {
808 return; 825 return;
809 } 826 }
810 } 827 }
811 FinalizeType(factory_type); 828 FinalizeType(factory_type);
829 factory_type = factory_type.Canonicalize();
830 cls.set_factory_type(factory_type);
812 } 831 }
813 } 832 }
814 // Finalize interface types (but not necessarily interface classes). 833 // Finalize interface types (but not necessarily interface classes).
815 Array& interface_types = Array::Handle(cls.interfaces()); 834 Array& interface_types = Array::Handle(cls.interfaces());
816 Type& interface_type = Type::Handle(); 835 Type& interface_type = Type::Handle();
817 for (intptr_t i = 0; i < interface_types.Length(); i++) { 836 for (intptr_t i = 0; i < interface_types.Length(); i++) {
818 interface_type ^= interface_types.At(i); 837 interface_type ^= interface_types.At(i);
819 FinalizeType(interface_type); 838 FinalizeType(interface_type);
839 interface_type = interface_type.Canonicalize();
840 interface_types.SetAt(i, interface_type);
820 } 841 }
821 // Mark as finalized before resolving member types in order to break cycles. 842 // Mark as finalized before resolving member types in order to break cycles.
822 cls.Finalize(); 843 cls.Finalize();
823 ResolveAndFinalizeMemberTypes(cls); 844 ResolveAndFinalizeMemberTypes(cls);
824 // Run additional checks after all types are finalized. 845 // Run additional checks after all types are finalized.
825 if (cls.is_const()) { 846 if (cls.is_const()) {
826 CheckForLegalConstClass(cls); 847 CheckForLegalConstClass(cls);
827 } 848 }
828 } 849 }
829 850
(...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after
1069 ASSERT(msg_buffer != NULL); 1090 ASSERT(msg_buffer != NULL);
1070 va_list args; 1091 va_list args;
1071 va_start(args, format); 1092 va_start(args, format);
1072 OS::VSNPrint(msg_buffer, kBufferLength, format, args); 1093 OS::VSNPrint(msg_buffer, kBufferLength, format, args);
1073 va_end(args); 1094 va_end(args);
1074 isolate->long_jump_base()->Jump(1, msg_buffer); 1095 isolate->long_jump_base()->Jump(1, msg_buffer);
1075 UNREACHABLE(); 1096 UNREACHABLE();
1076 } 1097 }
1077 1098
1078 } // namespace dart 1099 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698