src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Code.java
changeset 54568 b2ed96c35687
parent 52794 e4ba5414c8b4
child 59285 7799a51dbe30
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Code.java	Wed Apr 17 12:41:33 2019 +0200
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Code.java	Wed Apr 17 15:37:20 2019 +0100
@@ -27,15 +27,27 @@
 
 import com.sun.tools.javac.code.*;
 import com.sun.tools.javac.code.Symbol.*;
-import com.sun.tools.javac.code.Types.UniqueType;
 import com.sun.tools.javac.resources.CompilerProperties.Errors;
-import com.sun.tools.javac.tree.JCTree;
 import com.sun.tools.javac.util.*;
 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
 
+import java.util.function.ToIntBiFunction;
+import java.util.function.ToIntFunction;
+
 import static com.sun.tools.javac.code.TypeTag.BOT;
 import static com.sun.tools.javac.code.TypeTag.INT;
 import static com.sun.tools.javac.jvm.ByteCodes.*;
+import static com.sun.tools.javac.jvm.ClassFile.CONSTANT_Class;
+import static com.sun.tools.javac.jvm.ClassFile.CONSTANT_Double;
+import static com.sun.tools.javac.jvm.ClassFile.CONSTANT_Fieldref;
+import static com.sun.tools.javac.jvm.ClassFile.CONSTANT_Float;
+import static com.sun.tools.javac.jvm.ClassFile.CONSTANT_Integer;
+import static com.sun.tools.javac.jvm.ClassFile.CONSTANT_InterfaceMethodref;
+import static com.sun.tools.javac.jvm.ClassFile.CONSTANT_Long;
+import static com.sun.tools.javac.jvm.ClassFile.CONSTANT_MethodHandle;
+import static com.sun.tools.javac.jvm.ClassFile.CONSTANT_MethodType;
+import static com.sun.tools.javac.jvm.ClassFile.CONSTANT_Methodref;
+import static com.sun.tools.javac.jvm.ClassFile.CONSTANT_String;
 import static com.sun.tools.javac.jvm.UninitializedType.*;
 import static com.sun.tools.javac.jvm.ClassWriter.StackMapTableFrame;
 
@@ -72,6 +84,7 @@
 
     final Types types;
     final Symtab syms;
+    final PoolWriter poolWriter;
 
 /*---------- classfile fields: --------------- */
 
@@ -177,10 +190,6 @@
      */
     Position.LineMap lineMap;
 
-    /** The constant pool of the current class.
-     */
-    final Pool pool;
-
     final MethodSymbol meth;
 
     private int letExprStackPos = 0;
@@ -197,7 +206,7 @@
                 CRTable crt,
                 Symtab syms,
                 Types types,
-                Pool pool) {
+                PoolWriter poolWriter) {
         this.meth = meth;
         this.fatcode = fatcode;
         this.lineMap = lineMap;
@@ -206,6 +215,7 @@
         this.crt = crt;
         this.syms = syms;
         this.types = types;
+        this.poolWriter = poolWriter;
         this.debugCode = debugCode;
         this.stackMap = stackMap;
         switch (stackMap) {
@@ -218,7 +228,6 @@
         }
         state = new State();
         lvar = new LocalVar[20];
-        this.pool = pool;
     }
 
 
@@ -389,12 +398,13 @@
 
     /** Emit a ldc (or ldc_w) instruction, taking into account operand size
     */
-    public void emitLdc(int od) {
+    public void emitLdc(LoadableConstant constant) {
+        int od = poolWriter.putConstant(constant);
         if (od <= 255) {
-            emitop1(ldc1, od);
+            emitop1(ldc1, od, constant);
         }
         else {
-            emitop2(ldc2, od);
+            emitop2(ldc2, od, constant);
         }
     }
 
@@ -431,11 +441,11 @@
 
     /** Emit an invokeinterface instruction.
      */
-    public void emitInvokeinterface(int meth, Type mtype) {
+    public void emitInvokeinterface(Symbol member, Type mtype) {
         int argsize = width(mtype.getParameterTypes());
         emitop(invokeinterface);
         if (!alive) return;
-        emit2(meth);
+        emit2(poolWriter.putMember(member));
         emit1(argsize + 1);
         emit1(0);
         state.pop(argsize + 1);
@@ -444,14 +454,13 @@
 
     /** Emit an invokespecial instruction.
      */
-    public void emitInvokespecial(int meth, Type mtype) {
+    public void emitInvokespecial(Symbol member, Type mtype) {
         int argsize = width(mtype.getParameterTypes());
         emitop(invokespecial);
         if (!alive) return;
-        emit2(meth);
-        Symbol sym = (Symbol)pool.pool[meth];
+        emit2(poolWriter.putMember(member));
         state.pop(argsize);
-        if (sym.isConstructor())
+        if (member.isConstructor())
             state.markInitialized((UninitializedType)state.peek());
         state.pop(1);
         state.push(mtype.getReturnType());
@@ -459,33 +468,33 @@
 
     /** Emit an invokestatic instruction.
      */
-    public void emitInvokestatic(int meth, Type mtype) {
+    public void emitInvokestatic(Symbol member, Type mtype) {
         int argsize = width(mtype.getParameterTypes());
         emitop(invokestatic);
         if (!alive) return;
-        emit2(meth);
+        emit2(poolWriter.putMember(member));
         state.pop(argsize);
         state.push(mtype.getReturnType());
     }
 
     /** Emit an invokevirtual instruction.
      */
-    public void emitInvokevirtual(int meth, Type mtype) {
+    public void emitInvokevirtual(Symbol member, Type mtype) {
         int argsize = width(mtype.getParameterTypes());
         emitop(invokevirtual);
         if (!alive) return;
-        emit2(meth);
+        emit2(poolWriter.putMember(member));
         state.pop(argsize + 1);
         state.push(mtype.getReturnType());
     }
 
     /** Emit an invokedynamic instruction.
      */
-    public void emitInvokedynamic(int desc, Type mtype) {
+    public void emitInvokedynamic(DynamicMethodSymbol dynMember, Type mtype) {
         int argsize = width(mtype.getParameterTypes());
         emitop(invokedynamic);
         if (!alive) return;
-        emit2(desc);
+        emit2(poolWriter.putDynamic(dynMember));
         emit2(0);
         state.pop(argsize);
         state.push(mtype.getReturnType());
@@ -896,6 +905,10 @@
     /** Emit an opcode with a one-byte operand field.
      */
     public void emitop1(int op, int od) {
+        emitop1(op, od, null);
+    }
+
+    public void emitop1(int op, int od, PoolConstant data) {
         emitop(op);
         if (!alive) return;
         emit1(od);
@@ -904,7 +917,7 @@
             state.push(syms.intType);
             break;
         case ldc1:
-            state.push(typeForPool(pool.pool[od]));
+            state.push(types.constantType((LoadableConstant)data));
             break;
         default:
             throw new AssertionError(mnem(op));
@@ -912,25 +925,6 @@
         postop();
     }
 
-    /** The type of a constant pool entry. */
-    private Type typeForPool(Object o) {
-        if (o instanceof Integer) return syms.intType;
-        if (o instanceof Float) return syms.floatType;
-        if (o instanceof String) return syms.stringType;
-        if (o instanceof Long) return syms.longType;
-        if (o instanceof Double) return syms.doubleType;
-        if (o instanceof ClassSymbol) return syms.classType;
-        if (o instanceof Pool.MethodHandle) return syms.methodHandleType;
-        if (o instanceof UniqueType) return typeForPool(((UniqueType)o).type);
-        if (o instanceof Type) {
-            Type ty = (Type) o;
-
-            if (ty instanceof Type.ArrayType) return syms.classType;
-            if (ty instanceof Type.MethodType) return syms.methodTypeType;
-        }
-        throw new AssertionError("Invalid type of constant pool entry: " + o.getClass());
-    }
-
     /** Emit an opcode with a one-byte operand field;
      *  widen if field does not fit in a byte.
      */
@@ -1003,29 +997,31 @@
 
     /** Emit an opcode with a two-byte operand field.
      */
+    public <P extends PoolConstant> void emitop2(int op, P constant, ToIntBiFunction<PoolWriter, P> poolFunc) {
+        int od = poolFunc.applyAsInt(poolWriter, constant);
+        emitop2(op, od, constant);
+    }
+
     public void emitop2(int op, int od) {
+        emitop2(op, od, null);
+    }
+
+    public void emitop2(int op, int od, PoolConstant data) {
         emitop(op);
         if (!alive) return;
         emit2(od);
         switch (op) {
         case getstatic:
-            state.push(((Symbol)(pool.pool[od])).erasure(types));
+            state.push(((Symbol)data).erasure(types));
             break;
         case putstatic:
-            state.pop(((Symbol)(pool.pool[od])).erasure(types));
+            state.pop(((Symbol)data).erasure(types));
             break;
-        case new_:
-            Symbol sym;
-            if (pool.pool[od] instanceof UniqueType) {
-                // Required by change in Gen.makeRef to allow
-                // annotated types.
-                // TODO: is this needed anywhere else?
-                sym = ((UniqueType)(pool.pool[od])).type.tsym;
-            } else {
-                sym = (Symbol)(pool.pool[od]);
-            }
-            state.push(uninitializedObject(sym.erasure(types), cp-3));
+        case new_: {
+            Type t = (Type)data;
+            state.push(uninitializedObject(t.tsym.erasure(types), cp-3));
             break;
+        }
         case sipush:
             state.push(syms.intType);
             break;
@@ -1053,30 +1049,27 @@
             markDead();
             break;
         case putfield:
-            state.pop(((Symbol)(pool.pool[od])).erasure(types));
+            state.pop(((Symbol)data).erasure(types));
             state.pop(1); // object ref
             break;
         case getfield:
             state.pop(1); // object ref
-            state.push(((Symbol)(pool.pool[od])).erasure(types));
+            state.push(((Symbol)data).erasure(types));
             break;
         case checkcast: {
             state.pop(1); // object ref
-            Object o = pool.pool[od];
-            Type t = (o instanceof Symbol)
-                ? ((Symbol)o).erasure(types)
-                : types.erasure((((UniqueType)o).type));
+            Type t = types.erasure((Type)data);
             state.push(t);
             break; }
         case ldc2w:
-            state.push(typeForPool(pool.pool[od]));
+            state.push(types.constantType((LoadableConstant)data));
             break;
         case instanceof_:
             state.pop(1);
             state.push(syms.intType);
             break;
         case ldc2:
-            state.push(typeForPool(pool.pool[od]));
+            state.push(types.constantType((LoadableConstant)data));
             break;
         case jsr:
             break;