< prev index next >

src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Gen.java

Print this page

        

*** 1,7 **** /* ! * Copyright (c) 1999, 2019, 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 --- 1,7 ---- /* ! * Copyright (c) 1999, 2018, 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
*** 23,41 **** * questions. */ package com.sun.tools.javac.jvm; ! import com.sun.tools.javac.jvm.PoolConstant.LoadableConstant; import com.sun.tools.javac.tree.TreeInfo.PosKind; import com.sun.tools.javac.util.*; import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition; import com.sun.tools.javac.util.List; import com.sun.tools.javac.code.*; import com.sun.tools.javac.code.Attribute.TypeCompound; import com.sun.tools.javac.code.Symbol.VarSymbol; import com.sun.tools.javac.comp.*; import com.sun.tools.javac.tree.*; import com.sun.tools.javac.code.Symbol.*; import com.sun.tools.javac.code.Type.*; import com.sun.tools.javac.jvm.Code.*; --- 23,45 ---- * questions. */ package com.sun.tools.javac.jvm; ! ! import java.util.Optional; ! import com.sun.tools.javac.tree.TreeInfo.PosKind; import com.sun.tools.javac.util.*; import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition; import com.sun.tools.javac.util.List; import com.sun.tools.javac.code.*; import com.sun.tools.javac.code.Attribute.TypeCompound; + import com.sun.tools.javac.code.Source.Feature; import com.sun.tools.javac.code.Symbol.VarSymbol; import com.sun.tools.javac.comp.*; + import com.sun.tools.javac.resources.CompilerProperties.Errors; import com.sun.tools.javac.tree.*; import com.sun.tools.javac.code.Symbol.*; import com.sun.tools.javac.code.Type.*; import com.sun.tools.javac.jvm.Code.*;
*** 72,81 **** --- 76,86 ---- private final Name accessDollar; private final Types types; private final Lower lower; private final Annotate annotate; private final StringConcat concat; + private final Constables constables; /** Format of stackmap tables to be generated. */ private final Code.StackMapFormat stackMap; /** A type that serves as the expected type for all method expressions.
*** 87,99 **** if (instance == null) instance = new Gen(context); return instance; } ! /** Constant pool writer, set by genClass. */ ! final PoolWriter poolWriter; protected Gen(Context context) { context.put(genKey, this); names = Names.instance(context); --- 92,104 ---- if (instance == null) instance = new Gen(context); return instance; } ! /** Constant pool, reset by genClass. */ ! private final Pool pool; protected Gen(Context context) { context.put(genKey, this); names = Names.instance(context);
*** 103,112 **** --- 108,118 ---- rs = Resolve.instance(context); make = TreeMaker.instance(context); target = Target.instance(context); types = Types.instance(context); concat = StringConcat.instance(context); + constables = Constables.instance(context); methodType = new MethodType(null, null, null, syms.methodClass); accessDollar = names. fromString("access" + target.syntheticNameChar()); lower = Lower.instance(context);
*** 119,130 **** options.isUnset(G_CUSTOM) ? options.isSet(G) : options.isSet(G_CUSTOM, "vars"); genCrt = options.isSet(XJCOV); debugCode = options.isSet("debug.code"); disableVirtualizedPrivateInvoke = options.isSet("disableVirtualizedPrivateInvoke"); ! poolWriter = new PoolWriter(types, names); // ignore cldc because we cannot have both stackmap formats this.stackMap = StackMapFormat.JSR202; annotate = Annotate.instance(context); } --- 125,142 ---- options.isUnset(G_CUSTOM) ? options.isSet(G) : options.isSet(G_CUSTOM, "vars"); genCrt = options.isSet(XJCOV); debugCode = options.isSet("debug.code"); + // format: -XDfolding=true, which is the default, or -XDfolding=false + String foldingOp = options.get("folding"); + Source source = Source.instance(context); + doConstantFold = foldingOp != null ? + foldingOp.equals("true") : + Feature.CONSTABLES.allowedInSource(source); disableVirtualizedPrivateInvoke = options.isSet("disableVirtualizedPrivateInvoke"); ! pool = new Pool(types); // ignore cldc because we cannot have both stackmap formats this.stackMap = StackMapFormat.JSR202; annotate = Annotate.instance(context); }
*** 133,142 **** --- 145,155 ---- */ private final boolean lineDebugInfo; private final boolean varDebugInfo; private final boolean genCrt; private final boolean debugCode; + private final boolean doConstantFold; private boolean disableVirtualizedPrivateInvoke; /** Code buffer, set by genMethod. */ private Code code;
*** 251,271 **** * checking for an array with too many dimensions; * return the reference's index. * @param type The type for which a reference is inserted. */ int makeRef(DiagnosticPosition pos, Type type) { ! return poolWriter.putClass(checkDimension(pos, type)); } /** Check if the given type is an array with too many dimensions. */ ! private Type checkDimension(DiagnosticPosition pos, Type t) { ! checkDimensionInternal(pos, t); ! return t; ! } ! ! private void checkDimensionInternal(DiagnosticPosition pos, Type t) { switch (t.getTag()) { case METHOD: checkDimension(pos, t.getReturnType()); for (List<Type> args = t.getParameterTypes(); args.nonEmpty(); args = args.tail) checkDimension(pos, args.head); --- 264,284 ---- * checking for an array with too many dimensions; * return the reference's index. * @param type The type for which a reference is inserted. */ int makeRef(DiagnosticPosition pos, Type type) { ! checkDimension(pos, type); ! if (type.isAnnotated()) { ! return pool.put((Object)type); ! } else { ! return pool.put(type.hasTag(CLASS) ? (Object)type.tsym : (Object)type); ! } } /** Check if the given type is an array with too many dimensions. */ ! private void checkDimension(DiagnosticPosition pos, Type t) { switch (t.getTag()) { case METHOD: checkDimension(pos, t.getReturnType()); for (List<Type> args = t.getParameterTypes(); args.nonEmpty(); args = args.tail) checkDimension(pos, args.head);
*** 437,447 **** JCStatement init = make.at(vdef.pos()). Assignment(sym, vdef.init); initCode.append(init); endPosTable.replaceTree(vdef, init); initTAs.addAll(getAndRemoveNonFieldTAs(sym)); ! } else if (sym.getConstValue() == null) { // Initialize class (static) variables only if // they are not compile-time constants. JCStatement init = make.at(vdef.pos). Assignment(sym, vdef.init); clinitCode.append(init); --- 450,461 ---- JCStatement init = make.at(vdef.pos()). Assignment(sym, vdef.init); initCode.append(init); endPosTable.replaceTree(vdef, init); initTAs.addAll(getAndRemoveNonFieldTAs(sym)); ! } else if (sym.getConstValue() == null || ! (doConstantFold && !constables.skipCodeGeneration(vdef))) { // Initialize class (static) variables only if // they are not compile-time constants. JCStatement init = make.at(vdef.pos). Assignment(sym, vdef.init); clinitCode.append(init);
*** 515,525 **** */ private void checkStringConstant(DiagnosticPosition pos, Object constValue) { if (nerrs != 0 || // only complain about a long string once constValue == null || !(constValue instanceof String) || ! ((String)constValue).length() < PoolWriter.MAX_STRING_LENGTH) return; log.error(pos, Errors.LimitString); nerrs++; } --- 529,539 ---- */ private void checkStringConstant(DiagnosticPosition pos, Object constValue) { if (nerrs != 0 || // only complain about a long string once constValue == null || !(constValue instanceof String) || ! ((String)constValue).length() < Pool.MAX_STRING_LENGTH) return; log.error(pos, Errors.LimitString); nerrs++; }
*** 805,815 **** } @Override public void visitIdent(JCIdent tree) { if (tree.sym.owner instanceof ClassSymbol) { ! poolWriter.putClass((ClassSymbol)tree.sym.owner); } } @Override public void visitConditional(JCConditional tree) { --- 819,829 ---- } @Override public void visitIdent(JCIdent tree) { if (tree.sym.owner instanceof ClassSymbol) { ! pool.put(tree.sym.owner); } } @Override public void visitConditional(JCConditional tree) {
*** 866,881 **** } finally { this.pt = prevPt; } } - public boolean isConstantDynamic(Symbol sym) { - return sym.kind == VAR && - sym instanceof DynamicVarSymbol && - ((DynamicVarSymbol)sym).isDynamic(); - } - /** Derived visitor method: generate code for a list of method arguments. * @param trees The argument expressions to be visited. * @param pts The expression's expected types (i.e. the formal parameter * types of the invoked method). */ --- 880,889 ----
*** 1017,1028 **** debugCode, genCrt ? new CRTable(tree, env.toplevel.endPositions) : null, syms, types, ! poolWriter); ! items = new Items(poolWriter, code, syms, types); if (code.debugCode) { System.err.println(meth + " for body " + tree); } // If method is not static, create a new local variable address --- 1025,1036 ---- debugCode, genCrt ? new CRTable(tree, env.toplevel.endPositions) : null, syms, types, ! pool); ! items = new Items(pool, code, syms, types); if (code.debugCode) { System.err.println(meth + " for body " + tree); } // If method is not static, create a new local variable address
*** 1055,1065 **** public void visitVarDef(JCVariableDecl tree) { VarSymbol v = tree.sym; if (tree.init != null) { checkStringConstant(tree.init.pos(), v.getConstValue()); ! if (v.getConstValue() == null || varDebugInfo) { Assert.check(code.isStatementStart()); code.newLocal(v); genExpr(tree.init, v.erasure(types)).load(); items.makeLocalItem(v).store(); Assert.check(code.isStatementStart()); --- 1063,1076 ---- public void visitVarDef(JCVariableDecl tree) { VarSymbol v = tree.sym; if (tree.init != null) { checkStringConstant(tree.init.pos(), v.getConstValue()); ! if (v.getConstValue() == null || ! varDebugInfo || ! (doConstantFold && !constables.skipCodeGeneration(tree))) { ! code.newLocal(v); Assert.check(code.isStatementStart()); code.newLocal(v); genExpr(tree.init, v.erasure(types)).load(); items.makeLocalItem(v).store(); Assert.check(code.isStatementStart());
*** 1809,1830 **** * Visitor methods for expressions *************************************************************************/ public void visitApply(JCMethodInvocation tree) { setTypeAnnotationPositions(tree.pos); - // Generate code for method. - Item m = genExpr(tree.meth, methodType); - // Generate code for all arguments, where the expected types are - // the parameters of the method's external type (that is, any implicit - // outer instance of a super(...) call appears as first parameter). MethodSymbol msym = (MethodSymbol)TreeInfo.symbol(tree.meth); ! genArgs(tree.args, ! msym.externalType(types).getParameterTypes()); ! if (!msym.isDynamic()) { ! code.statBegin(tree.pos); } - result = m.invoke(); } public void visitConditional(JCConditional tree) { Chain thenExit = null; code.statBegin(tree.cond.pos); --- 1820,1855 ---- * Visitor methods for expressions *************************************************************************/ public void visitApply(JCMethodInvocation tree) { setTypeAnnotationPositions(tree.pos); MethodSymbol msym = (MethodSymbol)TreeInfo.symbol(tree.meth); ! Item m; ! if (msym.isIntrinsicsLDC()) { ! Object constant = ((IntrinsicsLDCMethodSymbol)msym).getConstant(); ! // primitives special case ! if (constant instanceof VarSymbol && ((VarSymbol)constant).name == names.TYPE) { ! m = items.makeStaticItem((Symbol)constant); ! } else if (constant instanceof Pool.DynamicVariable) { ! m = items.makeCondyItem((Pool.DynamicVariable)constant); ! } else { ! m = items.makeImmediateItem(pt, constant); ! } ! result = m.coerce(pt).load(); ! } else { ! // Generate code for method. ! m = genExpr(tree.meth, methodType); ! // Generate code for all arguments, where the expected types are ! // the parameters of the method's external type (that is, any implicit ! // outer instance of a super(...) call appears as first parameter). ! genArgs(tree.args, ! msym.externalType(types).getParameterTypes()); ! if (!msym.isDynamic()) { ! code.statBegin(tree.pos); ! } ! result = m.invoke(); } } public void visitConditional(JCConditional tree) { Chain thenExit = null; code.statBegin(tree.cond.pos);
*** 1896,1906 **** // Enclosing instances or anonymous classes should have been eliminated // by now. Assert.check(tree.encl == null && tree.def == null); setTypeAnnotationPositions(tree.pos); ! code.emitop2(new_, checkDimension(tree.pos(), tree.type), PoolWriter::putClass); code.emitop0(dup); // Generate code for all arguments, where the expected types are // the parameters of the constructor's external type (that is, // any implicit outer instance appears as first parameter). --- 1921,1931 ---- // Enclosing instances or anonymous classes should have been eliminated // by now. Assert.check(tree.encl == null && tree.def == null); setTypeAnnotationPositions(tree.pos); ! code.emitop2(new_, makeRef(tree.pos(), tree.type)); code.emitop0(dup); // Generate code for all arguments, where the expected types are // the parameters of the constructor's external type (that is, // any implicit outer instance appears as first parameter).
*** 2172,2182 **** // For basic types, the coerce(...) in genExpr(...) will do // the conversion. if (!tree.clazz.type.isPrimitive() && !types.isSameType(tree.expr.type, tree.clazz.type) && types.asSuper(tree.expr.type, tree.clazz.type.tsym) == null) { ! code.emitop2(checkcast, checkDimension(tree.pos(), tree.clazz.type), PoolWriter::putClass); } } public void visitWildcard(JCWildcard tree) { throw new AssertionError(this.getClass().getName()); --- 2197,2207 ---- // For basic types, the coerce(...) in genExpr(...) will do // the conversion. if (!tree.clazz.type.isPrimitive() && !types.isSameType(tree.expr.type, tree.clazz.type) && types.asSuper(tree.expr.type, tree.clazz.type.tsym) == null) { ! code.emitop2(checkcast, makeRef(tree.pos(), tree.clazz.type)); } } public void visitWildcard(JCWildcard tree) { throw new AssertionError(this.getClass().getName());
*** 2205,2215 **** // Generate code to address the constructor. res.load(); res = items.makeMemberItem(sym, true); } result = res; ! } else if (isInvokeDynamic(sym) || isConstantDynamic(sym)) { if (isConstantDynamic(sym)) { setTypeAnnotationPositions(tree.pos); } result = items.makeDynamicItem(sym); } else if (sym.kind == VAR && (sym.owner.kind == MTH || sym.owner.kind == VAR)) { --- 2230,2240 ---- // Generate code to address the constructor. res.load(); res = items.makeMemberItem(sym, true); } result = res; ! } else if (isInvokeDynamic(sym) || isConstantDynamic(sym)) { if (isConstantDynamic(sym)) { setTypeAnnotationPositions(tree.pos); } result = items.makeDynamicItem(sym); } else if (sym.kind == VAR && (sym.owner.kind == MTH || sym.owner.kind == VAR)) {
*** 2230,2244 **** boolean useVirtual = target.hasVirtualPrivateInvoke() && !disableVirtualizedPrivateInvoke; return !useVirtual && ((sym.flags() & PRIVATE) != 0); } public void visitSelect(JCFieldAccess tree) { Symbol sym = tree.sym; if (tree.name == names._class) { ! code.emitLdc((LoadableConstant)checkDimension(tree.pos(), tree.selected.type)); result = items.makeStackItem(pt); return; } Symbol ssym = TreeInfo.symbol(tree.selected); --- 2255,2275 ---- boolean useVirtual = target.hasVirtualPrivateInvoke() && !disableVirtualizedPrivateInvoke; return !useVirtual && ((sym.flags() & PRIVATE) != 0); } + public boolean isConstantDynamic(Symbol sym) { + return sym.kind == VAR && + sym instanceof DynamicVarSymbol && + ((DynamicVarSymbol)sym).isDynamic(); + } + public void visitSelect(JCFieldAccess tree) { Symbol sym = tree.sym; if (tree.name == names._class) { ! code.emitLdc(makeRef(tree.pos(), tree.selected.type)); result = items.makeStackItem(pt); return; } Symbol ssym = TreeInfo.symbol(tree.selected);
*** 2307,2318 **** else result = items.makeImmediateItem(tree.type, tree.value); } public void visitLetExpr(LetExpr tree) { - code.resolvePending(); - int limit = code.nextreg; int prevLetExprStart = code.setLetExprStackPos(code.state.stacksize); try { genStats(tree.defs, env); } finally { --- 2338,2347 ----
*** 2320,2330 **** } result = genExpr(tree.expr, tree.expr.type).load(); code.endScopes(limit); } ! private void generateReferencesToPrunedTree(ClassSymbol classSymbol) { List<JCTree> prunedInfo = lower.prunedTree.get(classSymbol); if (prunedInfo != null) { for (JCTree prunedTree: prunedInfo) { prunedTree.accept(classReferenceVisitor); } --- 2349,2359 ---- } result = genExpr(tree.expr, tree.expr.type).load(); 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); }
*** 2346,2367 **** try { attrEnv = env; ClassSymbol c = cdef.sym; this.toplevel = env.toplevel; this.endPosTable = toplevel.endPositions; /* method normalizeDefs() can add references to external classes into the constant pool */ cdef.defs = normalizeDefs(cdef.defs, c); ! generateReferencesToPrunedTree(c); Env<GenContext> localEnv = new Env<>(cdef, new GenContext()); localEnv.toplevel = env.toplevel; localEnv.enclClass = cdef; for (List<JCTree> l = cdef.defs; l.nonEmpty(); l = l.tail) { genDef(l.head, localEnv); } ! if (poolWriter.size() > PoolWriter.MAX_ENTRIES) { log.error(cdef.pos(), Errors.LimitPool); nerrs++; } if (nerrs != 0) { // if errors, discard code --- 2375,2398 ---- try { attrEnv = env; ClassSymbol c = cdef.sym; this.toplevel = env.toplevel; this.endPosTable = toplevel.endPositions; + c.pool = pool; + pool.reset(); /* method normalizeDefs() can add references to external classes into the constant pool */ cdef.defs = normalizeDefs(cdef.defs, c); ! generateReferencesToPrunedTree(c, pool); Env<GenContext> localEnv = new Env<>(cdef, new GenContext()); localEnv.toplevel = env.toplevel; localEnv.enclClass = cdef; for (List<JCTree> l = cdef.defs; l.nonEmpty(); l = l.tail) { genDef(l.head, localEnv); } ! if (pool.numEntries() > Pool.MAX_ENTRIES) { log.error(cdef.pos(), Errors.LimitPool); nerrs++; } if (nerrs != 0) { // if errors, discard code
< prev index next >