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

Unified 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, 11 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/class_finalizer.cc
===================================================================
--- runtime/vm/class_finalizer.cc (revision 32126)
+++ runtime/vm/class_finalizer.cc (working copy)
@@ -1423,17 +1423,35 @@
// cloning.
bool has_uninstantiated_bounds = false;
if ((num_super_type_params + num_mixin_type_params) > 0) {
- // First, clone the super class type parameters. Rename them so that
- // there can be no name conflict between the parameters of the super
- // class and the mixin class.
+ // If the last ampersand in the name of the mixin application class is
+ // doubled, the same type parameters can propagate the type arguments to
+ // the super type and to the mixin type.
+ bool share_type_params = false;
+ if (num_super_type_params == num_mixin_type_params) {
+ const String& name = String::Handle(isolate, mixin_app_class.Name());
+ 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.
+ if (name.CharAt(i) == '&') {
+ if (name.CharAt(i - 1) == '&') {
+ share_type_params = true;
+ }
+ break;
+ }
+ }
+ }
+
const TypeArguments& cloned_type_params = TypeArguments::Handle(isolate,
- TypeArguments::New(num_super_type_params + num_mixin_type_params));
+ TypeArguments::New((share_type_params ? 0 : num_super_type_params) +
+ num_mixin_type_params));
TypeParameter& param = TypeParameter::Handle(isolate);
TypeParameter& cloned_param = TypeParameter::Handle(isolate);
String& param_name = String::Handle(isolate);
AbstractType& param_bound = AbstractType::Handle(isolate);
intptr_t cloned_index = 0;
- if (num_super_type_params > 0) {
+
+ // First, clone the super class type parameters. Rename them so that
+ // there can be no name conflict between the parameters of the super
+ // class and the mixin class.
+ if (!share_type_params && (num_super_type_params > 0)) {
const TypeArguments& super_type_params =
TypeArguments::Handle(isolate, super_class.type_parameters());
const TypeArguments& super_type_args = TypeArguments::Handle(isolate,
@@ -1523,6 +1541,10 @@
// single interface type.
ASSERT(!mixin_type.IsFinalized());
mixin_type.set_arguments(mixin_type_args);
+ if (share_type_params) {
+ Type::Cast(super_type).set_arguments(mixin_type_args);
+ ASSERT(!super_type.IsFinalized());
+ }
}
mixin_app_class.set_type_parameters(cloned_type_params);
}
@@ -2377,6 +2399,8 @@
Class& mixin_app_class = Class::Handle();
String& mixin_app_class_name = String::Handle();
String& mixin_type_class_name = String::Handle();
+ AbstractType& super_type_arg = AbstractType::Handle();
+ AbstractType& mixin_type_arg = AbstractType::Handle();
const intptr_t depth = mixin_app_type.Depth();
for (intptr_t i = 0; i < depth; i++) {
mixin_type = mixin_app_type.MixinTypeAt(i);
@@ -2384,13 +2408,42 @@
ResolveType(cls, mixin_type);
ASSERT(mixin_type.HasResolvedTypeClass()); // Even if malformed.
ASSERT(mixin_type.IsType());
+ const intptr_t num_super_type_args = type_args.Length();
CollectTypeArguments(cls, Type::Cast(mixin_type), type_args);
+ // If the mixin type has identical type arguments as the super type, they
+ // can share the same type parameters of the mixin application class,
+ // thereby allowing for further optimizations, such as instantiator vector
+ // reuse or sharing of type arguments with the super class.
+ bool share_type_params = (num_super_type_args > 0) &&
+ (type_args.Length() == 2*num_super_type_args);
+ if (share_type_params) {
+ for (intptr_t i = 0; i < num_super_type_args; i++) {
+ super_type_arg ^= type_args.At(i);
+ mixin_type_arg ^= type_args.At(num_super_type_args + i);
+ if (!super_type_arg.Equals(mixin_type_arg)) {
+ share_type_params = false;
+ break;
+ }
+ }
+ if (share_type_params) {
+ // Cut the type argument vector in half.
+ type_args.SetLength(num_super_type_args);
+ }
+ }
+
// The name of the mixin application class is a combination of
// the super class name and mixin class name.
mixin_app_class_name = mixin_super_type.ClassName();
mixin_app_class_name = String::Concat(mixin_app_class_name,
Symbols::Ampersand());
+ // If the type parameters are shared between the super type and the mixin
+ // type, use two ampersand symbols, so that the class has a different name
+ // and is not reused in a context where this optimization is not possible.
+ if (share_type_params) {
+ mixin_app_class_name = String::Concat(mixin_app_class_name,
+ Symbols::Ampersand());
+ }
mixin_type_class_name = mixin_type.ClassName();
mixin_app_class_name = String::Concat(mixin_app_class_name,
mixin_type_class_name);
« 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