John Stalcup has uploaded a new change for review.
https://gwt-review.googlesource.com/3520
Change subject: replaces stale jProgram runAsync references and fixes
JRunAsync method inlining to occasionally benefit from tighter types
......................................................................
replaces stale jProgram runAsync references and fixes JRunAsync method
inlining to occasionally benefit from tighter types
Change-Id: I930a31272a5f9b689e8cb68971d7ffb77389488a
---
M dev/core/src/com/google/gwt/dev/jjs/JavaToJavaScriptCompiler.java
M dev/core/src/com/google/gwt/dev/jjs/ast/JRunAsync.java
M dev/core/src/com/google/gwt/dev/jjs/impl/CloneExpressionVisitor.java
M dev/core/src/com/google/gwt/dev/jjs/impl/MakeCallsStatic.java
M dev/core/src/com/google/gwt/dev/jjs/impl/MethodInliner.java
M dev/core/src/com/google/gwt/dev/jjs/impl/ReplaceRunAsyncs.java
A dev/core/src/com/google/gwt/dev/jjs/impl/RunAsyncsTightener.java
7 files changed, 116 insertions(+), 4 deletions(-)
diff --git
a/dev/core/src/com/google/gwt/dev/jjs/JavaToJavaScriptCompiler.java
b/dev/core/src/com/google/gwt/dev/jjs/JavaToJavaScriptCompiler.java
index 78fb2ca..ae47527 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/JavaToJavaScriptCompiler.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/JavaToJavaScriptCompiler.java
@@ -97,6 +97,7 @@
import com.google.gwt.dev.jjs.impl.ReplaceGetClassOverrides;
import com.google.gwt.dev.jjs.impl.ReplaceRunAsyncs;
import com.google.gwt.dev.jjs.impl.ResolveRebinds;
+import com.google.gwt.dev.jjs.impl.RunAsyncsTightener;
import com.google.gwt.dev.jjs.impl.SameParameterValueOptimizer;
import com.google.gwt.dev.jjs.impl.SourceInfoCorrelator;
import com.google.gwt.dev.jjs.impl.TypeTightener;
@@ -350,6 +351,8 @@
// prune all Object.getClass() overrides and replace with inline
field ref
ReplaceGetClassOverrides.exec(jprogram);
+ RunAsyncsTightener.exec(jprogram);
+
// (7) Generate a JavaScript code DOM from the Java type declarations
jprogram.typeOracle.recomputeAfterOptimizations();
Pair<? extends JavaToJavaScriptMap, Set<JsNode>> genAstResult =
diff --git a/dev/core/src/com/google/gwt/dev/jjs/ast/JRunAsync.java
b/dev/core/src/com/google/gwt/dev/jjs/ast/JRunAsync.java
index 50cd058..9cc0a39 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/ast/JRunAsync.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/ast/JRunAsync.java
@@ -82,6 +82,14 @@
return true;
}
+ public void setOnSuccessCall(JExpression onSuccessCall) {
+ this.onSuccessCall = onSuccessCall;
+ }
+
+ public void setRunAsyncCall(JExpression runAsyncCall) {
+ this.runAsyncCall = runAsyncCall;
+ }
+
public void traverse(JVisitor visitor, Context ctx) {
if (visitor.visit(this, ctx)) {
/*
diff --git
a/dev/core/src/com/google/gwt/dev/jjs/impl/CloneExpressionVisitor.java
b/dev/core/src/com/google/gwt/dev/jjs/impl/CloneExpressionVisitor.java
index d1089da..26c2e15 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/impl/CloneExpressionVisitor.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/impl/CloneExpressionVisitor.java
@@ -227,11 +227,10 @@
@Override
public boolean visit(JRunAsync x, Context ctx) {
- // Only the runAsync call itself needs cloning, the onSuccess can be
shared.
JExpression runAsyncCall = cloneExpression(x.getRunAsyncCall());
- expression =
- new JRunAsync(x.getSourceInfo(), x.getSplitPoint(), x.getName(),
runAsyncCall, x
- .getOnSuccessCall());
+ JExpression onSuccessCall = cloneExpression(x.getOnSuccessCall());
+ expression = new JRunAsync(
+ x.getSourceInfo(), x.getSplitPoint(), x.getName(), runAsyncCall,
onSuccessCall);
return false;
}
diff --git a/dev/core/src/com/google/gwt/dev/jjs/impl/MakeCallsStatic.java
b/dev/core/src/com/google/gwt/dev/jjs/impl/MakeCallsStatic.java
index 88cfd1c..3132ef0 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/impl/MakeCallsStatic.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/impl/MakeCallsStatic.java
@@ -30,6 +30,7 @@
import com.google.gwt.dev.jjs.ast.JParameterRef;
import com.google.gwt.dev.jjs.ast.JProgram;
import com.google.gwt.dev.jjs.ast.JReturnStatement;
+import com.google.gwt.dev.jjs.ast.JRunAsync;
import com.google.gwt.dev.jjs.ast.JStatement;
import com.google.gwt.dev.jjs.ast.JThisRef;
import com.google.gwt.dev.jjs.ast.JType;
@@ -113,6 +114,13 @@
}
@Override
+ public boolean visit(JRunAsync x, Context ctx) {
+ x.setRunAsyncCall(accept(x.getRunAsyncCall()));
+ x.setOnSuccessCall(accept(x.getOnSuccessCall()));
+ return false;
+ }
+
+ @Override
public void endVisit(JParameterRef x, Context ctx) {
JParameter param = varMap.get(x.getTarget());
JParameterRef paramRef = new JParameterRef(x.getSourceInfo(),
param);
diff --git a/dev/core/src/com/google/gwt/dev/jjs/impl/MethodInliner.java
b/dev/core/src/com/google/gwt/dev/jjs/impl/MethodInliner.java
index d2b05ae..49f406a 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/impl/MethodInliner.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/impl/MethodInliner.java
@@ -32,6 +32,7 @@
import com.google.gwt.dev.jjs.ast.JProgram;
import com.google.gwt.dev.jjs.ast.JReferenceType;
import com.google.gwt.dev.jjs.ast.JReturnStatement;
+import com.google.gwt.dev.jjs.ast.JRunAsync;
import com.google.gwt.dev.jjs.ast.JStatement;
import com.google.gwt.dev.jjs.ast.JThisRef;
import com.google.gwt.dev.jjs.ast.JType;
@@ -457,6 +458,13 @@
}
@Override
+ public boolean visit(JRunAsync x, Context ctx) {
+ x.setRunAsyncCall(accept(x.getRunAsyncCall()));
+ x.setOnSuccessCall(accept(x.getOnSuccessCall()));
+ return false;
+ }
+
+ @Override
public void endVisit(JParameterRef x, Context ctx) {
int paramIndex =
methodCall.getTarget().getParams().indexOf(x.getParameter());
assert paramIndex != -1;
diff --git a/dev/core/src/com/google/gwt/dev/jjs/impl/ReplaceRunAsyncs.java
b/dev/core/src/com/google/gwt/dev/jjs/impl/ReplaceRunAsyncs.java
index 2f50843..73cfaf5 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/impl/ReplaceRunAsyncs.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/impl/ReplaceRunAsyncs.java
@@ -117,6 +117,13 @@
+ "be passed to runAsync().");
return;
}
+
+ // It's illegal for two nodes in the AST to refer to the same node
and doing so will cause
+ // some visitors to run improperly. Duplicate asyncCallback before
adding this second
+ // reference in onSuccessCall.
+ CloneExpressionVisitor cloner = new CloneExpressionVisitor();
+ asyncCallback = cloner.cloneExpression(asyncCallback);
+
JMethodCall onSuccessCall = new JMethodCall(info, asyncCallback,
callbackMethod);
JRunAsync runAsyncNode = new JRunAsync(info, splitPoint, name,
runAsyncCall, onSuccessCall);
@@ -139,6 +146,7 @@
&& method.getName().equals("runAsync");
}
}
+
private class ReplaceRunAsyncResources extends JModVisitor {
private final Map<String, List<JRunAsync>> replacementsByName;
private final JMethod runAsyncCode;
diff --git
a/dev/core/src/com/google/gwt/dev/jjs/impl/RunAsyncsTightener.java
b/dev/core/src/com/google/gwt/dev/jjs/impl/RunAsyncsTightener.java
new file mode 100644
index 0000000..d442e8e
--- /dev/null
+++ b/dev/core/src/com/google/gwt/dev/jjs/impl/RunAsyncsTightener.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright 2013 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may
not
+ * use this file except in compliance with the License. You may obtain a
copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
under
+ * the License.
+ */
+package com.google.gwt.dev.jjs.impl;
+
+import com.google.gwt.dev.jjs.ast.Context;
+import com.google.gwt.dev.jjs.ast.JProgram;
+import com.google.gwt.dev.jjs.ast.JRunAsync;
+import com.google.gwt.dev.jjs.ast.JVisitor;
+import com.google.gwt.thirdparty.guava.common.collect.LinkedHashMultimap;
+import com.google.gwt.thirdparty.guava.common.collect.Lists;
+import com.google.gwt.thirdparty.guava.common.collect.Multimap;
+
+import java.util.Collection;
+import java.util.List;
+
+/**
+ * Replaces some JProgram references to JRunAsync nodes after optimization
to take advantage of
+ * tighter types.
+ */
+public class RunAsyncsTightener {
+
+ private static class RunAsyncsGathererVisitor extends JVisitor {
+ // Is a Multimap not a Map because after optimization there can be
duplicate versions
+ // of the same splitPoint in different contexts.
+ private Multimap<Integer, JRunAsync>
optimizedRunAsyncListsBySplitPoint =
+ LinkedHashMultimap.create();
+
+ @Override
+ public boolean visit(JRunAsync runAsync, Context ctx) {
+ optimizedRunAsyncListsBySplitPoint.put(runAsync.getSplitPoint(),
runAsync);
+ return super.visit(runAsync, ctx);
+ }
+ }
+
+ public static void exec(JProgram jProgram) {
+ RunAsyncsGathererVisitor runAsyncsGathererVisitor = new
RunAsyncsGathererVisitor();
+ runAsyncsGathererVisitor.accept(jProgram);
+
+ List<JRunAsync> updatedRunAsyncs = Lists.newArrayList();
+ for (JRunAsync originalRunAsync : jProgram.getRunAsyncs()) {
+ Collection<JRunAsync> optimizedRunAsyncs =
+ runAsyncsGathererVisitor.optimizedRunAsyncListsBySplitPoint.get(
+ originalRunAsync.getSplitPoint());
+
+ int optimizedRunAsyncCount = optimizedRunAsyncs.size();
+ // If after optimization there is still only one copy of a
particular runAsync.
+ if (optimizedRunAsyncCount == 1) {
+ // Then use the optimized version of it since the optimized
version may now have a tighter
+ // RunAsyncCallback type that will allow CodeSplitting to place
code more locally.
+ JRunAsync optimizedRunAsync = optimizedRunAsyncs.iterator().next();
+ updatedRunAsyncs.add(optimizedRunAsync);
+ } else {
+ // Expanding an original runAsync into multiple runAsyncs could
actually expand the leftOver
+ // fragment by causing some code to appear to be reachable from
multiple runAsyncs.
+ // CodeSplitter2 fragmentMerging could clean this back up
automatically but there's no need
+ // to add this computation overhead nor end-user tweaking. Just
keep the original
+ // non-duplicated runAsync.
+ updatedRunAsyncs.add(originalRunAsync);
+ continue;
+ }
+ }
+
+ jProgram.setRunAsyncs(updatedRunAsyncs);
+ }
+}
--
To view, visit https://gwt-review.googlesource.com/3520
To unsubscribe, visit https://gwt-review.googlesource.com/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I930a31272a5f9b689e8cb68971d7ffb77389488a
Gerrit-PatchSet: 1
Gerrit-Project: gwt
Gerrit-Branch: master
Gerrit-Owner: John Stalcup <[email protected]>
--
http://groups.google.com/group/Google-Web-Toolkit-Contributors
---
You received this message because you are subscribed to the Google Groups "GWT Contributors" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/groups/opt_out.