< prev index next >

test/compiler/jsr292/CallSiteDepContextTest.java

Print this page




   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 
  24 /**
  25  * @test
  26  * @bug 8057967
  27  * @ignore 8079205
  28  * @run main/bootclasspath -Xbatch java.lang.invoke.CallSiteDepContextTest

  29  */
  30 package java.lang.invoke;
  31 
  32 import java.lang.ref.*;


  33 import jdk.internal.org.objectweb.asm.*;
  34 import sun.misc.Unsafe;
  35 
  36 import static jdk.internal.org.objectweb.asm.Opcodes.*;
  37 
  38 public class CallSiteDepContextTest {
  39     static final Unsafe               UNSAFE = Unsafe.getUnsafe();
  40     static final MethodHandles.Lookup LOOKUP = MethodHandles.Lookup.IMPL_LOOKUP;
  41     static final String           CLASS_NAME = "java/lang/invoke/Test";
  42     static final String          METHOD_NAME = "m";
  43     static final MethodType             TYPE = MethodType.methodType(int.class);
  44 
  45     static MutableCallSite mcs;
  46     static MethodHandle bsmMH;
  47 
  48     static {
  49         try {
  50             bsmMH = LOOKUP.findStatic(
  51                     CallSiteDepContextTest.class, "bootstrap",
  52                     MethodType.methodType(CallSite.class, MethodHandles.Lookup.class, String.class, MethodType.class));


  79             mv.visitInvokeDynamicInsn("methodName", TYPE.toMethodDescriptorString(), bsm);
  80             mv.visitInsn(IRETURN);
  81             mv.visitMaxs(0, 0);
  82             mv.visitEnd();
  83         }
  84         cw.visitEnd();
  85         return cw.toByteArray();
  86     }
  87 
  88     private static void execute(int expected, MethodHandle... mhs) throws Throwable {
  89         for (int i = 0; i < 20_000; i++) {
  90             for (MethodHandle mh : mhs) {
  91                 int r = (int) mh.invokeExact();
  92                 if (r != expected) {
  93                     throw new Error(r + " != " + expected);
  94                 }
  95             }
  96         }
  97     }
  98 








  99     public static void testSharedCallSite() throws Throwable {
 100         Class<?> cls1 = UNSAFE.defineAnonymousClass(Object.class, getClassFile("CS_1"), null);
 101         Class<?> cls2 = UNSAFE.defineAnonymousClass(Object.class, getClassFile("CS_2"), null);
 102 
 103         MethodHandle[] mhs = new MethodHandle[] {
 104             LOOKUP.findStatic(cls1, METHOD_NAME, TYPE),
 105             LOOKUP.findStatic(cls2, METHOD_NAME, TYPE)
 106         };
 107 
 108         mcs = new MutableCallSite(LOOKUP.findStatic(T.class, "f1", TYPE));
 109         execute(1, mhs);
 110         mcs.setTarget(LOOKUP.findStatic(T.class, "f2", TYPE));
 111         execute(2, mhs);
 112     }
 113 
 114     public static void testNonBoundCallSite() throws Throwable {
 115         mcs = new MutableCallSite(LOOKUP.findStatic(T.class, "f1", TYPE));
 116 
 117         // mcs.context == null
 118         MethodHandle mh = mcs.dynamicInvoker();
 119         execute(1, mh);
 120 
 121         // mcs.context == cls1
 122         Class<?> cls1 = UNSAFE.defineAnonymousClass(Object.class, getClassFile("NonBound_1"), null);
 123         MethodHandle mh1 = LOOKUP.findStatic(cls1, METHOD_NAME, TYPE);
 124 
 125         execute(1, mh1);
 126 
 127         mcs.setTarget(LOOKUP.findStatic(T.class, "f2", TYPE));
 128 
 129         execute(2, mh, mh1);
 130     }
 131 
 132     static ReferenceQueue rq = new ReferenceQueue();
 133     static PhantomReference ref;
 134 
 135     public static void testGC() throws Throwable {


 136         mcs = new MutableCallSite(LOOKUP.findStatic(T.class, "f1", TYPE));
 137 
 138         Class<?>[] cls = new Class[] {
 139                 UNSAFE.defineAnonymousClass(Object.class, getClassFile("GC_1"), null),
 140                 UNSAFE.defineAnonymousClass(Object.class, getClassFile("GC_2"), null),
 141         };
 142 
 143         MethodHandle[] mhs = new MethodHandle[] {
 144                 LOOKUP.findStatic(cls[0], METHOD_NAME, TYPE),
 145                 LOOKUP.findStatic(cls[1], METHOD_NAME, TYPE),
 146         };
 147 
 148         // mcs.context == cls[0]
 149         int r = (int) mhs[0].invokeExact();
 150 
 151         execute(1, mhs);
 152 
 153         ref = new PhantomReference<>(cls[0], rq);
 154         cls[0] = UNSAFE.defineAnonymousClass(Object.class, getClassFile("GC_3"), null);
 155         mhs[0] = LOOKUP.findStatic(cls[0], METHOD_NAME, TYPE);
 156 
 157         do {
 158             System.gc();
 159             try {
 160                 Reference ref1 = rq.remove(1000);
 161                 if (ref1 == ref) {
 162                     ref1.clear();
 163                     System.gc(); // Ensure that the stale context is cleared
 164                     break;
 165                 }
 166             } catch(InterruptedException e) { /* ignore */ }
 167         } while (true);
 168 





 169         execute(1, mhs);

 170         mcs.setTarget(LOOKUP.findStatic(T.class, "f2", TYPE));
 171         execute(2, mhs);
 172     }
 173 
 174     public static void main(String[] args) throws Throwable {

 175         testSharedCallSite();
 176         testNonBoundCallSite();
 177         testGC();



 178         System.out.println("TEST PASSED");
 179     }
 180 }


   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 
  24 /**
  25  * @test
  26  * @bug 8057967
  27  * @run main/bootclasspath -Xbatch -XX:+IgnoreUnrecognizedVMOptions -XX:+TraceClassUnloading
  28  *                         -XX:+PrintCompilation -XX:+TraceDependencies -XX:+TraceReferenceGC
  29  *                         -verbose:gc java.lang.invoke.CallSiteDepContextTest
  30  */
  31 package java.lang.invoke;
  32 
  33 import java.lang.ref.*;
  34 import java.lang.reflect.Field;
  35 
  36 import jdk.internal.org.objectweb.asm.*;
  37 import sun.misc.Unsafe;
  38 
  39 import static jdk.internal.org.objectweb.asm.Opcodes.*;
  40 
  41 public class CallSiteDepContextTest {
  42     static final Unsafe               UNSAFE = Unsafe.getUnsafe();
  43     static final MethodHandles.Lookup LOOKUP = MethodHandles.Lookup.IMPL_LOOKUP;
  44     static final String           CLASS_NAME = "java/lang/invoke/Test";
  45     static final String          METHOD_NAME = "m";
  46     static final MethodType             TYPE = MethodType.methodType(int.class);
  47 
  48     static MutableCallSite mcs;
  49     static MethodHandle bsmMH;
  50 
  51     static {
  52         try {
  53             bsmMH = LOOKUP.findStatic(
  54                     CallSiteDepContextTest.class, "bootstrap",
  55                     MethodType.methodType(CallSite.class, MethodHandles.Lookup.class, String.class, MethodType.class));


  82             mv.visitInvokeDynamicInsn("methodName", TYPE.toMethodDescriptorString(), bsm);
  83             mv.visitInsn(IRETURN);
  84             mv.visitMaxs(0, 0);
  85             mv.visitEnd();
  86         }
  87         cw.visitEnd();
  88         return cw.toByteArray();
  89     }
  90 
  91     private static void execute(int expected, MethodHandle... mhs) throws Throwable {
  92         for (int i = 0; i < 20_000; i++) {
  93             for (MethodHandle mh : mhs) {
  94                 int r = (int) mh.invokeExact();
  95                 if (r != expected) {
  96                     throw new Error(r + " != " + expected);
  97                 }
  98             }
  99         }
 100     }
 101 
 102     public static void testHiddenDepField() throws Exception {
 103         Class<?> contextClass = Class.forName("java.lang.invoke.CallSite$Context");
 104         try {
 105             Field f = contextClass.getDeclaredField("dependencies");
 106             throw new AssertionError("Context.dependencies field should be hidden");
 107         } catch(NoSuchFieldException e) { /* expected */ }
 108     }
 109 
 110     public static void testSharedCallSite() throws Throwable {
 111         Class<?> cls1 = UNSAFE.defineAnonymousClass(Object.class, getClassFile("CS_1"), null);
 112         Class<?> cls2 = UNSAFE.defineAnonymousClass(Object.class, getClassFile("CS_2"), null);
 113 
 114         MethodHandle[] mhs = new MethodHandle[] {
 115             LOOKUP.findStatic(cls1, METHOD_NAME, TYPE),
 116             LOOKUP.findStatic(cls2, METHOD_NAME, TYPE)
 117         };
 118 
 119         mcs = new MutableCallSite(LOOKUP.findStatic(T.class, "f1", TYPE));
 120         execute(1, mhs);
 121         mcs.setTarget(LOOKUP.findStatic(T.class, "f2", TYPE));
 122         execute(2, mhs);
 123     }
 124 
 125     public static void testNonBoundCallSite() throws Throwable {
 126         mcs = new MutableCallSite(LOOKUP.findStatic(T.class, "f1", TYPE));
 127 
 128         // mcs.context == null
 129         MethodHandle mh = mcs.dynamicInvoker();
 130         execute(1, mh);
 131 
 132         // mcs.context == cls1
 133         Class<?> cls1 = UNSAFE.defineAnonymousClass(Object.class, getClassFile("NonBound_1"), null);
 134         MethodHandle mh1 = LOOKUP.findStatic(cls1, METHOD_NAME, TYPE);
 135 
 136         execute(1, mh1);
 137 
 138         mcs.setTarget(LOOKUP.findStatic(T.class, "f2", TYPE));
 139 
 140         execute(2, mh, mh1);
 141     }
 142 
 143     static ReferenceQueue rq = new ReferenceQueue();
 144     static PhantomReference ref;
 145 
 146     public static void testGC(boolean clear, boolean precompile) throws Throwable {
 147         String id = "_" + clear + "_" + precompile;
 148 
 149         mcs = new MutableCallSite(LOOKUP.findStatic(T.class, "f1", TYPE));
 150 
 151         Class<?>[] cls = new Class[] {
 152                 UNSAFE.defineAnonymousClass(Object.class, getClassFile("GC_1" + id), null),
 153                 UNSAFE.defineAnonymousClass(Object.class, getClassFile("GC_2" + id), null),
 154         };
 155 
 156         MethodHandle[] mhs = new MethodHandle[] {
 157                 LOOKUP.findStatic(cls[0], METHOD_NAME, TYPE),
 158                 LOOKUP.findStatic(cls[1], METHOD_NAME, TYPE),
 159         };
 160 
 161         // mcs.context == cls[0]
 162         int r = (int) mhs[0].invokeExact();
 163 
 164         execute(1, mhs);
 165 
 166         ref = new PhantomReference<>(cls[0], rq);
 167         cls[0] = UNSAFE.defineAnonymousClass(Object.class, getClassFile("GC_3" + id), null);
 168         mhs[0] = LOOKUP.findStatic(cls[0], METHOD_NAME, TYPE);
 169 
 170         do {
 171             System.gc();
 172             try {
 173                 Reference ref1 = rq.remove(100);
 174                 if (ref1 == ref) {


 175                     break;
 176                 }
 177             } catch(InterruptedException e) { /* ignore */ }
 178         } while (true);
 179 
 180         if (clear) {
 181             ref.clear();
 182             System.gc(); // Ensure that the stale context is unloaded
 183         }
 184         if (precompile) {
 185             execute(1, mhs);
 186         }
 187         mcs.setTarget(LOOKUP.findStatic(T.class, "f2", TYPE));
 188         execute(2, mhs);
 189     }
 190 
 191     public static void main(String[] args) throws Throwable {
 192         testHiddenDepField();
 193         testSharedCallSite();
 194         testNonBoundCallSite();
 195         testGC(false, false);
 196         testGC(false,  true);
 197         testGC( true, false);
 198         testGC( true,  true);
 199         System.out.println("TEST PASSED");
 200     }
 201 }
< prev index next >