< prev index next >

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

Print this page
*** 31,10 ***
--- 31,11 ---
  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;

*** 48,13 ***
--- 49,15 ---
  
  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;

*** 91,10 ***
--- 94,12 ---
      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;

*** 113,13 ***
--- 118,27 ---
      /**
       * 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);

*** 218,21 ***
      }
  
      /**
       * Enter an inner class into the `innerClasses' set.
       */
!     void enterInner(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());
              innerClasses.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);
--- 237,31 ---
      }
  
      /**
       * Enter an inner class into the `innerClasses' set.
       */
!     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)) {
!             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);

*** 314,11 ***
              sigbuf.appendName(name);
          }
  
          @Override
          protected void classReference(ClassSymbol c) {
!             enterInner(c);
          }
  
          protected void reset() {
              sigbuf.reset();
          }
--- 343,11 ---
              sigbuf.appendName(name);
          }
  
          @Override
          protected void classReference(ClassSymbol c) {
!             enterInnerClass(c);
          }
  
          protected void reset() {
              sigbuf.reset();
          }

*** 360,18 ***
  
          void writeConstant(PoolConstant c) {
              int tag = c.poolTag();
              switch (tag) {
                  case ClassFile.CONSTANT_Class: {
!                     Type ct = (Type)c;
                      Name name = ct.hasTag(ARRAY) ?
                              typeSig(ct) :
!                             names.fromUtf(externalize(ct.tsym.flatName()));
                      poolbuf.appendByte(tag);
                      poolbuf.appendChar(putName(name));
                      if (ct.hasTag(CLASS)) {
!                         enterInner((ClassSymbol)ct.tsym);
                      }
                      break;
                  }
                  case ClassFile.CONSTANT_Utf8: {
                      Name name = (Name)c;
--- 389,18 ---
  
          void writeConstant(PoolConstant c) {
              int tag = c.poolTag();
              switch (tag) {
                  case ClassFile.CONSTANT_Class: {
!                     Type ct = c instanceof ConstantPoolQType ? ((ConstantPoolQType)c).type : (Type)c;
                      Name name = ct.hasTag(ARRAY) ?
                              typeSig(ct) :
!                             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)) {
!                         enterInnerClass((ClassSymbol)ct.tsym);
                      }
                      break;
                  }
                  case ClassFile.CONSTANT_Utf8: {
                      Name name = (Name)c;

*** 500,14 ***
--- 529,16 ---
              signatureGen.assembleParamsSig(typarams);
          }
          signatureGen.assembleSig(types.supertype(t));
          for (Type i : types.interfaces(t))
              signatureGen.assembleSig(i);
+ 
          return signatureGen.toName();
      }
  
      void reset() {
          innerClasses.clear();
+         preloadClasses.clear();
          bootstrapMethods.clear();
          pool.reset();
      }
  }
< prev index next >