1 /*
2  * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * This code is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 only, as
7  * published by the Free Software Foundation.  Oracle designates this
8  * particular file as subject to the "Classpath" exception as provided
9  * by Oracle in the LICENSE file that accompanied this code.
10  *
11  * This code is distributed in the hope that it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14  * version 2 for more details (a copy is included in the LICENSE file that
15  * accompanied this code).
16  *
17  * You should have received a copy of the GNU General Public License version
18  * 2 along with this work; if not, write to the Free Software Foundation,
19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20  *
21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22  * or visit www.oracle.com if you need additional information or have any
23  * questions.
24  */
25 
26 package jdk.dynalink.support.test;
27 
28 import static jdk.dynalink.StandardNamespace.PROPERTY;
29 import static jdk.dynalink.StandardOperation.GET;
30 
31 import java.lang.invoke.CallSite;
32 import java.lang.invoke.MethodHandle;
33 import java.lang.invoke.MethodHandles;
34 import java.lang.invoke.MethodType;
35 import java.util.ArrayList;
36 import jdk.dynalink.CallSiteDescriptor;
37 import jdk.dynalink.DynamicLinker;
38 import jdk.dynalink.DynamicLinkerFactory;
39 import jdk.dynalink.Operation;
40 import jdk.dynalink.linker.GuardedInvocation;
41 import jdk.dynalink.support.SimpleRelinkableCallSite;
42 import org.testng.Assert;
43 import org.testng.annotations.Test;
44 
45 public class CallSiteTest {
46     private static final Operation GET_PROPERTY = GET.withNamespace(PROPERTY);
47 
48     @Test
testInitialize()49     public void testInitialize() {
50         final DynamicLinkerFactory factory = new DynamicLinkerFactory();
51         final DynamicLinker linker = factory.createLinker();
52         final MethodType mt = MethodType.methodType(Object.class, Object.class);
53         final boolean[] initializeCalled = { Boolean.FALSE };
54         linker.link(new SimpleRelinkableCallSite(new CallSiteDescriptor(
55             MethodHandles.publicLookup(), GET_PROPERTY.named("DO_NOT_CARE"), mt)) {
56                 @Override
57                 public void initialize(final MethodHandle relinkAndInvoke) {
58                     initializeCalled[0] = Boolean.TRUE;
59                     super.initialize(relinkAndInvoke);
60                 }
61             });
62 
63         Assert.assertTrue(initializeCalled[0]);
64     }
65 
66     @Test
testRelink()67     public void testRelink() {
68         final DynamicLinkerFactory factory = new DynamicLinkerFactory();
69         final DynamicLinker linker = factory.createLinker();
70         final MethodType mt = MethodType.methodType(Object.class, Object.class);
71         final boolean[] relinkCalled = { Boolean.FALSE };
72         final CallSite cs = linker.link(new SimpleRelinkableCallSite(new CallSiteDescriptor(
73             MethodHandles.publicLookup(), GET_PROPERTY.named("class"), mt)) {
74                 @Override
75                 public void relink(final GuardedInvocation guardedInvocation, final MethodHandle relinkAndInvoke) {
76                     relinkCalled[0] = Boolean.TRUE;
77                     super.relink(guardedInvocation, relinkAndInvoke);
78                 }
79             });
80 
81         Assert.assertFalse(relinkCalled[0]);
82         try {
83             cs.getTarget().invoke(new Object());
84         } catch (final Throwable th) {}
85 
86         Assert.assertTrue(relinkCalled[0]);
87     }
88 
89     @Test
testResetAndRelink()90     public void testResetAndRelink() {
91         final DynamicLinkerFactory factory = new DynamicLinkerFactory();
92         factory.setUnstableRelinkThreshold(1);
93         final DynamicLinker linker = factory.createLinker();
94         final MethodType mt = MethodType.methodType(Object.class, Object.class);
95         final boolean[] resetAndRelinkCalled = { Boolean.FALSE };
96         final CallSite cs = linker.link(new SimpleRelinkableCallSite(new CallSiteDescriptor(
97             MethodHandles.publicLookup(), GET_PROPERTY.named("length"), mt)) {
98                 @Override
99                 public void resetAndRelink(final GuardedInvocation guardedInvocation, final MethodHandle relinkAndInvoke) {
100                     resetAndRelinkCalled[0] = Boolean.TRUE;
101                     super.resetAndRelink(guardedInvocation, relinkAndInvoke);
102                 }
103             });
104 
105         Assert.assertFalse(resetAndRelinkCalled[0]);
106         try {
107             cs.getTarget().invoke(new Object[] {});
108         } catch (final Throwable th) {}
109 
110         Assert.assertFalse(resetAndRelinkCalled[0]);
111         try {
112             cs.getTarget().invoke(new ArrayList<Object>());
113         } catch (final Throwable th) {}
114 
115         Assert.assertTrue(resetAndRelinkCalled[0]);
116     }
117 }
118