提交 76d4415d 编写于 作者: K ksrini

8026758: Inefficient code in LambdaToMethod

Reviewed-by: jjg, jlahoda, rfield
上级 5d31cc04
...@@ -49,6 +49,7 @@ import com.sun.tools.javac.util.*; ...@@ -49,6 +49,7 @@ import com.sun.tools.javac.util.*;
import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition; import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
import com.sun.source.tree.MemberReferenceTree.ReferenceMode; import com.sun.source.tree.MemberReferenceTree.ReferenceMode;
import java.util.EnumMap;
import java.util.HashMap; import java.util.HashMap;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.Map; import java.util.Map;
...@@ -69,6 +70,7 @@ import static com.sun.tools.javac.tree.JCTree.Tag.*; ...@@ -69,6 +70,7 @@ import static com.sun.tools.javac.tree.JCTree.Tag.*;
*/ */
public class LambdaToMethod extends TreeTranslator { public class LambdaToMethod extends TreeTranslator {
private Attr attr;
private JCDiagnostic.Factory diags; private JCDiagnostic.Factory diags;
private Log log; private Log log;
private Lower lower; private Lower lower;
...@@ -104,6 +106,35 @@ public class LambdaToMethod extends TreeTranslator { ...@@ -104,6 +106,35 @@ public class LambdaToMethod extends TreeTranslator {
/** Flag for alternate metafactories indicating the lambda object requires multiple bridges */ /** Flag for alternate metafactories indicating the lambda object requires multiple bridges */
public static final int FLAG_BRIDGES = 1 << 2; public static final int FLAG_BRIDGES = 1 << 2;
// <editor-fold defaultstate="collapsed" desc="Instantiating">
protected static final Context.Key<LambdaToMethod> unlambdaKey =
new Context.Key<LambdaToMethod>();
public static LambdaToMethod instance(Context context) {
LambdaToMethod instance = context.get(unlambdaKey);
if (instance == null) {
instance = new LambdaToMethod(context);
}
return instance;
}
private LambdaToMethod(Context context) {
context.put(unlambdaKey, this);
diags = JCDiagnostic.Factory.instance(context);
log = Log.instance(context);
lower = Lower.instance(context);
names = Names.instance(context);
syms = Symtab.instance(context);
rs = Resolve.instance(context);
make = TreeMaker.instance(context);
types = Types.instance(context);
transTypes = TransTypes.instance(context);
analyzer = new LambdaAnalyzerPreprocessor();
Options options = Options.instance(context);
dumpLambdaToMethodStats = options.isSet("dumpLambdaToMethodStats");
attr = Attr.instance(context);
}
// </editor-fold>
private class KlassInfo { private class KlassInfo {
/** /**
...@@ -141,37 +172,6 @@ public class LambdaToMethod extends TreeTranslator { ...@@ -141,37 +172,6 @@ public class LambdaToMethod extends TreeTranslator {
} }
} }
// <editor-fold defaultstate="collapsed" desc="Instantiating">
private static final Context.Key<LambdaToMethod> unlambdaKey =
new Context.Key<LambdaToMethod>();
public static LambdaToMethod instance(Context context) {
LambdaToMethod instance = context.get(unlambdaKey);
if (instance == null) {
instance = new LambdaToMethod(context);
}
return instance;
}
private Attr attr;
private LambdaToMethod(Context context) {
diags = JCDiagnostic.Factory.instance(context);
log = Log.instance(context);
lower = Lower.instance(context);
names = Names.instance(context);
syms = Symtab.instance(context);
rs = Resolve.instance(context);
make = TreeMaker.instance(context);
types = Types.instance(context);
transTypes = TransTypes.instance(context);
analyzer = new LambdaAnalyzerPreprocessor();
Options options = Options.instance(context);
dumpLambdaToMethodStats = options.isSet("dumpLambdaToMethodStats");
attr = Attr.instance(context);
}
// </editor-fold>
// <editor-fold defaultstate="collapsed" desc="translate methods"> // <editor-fold defaultstate="collapsed" desc="translate methods">
@Override @Override
public <T extends JCTree> T translate(T tree) { public <T extends JCTree> T translate(T tree) {
...@@ -402,21 +402,9 @@ public class LambdaToMethod extends TreeTranslator { ...@@ -402,21 +402,9 @@ public class LambdaToMethod extends TreeTranslator {
super.visitIdent(tree); super.visitIdent(tree);
} else { } else {
LambdaTranslationContext lambdaContext = (LambdaTranslationContext) context; LambdaTranslationContext lambdaContext = (LambdaTranslationContext) context;
if (lambdaContext.getSymbolMap(PARAM).containsKey(tree.sym)) { JCTree ltree = lambdaContext.translate(tree);
Symbol translatedSym = lambdaContext.getSymbolMap(PARAM).get(tree.sym); if (ltree != null) {
result = make.Ident(translatedSym).setType(tree.type); result = ltree;
translatedSym.setTypeAttributes(tree.sym.getRawTypeAttributes());
} else if (lambdaContext.getSymbolMap(LOCAL_VAR).containsKey(tree.sym)) {
Symbol translatedSym = lambdaContext.getSymbolMap(LOCAL_VAR).get(tree.sym);
result = make.Ident(translatedSym).setType(tree.type);
translatedSym.setTypeAttributes(tree.sym.getRawTypeAttributes());
} else if (lambdaContext.getSymbolMap(TYPE_VAR).containsKey(tree.sym)) {
Symbol translatedSym = lambdaContext.getSymbolMap(TYPE_VAR).get(tree.sym);
result = make.Ident(translatedSym).setType(translatedSym.type);
translatedSym.setTypeAttributes(tree.sym.getRawTypeAttributes());
} else if (lambdaContext.getSymbolMap(CAPTURED_VAR).containsKey(tree.sym)) {
Symbol translatedSym = lambdaContext.getSymbolMap(CAPTURED_VAR).get(tree.sym);
result = make.Ident(translatedSym).setType(tree.type);
} else { } else {
//access to untranslated symbols (i.e. compile-time constants, //access to untranslated symbols (i.e. compile-time constants,
//members defined inside the lambda body, etc.) ) //members defined inside the lambda body, etc.) )
...@@ -1704,20 +1692,7 @@ public class LambdaToMethod extends TreeTranslator { ...@@ -1704,20 +1692,7 @@ public class LambdaToMethod extends TreeTranslator {
/** variable in the enclosing context to which this lambda is assigned */ /** variable in the enclosing context to which this lambda is assigned */
Symbol self; Symbol self;
/** map from original to translated lambda parameters */ Map<LambdaSymbolKind, Map<Symbol, Symbol>> translatedSymbols;
Map<Symbol, Symbol> lambdaParams = new LinkedHashMap<Symbol, Symbol>();
/** map from original to translated lambda locals */
Map<Symbol, Symbol> lambdaLocals = new LinkedHashMap<Symbol, Symbol>();
/** map from variables in enclosing scope to translated synthetic parameters */
Map<Symbol, Symbol> capturedLocals = new LinkedHashMap<Symbol, Symbol>();
/** map from class symbols to translated synthetic parameters (for captured member access) */
Map<Symbol, Symbol> capturedThis = new LinkedHashMap<Symbol, Symbol>();
/** map from original to translated lambda locals */
Map<Symbol, Symbol> typeVars = new LinkedHashMap<Symbol, Symbol>();
/** the synthetic symbol for the method hoisting the translated lambda */ /** the synthetic symbol for the method hoisting the translated lambda */
Symbol translatedSym; Symbol translatedSym;
...@@ -1735,6 +1710,13 @@ public class LambdaToMethod extends TreeTranslator { ...@@ -1735,6 +1710,13 @@ public class LambdaToMethod extends TreeTranslator {
if (dumpLambdaToMethodStats) { if (dumpLambdaToMethodStats) {
log.note(tree, "lambda.stat", needsAltMetafactory(), translatedSym); log.note(tree, "lambda.stat", needsAltMetafactory(), translatedSym);
} }
translatedSymbols = new EnumMap<>(LambdaSymbolKind.class);
translatedSymbols.put(PARAM, new LinkedHashMap<Symbol, Symbol>());
translatedSymbols.put(LOCAL_VAR, new LinkedHashMap<Symbol, Symbol>());
translatedSymbols.put(CAPTURED_VAR, new LinkedHashMap<Symbol, Symbol>());
translatedSymbols.put(CAPTURED_THIS, new LinkedHashMap<Symbol, Symbol>());
translatedSymbols.put(TYPE_VAR, new LinkedHashMap<Symbol, Symbol>());
} }
/** /**
...@@ -1786,27 +1768,22 @@ public class LambdaToMethod extends TreeTranslator { ...@@ -1786,27 +1768,22 @@ public class LambdaToMethod extends TreeTranslator {
} }
void addSymbol(Symbol sym, LambdaSymbolKind skind) { void addSymbol(Symbol sym, LambdaSymbolKind skind) {
Map<Symbol, Symbol> transMap = null; Map<Symbol, Symbol> transMap = getSymbolMap(skind);
Name preferredName; Name preferredName;
switch (skind) { switch (skind) {
case CAPTURED_THIS: case CAPTURED_THIS:
transMap = capturedThis; preferredName = names.fromString("encl$" + transMap.size());
preferredName = names.fromString("encl$" + capturedThis.size());
break; break;
case CAPTURED_VAR: case CAPTURED_VAR:
transMap = capturedLocals; preferredName = names.fromString("cap$" + transMap.size());
preferredName = names.fromString("cap$" + capturedLocals.size());
break; break;
case LOCAL_VAR: case LOCAL_VAR:
transMap = lambdaLocals;
preferredName = sym.name; preferredName = sym.name;
break; break;
case PARAM: case PARAM:
transMap = lambdaParams;
preferredName = sym.name; preferredName = sym.name;
break; break;
case TYPE_VAR: case TYPE_VAR:
transMap = typeVars;
preferredName = sym.name; preferredName = sym.name;
break; break;
default: throw new AssertionError(); default: throw new AssertionError();
...@@ -1816,29 +1793,22 @@ public class LambdaToMethod extends TreeTranslator { ...@@ -1816,29 +1793,22 @@ public class LambdaToMethod extends TreeTranslator {
} }
} }
Map<Symbol, Symbol> getSymbolMap(LambdaSymbolKind... skinds) { Map<Symbol, Symbol> getSymbolMap(LambdaSymbolKind skind) {
LinkedHashMap<Symbol, Symbol> translationMap = new LinkedHashMap<Symbol, Symbol>(); Map<Symbol, Symbol> m = translatedSymbols.get(skind);
for (LambdaSymbolKind skind : skinds) { Assert.checkNonNull(m);
switch (skind) { return m;
case CAPTURED_THIS: }
translationMap.putAll(capturedThis);
break; JCTree translate(JCIdent lambdaIdent) {
case CAPTURED_VAR: for (Map<Symbol, Symbol> m : translatedSymbols.values()) {
translationMap.putAll(capturedLocals); if (m.containsKey(lambdaIdent.sym)) {
break; Symbol tSym = m.get(lambdaIdent.sym);
case LOCAL_VAR: JCTree t = make.Ident(tSym).setType(lambdaIdent.type);
translationMap.putAll(lambdaLocals); tSym.setTypeAttributes(lambdaIdent.sym.getRawTypeAttributes());
break; return t;
case PARAM:
translationMap.putAll(lambdaParams);
break;
case TYPE_VAR:
translationMap.putAll(typeVars);
break;
default: throw new AssertionError();
} }
} }
return translationMap; return null;
} }
/** /**
...@@ -1869,10 +1839,12 @@ public class LambdaToMethod extends TreeTranslator { ...@@ -1869,10 +1839,12 @@ public class LambdaToMethod extends TreeTranslator {
// //
// 1) reference to enclosing contexts captured by the lambda expression // 1) reference to enclosing contexts captured by the lambda expression
// 2) enclosing locals captured by the lambda expression // 2) enclosing locals captured by the lambda expression
for (Symbol thisSym : getSymbolMap(CAPTURED_VAR, PARAM).values()) { for (Symbol thisSym : getSymbolMap(CAPTURED_VAR).values()) {
params.append(make.VarDef((VarSymbol) thisSym, null));
}
for (Symbol thisSym : getSymbolMap(PARAM).values()) {
params.append(make.VarDef((VarSymbol) thisSym, null)); params.append(make.VarDef((VarSymbol) thisSym, null));
} }
syntheticParams = params.toList(); syntheticParams = params.toList();
//prepend synthetic args to translated lambda method signature //prepend synthetic args to translated lambda method signature
...@@ -1964,12 +1936,16 @@ public class LambdaToMethod extends TreeTranslator { ...@@ -1964,12 +1936,16 @@ public class LambdaToMethod extends TreeTranslator {
} }
// </editor-fold> // </editor-fold>
/*
* These keys provide mappings for various translated lambda symbols
* and the prevailing order must be maintained.
*/
enum LambdaSymbolKind { enum LambdaSymbolKind {
CAPTURED_VAR, PARAM, // original to translated lambda parameters
CAPTURED_THIS, LOCAL_VAR, // original to translated lambda locals
LOCAL_VAR, CAPTURED_VAR, // variables in enclosing scope to translated synthetic parameters
PARAM, CAPTURED_THIS, // class symbols to translated synthetic parameters (for captured member access)
TYPE_VAR; TYPE_VAR; // original to translated lambda type variables
} }
/** /**
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册