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

Unified Diff: lib/compiler/implementation/compiler.dart

Issue 10827181: Collect call site information and use that for estimating parameter types (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Addressed review comments Created 8 years, 4 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 | lib/compiler/implementation/enqueue.dart » ('j') | lib/compiler/implementation/enqueue.dart » ('J')
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: lib/compiler/implementation/compiler.dart
diff --git a/lib/compiler/implementation/compiler.dart b/lib/compiler/implementation/compiler.dart
index ca6ca2ba8cb60374a28e6029a5089e9d50e33292..50f0f658cfc52f4dece791e7dbe0496f5e42de51 100644
--- a/lib/compiler/implementation/compiler.dart
+++ b/lib/compiler/implementation/compiler.dart
@@ -51,6 +51,23 @@ class Backend {
abstract List<CompilerTask> get tasks();
}
+class InvocationInfo {
ahe 2012/08/07 11:23:26 I don't think this class belongs in this file.
Søren Gjesse 2012/08/08 10:36:02 I agree. I will move this and the JavaScriptBacken
ahe 2012/08/08 13:00:27 SGTM
+ InvocationInfo(List<HType> types)
+ : parameterCount = types != null ? types.length : -1,
+ providedTypes = types,
+ compiledFunctions = new List<Element>();
+
+ addCompiledFunction(FunctionElement function) =>
+ compiledFunctions.add(function);
+
+ void clearTypeInformation() => providedTypes = null;
+ bool get hasTypeInformation() => providedTypes != null;
+
+ int parameterCount;
ahe 2012/08/07 11:23:26 Please follow this sequence of members: fields, c
Søren Gjesse 2012/08/08 10:36:02 Done.
+ List<HType> providedTypes;
+ List<Element> compiledFunctions;
+}
+
class JavaScriptBackend extends Backend {
SsaBuilderTask builder;
SsaOptimizerTask optimizer;
@@ -60,6 +77,8 @@ class JavaScriptBackend extends Backend {
final Map<Element, Map<Element, HType>> fieldConstructorSetters;
final Map<Element, Map<Element, HType>> fieldSettersType;
+ final Map<SourceString, Map<Selector, InvocationInfo>> invocationInfo;
+
List<CompilerTask> get tasks() {
return <CompilerTask>[builder, optimizer, generator, emitter];
}
@@ -69,6 +88,7 @@ class JavaScriptBackend extends Backend {
fieldInitializers = new Map<Element, Map<Element, HType>>(),
fieldConstructorSetters = new Map<Element, Map<Element, HType>>(),
fieldSettersType = new Map<Element, Map<Element, HType>>(),
+ invocationInfo = new Map<SourceString, Map<Selector, InvocationInfo>>(),
super(compiler) {
builder = new SsaBuilderTask(this);
optimizer = new SsaOptimizerTask(this);
@@ -204,6 +224,91 @@ class JavaScriptBackend extends Backend {
if (!fields.containsKey(field)) return HType.CONFLICTING;
return fields[field];
}
+
+ // Register a dynamic invocation and collects the provided types for the
ahe 2012/08/07 11:23:26 collects -> collect.
ahe 2012/08/07 11:23:26 This should be a documentation comment, that is, u
Søren Gjesse 2012/08/08 10:36:02 Done.
Søren Gjesse 2012/08/08 10:36:02 Done.
+ // named selector.
+ void registerDynamicInvocation(HInvokeDynamicMethod node, Selector selector) {
ahe 2012/08/07 11:23:26 It would be great if you could move this out of co
Søren Gjesse 2012/08/08 10:36:02 Will do.
+ Map<Selector, InvocationInfo> invocationInfos =
+ invocationInfo.putIfAbsent(node.name,
+ () => new Map<Selector, InvocationInfo>());
+ InvocationInfo info = invocationInfos[selector];
+ if (info != null) {
+ // If we don't know anything useful about the types adding more
+ // information will not help.
+ if (!info.hasTypeInformation) return;
+
+ // Update the type information with the provided types.
+ bool typesChanged = false;
+ List<HType> types = info.providedTypes;
+ bool allUnknown = true;
+ for (int i = 0; i < types.length; i++) {
+ HType newType = types[i].union(node.inputs[i + 1].propagatedType);
+ if (newType != types[i]) {
+ typesChanged = true;
+ types[i] = newType;
+ }
+ if (types[i] != HType.UNKNOWN) allUnknown = false;
+ }
+ // If the provided types change we need to recompile all functions which
+ // have been compiled under the now invalidated assumptions.
+ if (typesChanged && info.compiledFunctions.length != 0) {
+ if (compiler.phase == Compiler.PHASE_COMPILING) {
+ info.compiledFunctions.forEach(
ahe 2012/08/07 11:23:26 info.compiledFunctions.forEach(compiler.enqueuer.c
Søren Gjesse 2012/08/08 10:36:02 Done.
+ (e) => compiler.enqueuer.codegen.eagerRecompile(e)
+ );
+ info.compiledFunctions.clear();
+ }
+ }
+ // If all information is lost no need to keep it around.
+ if (allUnknown) info.clearTypeInformation();
+ } else {
+ // Gather the type information provided. If the types contains no useful
+ // information there is no need to actually store them.
+ bool allUnknown = true;
+ for (int i = 1; i < node.inputs.length; i++) {
+ if (node.inputs[i].propagatedType != HType.UNKNOWN) {
+ allUnknown = false;
+ break;
+ }
+ }
+ List<HType> types;
+ if (allUnknown) {
+ types == null;
ahe 2012/08/07 11:23:26 This is a no-op.
Søren Gjesse 2012/08/08 10:36:02 Fixed.
+ } else {
+ types = new List<HType>(node.inputs.length - 1);
+ for (int i = 0; i < types.length; i++) {
+ types[i] = node.inputs[i + 1].propagatedType;
+ }
+ }
+ InvocationInfo info = new InvocationInfo(types);
+ invocationInfos[selector] = info;
+ }
+ }
+
+ List<HType> optimisticParameterTypesWithRecompilationOnTypeChange(
ahe 2012/08/07 11:23:26 Please document this method.
Søren Gjesse 2012/08/08 10:36:02 Done.
+ FunctionElement element) {
+ Map<Selector, InvocationInfo> invocationInfos =
+ invocationInfo[element.name];
+ if (invocationInfos == null) return null;
+
+ int foundCount = 0;
+ InvocationInfo found = null;
+ invocationInfos.forEach((Selector selector, InvocationInfo info) {
+ if (selector.applies(element, compiler)) {
+ found = info;
+ foundCount++;
+ }
+ });
+
+ if (foundCount == 1 && found.hasTypeInformation) {
+ FunctionSignature signature = element.computeSignature(compiler);
+ if (signature.parameterCount == found.parameterCount) {
+ found.addCompiledFunction(element);
+ return found.providedTypes;
+ }
+ }
+ return null;
+ }
}
class Compiler implements DiagnosticListener {
« no previous file with comments | « no previous file | lib/compiler/implementation/enqueue.dart » ('j') | lib/compiler/implementation/enqueue.dart » ('J')

Powered by Google App Engine
This is Rietveld 408576698