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

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

Issue 2485993002: VM: Support bootstrapping core libraries from Kernel binaries instead of source. (Closed)
Patch Set: Done Created 4 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
OLDNEW
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/code_generator.h" 7 #include "vm/code_generator.h"
8 #include "vm/flags.h" 8 #include "vm/flags.h"
9 #include "vm/heap.h" 9 #include "vm/heap.h"
10 #include "vm/isolate.h" 10 #include "vm/isolate.h"
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
111 } 111 }
112 } 112 }
113 cids->Add(ifc.id()); 113 cids->Add(ifc.id());
114 } 114 }
115 } 115 }
116 116
117 117
118 // Processing ObjectStore::pending_classes_ occurs: 118 // Processing ObjectStore::pending_classes_ occurs:
119 // a) when bootstrap process completes (VerifyBootstrapClasses). 119 // a) when bootstrap process completes (VerifyBootstrapClasses).
120 // b) after the user classes are loaded (dart_api). 120 // b) after the user classes are loaded (dart_api).
121 bool ClassFinalizer::ProcessPendingClasses() { 121 bool ClassFinalizer::ProcessPendingClasses(bool from_kernel) {
122 Thread* thread = Thread::Current(); 122 Thread* thread = Thread::Current();
123 NOT_IN_PRODUCT(TimelineDurationScope tds(thread, Timeline::GetIsolateStream(), 123 NOT_IN_PRODUCT(TimelineDurationScope tds(thread, Timeline::GetIsolateStream(),
124 "ProcessPendingClasses")); 124 "ProcessPendingClasses"));
125 Isolate* isolate = thread->isolate(); 125 Isolate* isolate = thread->isolate();
126 ASSERT(isolate != NULL); 126 ASSERT(isolate != NULL);
127 HANDLESCOPE(thread); 127 HANDLESCOPE(thread);
128 ObjectStore* object_store = isolate->object_store(); 128 ObjectStore* object_store = isolate->object_store();
129 const Error& error = Error::Handle(thread->zone(), thread->sticky_error()); 129 const Error& error = Error::Handle(thread->zone(), thread->sticky_error());
130 if (!error.IsNull()) { 130 if (!error.IsNull()) {
131 return false; 131 return false;
(...skipping 11 matching lines...) Expand all
143 // First resolve all superclasses. 143 // First resolve all superclasses.
144 for (intptr_t i = 0; i < class_array.Length(); i++) { 144 for (intptr_t i = 0; i < class_array.Length(); i++) {
145 cls ^= class_array.At(i); 145 cls ^= class_array.At(i);
146 GrowableArray<intptr_t> visited_interfaces; 146 GrowableArray<intptr_t> visited_interfaces;
147 ResolveSuperTypeAndInterfaces(cls, &visited_interfaces); 147 ResolveSuperTypeAndInterfaces(cls, &visited_interfaces);
148 } 148 }
149 // Finalize all classes. 149 // Finalize all classes.
150 for (intptr_t i = 0; i < class_array.Length(); i++) { 150 for (intptr_t i = 0; i < class_array.Length(); i++) {
151 cls ^= class_array.At(i); 151 cls ^= class_array.At(i);
152 FinalizeTypesInClass(cls); 152 FinalizeTypesInClass(cls);
153 // Classes compiled from Dart sources are finalized more lazily, classes
154 // compiled from Kernel binaries can be finalized now (and should be,
155 // since we will not revisit them).
156 if (from_kernel) {
157 FinalizeClass(cls);
158 }
153 } 159 }
154 if (FLAG_print_classes) { 160 if (FLAG_print_classes) {
155 for (intptr_t i = 0; i < class_array.Length(); i++) { 161 for (intptr_t i = 0; i < class_array.Length(); i++) {
156 cls ^= class_array.At(i); 162 cls ^= class_array.At(i);
157 PrintClassInformation(cls); 163 PrintClassInformation(cls);
158 } 164 }
159 } 165 }
160 // Clear pending classes array. 166 // Clear pending classes array.
161 class_array = GrowableObjectArray::New(); 167 class_array = GrowableObjectArray::New();
162 object_store->set_pending_classes(class_array); 168 object_store->set_pending_classes(class_array);
(...skipping 18 matching lines...) Expand all
181 Class& interface_class = Class::Handle(zone); 187 Class& interface_class = Class::Handle(zone);
182 for (intptr_t i = 0; i < interface_array.Length(); i++) { 188 for (intptr_t i = 0; i < interface_array.Length(); i++) {
183 interface ^= interface_array.At(i); 189 interface ^= interface_array.At(i);
184 interface_class = interface.type_class(); 190 interface_class = interface.type_class();
185 collected->Add(&Class::ZoneHandle(zone, interface_class.raw())); 191 collected->Add(&Class::ZoneHandle(zone, interface_class.raw()));
186 CollectInterfaces(interface_class, collected); 192 CollectInterfaces(interface_class, collected);
187 } 193 }
188 } 194 }
189 195
190 196
191 #if defined(DART_NO_SNAPSHOT) 197 #if !defined(DART_PRECOMPILED_RUNTIME)
192 void ClassFinalizer::VerifyBootstrapClasses() { 198 void ClassFinalizer::VerifyBootstrapClasses() {
193 if (FLAG_trace_class_finalization) { 199 if (FLAG_trace_class_finalization) {
194 OS::Print("VerifyBootstrapClasses START.\n"); 200 OS::Print("VerifyBootstrapClasses START.\n");
195 } 201 }
196 ObjectStore* object_store = Isolate::Current()->object_store(); 202 ObjectStore* object_store = Isolate::Current()->object_store();
197 203
198 Class& cls = Class::Handle(); 204 Class& cls = Class::Handle();
199 #if defined(DEBUG) 205 #if defined(DEBUG)
200 // Basic checking. 206 // Basic checking.
201 cls = object_store->object_class(); 207 cls = object_store->object_class();
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
247 const Error& err = Error::Handle(Thread::Current()->sticky_error()); 253 const Error& err = Error::Handle(Thread::Current()->sticky_error());
248 OS::PrintErr("Could not verify bootstrap classes : %s\n", 254 OS::PrintErr("Could not verify bootstrap classes : %s\n",
249 err.ToErrorCString()); 255 err.ToErrorCString());
250 OS::Exit(255); 256 OS::Exit(255);
251 } 257 }
252 if (FLAG_trace_class_finalization) { 258 if (FLAG_trace_class_finalization) {
253 OS::Print("VerifyBootstrapClasses END.\n"); 259 OS::Print("VerifyBootstrapClasses END.\n");
254 } 260 }
255 Isolate::Current()->heap()->Verify(); 261 Isolate::Current()->heap()->Verify();
256 } 262 }
257 #endif // defined(DART_NO_SNAPSHOT). 263 #endif // !defined(DART_PRECOMPILED_RUNTIME)
258 264
259 265
260 static bool IsLoaded(const Type& type) { 266 static bool IsLoaded(const Type& type) {
261 if (type.HasResolvedTypeClass()) { 267 if (type.HasResolvedTypeClass()) {
262 return true; 268 return true;
263 } 269 }
264 const UnresolvedClass& unresolved_class = 270 const UnresolvedClass& unresolved_class =
265 UnresolvedClass::Handle(type.unresolved_class()); 271 UnresolvedClass::Handle(type.unresolved_class());
266 const LibraryPrefix& prefix = 272 const Object& prefix =
267 LibraryPrefix::Handle(unresolved_class.library_prefix()); 273 Object::Handle(unresolved_class.library_or_library_prefix());
268 return prefix.IsNull() || prefix.is_loaded(); 274 if (prefix.IsNull()) {
275 return true;
276 } else if (prefix.IsLibraryPrefix()) {
277 return LibraryPrefix::Cast(prefix).is_loaded();
278 } else {
279 return true;
280 }
269 } 281 }
270 282
271 283
272 // Resolve unresolved_class in the library of cls, or return null. 284 // Resolve unresolved_class in the library of cls, or return null.
273 RawClass* ClassFinalizer::ResolveClass( 285 RawClass* ClassFinalizer::ResolveClass(
274 const Class& cls, 286 const Class& cls,
275 const UnresolvedClass& unresolved_class) { 287 const UnresolvedClass& unresolved_class) {
276 const String& class_name = String::Handle(unresolved_class.ident()); 288 const String& class_name = String::Handle(unresolved_class.ident());
277 Library& lib = Library::Handle(); 289 Library& lib = Library::Handle();
278 Class& resolved_class = Class::Handle(); 290 Class& resolved_class = Class::Handle();
279 if (unresolved_class.library_prefix() == LibraryPrefix::null()) { 291 if (unresolved_class.library_or_library_prefix() == Object::null()) {
280 lib = cls.library(); 292 lib = cls.library();
281 ASSERT(!lib.IsNull()); 293 ASSERT(!lib.IsNull());
282 resolved_class = lib.LookupClass(class_name); 294 resolved_class = lib.LookupClass(class_name);
283 } else { 295 } else {
284 LibraryPrefix& lib_prefix = LibraryPrefix::Handle(); 296 const Object& prefix =
285 lib_prefix = unresolved_class.library_prefix(); 297 Object::Handle(unresolved_class.library_or_library_prefix());
286 ASSERT(!lib_prefix.IsNull()); 298
287 resolved_class = lib_prefix.LookupClass(class_name); 299 if (prefix.IsLibraryPrefix()) {
300 resolved_class = LibraryPrefix::Cast(prefix).LookupClass(class_name);
301 } else {
302 resolved_class = Library::Cast(prefix).LookupClass(class_name);
303 }
288 } 304 }
289 return resolved_class.raw(); 305 return resolved_class.raw();
290 } 306 }
291 307
292 308
293 void ClassFinalizer::ResolveRedirectingFactory(const Class& cls, 309 void ClassFinalizer::ResolveRedirectingFactory(const Class& cls,
294 const Function& factory) { 310 const Function& factory) {
295 const Function& target = Function::Handle(factory.RedirectionTarget()); 311 const Function& target = Function::Handle(factory.RedirectionTarget());
296 if (target.IsNull()) { 312 if (target.IsNull()) {
297 Type& type = Type::Handle(factory.RedirectionType()); 313 Type& type = Type::Handle(factory.RedirectionType());
(...skipping 1884 matching lines...) Expand 10 before | Expand all | Expand 10 after
2182 2198
2183 if (FLAG_trace_class_finalization) { 2199 if (FLAG_trace_class_finalization) {
2184 THR_Print("Applying mixin members of %s to %s at pos %s\n", 2200 THR_Print("Applying mixin members of %s to %s at pos %s\n",
2185 mixin_cls.ToCString(), cls.ToCString(), 2201 mixin_cls.ToCString(), cls.ToCString(),
2186 cls.token_pos().ToCString()); 2202 cls.token_pos().ToCString());
2187 } 2203 }
2188 2204
2189 const GrowableObjectArray& cloned_funcs = 2205 const GrowableObjectArray& cloned_funcs =
2190 GrowableObjectArray::Handle(zone, GrowableObjectArray::New()); 2206 GrowableObjectArray::Handle(zone, GrowableObjectArray::New());
2191 2207
2192 CreateForwardingConstructors(cls, mixin_cls, cloned_funcs);
2193
2194 Array& functions = Array::Handle(zone); 2208 Array& functions = Array::Handle(zone);
2195 Function& func = Function::Handle(zone); 2209 Function& func = Function::Handle(zone);
2210
2196 // The parser creates the mixin application class with no functions. 2211 // The parser creates the mixin application class with no functions.
2197 ASSERT((functions = cls.functions(), functions.Length() == 0)); 2212 // But the Kernel frontend will generate mixin classes with only
2213 // constructors inside them, which forward to the base class constructors.
2214 //
2215 // => We generate the constructors if they are not already there.
2216 functions = cls.functions();
2217 if (functions.Length() == 0) {
2218 CreateForwardingConstructors(cls, mixin_cls, cloned_funcs);
2219 } else {
2220 for (intptr_t i = 0; i < functions.Length(); i++) {
2221 func ^= functions.At(i);
2222 ASSERT(func.kernel_function() != 0);
2223 cloned_funcs.Add(func);
2224 }
2225 }
2226
2198 // Now clone the functions from the mixin class. 2227 // Now clone the functions from the mixin class.
2199 functions = mixin_cls.functions(); 2228 functions = mixin_cls.functions();
2200 const intptr_t num_functions = functions.Length(); 2229 const intptr_t num_functions = functions.Length();
2201 for (intptr_t i = 0; i < num_functions; i++) { 2230 for (intptr_t i = 0; i < num_functions; i++) {
2202 func ^= functions.At(i); 2231 func ^= functions.At(i);
2203 if (func.IsGenerativeConstructor()) { 2232 if (func.IsGenerativeConstructor()) {
2204 // A mixin class must not have explicit constructors. 2233 // A mixin class must not have explicit constructors.
2205 if (!func.IsImplicitConstructor()) { 2234 if (!func.IsImplicitConstructor()) {
2206 const Script& script = Script::Handle(cls.script()); 2235 const Script& script = Script::Handle(cls.script());
2207 const Error& error = Error::Handle(LanguageError::NewFormatted( 2236 const Error& error = Error::Handle(LanguageError::NewFormatted(
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after
2377 } else { 2406 } else {
2378 // This class should not contain any functions or user-defined fields yet, 2407 // This class should not contain any functions or user-defined fields yet,
2379 // because it has not been compiled yet. There may however be metadata 2408 // because it has not been compiled yet. There may however be metadata
2380 // fields because type parameters are parsed before the class body. Since 2409 // fields because type parameters are parsed before the class body. Since
2381 // 'ResolveAndFinalizeMemberTypes(cls)' has not been called yet, unfinalized 2410 // 'ResolveAndFinalizeMemberTypes(cls)' has not been called yet, unfinalized
2382 // member types could choke the snapshotter. 2411 // member types could choke the snapshotter.
2383 // Or 2412 // Or
2384 // if the class is being refinalized because a patch is being applied 2413 // if the class is being refinalized because a patch is being applied
2385 // after the class has been finalized then it is ok for the class to have 2414 // after the class has been finalized then it is ok for the class to have
2386 // functions. 2415 // functions.
2387 ASSERT((Array::Handle(cls.functions()).Length() == 0) || 2416 //
2388 cls.is_refinalize_after_patch()); 2417 // TODO(kmillikin): This ASSERT will fail when bootstrapping from Kernel
2418 // because classes are first created, methods are added, and then classes
2419 // are finalized. It is not easy to finalize classes earlier because not
2420 // all bootstrap classes have been created yet. It would be possible to
2421 // create all classes, delay adding methods, finalize the classes, and then
2422 // reprocess all classes to add methods, but that seems unnecessary.
2423 // Marking the bootstrap classes as is_refinalize_after_patch seems cute but
2424 // it causes other things to fail by violating their assumptions. Reenable
2425 // this ASSERT if it's important, remove it if it's just a sanity check and
2426 // not required for correctness.
2427 //
2428 // ASSERT((Array::Handle(cls.functions()).Length() == 0) ||
2429 // cls.is_refinalize_after_patch());
2389 } 2430 }
2390 } 2431 }
2391 2432
2392 2433
2393 void ClassFinalizer::FinalizeClass(const Class& cls) { 2434 void ClassFinalizer::FinalizeClass(const Class& cls) {
2394 Thread* thread = Thread::Current(); 2435 Thread* thread = Thread::Current();
2395 HANDLESCOPE(thread); 2436 HANDLESCOPE(thread);
2396 ASSERT(cls.is_type_finalized()); 2437 ASSERT(cls.is_type_finalized());
2397 if (cls.is_finalized()) { 2438 if (cls.is_finalized()) {
2398 return; 2439 return;
(...skipping 868 matching lines...) Expand 10 before | Expand all | Expand 10 after
3267 ASSERT(fields_array.Length() == ByteBuffer::NumberOfFields()); 3308 ASSERT(fields_array.Length() == ByteBuffer::NumberOfFields());
3268 field ^= fields_array.At(0); 3309 field ^= fields_array.At(0);
3269 ASSERT(field.Offset() == ByteBuffer::data_offset()); 3310 ASSERT(field.Offset() == ByteBuffer::data_offset());
3270 name ^= field.name(); 3311 name ^= field.name();
3271 expected_name ^= String::New("_data"); 3312 expected_name ^= String::New("_data");
3272 ASSERT(String::EqualsIgnoringPrivateKey(name, expected_name)); 3313 ASSERT(String::EqualsIgnoringPrivateKey(name, expected_name));
3273 #endif 3314 #endif
3274 } 3315 }
3275 3316
3276 } // namespace dart 3317 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698