提交 c47d08e2 编写于 作者: A aefimov

8134007: Improve string folding

Summary: Generalize string folding algorithm to detect mulitple groups of foldable constants within an concat expression
Reviewed-by: jlahoda
上级 c1e73080
...@@ -515,7 +515,7 @@ public class JavacParser implements Parser { ...@@ -515,7 +515,7 @@ public class JavacParser implements Parser {
if (mods != 0) { if (mods != 0) {
long lowestMod = mods & -mods; long lowestMod = mods & -mods;
error(token.pos, "mod.not.allowed.here", error(token.pos, "mod.not.allowed.here",
Flags.asFlagSet(lowestMod)); Flags.asFlagSet(lowestMod));
} }
} }
...@@ -954,10 +954,7 @@ public class JavacParser implements Parser { ...@@ -954,10 +954,7 @@ public class JavacParser implements Parser {
t = odStack[0]; t = odStack[0];
if (t.hasTag(JCTree.Tag.PLUS)) { if (t.hasTag(JCTree.Tag.PLUS)) {
StringBuilder buf = foldStrings(t); t = foldStrings(t);
if (buf != null) {
t = toP(F.at(startPos).Literal(TypeTag.CLASS, buf.toString()));
}
} }
odStackSupply.add(odStack); odStackSupply.add(odStack);
...@@ -981,37 +978,79 @@ public class JavacParser implements Parser { ...@@ -981,37 +978,79 @@ public class JavacParser implements Parser {
/** If tree is a concatenation of string literals, replace it /** If tree is a concatenation of string literals, replace it
* by a single literal representing the concatenated string. * by a single literal representing the concatenated string.
*/ */
protected StringBuilder foldStrings(JCTree tree) { protected JCExpression foldStrings(JCExpression tree) {
if (!allowStringFolding) if (!allowStringFolding)
return null; return null;
List<String> buf = List.nil(); ListBuffer<JCExpression> opStack = new ListBuffer<>();
ListBuffer<JCLiteral> litBuf = new ListBuffer<>();
boolean needsFolding = false;
JCExpression curr = tree;
while (true) { while (true) {
if (tree.hasTag(LITERAL)) { if (curr.hasTag(JCTree.Tag.PLUS)) {
JCLiteral lit = (JCLiteral) tree; JCBinary op = (JCBinary)curr;
if (lit.typetag == TypeTag.CLASS) { needsFolding |= foldIfNeeded(op.rhs, litBuf, opStack, false);
StringBuilder sbuf = curr = op.lhs;
new StringBuilder((String)lit.value); } else {
while (buf.nonEmpty()) { needsFolding |= foldIfNeeded(curr, litBuf, opStack, true);
sbuf.append(buf.head); break; //last one!
buf = buf.tail;
}
return sbuf;
}
} else if (tree.hasTag(JCTree.Tag.PLUS)) {
JCBinary op = (JCBinary)tree;
if (op.rhs.hasTag(LITERAL)) {
JCLiteral lit = (JCLiteral) op.rhs;
if (lit.typetag == TypeTag.CLASS) {
buf = buf.prepend((String) lit.value);
tree = op.lhs;
continue;
}
}
} }
return null; }
if (needsFolding) {
List<JCExpression> ops = opStack.toList();
JCExpression res = ops.head;
for (JCExpression op : ops.tail) {
res = F.at(op.getStartPosition()).Binary(optag(TokenKind.PLUS), res, op);
storeEnd(res, getEndPos(op));
}
return res;
} else {
return tree;
} }
} }
private boolean foldIfNeeded(JCExpression tree, ListBuffer<JCLiteral> litBuf,
ListBuffer<JCExpression> opStack, boolean last) {
JCLiteral str = stringLiteral(tree);
if (str != null) {
litBuf.prepend(str);
return last && merge(litBuf, opStack);
} else {
boolean res = merge(litBuf, opStack);
litBuf.clear();
opStack.prepend(tree);
return res;
}
}
boolean merge(ListBuffer<JCLiteral> litBuf, ListBuffer<JCExpression> opStack) {
if (litBuf.isEmpty()) {
return false;
} else if (litBuf.size() == 1) {
opStack.prepend(litBuf.first());
return false;
} else {
StringBuilder sb = new StringBuilder();
for (JCLiteral lit : litBuf) {
sb.append(lit.getValue());
}
JCExpression t = F.at(litBuf.first().getStartPosition()).Literal(TypeTag.CLASS, sb.toString());
storeEnd(t, litBuf.last().getEndPosition(endPosTable));
opStack.prepend(t);
return true;
}
}
private JCLiteral stringLiteral(JCTree tree) {
if (tree.hasTag(LITERAL)) {
JCLiteral lit = (JCLiteral)tree;
if (lit.typetag == TypeTag.CLASS) {
return lit;
}
}
return null;
}
/** optimization: To save allocating a new operand/operator stack /** optimization: To save allocating a new operand/operator stack
* for every binary operation, we use supplys. * for every binary operation, we use supplys.
*/ */
......
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册