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

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

Issue 2899323002: Heap::kNew-space allocations discovered by experimental code called transitively from parser
Patch Set: Created 3 years, 7 months 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
« no previous file with comments | « no previous file | runtime/vm/isolate_reload.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) 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/hash_table.h" 8 #include "vm/hash_table.h"
9 #include "vm/heap.h" 9 #include "vm/heap.h"
10 #include "vm/isolate.h" 10 #include "vm/isolate.h"
(...skipping 303 matching lines...) Expand 10 before | Expand all | Expand 10 after
314 } 314 }
315 315
316 316
317 void ClassFinalizer::ResolveRedirectingFactory(const Class& cls, 317 void ClassFinalizer::ResolveRedirectingFactory(const Class& cls,
318 const Function& factory) { 318 const Function& factory) {
319 const Function& target = Function::Handle(factory.RedirectionTarget()); 319 const Function& target = Function::Handle(factory.RedirectionTarget());
320 if (target.IsNull()) { 320 if (target.IsNull()) {
321 Type& type = Type::Handle(factory.RedirectionType()); 321 Type& type = Type::Handle(factory.RedirectionType());
322 if (!type.IsMalformed() && IsLoaded(type)) { 322 if (!type.IsMalformed() && IsLoaded(type)) {
323 const GrowableObjectArray& visited_factories = 323 const GrowableObjectArray& visited_factories =
324 GrowableObjectArray::Handle(GrowableObjectArray::New()); 324 GrowableObjectArray::Handle(GrowableObjectArray::New(Heap::kOld));
325 ResolveRedirectingFactoryTarget(cls, factory, visited_factories); 325 ResolveRedirectingFactoryTarget(cls, factory, visited_factories);
326 } 326 }
327 if (factory.is_const()) { 327 if (factory.is_const()) {
328 type = factory.RedirectionType(); 328 type = factory.RedirectionType();
329 if (type.IsMalformedOrMalbounded()) { 329 if (type.IsMalformedOrMalbounded()) {
330 ReportError(Error::Handle(type.error())); 330 ReportError(Error::Handle(type.error()));
331 } 331 }
332 } 332 }
333 } 333 }
334 } 334 }
335 335
336 336
337 void ClassFinalizer::ResolveRedirectingFactoryTarget( 337 void ClassFinalizer::ResolveRedirectingFactoryTarget(
338 const Class& cls, 338 const Class& cls,
339 const Function& factory, 339 const Function& factory,
340 const GrowableObjectArray& visited_factories) { 340 const GrowableObjectArray& visited_factories) {
341 ASSERT(factory.IsRedirectingFactory()); 341 ASSERT(factory.IsRedirectingFactory());
342 342
343 // Check for redirection cycle. 343 // Check for redirection cycle.
344 for (intptr_t i = 0; i < visited_factories.Length(); i++) { 344 for (intptr_t i = 0; i < visited_factories.Length(); i++) {
345 if (visited_factories.At(i) == factory.raw()) { 345 if (visited_factories.At(i) == factory.raw()) {
346 // A redirection cycle is reported as a compile-time error. 346 // A redirection cycle is reported as a compile-time error.
347 ReportError(cls, factory.token_pos(), 347 ReportError(cls, factory.token_pos(),
348 "factory '%s' illegally redirects to itself", 348 "factory '%s' illegally redirects to itself",
349 String::Handle(factory.name()).ToCString()); 349 String::Handle(factory.name()).ToCString());
350 } 350 }
351 } 351 }
352 visited_factories.Add(factory); 352 visited_factories.Add(factory, Heap::kOld);
353 353
354 // Check if target is already resolved. 354 // Check if target is already resolved.
355 Type& type = Type::Handle(factory.RedirectionType()); 355 Type& type = Type::Handle(factory.RedirectionType());
356 Function& target = Function::Handle(factory.RedirectionTarget()); 356 Function& target = Function::Handle(factory.RedirectionTarget());
357 if (type.IsMalformedOrMalbounded()) { 357 if (type.IsMalformedOrMalbounded()) {
358 // Already resolved to a malformed or malbounded type. Will throw on usage. 358 // Already resolved to a malformed or malbounded type. Will throw on usage.
359 ASSERT(target.IsNull()); 359 ASSERT(target.IsNull());
360 return; 360 return;
361 } 361 }
362 if (!target.IsNull()) { 362 if (!target.IsNull()) {
(...skipping 18 matching lines...) Expand all
381 type = NewFinalizedMalformedType(Error::Handle(), // No previous error. 381 type = NewFinalizedMalformedType(Error::Handle(), // No previous error.
382 Script::Handle(cls.script()), 382 Script::Handle(cls.script()),
383 factory.token_pos(), 383 factory.token_pos(),
384 "factory may not redirect to 'dynamic'"); 384 "factory may not redirect to 'dynamic'");
385 factory.SetRedirectionType(type); 385 factory.SetRedirectionType(type);
386 ASSERT(factory.RedirectionTarget() == Function::null()); 386 ASSERT(factory.RedirectionTarget() == Function::null());
387 return; 387 return;
388 } 388 }
389 const Class& target_class = Class::Handle(type.type_class()); 389 const Class& target_class = Class::Handle(type.type_class());
390 String& target_class_name = String::Handle(target_class.Name()); 390 String& target_class_name = String::Handle(target_class.Name());
391 String& target_name = 391 String& target_name = String::Handle(
392 String::Handle(String::Concat(target_class_name, Symbols::Dot())); 392 String::Concat(target_class_name, Symbols::Dot(), Heap::kOld));
393 const String& identifier = String::Handle(factory.RedirectionIdentifier()); 393 const String& identifier = String::Handle(factory.RedirectionIdentifier());
394 if (!identifier.IsNull()) { 394 if (!identifier.IsNull()) {
395 target_name = String::Concat(target_name, identifier); 395 target_name = String::Concat(target_name, identifier, Heap::kOld);
396 } 396 }
397 397
398 // Verify that the target constructor of the redirection exists. 398 // Verify that the target constructor of the redirection exists.
399 target = target_class.LookupConstructor(target_name); 399 target = target_class.LookupConstructor(target_name);
400 if (target.IsNull()) { 400 if (target.IsNull()) {
401 target = target_class.LookupFactory(target_name); 401 target = target_class.LookupFactory(target_name);
402 } 402 }
403 if (target.IsNull()) { 403 if (target.IsNull()) {
404 const String& user_visible_target_name = 404 const String& user_visible_target_name =
405 identifier.IsNull() ? target_class_name : target_name; 405 identifier.IsNull() ? target_class_name : target_name;
(...skipping 1892 matching lines...) Expand 10 before | Expand all | Expand 10 after
2298 const String& super_name = String::Handle(Z, super_class.Name()); 2298 const String& super_name = String::Handle(Z, super_class.Name());
2299 const Array& functions = Array::Handle(Z, super_class.functions()); 2299 const Array& functions = Array::Handle(Z, super_class.functions());
2300 const intptr_t num_functions = functions.Length(); 2300 const intptr_t num_functions = functions.Length();
2301 Function& func = Function::Handle(Z); 2301 Function& func = Function::Handle(Z);
2302 for (intptr_t i = 0; i < num_functions; i++) { 2302 for (intptr_t i = 0; i < num_functions; i++) {
2303 func ^= functions.At(i); 2303 func ^= functions.At(i);
2304 if (func.IsGenerativeConstructor()) { 2304 if (func.IsGenerativeConstructor()) {
2305 // Build constructor name from mixin application class name 2305 // Build constructor name from mixin application class name
2306 // and name of cloned super class constructor. 2306 // and name of cloned super class constructor.
2307 const String& ctor_name = String::Handle(Z, func.name()); 2307 const String& ctor_name = String::Handle(Z, func.name());
2308 String& clone_name = 2308 String& clone_name = String::Handle(
2309 String::Handle(Z, String::SubString(ctor_name, super_name.Length())); 2309 Z, String::SubString(ctor_name, super_name.Length(), Heap::kOld));
2310 clone_name = Symbols::FromConcat(T, mixin_name, clone_name); 2310 clone_name = Symbols::FromConcat(T, mixin_name, clone_name);
2311 2311
2312 if (FLAG_trace_class_finalization) { 2312 if (FLAG_trace_class_finalization) {
2313 THR_Print("Cloning constructor '%s' as '%s'\n", ctor_name.ToCString(), 2313 THR_Print("Cloning constructor '%s' as '%s'\n", ctor_name.ToCString(),
2314 clone_name.ToCString()); 2314 clone_name.ToCString());
2315 } 2315 }
2316 2316
2317 // The owner of the forwarding constructor is the mixin application 2317 // The owner of the forwarding constructor is the mixin application
2318 // class. The source is the mixin class. The source may be needed 2318 // class. The source is the mixin class. The source may be needed
2319 // to parse field initializer expressions in the mixin class. 2319 // to parse field initializer expressions in the mixin class.
(...skipping 13 matching lines...) Expand all
2333 clone.set_result_type(Object::dynamic_type()); 2333 clone.set_result_type(Object::dynamic_type());
2334 clone.set_is_debuggable(false); 2334 clone.set_is_debuggable(false);
2335 2335
2336 const intptr_t num_parameters = func.NumParameters(); 2336 const intptr_t num_parameters = func.NumParameters();
2337 // The cloned ctor shares the parameter names array with the 2337 // The cloned ctor shares the parameter names array with the
2338 // original. 2338 // original.
2339 const Array& parameter_names = Array::Handle(Z, func.parameter_names()); 2339 const Array& parameter_names = Array::Handle(Z, func.parameter_names());
2340 ASSERT(parameter_names.Length() == num_parameters); 2340 ASSERT(parameter_names.Length() == num_parameters);
2341 clone.set_parameter_names(parameter_names); 2341 clone.set_parameter_names(parameter_names);
2342 // The parameter types of the cloned constructor are 'dynamic'. 2342 // The parameter types of the cloned constructor are 'dynamic'.
2343 clone.set_parameter_types(Array::Handle(Z, Array::New(num_parameters))); 2343 clone.set_parameter_types(
2344 Array::Handle(Z, Array::New(num_parameters, Heap::kOld)));
2344 for (intptr_t n = 0; n < num_parameters; n++) { 2345 for (intptr_t n = 0; n < num_parameters; n++) {
2345 clone.SetParameterTypeAt(n, Object::dynamic_type()); 2346 clone.SetParameterTypeAt(n, Object::dynamic_type());
2346 } 2347 }
2347 cloned_funcs.Add(clone); 2348 cloned_funcs.Add(clone);
2348 } 2349 }
2349 } 2350 }
2350 } 2351 }
2351 2352
2352 2353
2353 void ClassFinalizer::ApplyMixinMembers(const Class& cls) { 2354 void ClassFinalizer::ApplyMixinMembers(const Class& cls) {
(...skipping 12 matching lines...) Expand all
2366 Class::Handle(zone, cls.SuperClass()).IsMixinApplication()); 2367 Class::Handle(zone, cls.SuperClass()).IsMixinApplication());
2367 // A default constructor will be created for the mixin app alias class. 2368 // A default constructor will be created for the mixin app alias class.
2368 2369
2369 if (FLAG_trace_class_finalization) { 2370 if (FLAG_trace_class_finalization) {
2370 THR_Print("Applying mixin members of %s to %s at pos %s\n", 2371 THR_Print("Applying mixin members of %s to %s at pos %s\n",
2371 mixin_cls.ToCString(), cls.ToCString(), 2372 mixin_cls.ToCString(), cls.ToCString(),
2372 cls.token_pos().ToCString()); 2373 cls.token_pos().ToCString());
2373 } 2374 }
2374 2375
2375 const GrowableObjectArray& cloned_funcs = 2376 const GrowableObjectArray& cloned_funcs =
2376 GrowableObjectArray::Handle(zone, GrowableObjectArray::New()); 2377 GrowableObjectArray::Handle(zone, GrowableObjectArray::New(Heap::kOld));
2377 2378
2378 Array& functions = Array::Handle(zone); 2379 Array& functions = Array::Handle(zone);
2379 Function& func = Function::Handle(zone); 2380 Function& func = Function::Handle(zone);
2380 2381
2381 // The parser creates the mixin application class with no functions. 2382 // The parser creates the mixin application class with no functions.
2382 // But the Kernel frontend will generate mixin classes with only 2383 // But the Kernel frontend will generate mixin classes with only
2383 // constructors inside them, which forward to the base class constructors. 2384 // constructors inside them, which forward to the base class constructors.
2384 // 2385 //
2385 // => We generate the constructors if they are not already there. 2386 // => We generate the constructors if they are not already there.
2386 functions = cls.functions(); 2387 functions = cls.functions();
(...skipping 11 matching lines...) Expand all
2398 functions = mixin_cls.functions(); 2399 functions = mixin_cls.functions();
2399 const intptr_t num_functions = functions.Length(); 2400 const intptr_t num_functions = functions.Length();
2400 for (intptr_t i = 0; i < num_functions; i++) { 2401 for (intptr_t i = 0; i < num_functions; i++) {
2401 func ^= functions.At(i); 2402 func ^= functions.At(i);
2402 if (func.IsGenerativeConstructor()) { 2403 if (func.IsGenerativeConstructor()) {
2403 // A mixin class must not have explicit constructors. 2404 // A mixin class must not have explicit constructors.
2404 if (!func.IsImplicitConstructor()) { 2405 if (!func.IsImplicitConstructor()) {
2405 const Script& script = Script::Handle(cls.script()); 2406 const Script& script = Script::Handle(cls.script());
2406 const Error& error = Error::Handle(LanguageError::NewFormatted( 2407 const Error& error = Error::Handle(LanguageError::NewFormatted(
2407 Error::Handle(), script, func.token_pos(), Report::AtLocation, 2408 Error::Handle(), script, func.token_pos(), Report::AtLocation,
2408 Report::kError, Heap::kNew, 2409 Report::kError, Heap::kOld,
2409 "constructor '%s' is illegal in mixin class %s", 2410 "constructor '%s' is illegal in mixin class %s",
2410 String::Handle(func.UserVisibleName()).ToCString(), 2411 String::Handle(func.UserVisibleName()).ToCString(),
2411 String::Handle(zone, mixin_cls.Name()).ToCString())); 2412 String::Handle(zone, mixin_cls.Name()).ToCString()));
2412 2413
2413 ReportErrors(error, cls, cls.token_pos(), 2414 ReportErrors(error, cls, cls.token_pos(),
2414 "mixin class '%s' must not have constructors", 2415 "mixin class '%s' must not have constructors",
2415 String::Handle(zone, mixin_cls.Name()).ToCString()); 2416 String::Handle(zone, mixin_cls.Name()).ToCString());
2416 } 2417 }
2417 continue; // Skip the implicit constructor. 2418 continue; // Skip the implicit constructor.
2418 } 2419 }
2419 if (!func.is_static() && !func.IsMethodExtractor() && 2420 if (!func.is_static() && !func.IsMethodExtractor() &&
2420 !func.IsNoSuchMethodDispatcher() && !func.IsInvokeFieldDispatcher()) { 2421 !func.IsNoSuchMethodDispatcher() && !func.IsInvokeFieldDispatcher()) {
2421 func = func.Clone(cls); 2422 func = func.Clone(cls);
2422 cloned_funcs.Add(func); 2423 cloned_funcs.Add(func, Heap::kOld);
2423 } 2424 }
2424 } 2425 }
2425 functions = Array::MakeArray(cloned_funcs); 2426 functions = Array::MakeArray(cloned_funcs);
2426 cls.SetFunctions(functions); 2427 cls.SetFunctions(functions);
2427 2428
2428 // Now clone the fields from the mixin class. There should be no 2429 // Now clone the fields from the mixin class. There should be no
2429 // existing fields in the mixin application class. 2430 // existing fields in the mixin application class.
2430 ASSERT(Array::Handle(cls.fields()).Length() == 0); 2431 ASSERT(Array::Handle(cls.fields()).Length() == 0);
2431 const Array& fields = Array::Handle(zone, mixin_cls.fields()); 2432 const Array& fields = Array::Handle(zone, mixin_cls.fields());
2432 const intptr_t num_fields = fields.Length(); 2433 const intptr_t num_fields = fields.Length();
(...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after
2643 // This has to happen before the check whether the methods of 2644 // This has to happen before the check whether the methods of
2644 // the class conflict with inherited methods. 2645 // the class conflict with inherited methods.
2645 ApplyMixinMembers(cls); 2646 ApplyMixinMembers(cls);
2646 } 2647 }
2647 // Mark as parsed and finalized. 2648 // Mark as parsed and finalized.
2648 cls.Finalize(); 2649 cls.Finalize();
2649 // Mixin app alias classes may still lack their forwarding constructor. 2650 // Mixin app alias classes may still lack their forwarding constructor.
2650 if (cls.is_mixin_app_alias() && 2651 if (cls.is_mixin_app_alias() &&
2651 (cls.functions() == Object::empty_array().raw())) { 2652 (cls.functions() == Object::empty_array().raw())) {
2652 const GrowableObjectArray& cloned_funcs = 2653 const GrowableObjectArray& cloned_funcs =
2653 GrowableObjectArray::Handle(GrowableObjectArray::New()); 2654 GrowableObjectArray::Handle(GrowableObjectArray::New(Heap::kOld));
2654 2655
2655 const Class& mixin_app_class = Class::Handle(cls.SuperClass()); 2656 const Class& mixin_app_class = Class::Handle(cls.SuperClass());
2656 const Type& mixin_type = Type::Handle(mixin_app_class.mixin()); 2657 const Type& mixin_type = Type::Handle(mixin_app_class.mixin());
2657 const Class& mixin_cls = Class::Handle(mixin_type.type_class()); 2658 const Class& mixin_cls = Class::Handle(mixin_type.type_class());
2658 2659
2659 CreateForwardingConstructors(cls, mixin_cls, cloned_funcs); 2660 CreateForwardingConstructors(cls, mixin_cls, cloned_funcs);
2660 const Array& functions = Array::Handle(Array::MakeArray(cloned_funcs)); 2661 const Array& functions = Array::Handle(Array::MakeArray(cloned_funcs));
2661 cls.SetFunctions(functions); 2662 cls.SetFunctions(functions);
2662 } 2663 }
2663 // Every class should have at least a constructor, unless it is a top level 2664 // Every class should have at least a constructor, unless it is a top level
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
2699 zone, enum_cls.LookupInstanceFieldAllowPrivate(Symbols::_name())); 2700 zone, enum_cls.LookupInstanceFieldAllowPrivate(Symbols::_name()));
2700 ASSERT(!name_field.IsNull()); 2701 ASSERT(!name_field.IsNull());
2701 const Field& values_field = 2702 const Field& values_field =
2702 Field::Handle(zone, enum_cls.LookupStaticField(Symbols::Values())); 2703 Field::Handle(zone, enum_cls.LookupStaticField(Symbols::Values()));
2703 ASSERT(!values_field.IsNull()); 2704 ASSERT(!values_field.IsNull());
2704 ASSERT(Instance::Handle(zone, values_field.StaticValue()).IsArray()); 2705 ASSERT(Instance::Handle(zone, values_field.StaticValue()).IsArray());
2705 Array& values_list = 2706 Array& values_list =
2706 Array::Handle(zone, Array::RawCast(values_field.StaticValue())); 2707 Array::Handle(zone, Array::RawCast(values_field.StaticValue()));
2707 const String& enum_name = String::Handle(enum_cls.ScrubbedName()); 2708 const String& enum_name = String::Handle(enum_cls.ScrubbedName());
2708 const String& name_prefix = 2709 const String& name_prefix =
2709 String::Handle(String::Concat(enum_name, Symbols::Dot())); 2710 String::Handle(String::Concat(enum_name, Symbols::Dot(), Heap::kOld));
2710 2711
2711 Field& field = Field::Handle(zone); 2712 Field& field = Field::Handle(zone);
2712 Instance& ordinal_value = Instance::Handle(zone); 2713 Instance& ordinal_value = Instance::Handle(zone);
2713 Instance& enum_value = Instance::Handle(zone); 2714 Instance& enum_value = Instance::Handle(zone);
2714 2715
2715 String& enum_ident = String::Handle(); 2716 String& enum_ident = String::Handle();
2716 2717
2717 enum_ident = 2718 enum_ident =
2718 Symbols::FromConcat(thread, Symbols::_DeletedEnumPrefix(), enum_name); 2719 Symbols::FromConcat(thread, Symbols::_DeletedEnumPrefix(), enum_name);
2719 enum_value = Instance::New(enum_cls, Heap::kOld); 2720 enum_value = Instance::New(enum_cls, Heap::kOld);
(...skipping 1080 matching lines...) Expand 10 before | Expand all | Expand 10 after
3800 ProgramVisitor::VisitFunctions(&function_visitor); 3801 ProgramVisitor::VisitFunctions(&function_visitor);
3801 3802
3802 class ClearCodeClassVisitor : public ClassVisitor { 3803 class ClearCodeClassVisitor : public ClassVisitor {
3803 void Visit(const Class& cls) { cls.DisableAllocationStub(); } 3804 void Visit(const Class& cls) { cls.DisableAllocationStub(); }
3804 }; 3805 };
3805 ClearCodeClassVisitor class_visitor; 3806 ClearCodeClassVisitor class_visitor;
3806 ProgramVisitor::VisitClasses(&class_visitor); 3807 ProgramVisitor::VisitClasses(&class_visitor);
3807 } 3808 }
3808 3809
3809 } // namespace dart 3810 } // namespace dart
OLDNEW
« no previous file with comments | « no previous file | runtime/vm/isolate_reload.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698