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 <stal...@google.com>
--
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 google-web-toolkit-contributors+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.