1 import jdk.incubator.code.Reflect;
 2 import jdk.incubator.code.Op;
 3 import jdk.incubator.code.interpreter.Interpreter;
 4 
 5 import org.junit.jupiter.api.Assertions;
 6 import org.junit.jupiter.api.Test;
 7 
 8 import java.lang.invoke.MethodHandles;
 9 import java.util.function.IntSupplier;
10 import java.util.function.IntUnaryOperator;
11 import java.util.stream.IntStream;
12 
13 /*
14  * @test
15  * @summary test that invoking Op#ofQuotable returns the same instance
16  * @modules jdk.incubator.code
17  * @run junit ReflectableLambdaSameInstanceTest
18  */
19 
20 public class ReflectableLambdaSameInstanceTest {
21 
22     @Reflect
23     private static final Runnable q1 = () -> { };
24 
25     @Test
26     public void testWithOneThread() {
27         Assertions.assertSame(Op.ofQuotable(q1).get(), Op.ofQuotable(q1).get());
28     }
29 
30     @Reflect
31     private static final IntUnaryOperator q2 = x -> x;
32 
33     @Test
34     public void testWithMultiThreads() {
35         Object[] quotedObjects = IntStream.range(0, 1024).parallel().mapToObj(__ -> Op.ofQuotable(q2).get()).toArray();
36         for (int i = 1; i < quotedObjects.length; i++) {
37             Assertions.assertSame(quotedObjects[i], quotedObjects[i - 1]);
38         }
39     }
40 
41     @Reflect
42     static IntSupplier q() {
43         return () -> 8;
44     }
45 
46     @Test
47     public void testMultiThreadsViaInterpreter() throws NoSuchMethodException {
48         var qm = this.getClass().getDeclaredMethod("q");
49         var q = Op.ofMethod(qm).get();
50         IntSupplier quotable = (IntSupplier) Interpreter.invoke(MethodHandles.lookup(), q);
51         Object[] quotedObjects = IntStream.range(0, 1024).parallel().mapToObj(__ -> Op.ofQuotable(quotable).get()).toArray();
52         for (int i = 1; i < quotedObjects.length; i++) {
53             Assertions.assertSame(quotedObjects[i-1], quotedObjects[i]);
54         }
55     }
56 }