< prev index next > src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/PoolWriter.java
Print this page
import com.sun.tools.javac.code.Symbol.DynamicMethodSymbol;
import com.sun.tools.javac.code.Symbol.MethodHandleSymbol;
import com.sun.tools.javac.code.Symbol.ModuleSymbol;
import com.sun.tools.javac.code.Symbol.PackageSymbol;
import com.sun.tools.javac.code.Type;
+ import com.sun.tools.javac.code.Type.ConstantPoolQType;
import com.sun.tools.javac.code.Types;
import com.sun.tools.javac.jvm.ClassWriter.PoolOverflow;
import com.sun.tools.javac.jvm.ClassWriter.StringOverflow;
import com.sun.tools.javac.jvm.PoolConstant.LoadableConstant;
import com.sun.tools.javac.jvm.PoolConstant.LoadableConstant.BasicConstant;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayDeque;
import java.util.HashMap;
+ import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.Map;
+ import java.util.Set;
import static com.sun.tools.javac.code.Kinds.Kind.TYP;
import static com.sun.tools.javac.code.TypeTag.ARRAY;
import static com.sun.tools.javac.code.TypeTag.CLASS;
import static com.sun.tools.javac.jvm.ClassFile.CONSTANT_Class;
final SharedSignatureGenerator signatureGen;
/** The inner classes to be written, as an ordered set (enclosing first). */
LinkedHashSet<ClassSymbol> innerClasses = new LinkedHashSet<>();
+ Set<ClassSymbol> preloadClasses = new HashSet<>();
+
/** The list of entries in the BootstrapMethods attribute. */
Map<BsmKey, Integer> bootstrapMethods = new LinkedHashMap<>();
public PoolWriter(Types types, Names names) {
this.types = types;
/**
* Puts a type into the pool and return its index. The type could be either a class, a type variable
* or an array type.
*/
int putClass(Type t) {
+ /* Their is nothing to be gained by having the pair of class types Foo.ref and Foo.val
+ result in two different CONSTANT_Class_info strucures in the pool. These are
+ indistinguishable at the class file level. Hence we coalesce them here.
+ */
+ if (t.isReferenceProjection())
+ t = t.valueProjection();
return pool.writeIfNeeded(types.erasure(t));
}
+ /**
+ * Puts a type into the pool and return its index. The type could be either a class, a type variable
+ * or an array type.
+ */
+ int putClass(ConstantPoolQType t) {
+ return pool.writeIfNeeded(t);
+ }
+
/**
* Puts a member reference into the constant pool. Valid members are either field or method symbols.
*/
int putMember(Symbol s) {
return pool.writeIfNeeded(s);
}
/**
* Enter an inner class into the `innerClasses' set.
*/
- void enterInner(ClassSymbol c) {
+ void enterInnerClass(ClassSymbol c) {
if (c.type.isCompound()) {
throw new AssertionError("Unexpected intersection type: " + c.type);
}
c.complete();
if (c.owner.enclClass() != null && !innerClasses.contains(c)) {
- enterInner(c.owner.enclClass());
+ enterInnerClass(c.owner.enclClass());
innerClasses.add(c);
}
}
+ /** Enter a value class into the `preloadClasses' set.
+ */
+ void enterPreloadClass(ClassSymbol c) {
+ if (c.type.isCompound()) {
+ throw new AssertionError("Unexpected intersection type: " + c.type);
+ }
+ c.complete();
+ preloadClasses.add(c);
+ }
+
/**
* Create a new Utf8 entry representing a descriptor for given (member) symbol.
*/
private Type descriptorType(Symbol s) {
return s.kind == Kind.MTH ? s.externalType(types) : s.erasure(types);
sigbuf.appendName(name);
}
@Override
protected void classReference(ClassSymbol c) {
- enterInner(c);
+ enterInnerClass(c);
}
protected void reset() {
sigbuf.reset();
}
void writeConstant(PoolConstant c) {
int tag = c.poolTag();
switch (tag) {
case ClassFile.CONSTANT_Class: {
- Type ct = (Type)c;
+ Type ct = c instanceof ConstantPoolQType ? ((ConstantPoolQType)c).type : (Type)c;
Name name = ct.hasTag(ARRAY) ?
typeSig(ct) :
- names.fromUtf(externalize(ct.tsym.flatName()));
+ c instanceof ConstantPoolQType ? names.fromString("Q" + new String(externalize(ct.tsym.flatName())) + ";") : names.fromUtf(externalize(ct.tsym.flatName()));
poolbuf.appendByte(tag);
poolbuf.appendChar(putName(name));
if (ct.hasTag(CLASS)) {
- enterInner((ClassSymbol)ct.tsym);
+ enterInnerClass((ClassSymbol)ct.tsym);
}
break;
}
case ClassFile.CONSTANT_Utf8: {
Name name = (Name)c;
return signatureGen.toName();
}
void reset() {
innerClasses.clear();
+ preloadClasses.clear();
bootstrapMethods.clear();
pool.reset();
}
}
< prev index next >