提交 fe8b3c1d 编写于 作者: V vromero

7153958: add constant pool reference to class containing inlined constants

Reviewed-by: jjg, mcimadamore
上级 5941a8c4
......@@ -138,6 +138,10 @@ public class Lower extends TreeTranslator {
*/
Map<ClassSymbol, JCClassDecl> classdefs;
/** A hash table mapping local classes to a list of pruned trees.
*/
public Map<ClassSymbol, List<JCTree>> prunedTree = new WeakHashMap<ClassSymbol, List<JCTree>>();
/** A hash table mapping virtual accessed symbols in outer subclasses
* to the actually referred symbol in superclasses.
*/
......@@ -1039,6 +1043,12 @@ public class Lower extends TreeTranslator {
}
}
private void addPrunedInfo(JCTree tree) {
List<JCTree> infoList = prunedTree.get(currentClass);
infoList = (infoList == null) ? List.of(tree) : infoList.prepend(tree);
prunedTree.put(currentClass, infoList);
}
/** Ensure that identifier is accessible, return tree accessing the identifier.
* @param sym The accessed symbol.
* @param tree The tree referring to the symbol.
......@@ -1111,7 +1121,10 @@ public class Lower extends TreeTranslator {
// Constants are replaced by their constant value.
if (sym.kind == VAR) {
Object cv = ((VarSymbol)sym).getConstValue();
if (cv != null) return makeLit(sym.type, cv);
if (cv != null) {
addPrunedInfo(tree);
return makeLit(sym.type, cv);
}
}
// Private variables and methods are replaced by calls
......@@ -2746,12 +2759,15 @@ public class Lower extends TreeTranslator {
/** Visitor method for conditional expressions.
*/
@Override
public void visitConditional(JCConditional tree) {
JCTree cond = tree.cond = translate(tree.cond, syms.booleanType);
if (cond.type.isTrue()) {
result = convert(translate(tree.truepart, tree.type), tree.type);
addPrunedInfo(cond);
} else if (cond.type.isFalse()) {
result = convert(translate(tree.falsepart, tree.type), tree.type);
addPrunedInfo(cond);
} else {
// Condition is not a compile-time constant.
tree.truepart = translate(tree.truepart, tree.type);
......@@ -2760,14 +2776,14 @@ public class Lower extends TreeTranslator {
}
}
//where
private JCTree convert(JCTree tree, Type pt) {
if (tree.type == pt || tree.type.hasTag(BOT))
return tree;
JCTree result = make_at(tree.pos()).TypeCast(make.Type(pt), (JCExpression)tree);
result.type = (tree.type.constValue() != null) ? cfolder.coerce(tree.type, pt)
: pt;
return result;
}
private JCTree convert(JCTree tree, Type pt) {
if (tree.type == pt || tree.type.hasTag(BOT))
return tree;
JCTree result = make_at(tree.pos()).TypeCast(make.Type(pt), (JCExpression)tree);
result.type = (tree.type.constValue() != null) ? cfolder.coerce(tree.type, pt)
: pt;
return result;
}
/** Visitor method for if statements.
*/
......@@ -2775,12 +2791,14 @@ public class Lower extends TreeTranslator {
JCTree cond = tree.cond = translate(tree.cond, syms.booleanType);
if (cond.type.isTrue()) {
result = translate(tree.thenpart);
addPrunedInfo(cond);
} else if (cond.type.isFalse()) {
if (tree.elsepart != null) {
result = translate(tree.elsepart);
} else {
result = make.Skip();
}
addPrunedInfo(cond);
} else {
// Condition is not a compile-time constant.
tree.thenpart = translate(tree.thenpart);
......
......@@ -71,6 +71,7 @@ public class Gen extends JCTree.Visitor {
private final Map<Type,Symbol> stringBufferAppend;
private Name accessDollar;
private final Types types;
private final Lower lower;
/** Switch: GJ mode?
*/
......@@ -112,6 +113,7 @@ public class Gen extends JCTree.Visitor {
stringBufferAppend = new HashMap<Type,Symbol>();
accessDollar = names.
fromString("access" + target.syntheticNameChar());
lower = Lower.instance(context);
Options options = Options.instance(context);
lineDebugInfo =
......@@ -816,6 +818,62 @@ public class Gen extends JCTree.Visitor {
}
}
/** Visitor class for expressions which might be constant expressions.
* This class is a subset of TreeScanner. Intended to visit trees pruned by
* Lower as long as constant expressions looking for references to any
* ClassSymbol. Any such reference will be added to the constant pool so
* automated tools can detect class dependencies better.
*/
class ClassReferenceVisitor extends JCTree.Visitor {
@Override
public void visitTree(JCTree tree) {}
@Override
public void visitBinary(JCBinary tree) {
tree.lhs.accept(this);
tree.rhs.accept(this);
}
@Override
public void visitSelect(JCFieldAccess tree) {
if (tree.selected.type.hasTag(CLASS)) {
makeRef(tree.selected.pos(), tree.selected.type);
}
}
@Override
public void visitIdent(JCIdent tree) {
if (tree.sym.owner instanceof ClassSymbol) {
pool.put(tree.sym.owner);
}
}
@Override
public void visitConditional(JCConditional tree) {
tree.cond.accept(this);
tree.truepart.accept(this);
tree.falsepart.accept(this);
}
@Override
public void visitUnary(JCUnary tree) {
tree.arg.accept(this);
}
@Override
public void visitParens(JCParens tree) {
tree.expr.accept(this);
}
@Override
public void visitTypeCast(JCTypeCast tree) {
tree.expr.accept(this);
}
}
private ClassReferenceVisitor classReferenceVisitor = new ClassReferenceVisitor();
/** Visitor method: generate code for an expression, catching and reporting
* any completion failures.
* @param tree The expression to be visited.
......@@ -826,6 +884,7 @@ public class Gen extends JCTree.Visitor {
try {
if (tree.type.constValue() != null) {
// Short circuit any expressions which are constants
tree.accept(classReferenceVisitor);
checkStringConstant(tree.pos(), tree.type.constValue());
result = items.makeImmediateItem(tree.type, tree.type.constValue());
} else {
......@@ -2205,6 +2264,15 @@ public class Gen extends JCTree.Visitor {
code.endScopes(limit);
}
private void generateReferencesToPrunedTree(ClassSymbol classSymbol, Pool pool) {
List<JCTree> prunedInfo = lower.prunedTree.get(classSymbol);
if (prunedInfo != null) {
for (JCTree prunedTree: prunedInfo) {
prunedTree.accept(classReferenceVisitor);
}
}
}
/* ************************************************************************
* main method
*************************************************************************/
......@@ -2232,6 +2300,7 @@ public class Gen extends JCTree.Visitor {
cdef.defs = normalizeDefs(cdef.defs, c);
c.pool = pool;
pool.reset();
generateReferencesToPrunedTree(c, pool);
Env<GenContext> localEnv =
new Env<GenContext>(cdef, new GenContext());
localEnv.toplevel = env.toplevel;
......
/*
* Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 7153958
* @summary add constant pool reference to class containing inlined constants
* @compile pkg/ClassToBeStaticallyImported.java
* @run main CPoolRefClassContainingInlinedCts
*/
import com.sun.tools.classfile.ClassFile;
import com.sun.tools.classfile.ConstantPool.CONSTANT_Class_info;
import com.sun.tools.classfile.ConstantPool.CPInfo;
import com.sun.tools.classfile.ConstantPoolException;
import java.io.File;
import java.io.IOException;
import static pkg.ClassToBeStaticallyImported.staticField;
public class CPoolRefClassContainingInlinedCts {
public static void main(String args[]) throws Exception {
new CPoolRefClassContainingInlinedCts().run();
}
void run() throws Exception {
checkReferences();
}
int numberOfReferencedClassesToBeChecked = 0;
void checkClassName(String className) {
switch (className) {
case "SimpleAssignClass" : case "BinaryExpClass":
case "UnaryExpClass" : case "CastClass":
case "ParensClass" : case "CondClass":
case "IfClass" : case "pkg/ClassToBeStaticallyImported":
numberOfReferencedClassesToBeChecked++;
}
}
void checkReferences() throws IOException, ConstantPoolException {
File testClasses = new File(System.getProperty("test.classes"));
File file = new File(testClasses,
CPoolRefClassContainingInlinedCts.class.getName() + ".class");
ClassFile classFile = ClassFile.read(file);
int i = 1;
CPInfo cpInfo;
while (i < classFile.constant_pool.size()) {
cpInfo = classFile.constant_pool.get(i);
if (cpInfo instanceof CONSTANT_Class_info) {
checkClassName(((CONSTANT_Class_info)cpInfo).getName());
}
i += cpInfo.size();
}
if (numberOfReferencedClassesToBeChecked != 8) {
throw new AssertionError("Class reference missing in the constant pool");
}
}
private int assign = SimpleAssignClass.x;
private int binary = BinaryExpClass.x + 1;
private int unary = -UnaryExpClass.x;
private int cast = (int)CastClass.x;
private int parens = (ParensClass.x);
private int cond = (CondClass.x == 1) ? 1 : 2;
private static int ifConstant;
private static int importStatic;
static {
if (IfClass.x == 1) {
ifConstant = 1;
} else {
ifConstant = 2;
}
}
static {
if (staticField == 1) {
importStatic = 1;
} else {
importStatic = 2;
}
}
}
class SimpleAssignClass {
public static final int x = 1;
}
class BinaryExpClass {
public static final int x = 1;
}
class UnaryExpClass {
public static final int x = 1;
}
class CastClass {
public static final int x = 1;
}
class ParensClass {
public static final int x = 1;
}
class CondClass {
public static final int x = 1;
}
class IfClass {
public static final int x = 1;
}
/*
* Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package pkg;
public class ClassToBeStaticallyImported {
public static final int staticField = 1;
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册