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

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

Issue 149723002: Share the same type parameters of a mixin application class to propagate (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 6 years, 10 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 | Annotate | Revision Log
« no previous file with comments | « no previous file | no next file » | 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/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 1405 matching lines...) Expand 10 before | Expand all | Expand 10 after
1416 const Array& interfaces = Array::Handle(isolate, Array::New(1)); 1416 const Array& interfaces = Array::Handle(isolate, Array::New(1));
1417 interfaces.SetAt(0, mixin_type); 1417 interfaces.SetAt(0, mixin_type);
1418 ASSERT(mixin_app_class.interfaces() == Object::empty_array().raw()); 1418 ASSERT(mixin_app_class.interfaces() == Object::empty_array().raw());
1419 mixin_app_class.set_interfaces(interfaces); 1419 mixin_app_class.set_interfaces(interfaces);
1420 1420
1421 // If both the super type and the mixin type are non generic, the mixin 1421 // If both the super type and the mixin type are non generic, the mixin
1422 // application class is non generic as well and we can skip type parameter 1422 // application class is non generic as well and we can skip type parameter
1423 // cloning. 1423 // cloning.
1424 bool has_uninstantiated_bounds = false; 1424 bool has_uninstantiated_bounds = false;
1425 if ((num_super_type_params + num_mixin_type_params) > 0) { 1425 if ((num_super_type_params + num_mixin_type_params) > 0) {
1426 // First, clone the super class type parameters. Rename them so that 1426 // If the last ampersand in the name of the mixin application class is
1427 // there can be no name conflict between the parameters of the super 1427 // doubled, the same type parameters can propagate the type arguments to
1428 // class and the mixin class. 1428 // the super type and to the mixin type.
1429 bool share_type_params = false;
1430 if (num_super_type_params == num_mixin_type_params) {
1431 const String& name = String::Handle(isolate, mixin_app_class.Name());
1432 for (intptr_t i = name.Length(); --i > 0; ) {
srdjan 2014/01/29 20:33:27 Why that form? Wouldn't this be simpler to read: f
regis 2014/01/29 21:10:34 Done.
1433 if (name.CharAt(i) == '&') {
1434 if (name.CharAt(i - 1) == '&') {
1435 share_type_params = true;
1436 }
1437 break;
1438 }
1439 }
1440 }
1441
1429 const TypeArguments& cloned_type_params = TypeArguments::Handle(isolate, 1442 const TypeArguments& cloned_type_params = TypeArguments::Handle(isolate,
1430 TypeArguments::New(num_super_type_params + num_mixin_type_params)); 1443 TypeArguments::New((share_type_params ? 0 : num_super_type_params) +
1444 num_mixin_type_params));
1431 TypeParameter& param = TypeParameter::Handle(isolate); 1445 TypeParameter& param = TypeParameter::Handle(isolate);
1432 TypeParameter& cloned_param = TypeParameter::Handle(isolate); 1446 TypeParameter& cloned_param = TypeParameter::Handle(isolate);
1433 String& param_name = String::Handle(isolate); 1447 String& param_name = String::Handle(isolate);
1434 AbstractType& param_bound = AbstractType::Handle(isolate); 1448 AbstractType& param_bound = AbstractType::Handle(isolate);
1435 intptr_t cloned_index = 0; 1449 intptr_t cloned_index = 0;
1436 if (num_super_type_params > 0) { 1450
1451 // First, clone the super class type parameters. Rename them so that
1452 // there can be no name conflict between the parameters of the super
1453 // class and the mixin class.
1454 if (!share_type_params && (num_super_type_params > 0)) {
1437 const TypeArguments& super_type_params = 1455 const TypeArguments& super_type_params =
1438 TypeArguments::Handle(isolate, super_class.type_parameters()); 1456 TypeArguments::Handle(isolate, super_class.type_parameters());
1439 const TypeArguments& super_type_args = TypeArguments::Handle(isolate, 1457 const TypeArguments& super_type_args = TypeArguments::Handle(isolate,
1440 TypeArguments::New(num_super_type_params)); 1458 TypeArguments::New(num_super_type_params));
1441 // The cloned super class type parameters do not need to repeat their 1459 // The cloned super class type parameters do not need to repeat their
1442 // bounds, since the bound checks will be performed at the super class 1460 // bounds, since the bound checks will be performed at the super class
1443 // level. 1461 // level.
1444 param_bound = isolate->object_store()->object_type(); 1462 param_bound = isolate->object_store()->object_type();
1445 for (intptr_t i = 0; i < num_super_type_params; i++) { 1463 for (intptr_t i = 0; i < num_super_type_params; i++) {
1446 param ^= super_type_params.TypeAt(i); 1464 param ^= super_type_params.TypeAt(i);
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
1516 ASSERT(!param_bound.IsInstantiated()); 1534 ASSERT(!param_bound.IsInstantiated());
1517 param.set_bound(param_bound); 1535 param.set_bound(param_bound);
1518 } 1536 }
1519 } 1537 }
1520 } 1538 }
1521 1539
1522 // Lastly, set the type arguments of the mixin type, which is also the 1540 // Lastly, set the type arguments of the mixin type, which is also the
1523 // single interface type. 1541 // single interface type.
1524 ASSERT(!mixin_type.IsFinalized()); 1542 ASSERT(!mixin_type.IsFinalized());
1525 mixin_type.set_arguments(mixin_type_args); 1543 mixin_type.set_arguments(mixin_type_args);
1544 if (share_type_params) {
1545 Type::Cast(super_type).set_arguments(mixin_type_args);
1546 ASSERT(!super_type.IsFinalized());
1547 }
1526 } 1548 }
1527 mixin_app_class.set_type_parameters(cloned_type_params); 1549 mixin_app_class.set_type_parameters(cloned_type_params);
1528 } 1550 }
1529 // If the mixin class is a mixin application alias class, we insert a new 1551 // If the mixin class is a mixin application alias class, we insert a new
1530 // synthesized mixin application class in the super chain of this mixin 1552 // synthesized mixin application class in the super chain of this mixin
1531 // application class. The new class will have the aliased mixin as actual 1553 // application class. The new class will have the aliased mixin as actual
1532 // mixin. 1554 // mixin.
1533 if (mixin_class.is_mixin_app_alias()) { 1555 if (mixin_class.is_mixin_app_alias()) {
1534 ApplyMixinAppAlias(mixin_app_class, has_uninstantiated_bounds); 1556 ApplyMixinAppAlias(mixin_app_class, has_uninstantiated_bounds);
1535 } 1557 }
(...skipping 834 matching lines...) Expand 10 before | Expand all | Expand 10 after
2370 ASSERT(mixin_super_type.HasResolvedTypeClass()); // Even if malformed. 2392 ASSERT(mixin_super_type.HasResolvedTypeClass()); // Even if malformed.
2371 // The super type may have a BoundedType as type argument, but cannot be 2393 // The super type may have a BoundedType as type argument, but cannot be
2372 // a BoundedType itself. 2394 // a BoundedType itself.
2373 CollectTypeArguments(cls, Type::Cast(mixin_super_type), type_args); 2395 CollectTypeArguments(cls, Type::Cast(mixin_super_type), type_args);
2374 AbstractType& mixin_type = AbstractType::Handle(); 2396 AbstractType& mixin_type = AbstractType::Handle();
2375 Type& generic_mixin_type = Type::Handle(); 2397 Type& generic_mixin_type = Type::Handle();
2376 Class& mixin_type_class = Class::Handle(); 2398 Class& mixin_type_class = Class::Handle();
2377 Class& mixin_app_class = Class::Handle(); 2399 Class& mixin_app_class = Class::Handle();
2378 String& mixin_app_class_name = String::Handle(); 2400 String& mixin_app_class_name = String::Handle();
2379 String& mixin_type_class_name = String::Handle(); 2401 String& mixin_type_class_name = String::Handle();
2402 AbstractType& super_type_arg = AbstractType::Handle();
2403 AbstractType& mixin_type_arg = AbstractType::Handle();
2380 const intptr_t depth = mixin_app_type.Depth(); 2404 const intptr_t depth = mixin_app_type.Depth();
2381 for (intptr_t i = 0; i < depth; i++) { 2405 for (intptr_t i = 0; i < depth; i++) {
2382 mixin_type = mixin_app_type.MixinTypeAt(i); 2406 mixin_type = mixin_app_type.MixinTypeAt(i);
2383 ASSERT(!mixin_type.IsNull()); 2407 ASSERT(!mixin_type.IsNull());
2384 ResolveType(cls, mixin_type); 2408 ResolveType(cls, mixin_type);
2385 ASSERT(mixin_type.HasResolvedTypeClass()); // Even if malformed. 2409 ASSERT(mixin_type.HasResolvedTypeClass()); // Even if malformed.
2386 ASSERT(mixin_type.IsType()); 2410 ASSERT(mixin_type.IsType());
2411 const intptr_t num_super_type_args = type_args.Length();
2387 CollectTypeArguments(cls, Type::Cast(mixin_type), type_args); 2412 CollectTypeArguments(cls, Type::Cast(mixin_type), type_args);
2388 2413
2414 // If the mixin type has identical type arguments as the super type, they
2415 // can share the same type parameters of the mixin application class,
2416 // thereby allowing for further optimizations, such as instantiator vector
2417 // reuse or sharing of type arguments with the super class.
2418 bool share_type_params = (num_super_type_args > 0) &&
2419 (type_args.Length() == 2*num_super_type_args);
2420 if (share_type_params) {
2421 for (intptr_t i = 0; i < num_super_type_args; i++) {
2422 super_type_arg ^= type_args.At(i);
2423 mixin_type_arg ^= type_args.At(num_super_type_args + i);
2424 if (!super_type_arg.Equals(mixin_type_arg)) {
2425 share_type_params = false;
2426 break;
2427 }
2428 }
2429 if (share_type_params) {
2430 // Cut the type argument vector in half.
2431 type_args.SetLength(num_super_type_args);
2432 }
2433 }
2434
2389 // The name of the mixin application class is a combination of 2435 // The name of the mixin application class is a combination of
2390 // the super class name and mixin class name. 2436 // the super class name and mixin class name.
2391 mixin_app_class_name = mixin_super_type.ClassName(); 2437 mixin_app_class_name = mixin_super_type.ClassName();
2392 mixin_app_class_name = String::Concat(mixin_app_class_name, 2438 mixin_app_class_name = String::Concat(mixin_app_class_name,
2393 Symbols::Ampersand()); 2439 Symbols::Ampersand());
2440 // If the type parameters are shared between the super type and the mixin
2441 // type, use two ampersand symbols, so that the class has a different name
2442 // and is not reused in a context where this optimization is not possible.
2443 if (share_type_params) {
2444 mixin_app_class_name = String::Concat(mixin_app_class_name,
2445 Symbols::Ampersand());
2446 }
2394 mixin_type_class_name = mixin_type.ClassName(); 2447 mixin_type_class_name = mixin_type.ClassName();
2395 mixin_app_class_name = String::Concat(mixin_app_class_name, 2448 mixin_app_class_name = String::Concat(mixin_app_class_name,
2396 mixin_type_class_name); 2449 mixin_type_class_name);
2397 mixin_app_class = library.LookupLocalClass(mixin_app_class_name); 2450 mixin_app_class = library.LookupLocalClass(mixin_app_class_name);
2398 if (mixin_app_class.IsNull()) { 2451 if (mixin_app_class.IsNull()) {
2399 mixin_app_class_name = Symbols::New(mixin_app_class_name); 2452 mixin_app_class_name = Symbols::New(mixin_app_class_name);
2400 mixin_app_class = Class::New(mixin_app_class_name, 2453 mixin_app_class = Class::New(mixin_app_class_name,
2401 script, 2454 script,
2402 mixin_type.token_pos()); 2455 mixin_type.token_pos());
2403 mixin_app_class.set_super_type(mixin_super_type); 2456 mixin_app_class.set_super_type(mixin_super_type);
(...skipping 451 matching lines...) Expand 10 before | Expand all | Expand 10 after
2855 expected_name ^= String::New("_offset"); 2908 expected_name ^= String::New("_offset");
2856 ASSERT(String::EqualsIgnoringPrivateKey(name, expected_name)); 2909 ASSERT(String::EqualsIgnoringPrivateKey(name, expected_name));
2857 field ^= fields_array.At(2); 2910 field ^= fields_array.At(2);
2858 ASSERT(field.Offset() == TypedDataView::length_offset()); 2911 ASSERT(field.Offset() == TypedDataView::length_offset());
2859 name ^= field.name(); 2912 name ^= field.name();
2860 ASSERT(name.Equals("length")); 2913 ASSERT(name.Equals("length"));
2861 #endif 2914 #endif
2862 } 2915 }
2863 2916
2864 } // namespace dart 2917 } // namespace dart
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698