OLD | NEW |
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
47 Class& cls = Class::Handle(); | 47 Class& cls = Class::Handle(); |
48 Array& array = Array::Handle(); | 48 Array& array = Array::Handle(); |
49 Function& function = Function::Handle(); | 49 Function& function = Function::Handle(); |
50 for (intptr_t i = 0; i < added_subclasses_to_cids.length(); i++) { | 50 for (intptr_t i = 0; i < added_subclasses_to_cids.length(); i++) { |
51 intptr_t cid = added_subclasses_to_cids[i]; | 51 intptr_t cid = added_subclasses_to_cids[i]; |
52 cls = class_table.At(cid); | 52 cls = class_table.At(cid); |
53 ASSERT(!cls.IsNull()); | 53 ASSERT(!cls.IsNull()); |
54 array = cls.functions(); | 54 array = cls.functions(); |
55 intptr_t num_functions = array.IsNull() ? 0 : array.Length(); | 55 intptr_t num_functions = array.IsNull() ? 0 : array.Length(); |
56 for (intptr_t f = 0; f < num_functions; f++) { | 56 for (intptr_t f = 0; f < num_functions; f++) { |
57 function |= array.At(f); | 57 function ^= array.At(f); |
58 ASSERT(!function.IsNull()); | 58 ASSERT(!function.IsNull()); |
59 if (function.HasOptimizedCode()) { | 59 if (function.HasOptimizedCode()) { |
60 function.SwitchToUnoptimizedCode(); | 60 function.SwitchToUnoptimizedCode(); |
61 } | 61 } |
62 } | 62 } |
63 } | 63 } |
64 #endif | 64 #endif |
65 } | 65 } |
66 | 66 |
67 | 67 |
(...skipping 19 matching lines...) Expand all Loading... |
87 | 87 |
88 | 88 |
89 // Use array instead of set since we expect very few subclassed classes | 89 // Use array instead of set since we expect very few subclassed classes |
90 // to occur. | 90 // to occur. |
91 static void CollectFinalizedSuperClasses( | 91 static void CollectFinalizedSuperClasses( |
92 const GrowableObjectArray& pending_classes, | 92 const GrowableObjectArray& pending_classes, |
93 GrowableArray<intptr_t>* finalized_super_classes) { | 93 GrowableArray<intptr_t>* finalized_super_classes) { |
94 Class& cls = Class::Handle(); | 94 Class& cls = Class::Handle(); |
95 Type& super_type = Type::Handle(); | 95 Type& super_type = Type::Handle(); |
96 for (intptr_t i = 0; i < pending_classes.Length(); i++) { | 96 for (intptr_t i = 0; i < pending_classes.Length(); i++) { |
97 cls |= pending_classes.At(i); | 97 cls ^= pending_classes.At(i); |
98 ASSERT(!cls.is_finalized()); | 98 ASSERT(!cls.is_finalized()); |
99 super_type ^= cls.super_type(); | 99 super_type ^= cls.super_type(); |
100 if (!super_type.IsNull()) { | 100 if (!super_type.IsNull()) { |
101 if (super_type.HasResolvedTypeClass() && | 101 if (super_type.HasResolvedTypeClass() && |
102 Class::Handle(super_type.type_class()).is_finalized()) { | 102 Class::Handle(super_type.type_class()).is_finalized()) { |
103 AddSuperType(super_type, finalized_super_classes); | 103 AddSuperType(super_type, finalized_super_classes); |
104 } | 104 } |
105 } | 105 } |
106 } | 106 } |
107 } | 107 } |
(...skipping 23 matching lines...) Expand all Loading... |
131 if (setjmp(*jump.Set()) == 0) { | 131 if (setjmp(*jump.Set()) == 0) { |
132 GrowableObjectArray& class_array = GrowableObjectArray::Handle(); | 132 GrowableObjectArray& class_array = GrowableObjectArray::Handle(); |
133 class_array = object_store->pending_classes(); | 133 class_array = object_store->pending_classes(); |
134 ASSERT(!class_array.IsNull()); | 134 ASSERT(!class_array.IsNull()); |
135 // Collect superclasses that were already finalized before this run of | 135 // Collect superclasses that were already finalized before this run of |
136 // finalization. | 136 // finalization. |
137 CollectFinalizedSuperClasses(class_array, &added_subclasses_to_cids); | 137 CollectFinalizedSuperClasses(class_array, &added_subclasses_to_cids); |
138 Class& cls = Class::Handle(); | 138 Class& cls = Class::Handle(); |
139 // First resolve all superclasses. | 139 // First resolve all superclasses. |
140 for (intptr_t i = 0; i < class_array.Length(); i++) { | 140 for (intptr_t i = 0; i < class_array.Length(); i++) { |
141 cls |= class_array.At(i); | 141 cls ^= class_array.At(i); |
142 if (FLAG_trace_class_finalization) { | 142 if (FLAG_trace_class_finalization) { |
143 OS::Print("Resolving super and interfaces: %s\n", cls.ToCString()); | 143 OS::Print("Resolving super and interfaces: %s\n", cls.ToCString()); |
144 } | 144 } |
145 GrowableArray<intptr_t> visited_interfaces; | 145 GrowableArray<intptr_t> visited_interfaces; |
146 ResolveSuperTypeAndInterfaces(cls, &visited_interfaces); | 146 ResolveSuperTypeAndInterfaces(cls, &visited_interfaces); |
147 } | 147 } |
148 // Finalize all classes. | 148 // Finalize all classes. |
149 for (intptr_t i = 0; i < class_array.Length(); i++) { | 149 for (intptr_t i = 0; i < class_array.Length(); i++) { |
150 cls |= class_array.At(i); | 150 cls ^= class_array.At(i); |
151 FinalizeClass(cls); | 151 FinalizeClass(cls); |
152 } | 152 } |
153 if (FLAG_print_classes) { | 153 if (FLAG_print_classes) { |
154 for (intptr_t i = 0; i < class_array.Length(); i++) { | 154 for (intptr_t i = 0; i < class_array.Length(); i++) { |
155 cls |= class_array.At(i); | 155 cls ^= class_array.At(i); |
156 PrintClassInformation(cls); | 156 PrintClassInformation(cls); |
157 } | 157 } |
158 } | 158 } |
159 // Clear pending classes array. | 159 // Clear pending classes array. |
160 class_array = GrowableObjectArray::New(); | 160 class_array = GrowableObjectArray::New(); |
161 object_store->set_pending_classes(class_array); | 161 object_store->set_pending_classes(class_array); |
162 } else { | 162 } else { |
163 retval = false; | 163 retval = false; |
164 } | 164 } |
165 isolate->set_long_jump_base(base); | 165 isolate->set_long_jump_base(base); |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
263 ASSERT(ExternalFloat64Array::InstanceSize() == cls.instance_size()); | 263 ASSERT(ExternalFloat64Array::InstanceSize() == cls.instance_size()); |
264 cls = object_store->weak_property_class(); | 264 cls = object_store->weak_property_class(); |
265 ASSERT(WeakProperty::InstanceSize() == cls.instance_size()); | 265 ASSERT(WeakProperty::InstanceSize() == cls.instance_size()); |
266 #endif // defined(DEBUG) | 266 #endif // defined(DEBUG) |
267 | 267 |
268 // Remember the currently pending classes. | 268 // Remember the currently pending classes. |
269 const GrowableObjectArray& class_array = | 269 const GrowableObjectArray& class_array = |
270 GrowableObjectArray::Handle(object_store->pending_classes()); | 270 GrowableObjectArray::Handle(object_store->pending_classes()); |
271 for (intptr_t i = 0; i < class_array.Length(); i++) { | 271 for (intptr_t i = 0; i < class_array.Length(); i++) { |
272 // TODO(iposva): Add real checks. | 272 // TODO(iposva): Add real checks. |
273 cls |= class_array.At(i); | 273 cls ^= class_array.At(i); |
274 if (cls.is_finalized() || cls.is_prefinalized()) { | 274 if (cls.is_finalized() || cls.is_prefinalized()) { |
275 // Pre-finalized bootstrap classes must not define any fields. | 275 // Pre-finalized bootstrap classes must not define any fields. |
276 ASSERT(!cls.HasInstanceFields()); | 276 ASSERT(!cls.HasInstanceFields()); |
277 } | 277 } |
278 } | 278 } |
279 | 279 |
280 // Finalize classes that aren't pre-finalized by Object::Init(). | 280 // Finalize classes that aren't pre-finalized by Object::Init(). |
281 if (!FinalizePendingClasses()) { | 281 if (!FinalizePendingClasses()) { |
282 // TODO(srdjan): Exit like a real VM instead. | 282 // TODO(srdjan): Exit like a real VM instead. |
283 const Error& err = Error::Handle(object_store->sticky_error()); | 283 const Error& err = Error::Handle(object_store->sticky_error()); |
(...skipping 678 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
962 // method) having the same name as an instance member in a super class. | 962 // method) having the same name as an instance member in a super class. |
963 | 963 |
964 // Resolve type of fields and check for conflicts in super classes. | 964 // Resolve type of fields and check for conflicts in super classes. |
965 Array& array = Array::Handle(cls.fields()); | 965 Array& array = Array::Handle(cls.fields()); |
966 Field& field = Field::Handle(); | 966 Field& field = Field::Handle(); |
967 AbstractType& type = AbstractType::Handle(); | 967 AbstractType& type = AbstractType::Handle(); |
968 String& name = String::Handle(); | 968 String& name = String::Handle(); |
969 Class& super_class = Class::Handle(); | 969 Class& super_class = Class::Handle(); |
970 intptr_t num_fields = array.Length(); | 970 intptr_t num_fields = array.Length(); |
971 for (intptr_t i = 0; i < num_fields; i++) { | 971 for (intptr_t i = 0; i < num_fields; i++) { |
972 field |= array.At(i); | 972 field ^= array.At(i); |
973 type = field.type(); | 973 type = field.type(); |
974 ResolveType(cls, type, kCanonicalize); | 974 ResolveType(cls, type, kCanonicalize); |
975 type = FinalizeType(cls, type, kCanonicalize); | 975 type = FinalizeType(cls, type, kCanonicalize); |
976 field.set_type(type); | 976 field.set_type(type); |
977 name = field.name(); | 977 name = field.name(); |
978 if (field.is_static()) { | 978 if (field.is_static()) { |
979 super_class = FindSuperOwnerOfInstanceMember(cls, name); | 979 super_class = FindSuperOwnerOfInstanceMember(cls, name); |
980 if (!super_class.IsNull()) { | 980 if (!super_class.IsNull()) { |
981 const String& class_name = String::Handle(cls.Name()); | 981 const String& class_name = String::Handle(cls.Name()); |
982 const String& super_class_name = String::Handle(super_class.Name()); | 982 const String& super_class_name = String::Handle(super_class.Name()); |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1018 super_class = super_class.SuperClass(); | 1018 super_class = super_class.SuperClass(); |
1019 } | 1019 } |
1020 // Resolve function signatures and check for conflicts in super classes and | 1020 // Resolve function signatures and check for conflicts in super classes and |
1021 // interfaces. | 1021 // interfaces. |
1022 array = cls.functions(); | 1022 array = cls.functions(); |
1023 Function& function = Function::Handle(); | 1023 Function& function = Function::Handle(); |
1024 Function& overridden_function = Function::Handle(); | 1024 Function& overridden_function = Function::Handle(); |
1025 intptr_t num_functions = array.Length(); | 1025 intptr_t num_functions = array.Length(); |
1026 String& function_name = String::Handle(); | 1026 String& function_name = String::Handle(); |
1027 for (intptr_t i = 0; i < num_functions; i++) { | 1027 for (intptr_t i = 0; i < num_functions; i++) { |
1028 function |= array.At(i); | 1028 function ^= array.At(i); |
1029 ResolveAndFinalizeSignature(cls, function); | 1029 ResolveAndFinalizeSignature(cls, function); |
1030 function_name = function.name(); | 1030 function_name = function.name(); |
1031 if (function.is_static()) { | 1031 if (function.is_static()) { |
1032 super_class = FindSuperOwnerOfInstanceMember(cls, function_name); | 1032 super_class = FindSuperOwnerOfInstanceMember(cls, function_name); |
1033 if (!super_class.IsNull()) { | 1033 if (!super_class.IsNull()) { |
1034 const String& class_name = String::Handle(cls.Name()); | 1034 const String& class_name = String::Handle(cls.Name()); |
1035 const String& super_class_name = String::Handle(super_class.Name()); | 1035 const String& super_class_name = String::Handle(super_class.Name()); |
1036 const Script& script = Script::Handle(cls.script()); | 1036 const Script& script = Script::Handle(cls.script()); |
1037 ReportError(script, function.token_pos(), | 1037 ReportError(script, function.token_pos(), |
1038 "static function '%s' of class '%s' conflicts with " | 1038 "static function '%s' of class '%s' conflicts with " |
1039 "instance member '%s' of super class '%s'", | 1039 "instance member '%s' of super class '%s'", |
1040 function_name.ToCString(), | 1040 function_name.ToCString(), |
1041 class_name.ToCString(), | 1041 class_name.ToCString(), |
1042 function_name.ToCString(), | 1042 function_name.ToCString(), |
1043 super_class_name.ToCString()); | 1043 super_class_name.ToCString()); |
1044 } | 1044 } |
1045 if (function.IsRedirectingFactory()) { | 1045 if (function.IsRedirectingFactory()) { |
1046 const GrowableObjectArray& redirecting_factories = | 1046 const GrowableObjectArray& redirecting_factories = |
1047 GrowableObjectArray::Handle(GrowableObjectArray::New()); | 1047 GrowableObjectArray::Handle(GrowableObjectArray::New()); |
1048 ResolveRedirectingFactoryTarget(cls, function, redirecting_factories); | 1048 ResolveRedirectingFactoryTarget(cls, function, redirecting_factories); |
1049 } | 1049 } |
1050 } else { | 1050 } else { |
1051 for (int i = 0; i < interfaces.Length(); i++) { | 1051 for (int i = 0; i < interfaces.Length(); i++) { |
1052 super_class |= interfaces.At(i); | 1052 super_class ^= interfaces.At(i); |
1053 overridden_function = super_class.LookupDynamicFunction(function_name); | 1053 overridden_function = super_class.LookupDynamicFunction(function_name); |
1054 if (!overridden_function.IsNull() && | 1054 if (!overridden_function.IsNull() && |
1055 !function.HasCompatibleParametersWith(overridden_function)) { | 1055 !function.HasCompatibleParametersWith(overridden_function)) { |
1056 // Function types are purposely not checked for subtyping. | 1056 // Function types are purposely not checked for subtyping. |
1057 const String& class_name = String::Handle(cls.Name()); | 1057 const String& class_name = String::Handle(cls.Name()); |
1058 const String& super_class_name = String::Handle(super_class.Name()); | 1058 const String& super_class_name = String::Handle(super_class.Name()); |
1059 const Script& script = Script::Handle(cls.script()); | 1059 const Script& script = Script::Handle(cls.script()); |
1060 ReportError(script, function.token_pos(), | 1060 ReportError(script, function.token_pos(), |
1061 "class '%s' overrides function '%s' of super class '%s' " | 1061 "class '%s' overrides function '%s' of super class '%s' " |
1062 "with incompatible parameters", | 1062 "with incompatible parameters", |
(...skipping 352 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1415 if (!super.IsNull() && !super.is_const()) { | 1415 if (!super.IsNull() && !super.is_const()) { |
1416 String& name = String::Handle(super.Name()); | 1416 String& name = String::Handle(super.Name()); |
1417 const Script& script = Script::Handle(cls.script()); | 1417 const Script& script = Script::Handle(cls.script()); |
1418 ReportError(script, cls.token_pos(), | 1418 ReportError(script, cls.token_pos(), |
1419 "superclass '%s' must be const", name.ToCString()); | 1419 "superclass '%s' must be const", name.ToCString()); |
1420 } | 1420 } |
1421 const Array& fields_array = Array::Handle(cls.fields()); | 1421 const Array& fields_array = Array::Handle(cls.fields()); |
1422 intptr_t len = fields_array.Length(); | 1422 intptr_t len = fields_array.Length(); |
1423 Field& field = Field::Handle(); | 1423 Field& field = Field::Handle(); |
1424 for (intptr_t i = 0; i < len; i++) { | 1424 for (intptr_t i = 0; i < len; i++) { |
1425 field |= fields_array.At(i); | 1425 field ^= fields_array.At(i); |
1426 if (!field.is_static() && !field.is_final()) { | 1426 if (!field.is_static() && !field.is_final()) { |
1427 const String& class_name = String::Handle(cls.Name()); | 1427 const String& class_name = String::Handle(cls.Name()); |
1428 const String& field_name = String::Handle(field.name()); | 1428 const String& field_name = String::Handle(field.name()); |
1429 const Script& script = Script::Handle(cls.script()); | 1429 const Script& script = Script::Handle(cls.script()); |
1430 ReportError(script, field.token_pos(), | 1430 ReportError(script, field.token_pos(), |
1431 "const class '%s' has non-final field '%s'", | 1431 "const class '%s' has non-final field '%s'", |
1432 class_name.ToCString(), field_name.ToCString()); | 1432 class_name.ToCString(), field_name.ToCString()); |
1433 } | 1433 } |
1434 } | 1434 } |
1435 } | 1435 } |
(...skipping 26 matching lines...) Expand all Loading... |
1462 for (intptr_t i = 0; i < len; i++) { | 1462 for (intptr_t i = 0; i < len; i++) { |
1463 interface ^= interfaces_array.At(i); | 1463 interface ^= interfaces_array.At(i); |
1464 OS::Print(" %s ", interface.ToCString()); | 1464 OS::Print(" %s ", interface.ToCString()); |
1465 } | 1465 } |
1466 } | 1466 } |
1467 OS::Print("\n"); | 1467 OS::Print("\n"); |
1468 const Array& functions_array = Array::Handle(cls.functions()); | 1468 const Array& functions_array = Array::Handle(cls.functions()); |
1469 Function& function = Function::Handle(); | 1469 Function& function = Function::Handle(); |
1470 intptr_t len = functions_array.Length(); | 1470 intptr_t len = functions_array.Length(); |
1471 for (intptr_t i = 0; i < len; i++) { | 1471 for (intptr_t i = 0; i < len; i++) { |
1472 function |= functions_array.At(i); | 1472 function ^= functions_array.At(i); |
1473 OS::Print(" %s\n", function.ToCString()); | 1473 OS::Print(" %s\n", function.ToCString()); |
1474 } | 1474 } |
1475 const Array& fields_array = Array::Handle(cls.fields()); | 1475 const Array& fields_array = Array::Handle(cls.fields()); |
1476 Field& field = Field::Handle(); | 1476 Field& field = Field::Handle(); |
1477 len = fields_array.Length(); | 1477 len = fields_array.Length(); |
1478 for (intptr_t i = 0; i < len; i++) { | 1478 for (intptr_t i = 0; i < len; i++) { |
1479 field |= fields_array.At(i); | 1479 field ^= fields_array.At(i); |
1480 OS::Print(" %s\n", field.ToCString()); | 1480 OS::Print(" %s\n", field.ToCString()); |
1481 } | 1481 } |
1482 } | 1482 } |
1483 | 1483 |
1484 // Either report an error or mark the type as malformed. | 1484 // Either report an error or mark the type as malformed. |
1485 void ClassFinalizer::ReportMalformedType(const Error& prev_error, | 1485 void ClassFinalizer::ReportMalformedType(const Error& prev_error, |
1486 const Class& cls, | 1486 const Class& cls, |
1487 const Type& type, | 1487 const Type& type, |
1488 FinalizationKind finalization, | 1488 FinalizationKind finalization, |
1489 const char* format, | 1489 const char* format, |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1582 void ClassFinalizer::ReportError(const char* format, ...) { | 1582 void ClassFinalizer::ReportError(const char* format, ...) { |
1583 va_list args; | 1583 va_list args; |
1584 va_start(args, format); | 1584 va_start(args, format); |
1585 const Error& error = Error::Handle( | 1585 const Error& error = Error::Handle( |
1586 Parser::FormatError(Script::Handle(), -1, "Error", format, args)); | 1586 Parser::FormatError(Script::Handle(), -1, "Error", format, args)); |
1587 va_end(args); | 1587 va_end(args); |
1588 ReportError(error); | 1588 ReportError(error); |
1589 } | 1589 } |
1590 | 1590 |
1591 } // namespace dart | 1591 } // namespace dart |
OLD | NEW |