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

Unified Diff: sdk/lib/_internal/compiler/implementation/js_backend/backend.dart

Issue 16077015: Rip-off the backend type inferrer. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 6 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 | sdk/lib/_internal/compiler/implementation/ssa/builder.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: sdk/lib/_internal/compiler/implementation/js_backend/backend.dart
===================================================================
--- sdk/lib/_internal/compiler/implementation/js_backend/backend.dart (revision 23797)
+++ sdk/lib/_internal/compiler/implementation/js_backend/backend.dart (working copy)
@@ -4,607 +4,6 @@
part of js_backend;
-typedef void Recompile(Element element);
-
-class ReturnInfo {
- HType returnType;
- List<Element> compiledFunctions;
-
- ReturnInfo(HType this.returnType)
- : compiledFunctions = new List<Element>();
-
- ReturnInfo.unknownType() : this(null);
-
- void update(HType type, Recompile recompile, Compiler compiler) {
- HType newType =
- returnType != null ? returnType.union(type, compiler) : type;
- if (newType != returnType) {
- if (returnType == null && identical(newType, HType.UNKNOWN)) {
- // If the first actual piece of information is not providing any type
- // information there is no need to recompile callers.
- compiledFunctions.clear();
- }
- returnType = newType;
- if (recompile != null) {
- compiledFunctions.forEach(recompile);
- }
- compiledFunctions.clear();
- }
- }
-
- // Note that lazy initializers are treated like functions (but are not
- // of type [FunctionElement].
- addCompiledFunction(Element function) => compiledFunctions.add(function);
-}
-
-class OptionalParameterTypes {
- final List<SourceString> names;
- final List<HType> types;
-
- OptionalParameterTypes(int optionalArgumentsCount)
- : names = new List<SourceString>(optionalArgumentsCount),
- types = new List<HType>(optionalArgumentsCount);
-
- int get length => names.length;
- SourceString name(int index) => names[index];
- HType type(int index) => types[index];
- int indexOf(SourceString name) => names.indexOf(name);
-
- HType typeFor(SourceString name) {
- int index = indexOf(name);
- if (index == -1) return null;
- return type(index);
- }
-
- void update(int index, SourceString name, HType type) {
- names[index] = name;
- types[index] = type;
- }
-
- String toString() => "OptionalParameterTypes($names, $types)";
-}
-
-class HTypeList {
- final List<HType> types;
- final List<SourceString> namedArguments;
-
- HTypeList(int length)
- : types = new List<HType>(length),
- namedArguments = null;
- HTypeList.withNamedArguments(int length, this.namedArguments)
- : types = new List<HType>(length);
- const HTypeList.withAllUnknown()
- : types = null,
- namedArguments = null;
-
- factory HTypeList.fromStaticInvocation(HInvokeStatic node) {
- bool allUnknown = true;
- for (int i = 0; i < node.inputs.length; i++) {
- if (node.inputs[i].instructionType != HType.UNKNOWN) {
- allUnknown = false;
- break;
- }
- }
- if (allUnknown) return HTypeList.ALL_UNKNOWN;
-
- HTypeList result = new HTypeList(node.inputs.length);
- for (int i = 0; i < result.types.length; i++) {
- result.types[i] = node.inputs[i].instructionType;
- }
- return result;
- }
-
- factory HTypeList.fromDynamicInvocation(HInvoke node,
- Selector selector) {
- HTypeList result;
- int argumentsCount = node.inputs.length - 1;
- int startInvokeIndex = HInvoke.ARGUMENTS_OFFSET;
-
- if (node.isInterceptedCall) {
- argumentsCount--;
- startInvokeIndex++;
- }
-
- if (selector.namedArgumentCount > 0) {
- result =
- new HTypeList.withNamedArguments(
- argumentsCount, selector.namedArguments);
- } else {
- result = new HTypeList(argumentsCount);
- }
-
- for (int i = 0; i < result.types.length; i++) {
- result.types[i] = node.inputs[i + startInvokeIndex].instructionType;
- }
- return result;
- }
-
- static const HTypeList ALL_UNKNOWN = const HTypeList.withAllUnknown();
-
- bool get allUnknown => types == null;
- bool get hasNamedArguments => namedArguments != null;
- int get length => types.length;
- HType operator[](int index) => types[index];
- void operator[]=(int index, HType type) { types[index] = type; }
-
- HTypeList union(HTypeList other, Compiler compiler) {
- if (allUnknown) return this;
- if (other.allUnknown) return other;
- if (length != other.length) return HTypeList.ALL_UNKNOWN;
- bool onlyUnknown = true;
- HTypeList result = this;
- for (int i = 0; i < length; i++) {
- HType newType = this[i].union(other[i], compiler);
- if (result == this && newType != this[i]) {
- // Create a new argument types object with the matching types copied.
- result = new HTypeList(length);
- result.types.setRange(0, i, this.types);
- }
- if (result != this) {
- result.types[i] = newType;
- }
- if (result[i] != HType.UNKNOWN) onlyUnknown = false;
- }
- return onlyUnknown ? HTypeList.ALL_UNKNOWN : result;
- }
-
- HTypeList unionWithOptionalParameters(
- Selector selector,
- FunctionSignature signature,
- OptionalParameterTypes defaultValueTypes) {
- assert(allUnknown || selector.argumentCount == this.length);
- // Create a new HTypeList for holding types for all parameters.
- HTypeList result = new HTypeList(signature.parameterCount);
-
- // First fill in the type of the positional arguments.
- int nextTypeIndex = -1;
- if (allUnknown) {
- for (int i = 0; i < selector.positionalArgumentCount; i++) {
- result.types[i] = HType.UNKNOWN;
- }
- } else {
- result.types.setRange(0, selector.positionalArgumentCount, this.types);
- nextTypeIndex = selector.positionalArgumentCount;
- }
-
- // Next fill the type of the optional arguments.
- // As the selector can pass optional arguments positionally some of the
- // optional arguments might already have a type set. We only need to look
- // at the optional arguments not passed positionally.
- // The variable 'index' is counting the signatures optional arguments, the
- // variable 'next' is set to the next optional arguments to look at and
- // is used to skip some optional arguments.
- int next = selector.positionalArgumentCount;
- int index = signature.requiredParameterCount;
- signature.forEachOptionalParameter((Element element) {
- // If some optional parameters were passed positionally these have
- // already been filled.
- if (index == next) {
- assert(result.types[index] == null);
- HType type = null;
- if (hasNamedArguments &&
- selector.namedArguments.indexOf(element.name) >= 0) {
- type = types[nextTypeIndex++];
- } else {
- type = defaultValueTypes.typeFor(element.name);
- }
- result.types[index] = type;
- next++;
- }
- index++;
- });
- return result;
- }
-
- String toString() =>
- allUnknown ? "HTypeList.ALL_UNKNOWN" : "HTypeList $types";
-}
-
-class FieldTypesRegistry {
- final JavaScriptBackend backend;
-
- /**
- * For each class, [constructors] holds the set of constructors. If there is
- * more than one constructor for a class it is currently not possible to
- * infer the field types from construction, as the information collected does
- * not correlate the generative constructors and generative constructor
- * body/bodies.
- */
- final Map<ClassElement, Set<Element>> constructors;
-
- /**
- * The collected type information is stored in three maps. One for types
- * assigned in the initializer list(s) [fieldInitializerTypeMap], one for
- * types assigned in the constructor(s) [fieldConstructorTypeMap], and one
- * for types assigned in the rest of the code, where the field can be
- * resolved [fieldTypeMap].
- *
- * If a field has a type both from constructors and from the initializer
- * list(s), then the type from the constructor(s) will owerride the one from
- * the initializer list(s).
- *
- * Because the order in which generative constructors, generative constructor
- * bodies and normal method/function bodies are compiled is undefined, and
- * because they can all be recompiled, it is not possible to combine this
- * information into one map at the moment.
- */
- final Map<Element, HType> fieldInitializerTypeMap;
- final Map<Element, HType> fieldConstructorTypeMap;
- final Map<Element, HType> fieldTypeMap;
-
- /**
- * The set of current names setter selectors used. If a named selector is
- * used it is currently not possible to infer the type of the field.
- */
- final Set<SourceString> setterSelectorsUsed;
-
- final Map<Element, Set<Element>> optimizedStaticFunctions;
- final Map<Element, FunctionSet> optimizedFunctions;
-
- FieldTypesRegistry(JavaScriptBackend backend)
- : constructors = new Map<ClassElement, Set<Element>>(),
- fieldInitializerTypeMap = new Map<Element, HType>(),
- fieldConstructorTypeMap = new Map<Element, HType>(),
- fieldTypeMap = new Map<Element, HType>(),
- setterSelectorsUsed = new Set<SourceString>(),
- optimizedStaticFunctions = new Map<Element, Set<Element>>(),
- optimizedFunctions = new Map<Element, FunctionSet>(),
- this.backend = backend;
-
- Compiler get compiler => backend.compiler;
-
- void scheduleRecompilation(Element field) {
- Set optimizedStatics = optimizedStaticFunctions[field];
- if (optimizedStatics != null) {
- optimizedStatics.forEach(backend.scheduleForRecompilation);
- optimizedStaticFunctions.remove(field);
- }
- FunctionSet optimized = optimizedFunctions[field];
- if (optimized != null) {
- optimized.forEach(backend.scheduleForRecompilation);
- optimizedFunctions.remove(field);
- }
- }
-
- int constructorCount(Element element) {
- assert(element.isClass());
- Set<Element> ctors = constructors[element];
- return ctors == null ? 0 : ctors.length;
- }
-
- void registerFieldType(Map<Element, HType> typeMap,
- Element field,
- HType type) {
- assert(field.isField());
- HType before = optimisticFieldType(field);
-
- HType oldType = typeMap[field];
- HType newType;
-
- if (oldType != null) {
- newType = oldType.union(type, compiler);
- } else {
- newType = type;
- }
- typeMap[field] = newType;
- if (oldType != newType) {
- scheduleRecompilation(field);
- }
- }
-
- void registerConstructor(Element element) {
- assert(element.isGenerativeConstructor());
- Element cls = element.getEnclosingClass();
- constructors.putIfAbsent(cls, () => new Set<Element>());
- Set<Element> ctors = constructors[cls];
- if (ctors.contains(element)) return;
- ctors.add(element);
- // We cannot infer field types for classes with more than one constructor.
- // When the second constructor is seen, recompile all functions relying on
- // optimistic field types for that class.
- // TODO(sgjesse): Handle field types for classes with more than one
- // constructor.
- if (ctors.length == 2) {
- optimizedFunctions.keys.toList().forEach((Element field) {
- if (identical(field.enclosingElement, cls)) {
- scheduleRecompilation(field);
- }
- });
- }
- }
-
- void registerFieldInitializer(Element field, HType type) {
- registerFieldType(fieldInitializerTypeMap, field, type);
- }
-
- void registerFieldConstructor(Element field, HType type) {
- registerFieldType(fieldConstructorTypeMap, field, type);
- }
-
- void registerFieldSetter(Element element, Element field, HType type) {
- HType initializerType = fieldInitializerTypeMap[field];
- HType constructorType = fieldConstructorTypeMap[field];
- HType setterType = fieldTypeMap[field];
- if (type == HType.UNKNOWN
- && initializerType == null
- && constructorType == null
- && setterType == null) {
- // Don't register UNKNOWN if there is currently no type information
- // present for the field. Instead register the function holding the
- // setter for recompilation if better type information for the field
- // becomes available.
- registerOptimizedFunction(element, field, type);
- return;
- }
- registerFieldType(fieldTypeMap, field, type);
- }
-
- void addedDynamicSetter(Selector setter, HType type) {
- // Field type optimizations are disabled for all fields matching a
- // setter selector.
- assert(setter.isSetter());
- // TODO(sgjesse): Take the type of the setter into account.
- if (setterSelectorsUsed.contains(setter.name)) return;
- setterSelectorsUsed.add(setter.name);
- optimizedStaticFunctions.keys.toList().forEach((Element field) {
- if (field.name == setter.name) {
- scheduleRecompilation(field);
- }
- });
- optimizedFunctions.keys.toList().forEach((Element field) {
- if (field.name == setter.name) {
- scheduleRecompilation(field);
- }
- });
- }
-
- HType optimisticFieldType(Element field) {
- assert(field.isField());
- if (constructorCount(field.getEnclosingClass()) > 1) {
- return HType.UNKNOWN;
- }
- if (setterSelectorsUsed.contains(field.name)) {
- return HType.UNKNOWN;
- }
- HType initializerType = fieldInitializerTypeMap[field];
- HType constructorType = fieldConstructorTypeMap[field];
- if (initializerType == null && constructorType == null) {
- // If there are no constructor type information return UNKNOWN. This
- // ensures that the function will be recompiled if useful constructor
- // type information becomes available.
- return HType.UNKNOWN;
- }
- // A type set through the constructor overrides the type from the
- // initializer list.
- HType result = constructorType != null ? constructorType : initializerType;
- HType type = fieldTypeMap[field];
- if (type != null) result = result.union(type, compiler);
- return result;
- }
-
- void registerOptimizedFunction(Element element,
- Element field,
- HType type) {
- assert(field.isField());
- if (Elements.isStaticOrTopLevel(element)) {
- optimizedStaticFunctions.putIfAbsent(
- field, () => new Set<Element>());
- optimizedStaticFunctions[field].add(element);
- } else {
- optimizedFunctions.putIfAbsent(
- field, () => new FunctionSet(backend.compiler));
- optimizedFunctions[field].add(element);
- }
- }
-
- void dump() {
- Set<Element> allFields = new Set<Element>();
- fieldInitializerTypeMap.keys.forEach(allFields.add);
- fieldConstructorTypeMap.keys.forEach(allFields.add);
- fieldTypeMap.keys.forEach(allFields.add);
- allFields.forEach((Element field) {
- print("Inferred $field has type ${optimisticFieldType(field)}");
- });
- }
-}
-
-class ArgumentTypesRegistry {
- final JavaScriptBackend backend;
-
- /**
- * Documentation wanted -- johnniwinther
- *
- * Invariant: Keys must be declaration elements.
- */
- final Map<Element, HTypeList> staticTypeMap;
-
- /**
- * Documentation wanted -- johnniwinther
- *
- * Invariant: Elements must be declaration elements.
- */
- final Set<Element> optimizedStaticFunctions;
- final SelectorMap<HTypeList> selectorTypeMap;
- final FunctionSet optimizedFunctions;
-
- /**
- * Documentation wanted -- johnniwinther
- *
- * Invariant: Keys must be declaration elements.
- */
- final Map<Element, HTypeList> optimizedTypes;
- final Map<Element, OptionalParameterTypes> optimizedDefaultValueTypes;
-
- ArgumentTypesRegistry(JavaScriptBackend backend)
- : staticTypeMap = new Map<Element, HTypeList>(),
- optimizedStaticFunctions = new Set<Element>(),
- selectorTypeMap = new SelectorMap<HTypeList>(backend.compiler),
- optimizedFunctions = new FunctionSet(backend.compiler),
- optimizedTypes = new Map<Element, HTypeList>(),
- optimizedDefaultValueTypes =
- new Map<Element, OptionalParameterTypes>(),
- this.backend = backend;
-
- Compiler get compiler => backend.compiler;
-
- bool updateTypes(HTypeList oldTypes, HTypeList newTypes, var key, var map) {
- if (oldTypes.allUnknown) return false;
- newTypes = oldTypes.union(newTypes, backend.compiler);
- if (identical(newTypes, oldTypes)) return false;
- map[key] = newTypes;
- return true;
- }
-
- void registerStaticInvocation(HInvokeStatic node) {
- Element element = node.element;
- assert(invariant(node, element.isDeclaration));
- HTypeList oldTypes = staticTypeMap[element];
- HTypeList newTypes = new HTypeList.fromStaticInvocation(node);
- if (oldTypes == null) {
- staticTypeMap[element] = newTypes;
- } else if (updateTypes(oldTypes, newTypes, element, staticTypeMap)) {
- if (optimizedStaticFunctions.contains(element)) {
- backend.scheduleForRecompilation(element);
- }
- }
- }
-
- void registerNonCallStaticUse(HStatic node) {
- // When a static is used for anything else than a call target we cannot
- // infer anything about its parameter types.
- Element element = node.element;
- assert(invariant(node, element.isDeclaration));
- if (optimizedStaticFunctions.contains(element)) {
- backend.scheduleForRecompilation(element);
- }
- staticTypeMap[element] = HTypeList.ALL_UNKNOWN;
- }
-
- void registerDynamicInvocation(HTypeList providedTypes, Selector selector) {
- if (selector.isClosureCall()) {
- // We cannot use the current framework to do optimizations based
- // on the 'call' selector because we are also generating closure
- // calls during the emitter phase, which at this point, does not
- // track parameter types, nor invalidates optimized methods.
- return;
- }
- if (!selectorTypeMap.containsKey(selector)) {
- selectorTypeMap[selector] = providedTypes;
- } else {
- HTypeList oldTypes = selectorTypeMap[selector];
- updateTypes(oldTypes, providedTypes, selector, selectorTypeMap);
- }
-
- // If we're not compiling, we don't have to do anything.
- if (compiler.phase != Compiler.PHASE_COMPILING) return;
-
- // Run through all optimized functions and figure out if they need
- // to be recompiled because of this new invocation.
- for (Element element in optimizedFunctions.filter(selector)) {
- // TODO(kasperl): Maybe check if the element is already marked for
- // recompilation? Could be pretty cheap compared to computing
- // union types.
- HTypeList newTypes =
- parameterTypes(element, optimizedDefaultValueTypes[element]);
- bool recompile = false;
- if (newTypes.allUnknown) {
- recompile = true;
- } else {
- HTypeList oldTypes = optimizedTypes[element];
- assert(newTypes.length == oldTypes.length);
- for (int i = 0; i < oldTypes.length; i++) {
- if (newTypes[i] != oldTypes[i]) {
- recompile = true;
- break;
- }
- }
- }
- if (recompile) backend.scheduleForRecompilation(element);
- }
- }
-
- HTypeList parameterTypes(FunctionElement element,
- OptionalParameterTypes defaultValueTypes) {
- assert(invariant(element, element.isDeclaration));
- // Handle static functions separately.
- if (Elements.isStaticOrTopLevelFunction(element) ||
- element.kind == ElementKind.GENERATIVE_CONSTRUCTOR) {
- HTypeList types = staticTypeMap[element];
- if (types != null) {
- if (!optimizedStaticFunctions.contains(element)) {
- optimizedStaticFunctions.add(element);
- }
- return types;
- } else {
- return HTypeList.ALL_UNKNOWN;
- }
- }
-
- // Getters have no parameters.
- if (element.isGetter()) return HTypeList.ALL_UNKNOWN;
-
- // TODO(kasperl): What kind of non-members do we get here?
- if (!element.isMember()) return HTypeList.ALL_UNKNOWN;
-
- // If there are any getters for this method we cannot know anything about
- // the types of the provided parameters. Use resolverWorld for now as that
- // information does not change during compilation.
- // TODO(ngeoffray): These checks should use the codegenWorld and keep track
- // of changes to this information.
- if (compiler.resolverWorld.hasInvokedGetter(element, compiler)) {
- return HTypeList.ALL_UNKNOWN;
- }
-
- FunctionSignature signature = element.computeSignature(compiler);
- HTypeList found = null;
- selectorTypeMap.visitMatching(element,
- (Selector selector, HTypeList types) {
- if (selector.argumentCount != signature.parameterCount ||
- selector.namedArgumentCount > 0) {
- types = types.unionWithOptionalParameters(selector,
- signature,
- defaultValueTypes);
- }
- assert(types.allUnknown || types.length == signature.parameterCount);
- found = (found == null) ? types : found.union(types, compiler);
- return !found.allUnknown;
- });
- return found != null ? found : HTypeList.ALL_UNKNOWN;
- }
-
- void registerOptimizedFunction(Element element,
- HTypeList parameterTypes,
- OptionalParameterTypes defaultValueTypes) {
- if (Elements.isStaticOrTopLevelFunction(element)) {
- if (parameterTypes.allUnknown) {
- optimizedStaticFunctions.remove(element);
- } else {
- optimizedStaticFunctions.add(element);
- }
- }
-
- // TODO(kasperl): What kind of non-members do we get here?
- if (!element.isInstanceMember()) return;
-
- if (parameterTypes.allUnknown) {
- optimizedFunctions.remove(element);
- optimizedTypes.remove(element);
- optimizedDefaultValueTypes.remove(element);
- } else {
- optimizedFunctions.add(element);
- optimizedTypes[element] = parameterTypes;
- optimizedDefaultValueTypes[element] = defaultValueTypes;
- }
- }
-
- void dump() {
- optimizedFunctions.forEach((Element element) {
- HTypeList types = optimizedTypes[element];
- print("Inferred $element has argument types ${types.types}");
- });
- }
-}
-
class JavaScriptItemCompilationContext extends ItemCompilationContext {
final Set<HInstruction> boundsChecked;
@@ -691,18 +90,7 @@
*/
ClassElement jsIndexingBehaviorInterface;
- final Map<Element, ReturnInfo> returnInfo;
-
/**
- * Documentation wanted -- johnniwinther
- *
- * Invariant: Elements must be declaration elements.
- */
- final List<Element> invalidateAfterCodegen;
- ArgumentTypesRegistry argumentTypes;
- FieldTypesRegistry fieldTypes;
-
- /**
* A collection of selectors of intercepted method calls. The
* emitter uses this set to generate the [:ObjectInterceptor:] class
* whose members just forward the call to the intercepted receiver.
@@ -762,8 +150,6 @@
JavaScriptBackend(Compiler compiler, bool generateSourceMap, bool disableEval)
: namer = determineNamer(compiler),
- returnInfo = new Map<Element, ReturnInfo>(),
- invalidateAfterCodegen = new List<Element>(),
usedInterceptors = new Set<Selector>(),
oneShotInterceptors = new Map<String, Selector>(),
interceptedElements = new Map<SourceString, Set<Element>>(),
@@ -776,8 +162,6 @@
builder = new SsaBuilderTask(this);
optimizer = new SsaOptimizerTask(this);
generator = new SsaCodeGeneratorTask(this);
- argumentTypes = new ArgumentTypesRegistry(this);
- fieldTypes = new FieldTypesRegistry(this);
}
static Namer determineNamer(Compiler compiler) {
@@ -1052,23 +436,10 @@
}
}
- void initializeNoSuchMethod() {
- // In case the emitter generates noSuchMethod calls, we need to
- // make sure all [noSuchMethod] methods know they might take a
- // [JsInvocationMirror] as parameter.
- HTypeList types = new HTypeList(1);
- types[0] = new HType.nonNullExact(
- compiler.jsInvocationMirrorClass.computeType(compiler),
- compiler);
- argumentTypes.registerDynamicInvocation(
- types, compiler.noSuchMethodSelector);
- }
-
void registerInstantiatedClass(ClassElement cls,
Enqueuer enqueuer,
TreeElements elements) {
if (!seenAnyClass) {
- initializeNoSuchMethod();
seenAnyClass = true;
if (enqueuer.isResolutionQueue) {
// TODO(9577): Make it so that these are not needed when there are no
@@ -1411,8 +782,6 @@
}
jsAst.Expression code = generator.generateCode(work, graph);
generatedCode[element] = code;
- invalidateAfterCodegen.forEach(eagerRecompile);
- invalidateAfterCodegen.clear();
}
native.NativeEnqueuer nativeResolutionEnqueuer(Enqueuer world) {
@@ -1442,153 +811,6 @@
emitter.assembleProgram();
}
- /**
- * Documentation wanted -- johnniwinther
- *
- * Invariant: [element] must be a declaration element.
- */
- void scheduleForRecompilation(Element element) {
- assert(invariant(element, element.isDeclaration));
- if (compiler.phase == Compiler.PHASE_COMPILING) {
- invalidateAfterCodegen.add(element);
- }
- }
-
- /**
- * Register a dynamic invocation and collect the provided types for the
- * named selector.
- */
- void registerDynamicInvocation(HInvoke node, Selector selector) {
- HTypeList providedTypes =
- new HTypeList.fromDynamicInvocation(node, selector);
- argumentTypes.registerDynamicInvocation(providedTypes, selector);
- }
-
- /**
- * Register a static invocation and collect the provided types for the
- * named selector.
- */
- void registerStaticInvocation(HInvokeStatic node) {
- argumentTypes.registerStaticInvocation(node);
- }
-
- /**
- * Register that a static is used for something else than a direct call
- * target.
- */
- void registerNonCallStaticUse(HStatic node) {
- argumentTypes.registerNonCallStaticUse(node);
- }
-
- /**
- * Retrieve the types of the parameters used for calling the [element]
- * function. The types are optimistic in the sense as they are based on the
- * possible invocations of the function seen so far.
- *
- * Invariant: [element] must be a declaration element.
- */
- HTypeList optimisticParameterTypes(
- FunctionElement element,
- OptionalParameterTypes defaultValueTypes) {
- assert(invariant(element, element.isDeclaration));
- if (element.parameterCount(compiler) == 0) return HTypeList.ALL_UNKNOWN;
- return argumentTypes.parameterTypes(element, defaultValueTypes);
- }
-
- /**
- * Register that the function [element] has been optimized under the
- * assumptions that the types [parameterType] will be used for calling it.
- * The passed [defaultValueTypes] holds the types of default values for
- * the optional parameters. If this assumption fail the function will be
- * scheduled for recompilation.
- *
- * Invariant: [element] must be a declaration element.
- */
- registerParameterTypesOptimization(
- FunctionElement element,
- HTypeList parameterTypes,
- OptionalParameterTypes defaultValueTypes) {
- assert(invariant(element, element.isDeclaration));
- if (element.parameterCount(compiler) == 0) return;
- argumentTypes.registerOptimizedFunction(
- element, parameterTypes, defaultValueTypes);
- }
-
- registerFieldTypesOptimization(Element element,
- Element field,
- HType type) {
- fieldTypes.registerOptimizedFunction(element, field, type);
- }
-
- /**
- * Documentation wanted -- johnniwinther
- *
- * Invariant: [element] must be a declaration element.
- */
- void registerReturnType(FunctionElement element, HType returnType) {
- assert(invariant(element, element.isDeclaration));
- ReturnInfo info = returnInfo[element];
- if (info != null) {
- info.update(returnType, scheduleForRecompilation, compiler);
- } else {
- returnInfo[element] = new ReturnInfo(returnType);
- }
- }
-
- /**
- * Retrieve the return type of the function [callee]. The type is optimistic
- * in the sense that is is based on the compilation of [callee]. If [callee]
- * is recompiled the return type might change to someting broader. For that
- * reason [caller] is registered for recompilation if this happens. If the
- * function [callee] has not yet been compiled the returned type is [null].
- *
- * Invariant: Both [caller] and [callee] must be declaration elements.
- */
- HType optimisticReturnTypesWithRecompilationOnTypeChange(
- Element caller, FunctionElement callee) {
- assert(invariant(callee, callee.isDeclaration));
- returnInfo.putIfAbsent(callee, () => new ReturnInfo.unknownType());
- ReturnInfo info = returnInfo[callee];
- HType returnType = info.returnType;
- if (returnType != HType.UNKNOWN && returnType != null && caller != null) {
- assert(invariant(caller, caller.isDeclaration));
- info.addCompiledFunction(caller);
- }
- return info.returnType;
- }
-
- void dumpReturnTypes() {
- returnInfo.forEach((Element element, ReturnInfo info) {
- if (info.returnType != HType.UNKNOWN) {
- print("Inferred $element has return type ${info.returnType}");
- }
- });
- }
-
- void registerConstructor(Element element) {
- fieldTypes.registerConstructor(element);
- }
-
- void registerFieldInitializer(Element field, HType type) {
- fieldTypes.registerFieldInitializer(field, type);
- }
-
- void registerFieldConstructor(Element field, HType type) {
- fieldTypes.registerFieldConstructor(field, type);
- }
-
- void registerFieldSetter(Element element, Element field, HType type) {
- fieldTypes.registerFieldSetter(element, field, type);
- }
-
- void addedDynamicSetter(Selector setter, HType type) {
- fieldTypes.addedDynamicSetter(setter, type);
- }
-
- HType optimisticFieldType(Element element) {
- return fieldTypes.optimisticFieldType(element);
- }
-
Element getImplementationClass(Element element) {
if (element == compiler.intClass) {
return jsIntClass;
@@ -1740,21 +962,6 @@
}
}
- void dumpInferredTypes() {
- print("Inferred argument types:");
- print("------------------------");
- argumentTypes.dump();
- print("");
- print("Inferred return types:");
- print("----------------------");
- dumpReturnTypes();
- print("");
- print("Inferred field types:");
- print("------------------------");
- fieldTypes.dump();
- print("");
- }
-
Element getExceptionUnwrapper() {
return compiler.findHelper(const SourceString('unwrapException'));
}
« no previous file with comments | « no previous file | sdk/lib/_internal/compiler/implementation/ssa/builder.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698