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

Unified Diff: pkg/compiler/lib/src/js_backend/type_variable_handler.dart

Issue 1086413002: dart2js: reify type variables as result of class enqueueing. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Rebased Created 5 years, 8 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 | « pkg/compiler/lib/src/js_backend/backend.dart ('k') | tests/compiler/dart2js/compiler_helper.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: pkg/compiler/lib/src/js_backend/type_variable_handler.dart
diff --git a/pkg/compiler/lib/src/js_backend/type_variable_handler.dart b/pkg/compiler/lib/src/js_backend/type_variable_handler.dart
index bf9a5f2fb0431b0c7f2f42aa7e2c9eb325d630ab..0658a5a01473417f130763a02e920743bdc57fae 100644
--- a/pkg/compiler/lib/src/js_backend/type_variable_handler.dart
+++ b/pkg/compiler/lib/src/js_backend/type_variable_handler.dart
@@ -8,60 +8,66 @@ part of js_backend;
* Handles construction of TypeVariable constants needed at runtime.
*/
class TypeVariableHandler {
- JavaScriptBackend backend;
- FunctionElement typeVariableConstructor;
- CompileTimeConstantEvaluator evaluator;
+ final Compiler _compiler;
+ FunctionElement _typeVariableConstructor;
+ CompileTimeConstantEvaluator _evaluator;
/**
- * Contains all instantiated classes that have type variables and are needed
- * for reflection.
+ * Set to 'true' on first encounter of a class with type variables.
*/
- List<ClassElement> typeVariableClasses = new List<ClassElement>();
+ bool _seenClassesWithTypeVariables = false;
/**
* Maps a class element to a list with indices that point to type variables
* constants for each of the class' type variables.
*/
- Map<ClassElement, List<int>> typeVariables =
+ Map<ClassElement, List<int>> _typeVariables =
new Map<ClassElement, List<int>>();
/**
* Maps a TypeVariableType to the index pointing to the constant representing
* the corresponding type variable at runtime.
*/
- Map<TypeVariableElement, int> typeVariableConstants =
+ Map<TypeVariableElement, int> _typeVariableConstants =
new Map<TypeVariableElement, int>();
- TypeVariableHandler(this.backend);
+ TypeVariableHandler(this._compiler);
- ClassElement get typeVariableClass => backend.typeVariableClass;
- CodeEmitterTask get task => backend.emitter;
- MetadataCollector get metadataCollector => task.metadataCollector;
- Compiler get compiler => backend.compiler;
+ ClassElement get _typeVariableClass => _backend.typeVariableClass;
+ CodeEmitterTask get _task => _backend.emitter;
+ MetadataCollector get _metadataCollector => _task.metadataCollector;
+ JavaScriptBackend get _backend => _compiler.backend;
- void registerClassWithTypeVariables(ClassElement cls) {
- if (typeVariableClasses != null) {
- typeVariableClasses.add(cls);
+ void registerClassWithTypeVariables(ClassElement cls, Enqueuer enqueuer,
+ Registry registry) {
+ if (enqueuer.isResolutionQueue) {
+ // On first encounter, we have to ensure that the support classes get
+ // resolved.
+ if (!_seenClassesWithTypeVariables) {
+ _backend.enqueueClass(
+ enqueuer, _typeVariableClass, registry);
+ _typeVariableClass.ensureResolved(_compiler);
+ Link constructors = _typeVariableClass.constructors;
+ if (constructors.isEmpty && constructors.tail.isEmpty) {
+ _compiler.internalError(_typeVariableClass,
+ "Class '$_typeVariableClass' should only have one constructor");
+ }
+ _typeVariableConstructor = _typeVariableClass.constructors.head;
+ _backend.enqueueInResolution(_typeVariableConstructor, registry);
+ enqueuer.registerInstantiatedType(_typeVariableClass.rawType,
+ registry);
+ enqueuer.registerStaticUse(_backend.getCreateRuntimeType());
+ _seenClassesWithTypeVariables = true;
+ }
+ } else {
+ if (_backend.isAccessibleByReflection(cls)) {
+ _processTypeVariablesOf(cls);
+ }
}
}
- void processTypeVariablesOf(ClassElement cls) {
- //TODO(zarah): Running through all the members is suboptimal. Change this
- // as part of marking elements for reflection.
- bool hasMemberNeededForReflection(ClassElement cls) {
- bool result = false;
- cls.implementation.forEachMember((ClassElement cls, Element member) {
- result = result || backend.referencedFromMirrorSystem(member);
- });
- return result;
- }
-
- if (!backend.referencedFromMirrorSystem(cls) &&
- !hasMemberNeededForReflection(cls)) {
- return;
- }
-
- InterfaceType typeVariableType = typeVariableClass.thisType;
+ void _processTypeVariablesOf(ClassElement cls) {
+ InterfaceType typeVariableType = _typeVariableClass.thisType;
List<int> constants = <int>[];
for (TypeVariableType currentTypeVariable in cls.typeVariables) {
@@ -74,12 +80,12 @@ class TypeVariableHandler {
}
ConstantExpression name = new PrimitiveConstantExpression(
- backend.constantSystem.createString(
+ _backend.constantSystem.createString(
new DartString.literal(currentTypeVariable.name)));
ConstantExpression bound = new PrimitiveConstantExpression(
- backend.constantSystem.createInt(
- metadataCollector.reifyType(typeVariableElement.bound)));
- ConstantExpression type = backend.constants.createTypeConstant(cls);
+ _backend.constantSystem.createInt(
+ _metadataCollector.reifyType(typeVariableElement.bound)));
+ ConstantExpression type = _backend.constants.createTypeConstant(cls);
List<AstConstant> arguments =
[wrapConstant(type), wrapConstant(name), wrapConstant(bound)];
@@ -87,45 +93,22 @@ class TypeVariableHandler {
// constructed constants.
AstConstant constant =
CompileTimeConstantEvaluator.makeConstructedConstant(
- compiler,
- backend.constants,
+ _compiler,
+ _backend.constants,
typeVariableElement,
typeVariableElement.node,
typeVariableType,
- typeVariableConstructor,
+ _typeVariableConstructor,
const CallStructure.unnamed(3),
arguments,
arguments);
ConstantValue value = constant.value;
- backend.registerCompileTimeConstant(value, compiler.globalDependencies);
- backend.constants.addCompileTimeConstantForEmission(value);
+ _backend.registerCompileTimeConstant(value, _compiler.globalDependencies);
+ _backend.constants.addCompileTimeConstantForEmission(value);
constants.add(
- reifyTypeVariableConstant(value, currentTypeVariable.element));
- }
- typeVariables[cls] = constants;
- }
-
- void onTreeShakingDisabled(Enqueuer enqueuer) {
- if (enqueuer.isResolutionQueue) {
- backend.enqueueClass(
- enqueuer, typeVariableClass, compiler.globalDependencies);
- typeVariableClass.ensureResolved(compiler);
- Link constructors = typeVariableClass.constructors;
- if (constructors.isEmpty && constructors.tail.isEmpty) {
- compiler.internalError(typeVariableClass,
- "Class '$typeVariableClass' should only have one constructor");
- }
- typeVariableConstructor = typeVariableClass.constructors.head;
- backend.enqueueInResolution(typeVariableConstructor,
- compiler.globalDependencies);
- enqueuer.registerInstantiatedType(typeVariableClass.rawType,
- compiler.globalDependencies);
- enqueuer.registerStaticUse(backend.getCreateRuntimeType());
- } else if (typeVariableClasses != null) {
- List<ClassElement> worklist = typeVariableClasses;
- typeVariableClasses = null;
- worklist.forEach((cls) => processTypeVariablesOf(cls));
+ _reifyTypeVariableConstant(value, currentTypeVariable.element));
}
+ _typeVariables[cls] = constants;
}
/**
@@ -136,16 +119,16 @@ class TypeVariableHandler {
* entry in the list has already been reserved and the constant is added
* there, otherwise a new entry for [c] is created.
*/
- int reifyTypeVariableConstant(ConstantValue c, TypeVariableElement variable) {
- String name = jsAst.prettyPrint(task.constantReference(c),
- compiler).getText();
+ int _reifyTypeVariableConstant(ConstantValue c, TypeVariableElement variable) {
+ String name = jsAst.prettyPrint(_task.constantReference(c),
+ _compiler).getText();
int index;
- if (typeVariableConstants.containsKey(variable)) {
- index = typeVariableConstants[variable];
- metadataCollector.globalMetadata[index] = name;
+ if (_typeVariableConstants.containsKey(variable)) {
+ index = _typeVariableConstants[variable];
+ _metadataCollector.globalMetadata[index] = name;
} else {
- index = metadataCollector.addGlobalMetadata(name);
- typeVariableConstants[variable] = index;
+ index = _metadataCollector.addGlobalMetadata(name);
+ _typeVariableConstants[variable] = index;
}
return index;
}
@@ -161,18 +144,18 @@ class TypeVariableHandler {
* on the allocated entry.
*/
int reifyTypeVariable(TypeVariableElement variable) {
- if (typeVariableConstants.containsKey(variable)) {
- return typeVariableConstants[variable];
+ if (_typeVariableConstants.containsKey(variable)) {
+ return _typeVariableConstants[variable];
}
// TODO(15613): Remove quotes.
- metadataCollector.globalMetadata.add('"Placeholder for ${variable}"');
- return typeVariableConstants[variable] =
- metadataCollector.globalMetadata.length - 1;
+ _metadataCollector.globalMetadata.add('"Placeholder for ${variable}"');
+ return _typeVariableConstants[variable] =
+ _metadataCollector.globalMetadata.length - 1;
}
List<int> typeVariablesOf(ClassElement classElement) {
- List<int> result = typeVariables[classElement];
+ List<int> result = _typeVariables[classElement];
if (result == null) {
result = const <int>[];
}
« no previous file with comments | « pkg/compiler/lib/src/js_backend/backend.dart ('k') | tests/compiler/dart2js/compiler_helper.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698