< prev index next >

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

Print this page

        

@@ -25,31 +25,20 @@
 
 package com.sun.tools.javac.jvm;
 
 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.jvm.Pool.DynamicVariable;
+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;
 
 /** An internal structure that corresponds to the code attribute of
  *  methods in a classfile. The class also provides some utility operations to

@@ -82,11 +71,10 @@
         }
     }
 
     final Types types;
     final Symtab syms;
-    final PoolWriter poolWriter;
 
 /*---------- classfile fields: --------------- */
 
     /** The maximum stack size.
      */

@@ -188,10 +176,14 @@
 
     /** Emit line number info if map supplied
      */
     Position.LineMap lineMap;
 
+    /** The constant pool of the current class.
+     */
+    final Pool pool;
+
     final MethodSymbol meth;
 
     private int letExprStackPos = 0;
 
     /** Construct a code object, given the settings of the fatcode,

@@ -204,20 +196,19 @@
                 StackMapFormat stackMap,
                 boolean debugCode,
                 CRTable crt,
                 Symtab syms,
                 Types types,
-                PoolWriter poolWriter) {
+                Pool pool) {
         this.meth = meth;
         this.fatcode = fatcode;
         this.lineMap = lineMap;
         this.lineDebugInfo = lineMap != null;
         this.varDebugInfo = varDebugInfo;
         this.crt = crt;
         this.syms = syms;
         this.types = types;
-        this.poolWriter = poolWriter;
         this.debugCode = debugCode;
         this.stackMap = stackMap;
         switch (stackMap) {
         case CLDC:
         case JSR202:

@@ -226,10 +217,11 @@
         default:
             this.needStackMap = false;
         }
         state = new State();
         lvar = new LocalVar[20];
+        this.pool = pool;
     }
 
 
 /* **************************************************************************
  * Typecodes & related stuff

@@ -396,17 +388,16 @@
         Assert.check(alive || isStatementStart());
     }
 
     /** Emit a ldc (or ldc_w) instruction, taking into account operand size
     */
-    public void emitLdc(LoadableConstant constant) {
-        int od = poolWriter.putConstant(constant);
+    public void emitLdc(int od) {
         if (od <= 255) {
-            emitop1(ldc1, od, constant);
+            emitop1(ldc1, od);
         }
         else {
-            emitop2(ldc2, od, constant);
+            emitop2(ldc2, od);
         }
     }
 
     /** Emit a multinewarray instruction.
      */

@@ -439,64 +430,65 @@
         state.push(arrayType);
     }
 
     /** Emit an invokeinterface instruction.
      */
-    public void emitInvokeinterface(Symbol member, Type mtype) {
+    public void emitInvokeinterface(int meth, Type mtype) {
         int argsize = width(mtype.getParameterTypes());
         emitop(invokeinterface);
         if (!alive) return;
-        emit2(poolWriter.putMember(member));
+        emit2(meth);
         emit1(argsize + 1);
         emit1(0);
         state.pop(argsize + 1);
         state.push(mtype.getReturnType());
     }
 
     /** Emit an invokespecial instruction.
      */
-    public void emitInvokespecial(Symbol member, Type mtype) {
+    public void emitInvokespecial(int meth, Type mtype) {
         int argsize = width(mtype.getParameterTypes());
         emitop(invokespecial);
         if (!alive) return;
-        emit2(poolWriter.putMember(member));
+        emit2(meth);
+        Symbol sym = (Symbol)pool.pool[meth];
         state.pop(argsize);
-        if (member.isConstructor())
+        if (sym.isConstructor())
             state.markInitialized((UninitializedType)state.peek());
         state.pop(1);
         state.push(mtype.getReturnType());
     }
 
     /** Emit an invokestatic instruction.
      */
-    public void emitInvokestatic(Symbol member, Type mtype) {
+    public void emitInvokestatic(int meth, Type mtype) {
         int argsize = width(mtype.getParameterTypes());
         emitop(invokestatic);
         if (!alive) return;
-        emit2(poolWriter.putMember(member));
+        emit2(meth);
         state.pop(argsize);
         state.push(mtype.getReturnType());
     }
 
     /** Emit an invokevirtual instruction.
      */
-    public void emitInvokevirtual(Symbol member, Type mtype) {
+    public void emitInvokevirtual(int meth, Type mtype) {
         int argsize = width(mtype.getParameterTypes());
         emitop(invokevirtual);
         if (!alive) return;
-        emit2(poolWriter.putMember(member));
+        emit2(meth);
         state.pop(argsize + 1);
         state.push(mtype.getReturnType());
     }
 
     /** Emit an invokedynamic instruction.
      */
-    public void emitInvokedynamic(DynamicMethodSymbol dynMember, Type mtype) {
+    public void emitInvokedynamic(int desc, Type mtype) {
         int argsize = width(mtype.getParameterTypes());
         emitop(invokedynamic);
         if (!alive) return;
-        emit2(poolWriter.putDynamic(dynMember));
+        emit2(desc);
         emit2(0);
         state.pop(argsize);
         state.push(mtype.getReturnType());
     }
 

@@ -903,30 +895,46 @@
     }
 
     /** 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);
         switch (op) {
         case bipush:
             state.push(syms.intType);
             break;
         case ldc1:
-            state.push(types.constantType((LoadableConstant)data));
+            state.push(typeForPool(pool.pool[od]));
             break;
         default:
             throw new AssertionError(mnem(op));
         }
         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 Pool.DynamicVariable) return ((Pool.DynamicVariable)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.
      */
     public void emitop1w(int op, int od) {
         if (od > 0xFF) {

@@ -995,35 +1003,33 @@
         }
     }
 
     /** 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)data).erasure(types));
+            state.push(((Symbol)(pool.pool[od])).erasure(types));
             break;
         case putstatic:
-            state.pop(((Symbol)data).erasure(types));
+            state.pop(((Symbol)(pool.pool[od])).erasure(types));
             break;
-        case new_: {
-            Type t = (Type)data;
-            state.push(uninitializedObject(t.tsym.erasure(types), cp-3));
+        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));
             break;
-        }
         case sipush:
             state.push(syms.intType);
             break;
         case if_acmp_null:
         case if_acmp_nonnull:

@@ -1047,31 +1053,34 @@
             break;
         case goto_:
             markDead();
             break;
         case putfield:
-            state.pop(((Symbol)data).erasure(types));
+            state.pop(((Symbol)(pool.pool[od])).erasure(types));
             state.pop(1); // object ref
             break;
         case getfield:
             state.pop(1); // object ref
-            state.push(((Symbol)data).erasure(types));
+            state.push(((Symbol)(pool.pool[od])).erasure(types));
             break;
         case checkcast: {
             state.pop(1); // object ref
-            Type t = types.erasure((Type)data);
+            Object o = pool.pool[od];
+            Type t = (o instanceof Symbol)
+                ? ((Symbol)o).erasure(types)
+                : types.erasure((((UniqueType)o).type));
             state.push(t);
             break; }
         case ldc2w:
-            state.push(types.constantType((LoadableConstant)data));
+            state.push(typeForPool(pool.pool[od]));
             break;
         case instanceof_:
             state.pop(1);
             state.push(syms.intType);
             break;
         case ldc2:
-            state.push(types.constantType((LoadableConstant)data));
+            state.push(typeForPool(pool.pool[od]));
             break;
         case jsr:
             break;
         default:
             throw new AssertionError(mnem(op));
< prev index next >