< prev index next >

src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.java/src/org/graalvm/compiler/java/BytecodeParser.java

Print this page

        

@@ -1,7 +1,7 @@
 /*
- * Copyright (c) 2009, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2017, 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.

@@ -372,10 +372,11 @@
 import org.graalvm.compiler.nodes.extended.LoadMethodNode;
 import org.graalvm.compiler.nodes.extended.MembarNode;
 import org.graalvm.compiler.nodes.extended.StateSplitProxyNode;
 import org.graalvm.compiler.nodes.extended.ValueAnchorNode;
 import org.graalvm.compiler.nodes.graphbuilderconf.ClassInitializationPlugin;
+import org.graalvm.compiler.nodes.graphbuilderconf.InvokeDynamicPlugin;
 import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderConfiguration;
 import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderConfiguration.BytecodeExceptionMode;
 import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderContext;
 import org.graalvm.compiler.nodes.graphbuilderconf.InlineInvokePlugin;
 import org.graalvm.compiler.nodes.graphbuilderconf.InlineInvokePlugin.InlineInfo;

@@ -931,97 +932,110 @@
 
     /**
      * @param type the unresolved type of the constant
      */
     protected void handleUnresolvedLoadConstant(JavaType type) {
-        assert !graphBuilderConfig.eagerResolving();
-        append(new DeoptimizeNode(InvalidateRecompile, Unresolved));
+        assert !graphBuilderConfig.unresolvedIsError();
+        DeoptimizeNode deopt = append(new DeoptimizeNode(InvalidateRecompile, Unresolved));
+        /*
+         * Track source position for deopt nodes even if
+         * GraphBuilderConfiguration.trackNodeSourcePosition is not set.
+         */
+        deopt.updateNodeSourcePosition(() -> createBytecodePosition());
     }
 
     /**
      * @param type the unresolved type of the type check
      * @param object the object value whose type is being checked against {@code type}
      */
     protected void handleUnresolvedCheckCast(JavaType type, ValueNode object) {
-        assert !graphBuilderConfig.eagerResolving();
+        assert !graphBuilderConfig.unresolvedIsError();
         append(new FixedGuardNode(graph.addOrUniqueWithInputs(IsNullNode.create(object)), Unresolved, InvalidateRecompile));
         frameState.push(JavaKind.Object, appendConstant(JavaConstant.NULL_POINTER));
     }
 
     /**
      * @param type the unresolved type of the type check
      * @param object the object value whose type is being checked against {@code type}
      */
     protected void handleUnresolvedInstanceOf(JavaType type, ValueNode object) {
-        assert !graphBuilderConfig.eagerResolving();
+        assert !graphBuilderConfig.unresolvedIsError();
         AbstractBeginNode successor = graph.add(new BeginNode());
         DeoptimizeNode deopt = graph.add(new DeoptimizeNode(InvalidateRecompile, Unresolved));
+        deopt.updateNodeSourcePosition(() -> createBytecodePosition());
         append(new IfNode(graph.addOrUniqueWithInputs(IsNullNode.create(object)), successor, deopt, 1));
         lastInstr = successor;
         frameState.push(JavaKind.Int, appendConstant(JavaConstant.INT_0));
     }
 
     /**
      * @param type the type being instantiated
      */
     protected void handleUnresolvedNewInstance(JavaType type) {
-        assert !graphBuilderConfig.eagerResolving();
-        append(new DeoptimizeNode(InvalidateRecompile, Unresolved));
+        assert !graphBuilderConfig.unresolvedIsError();
+        DeoptimizeNode deopt = append(new DeoptimizeNode(InvalidateRecompile, Unresolved));
+        deopt.updateNodeSourcePosition(() -> createBytecodePosition());
     }
 
     /**
      * @param type the type of the array being instantiated
      * @param length the length of the array
      */
     protected void handleUnresolvedNewObjectArray(JavaType type, ValueNode length) {
-        assert !graphBuilderConfig.eagerResolving();
-        append(new DeoptimizeNode(InvalidateRecompile, Unresolved));
+        assert !graphBuilderConfig.unresolvedIsError();
+        DeoptimizeNode deopt = append(new DeoptimizeNode(InvalidateRecompile, Unresolved));
+        deopt.updateNodeSourcePosition(() -> createBytecodePosition());
     }
 
     /**
      * @param type the type being instantiated
      * @param dims the dimensions for the multi-array
      */
     protected void handleUnresolvedNewMultiArray(JavaType type, ValueNode[] dims) {
-        assert !graphBuilderConfig.eagerResolving();
-        append(new DeoptimizeNode(InvalidateRecompile, Unresolved));
+        assert !graphBuilderConfig.unresolvedIsError();
+        DeoptimizeNode deopt = append(new DeoptimizeNode(InvalidateRecompile, Unresolved));
+        deopt.updateNodeSourcePosition(() -> createBytecodePosition());
     }
 
     /**
      * @param field the unresolved field
      * @param receiver the object containing the field or {@code null} if {@code field} is static
      */
     protected void handleUnresolvedLoadField(JavaField field, ValueNode receiver) {
-        assert !graphBuilderConfig.eagerResolving();
-        append(new DeoptimizeNode(InvalidateRecompile, Unresolved));
+        assert !graphBuilderConfig.unresolvedIsError();
+        DeoptimizeNode deopt = append(new DeoptimizeNode(InvalidateRecompile, Unresolved));
+        deopt.updateNodeSourcePosition(() -> createBytecodePosition());
     }
 
     /**
      * @param field the unresolved field
      * @param value the value being stored to the field
      * @param receiver the object containing the field or {@code null} if {@code field} is static
      */
     protected void handleUnresolvedStoreField(JavaField field, ValueNode value, ValueNode receiver) {
-        assert !graphBuilderConfig.eagerResolving();
-        append(new DeoptimizeNode(InvalidateRecompile, Unresolved));
+        assert !graphBuilderConfig.unresolvedIsError();
+        DeoptimizeNode deopt = append(new DeoptimizeNode(InvalidateRecompile, Unresolved));
+        deopt.updateNodeSourcePosition(() -> createBytecodePosition());
     }
 
     /**
      * @param type
      */
     protected void handleUnresolvedExceptionType(JavaType type) {
-        assert !graphBuilderConfig.eagerResolving();
-        append(new DeoptimizeNode(InvalidateRecompile, Unresolved));
+        assert !graphBuilderConfig.unresolvedIsError();
+        DeoptimizeNode deopt = append(new DeoptimizeNode(InvalidateRecompile, Unresolved));
+        deopt.updateNodeSourcePosition(() -> createBytecodePosition());
     }
 
     /**
      * @param javaMethod
      * @param invokeKind
      */
     protected void handleUnresolvedInvoke(JavaMethod javaMethod, InvokeKind invokeKind) {
-        assert !graphBuilderConfig.eagerResolving();
-        append(new DeoptimizeNode(InvalidateRecompile, Unresolved));
+        assert !graphBuilderConfig.unresolvedIsError();
+        DeoptimizeNode deopt = append(new DeoptimizeNode(InvalidateRecompile, Unresolved));
+        deopt.updateNodeSourcePosition(() -> createBytecodePosition());
     }
 
     private AbstractBeginNode handleException(ValueNode exceptionObject, int bci) {
         assert bci == BytecodeFrame.BEFORE_BCI || bci == bci() : "invalid bci";
         debug.log("Creating exception dispatch edges at %d, exception object=%s, exception seen=%s", bci, exceptionObject, (profilingInfo == null ? "" : profilingInfo.getExceptionSeen(bci)));

@@ -1305,11 +1319,16 @@
             return resolvedType.isInterface() || resolvedType.isLinked();
         }
         return false;
     }
 
-    protected void genInvokeStatic(JavaMethod target) {
+    protected void genInvokeStatic(int cpi, int opcode) {
+        JavaMethod target = lookupMethod(cpi, opcode);
+        genInvokeStatic(target);
+    }
+
+    void genInvokeStatic(JavaMethod target) {
         if (callTargetIsResolved(target)) {
             ResolvedJavaMethod resolvedTarget = (ResolvedJavaMethod) target;
             ResolvedJavaType holder = resolvedTarget.getDeclaringClass();
             if (!holder.isInitialized() && ResolveClassBeforeStaticInvoke.getValue(options)) {
                 handleUnresolvedInvoke(target, InvokeKind.Static);

@@ -1330,57 +1349,126 @@
         } else {
             handleUnresolvedInvoke(target, InvokeKind.Static);
         }
     }
 
+    protected void genInvokeInterface(int cpi, int opcode) {
+        JavaMethod target = lookupMethod(cpi, opcode);
+        genInvokeInterface(target);
+    }
+
     protected void genInvokeInterface(JavaMethod target) {
         if (callTargetIsResolved(target)) {
             ValueNode[] args = frameState.popArguments(target.getSignature().getParameterCount(true));
             appendInvoke(InvokeKind.Interface, (ResolvedJavaMethod) target, args);
         } else {
             handleUnresolvedInvoke(target, InvokeKind.Interface);
         }
     }
 
-    protected void genInvokeDynamic(JavaMethod target) {
-        if (target instanceof ResolvedJavaMethod) {
-            JavaConstant appendix = constantPool.lookupAppendix(stream.readCPI4(), Bytecodes.INVOKEDYNAMIC);
-            if (appendix != null) {
-                frameState.push(JavaKind.Object, ConstantNode.forConstant(appendix, metaAccess, graph));
+    protected void genInvokeDynamic(int cpi, int opcode) {
+        JavaMethod target = lookupMethod(cpi, opcode);
+        genInvokeDynamic(target);
             }
-            ValueNode[] args = frameState.popArguments(target.getSignature().getParameterCount(false));
-            appendInvoke(InvokeKind.Static, (ResolvedJavaMethod) target, args);
-        } else {
+
+    void genInvokeDynamic(JavaMethod target) {
+        if (!(target instanceof ResolvedJavaMethod) || !genDynamicInvokeHelper((ResolvedJavaMethod) target, stream.readCPI4(), INVOKEDYNAMIC)) {
             handleUnresolvedInvoke(target, InvokeKind.Static);
         }
     }
 
-    protected void genInvokeVirtual(JavaMethod target) {
-        if (callTargetIsResolved(target)) {
-            /*
-             * Special handling for runtimes that rewrite an invocation of MethodHandle.invoke(...)
-             * or MethodHandle.invokeExact(...) to a static adapter. HotSpot does this - see
-             * https://wikis.oracle.com/display/HotSpotInternals/Method+handles +and+invokedynamic
-             */
-            boolean hasReceiver = !((ResolvedJavaMethod) target).isStatic();
-            JavaConstant appendix = constantPool.lookupAppendix(stream.readCPI(), Bytecodes.INVOKEVIRTUAL);
+    protected void genInvokeVirtual(int cpi, int opcode) {
+        JavaMethod target = lookupMethod(cpi, opcode);
+        genInvokeVirtual(target);
+    }
+
+    private boolean genDynamicInvokeHelper(ResolvedJavaMethod target, int cpi, int opcode) {
+        assert opcode == INVOKEDYNAMIC || opcode == INVOKEVIRTUAL;
+
+        InvokeDynamicPlugin invokeDynamicPlugin = graphBuilderConfig.getPlugins().getInvokeDynamicPlugin();
+
+        if (opcode == INVOKEVIRTUAL && invokeDynamicPlugin != null && !invokeDynamicPlugin.isResolvedDynamicInvoke(this, cpi, opcode)) {
+            // regular invokevirtual, let caller handle it
+            return false;
+        }
+
+        if (GeneratePIC.getValue(options) && (invokeDynamicPlugin == null || !invokeDynamicPlugin.supportsDynamicInvoke(this, cpi, opcode))) {
+            // bail out if static compiler and no dynamic type support
+            append(new DeoptimizeNode(InvalidateRecompile, Unresolved));
+            return true;
+        }
+
+        JavaConstant appendix = constantPool.lookupAppendix(cpi, opcode);
+        ValueNode appendixNode = null;
+
             if (appendix != null) {
-                frameState.push(JavaKind.Object, ConstantNode.forConstant(appendix, metaAccess, graph));
+            if (invokeDynamicPlugin != null) {
+                invokeDynamicPlugin.recordDynamicMethod(this, cpi, opcode, target);
+
+                // Will perform runtime type checks and static initialization
+                FrameState stateBefore = frameState.create(bci(), getNonIntrinsicAncestor(), false, null, null);
+                appendixNode = invokeDynamicPlugin.genAppendixNode(this, cpi, opcode, appendix, stateBefore);
+            } else {
+                appendixNode = ConstantNode.forConstant(appendix, metaAccess, graph);
+            }
+
+            frameState.push(JavaKind.Object, appendixNode);
+
+        } else if (GeneratePIC.getValue(options)) {
+            // Need to emit runtime guard and perform static initialization.
+            // Not implemented yet.
+            append(new DeoptimizeNode(InvalidateRecompile, Unresolved));
+            return true;
             }
+
+        boolean hasReceiver = (opcode == INVOKEDYNAMIC) ? false : !target.isStatic();
             ValueNode[] args = frameState.popArguments(target.getSignature().getParameterCount(hasReceiver));
             if (hasReceiver) {
-                appendInvoke(InvokeKind.Virtual, (ResolvedJavaMethod) target, args);
+            appendInvoke(InvokeKind.Virtual, target, args);
             } else {
-                appendInvoke(InvokeKind.Static, (ResolvedJavaMethod) target, args);
+            appendInvoke(InvokeKind.Static, target, args);
             }
-        } else {
+
+        return true;
+    }
+
+    void genInvokeVirtual(JavaMethod target) {
+        if (!genInvokeVirtualHelper(target)) {
             handleUnresolvedInvoke(target, InvokeKind.Virtual);
         }
+    }
 
+    private boolean genInvokeVirtualHelper(JavaMethod target) {
+        if (!callTargetIsResolved(target)) {
+            return false;
+        }
+
+        ResolvedJavaMethod resolvedTarget = (ResolvedJavaMethod) target;
+        int cpi = stream.readCPI();
+
+        /*
+         * Special handling for runtimes that rewrite an invocation of MethodHandle.invoke(...) or
+         * MethodHandle.invokeExact(...) to a static adapter. HotSpot does this - see
+         * https://wiki.openjdk.java.net/display/HotSpot/Method+handles+and+invokedynamic
+         */
+
+        if (genDynamicInvokeHelper(resolvedTarget, cpi, INVOKEVIRTUAL)) {
+            return true;
     }
 
-    protected void genInvokeSpecial(JavaMethod target) {
+        ValueNode[] args = frameState.popArguments(target.getSignature().getParameterCount(true));
+        appendInvoke(InvokeKind.Virtual, (ResolvedJavaMethod) target, args);
+
+        return true;
+    }
+
+    protected void genInvokeSpecial(int cpi, int opcode) {
+        JavaMethod target = lookupMethod(cpi, opcode);
+        genInvokeSpecial(target);
+    }
+
+    void genInvokeSpecial(JavaMethod target) {
         if (callTargetIsResolved(target)) {
             assert target != null;
             assert target.getSignature() != null;
             ValueNode[] args = frameState.popArguments(target.getSignature().getParameterCount(true));
             appendInvoke(InvokeKind.Special, (ResolvedJavaMethod) target, args);

@@ -2147,21 +2235,21 @@
         String s = format("%s%s (%s:%d) %s", nSpaces(getDepth()), method.isConstructor() ? method.format("%h.%n") : method.getName(), where.getFileName(), where.getLineNumber(),
                         format(format, args));
         TTY.println(s);
     }
 
-    protected BytecodeParserError asParserError(Throwable e) {
+    protected RuntimeException throwParserError(Throwable e) {
         if (e instanceof BytecodeParserError) {
-            return (BytecodeParserError) e;
+            throw (BytecodeParserError) e;
         }
         BytecodeParser bp = this;
         BytecodeParserError res = new BytecodeParserError(e);
         while (bp != null) {
             res.addContext("parsing " + bp.code.asStackTraceElement(bp.bci()));
             bp = bp.parent;
         }
-        return res;
+        throw res;
     }
 
     protected void parseAndInlineCallee(ResolvedJavaMethod targetMethod, ValueNode[] args, IntrinsicContext calleeIntrinsicContext) {
         try (IntrinsicScope s = calleeIntrinsicContext != null && !parsingIntrinsic() ? new IntrinsicScope(this, targetMethod.getSignature().toParameterKinds(!targetMethod.isStatic()), args) : null) {
 

@@ -2835,11 +2923,11 @@
                 processBytecode(bci, opcode);
             } catch (BailoutException e) {
                 // Don't wrap bailouts as parser errors
                 throw e;
             } catch (Throwable e) {
-                throw asParserError(e);
+                throw throwParserError(e);
             }
 
             if (lastInstr == null || lastInstr.next() != null) {
                 break;
             }

@@ -3255,11 +3343,11 @@
 
         int nextBCI = stream.nextBCI();
         int nextBC = stream.readUByte(nextBCI);
         if (nextBCI <= currentBlock.endBci && nextBC == Bytecodes.GETFIELD) {
             stream.next();
-            genGetField(lookupField(stream.readCPI(), Bytecodes.GETFIELD), value);
+            genGetField(stream.readCPI(), Bytecodes.GETFIELD, value);
         } else {
             frameState.push(JavaKind.Object, value);
         }
     }
 

@@ -3504,33 +3592,36 @@
         assert !graphBuilderConfig.unresolvedIsError() ||
                         (result instanceof ResolvedJavaMethod && (opcode != INVOKESTATIC || ((ResolvedJavaMethod) result).getDeclaringClass().isInitialized())) : result;
         return result;
     }
 
-    private JavaField lookupField(int cpi, int opcode) {
+    protected JavaField lookupField(int cpi, int opcode) {
         maybeEagerlyResolve(cpi, opcode);
         JavaField result = constantPool.lookupField(cpi, method, opcode);
+
         if (graphBuilderConfig.eagerResolving()) {
-            assert result instanceof ResolvedJavaField : "Not resolved: " + result;
+            assert !graphBuilderConfig.unresolvedIsError() || result instanceof ResolvedJavaField : "Not resolved: " + result;
+            if (result instanceof ResolvedJavaField) {
             ResolvedJavaType declaringClass = ((ResolvedJavaField) result).getDeclaringClass();
             if (!declaringClass.isInitialized()) {
                 assert declaringClass.isInterface() : "Declaring class not initialized but not an interface? " + declaringClass;
                 declaringClass.initialize();
             }
         }
+        }
         assert !graphBuilderConfig.unresolvedIsError() || (result instanceof ResolvedJavaField && ((ResolvedJavaField) result).getDeclaringClass().isInitialized()) : result;
         return result;
     }
 
     private Object lookupConstant(int cpi, int opcode) {
         maybeEagerlyResolve(cpi, opcode);
         Object result = constantPool.lookupConstant(cpi);
-        assert !graphBuilderConfig.eagerResolving() || !(result instanceof JavaType) || (result instanceof ResolvedJavaType) : result;
+        assert !graphBuilderConfig.unresolvedIsError() || !(result instanceof JavaType) || (result instanceof ResolvedJavaType) : result;
         return result;
     }
 
-    private void maybeEagerlyResolve(int cpi, int bytecode) {
+    protected void maybeEagerlyResolve(int cpi, int bytecode) {
         if (intrinsicContext != null) {
             constantPool.loadReferencedType(cpi, bytecode);
         } else if (graphBuilderConfig.eagerResolving()) {
             /*
              * Since we're potentially triggering class initialization here, we need synchronization

@@ -3651,13 +3742,16 @@
             // Most frequent for value is IRETURN, followed by ISTORE.
             frameState.push(JavaKind.Int, append(genConditional(logicNode)));
         }
     }
 
-    void genNewInstance(int cpi) {
+    protected void genNewInstance(int cpi) {
         JavaType type = lookupType(cpi, NEW);
+        genNewInstance(type);
+    }
 
+    void genNewInstance(JavaType type) {
         if (!(type instanceof ResolvedJavaType) || !((ResolvedJavaType) type).isInitialized()) {
             handleUnresolvedNewInstance(type);
             return;
         }
         ResolvedJavaType resolvedType = (ResolvedJavaType) type;

@@ -3788,12 +3882,17 @@
         }
 
         frameState.push(JavaKind.Object, append(createNewMultiArray(resolvedType, dims)));
     }
 
-    private void genGetField(JavaField field) {
-        genGetField(field, frameState.pop(JavaKind.Object));
+    protected void genGetField(int cpi, int opcode) {
+        genGetField(cpi, opcode, frameState.pop(JavaKind.Object));
+    }
+
+    protected void genGetField(int cpi, int opcode, ValueNode receiverInput) {
+        JavaField field = lookupField(cpi, opcode);
+        genGetField(field, receiverInput);
     }
 
     private void genGetField(JavaField field, ValueNode receiverInput) {
         ValueNode receiver = emitExplicitExceptions(receiverInput);
         if (field instanceof ResolvedJavaField) {

@@ -3865,11 +3964,16 @@
             return profilingInfo.getExceptionSeen(bci()) == TriState.TRUE;
         }
         return false;
     }
 
-    private void genPutField(JavaField field) {
+    protected void genPutField(int cpi, int opcode) {
+        JavaField field = lookupField(cpi, opcode);
+        genPutField(field);
+    }
+
+    protected void genPutField(JavaField field) {
         genPutField(field, frameState.pop(field.getJavaKind()));
     }
 
     private void genPutField(JavaField field, ValueNode value) {
         ValueNode receiver = emitExplicitExceptions(frameState.pop(JavaKind.Object));

@@ -3893,10 +3997,15 @@
         } else {
             handleUnresolvedStoreField(field, value, receiver);
         }
     }
 
+    protected void genGetStatic(int cpi, int opcode) {
+        JavaField field = lookupField(cpi, opcode);
+        genGetStatic(field);
+    }
+
     private void genGetStatic(JavaField field) {
         ResolvedJavaField resolvedField = resolveStaticFieldAccess(field, null);
         if (resolvedField == null) {
             return;
         }

@@ -3954,11 +4063,16 @@
 
         }
         return null;
     }
 
-    private void genPutStatic(JavaField field) {
+    protected void genPutStatic(int cpi, int opcode) {
+        JavaField field = lookupField(cpi, opcode);
+        genPutStatic(field);
+    }
+
+    protected void genPutStatic(JavaField field) {
         ValueNode value = frameState.pop(field.getJavaKind());
         ResolvedJavaField resolvedField = resolveStaticFieldAccess(field, value);
         if (resolvedField == null) {
             return;
         }

@@ -4318,19 +4432,19 @@
             case LRETURN        : genReturn(frameState.pop(JavaKind.Long), JavaKind.Long); break;
             case FRETURN        : genReturn(frameState.pop(JavaKind.Float), JavaKind.Float); break;
             case DRETURN        : genReturn(frameState.pop(JavaKind.Double), JavaKind.Double); break;
             case ARETURN        : genReturn(frameState.pop(JavaKind.Object), JavaKind.Object); break;
             case RETURN         : genReturn(null, JavaKind.Void); break;
-            case GETSTATIC      : cpi = stream.readCPI(); genGetStatic(lookupField(cpi, opcode)); break;
-            case PUTSTATIC      : cpi = stream.readCPI(); genPutStatic(lookupField(cpi, opcode)); break;
-            case GETFIELD       : cpi = stream.readCPI(); genGetField(lookupField(cpi, opcode)); break;
-            case PUTFIELD       : cpi = stream.readCPI(); genPutField(lookupField(cpi, opcode)); break;
-            case INVOKEVIRTUAL  : cpi = stream.readCPI(); genInvokeVirtual(lookupMethod(cpi, opcode)); break;
-            case INVOKESPECIAL  : cpi = stream.readCPI(); genInvokeSpecial(lookupMethod(cpi, opcode)); break;
-            case INVOKESTATIC   : cpi = stream.readCPI(); genInvokeStatic(lookupMethod(cpi, opcode)); break;
-            case INVOKEINTERFACE: cpi = stream.readCPI(); genInvokeInterface(lookupMethod(cpi, opcode)); break;
-            case INVOKEDYNAMIC  : cpi = stream.readCPI4(); genInvokeDynamic(lookupMethod(cpi, opcode)); break;
+            case GETSTATIC      : cpi = stream.readCPI(); genGetStatic(cpi, opcode); break;
+            case PUTSTATIC      : cpi = stream.readCPI(); genPutStatic(cpi, opcode); break;
+            case GETFIELD       : cpi = stream.readCPI(); genGetField(cpi, opcode); break;
+            case PUTFIELD       : cpi = stream.readCPI(); genPutField(cpi, opcode); break;
+            case INVOKEVIRTUAL  : cpi = stream.readCPI(); genInvokeVirtual(cpi, opcode); break;
+            case INVOKESPECIAL  : cpi = stream.readCPI(); genInvokeSpecial(cpi, opcode); break;
+            case INVOKESTATIC   : cpi = stream.readCPI(); genInvokeStatic(cpi, opcode); break;
+            case INVOKEINTERFACE: cpi = stream.readCPI(); genInvokeInterface(cpi, opcode); break;
+            case INVOKEDYNAMIC  : cpi = stream.readCPI4(); genInvokeDynamic(cpi, opcode); break;
             case NEW            : genNewInstance(stream.readCPI()); break;
             case NEWARRAY       : genNewPrimitiveArray(stream.readLocalIndex()); break;
             case ANEWARRAY      : genNewObjectArray(stream.readCPI()); break;
             case ARRAYLENGTH    : genArrayLength(); break;
             case ATHROW         : genThrow(); break;
< prev index next >