Path: blob/master/test/functional/Jsr292/src/com/ibm/j9/jsr292/ConstantCallSiteTest.java
6007 views
/*******************************************************************************1* Copyright (c) 2001, 2018 IBM Corp. and others2*3* This program and the accompanying materials are made available under4* the terms of the Eclipse Public License 2.0 which accompanies this5* distribution and is available at https://www.eclipse.org/legal/epl-2.0/6* or the Apache License, Version 2.0 which accompanies this distribution and7* is available at https://www.apache.org/licenses/LICENSE-2.0.8*9* This Source Code may also be made available under the following10* Secondary Licenses when the conditions for such availability set11* forth in the Eclipse Public License, v. 2.0 are satisfied: GNU12* General Public License, version 2 with the GNU Classpath13* Exception [1] and GNU General Public License, version 2 with the14* OpenJDK Assembly Exception [2].15*16* [1] https://www.gnu.org/software/classpath/license.html17* [2] http://openjdk.java.net/legal/assembly-exception.html18*19* SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 OR LicenseRef-GPL-2.0 WITH Assembly-exception20*******************************************************************************/21package com.ibm.j9.jsr292;2223import org.testng.annotations.Test;24import org.testng.AssertJUnit;25import java.lang.invoke.CallSite;26import java.lang.invoke.ConstantCallSite;27import java.lang.invoke.MethodHandle;28import java.lang.invoke.MethodHandles;29import java.lang.invoke.MethodType;30import java.lang.invoke.MutableCallSite;31import java.lang.invoke.WrongMethodTypeException;32import examples.PackageExamples;3334/**35* @author mesbah36* This class contains tests for ConstantCallSite API37*/38public class ConstantCallSiteTest {3940/**41* A basic sanity test for ConstantCallSite42* @throws Throwable43*/44@Test(groups = { "level.extended" })45public void testBasic_ConstantCallSite() throws Throwable {46MethodHandle mh = MethodHandles.lookup().findStatic(SamePackageExample.class, "addPublicStatic", MethodType.methodType(int.class,int.class,int.class));47ConstantCallSite ccs = new ConstantCallSite(mh);48int result = (int)ccs.dynamicInvoker().invokeExact(1,2);4950AssertJUnit.assertEquals(3,result);5152AssertJUnit.assertEquals(mh,ccs.getTarget());5354AssertJUnit.assertEquals(mh.type(),ccs.type());55}5657/**58* A basic negative test for ConstantCallSite59* @throws Throwable60*/61@Test(groups = { "level.extended" })62public void testBasicNegative_ConstantCallSite() throws Throwable {63MethodHandle mh = MethodHandles.lookup().findStatic(SamePackageExample.class, "addPublicStatic", MethodType.methodType(int.class,int.class,int.class));64ConstantCallSite ccs = new ConstantCallSite(mh);65boolean wmtHit = false;66try {67int result = (int)ccs.dynamicInvoker().invokeExact(1,2,3);68AssertJUnit.assertEquals(3,result);69}70catch(WrongMethodTypeException e) {71wmtHit = true;72}7374AssertJUnit.assertTrue(wmtHit);75}7677/**78* Negative test - attempts to set a target to a ConstantCallSite instance79* @throws Throwable80*/81@Test(groups = { "level.extended" })82public void testConstantCallSiteSetTarget() throws Throwable {83MethodHandle mh1 = MethodHandles.lookup().findStatic(SamePackageExample.class, "addPublicStatic", MethodType.methodType(int.class,int.class,int.class));84MethodHandle mh2 = MethodHandles.lookup().findStatic(PackageExamples.class, "addPublicStatic", MethodType.methodType(int.class,int.class,int.class));85ConstantCallSite ccs = new ConstantCallSite(mh1);86boolean uoHit = false;8788try {89ccs.setTarget(null);90}91catch(UnsupportedOperationException e) {92uoHit = true;93}9495AssertJUnit.assertTrue(uoHit);9697uoHit = false;9899try {100ccs.setTarget(mh2);101}102catch(UnsupportedOperationException e) {103uoHit = true;104}105106AssertJUnit.assertTrue(uoHit);107108uoHit = false;109110try {111ccs.setTarget(mh1);112}113catch(UnsupportedOperationException e) {114uoHit = true;115}116AssertJUnit.assertTrue(uoHit);117}118119/**120* Tests protected ConstantCallSite(MethodType targetType,MethodHandle createTargetHook) throws Throwable121* A subclass of ConstantCallSite is used to invoke the protected constructor122* @throws Throwable123*/124@Test(groups = { "level.extended" })125public void testTargetHookConstructor() throws Throwable {126127MethodType targetType = MethodType.methodType(int.class);128MethodHandle hook = MethodHandles.lookup().findStatic(ConstantCallSiteTest.class, "createTargetHook", MethodType.methodType(MethodHandle.class,ConstantCallSite.class));129130MyConstantCallSite myCcs = new MyConstantCallSite(targetType,hook);131132int returnVal = (int)myCcs.dynamicInvoker().invokeExact();133134AssertJUnit.assertEquals(1,returnVal);135}136137/**138* Negative test for protected ConstantCallSite(MethodType targetType,MethodHandle createTargetHook).139* There is a mismatch between the MT passed in and the MH.type() returned by the hook.140* A subclass of ConstantCallSite is used to invoke the protected constructor141* @throws Throwable142*/143@Test(groups = { "level.extended" })144public void testTypeMismatch_TargetHookConstructor() throws Throwable {145146MethodType targetType = MethodType.methodType(String.class);147MethodHandle hook = MethodHandles.lookup().findStatic(ConstantCallSiteTest.class, "createTargetHook", MethodType.methodType(MethodHandle.class,ConstantCallSite.class));148boolean wmtHit = false;149150try {151MyConstantCallSite myCcs = new MyConstantCallSite(targetType,hook);152153}catch ( WrongMethodTypeException e ) {154wmtHit = true;155}156157AssertJUnit.assertTrue(wmtHit);158}159160/**161* Negative test for protected ConstantCallSite(MethodType targetType,MethodHandle createTargetHook).162* The hook returns null.163* A subclass of ConstantCallSite is used to invoke the protected constructor164* @throws Throwable165*/166@Test(groups = { "level.extended" })167public void testNullHook_TargetHookConstructor() throws Throwable {168169MethodType targetType = MethodType.methodType(String.class);170MethodHandle hook = MethodHandles.lookup().findStatic(ConstantCallSiteTest.class, "createTargetHook_Null", MethodType.methodType(MethodHandle.class,ConstantCallSite.class));171boolean npeHit = false;172173try {174MyConstantCallSite myCcs = new MyConstantCallSite(targetType,hook);175176}catch ( NullPointerException e ) {177npeHit = true;178}179180AssertJUnit.assertTrue(npeHit);181}182183184/**185* Negative test for protected ConstantCallSite(MethodType targetType,MethodHandle createTargetHook).186* The hook does not return a MethodHandle object.187* A subclass of ConstantCallSite is used to invoke the protected constructor188* @throws Throwable189*/190@Test(groups = { "level.extended" })191public void testClassCast_TargetHookConstructor() throws Throwable {192193MethodType targetType = MethodType.methodType(String.class);194MethodHandle hook = MethodHandles.lookup().findStatic(ConstantCallSiteTest.class, "createTargetHook_NonMH", MethodType.methodType(ConstantCallSiteTest.class,ConstantCallSite.class));195boolean cceHit = false;196197try {198MyConstantCallSite myCcs = new MyConstantCallSite(targetType,hook);199200}catch ( ClassCastException e ) {201cceHit = true;202}203204AssertJUnit.assertTrue(cceHit);205}206207/**208* Test to validate that a partially constructed ConstantCallSite can't be incorrectly used209* @throws Throwable210*/211CallSite unconstructedCS;212213@Test(groups = { "level.extended" })214public void testUnconstructedCCS() throws Throwable {215ConstantCallSiteTest ccs = new ConstantCallSiteTest();216MethodHandle hookMH = MethodHandles.lookup().bind(ccs, "hook", MethodType.methodType(MethodHandle.class, ConstantCallSite.class));217218try {219ConstantCallSite cs = new MyConstantCallSite(MethodType.methodType(void.class), hookMH);220} catch(NullPointerException e) {};221222boolean illegalState = false;223224try {225ccs.unconstructedCS.dynamicInvoker();226} catch(IllegalStateException e) {227illegalState = true;228}229230AssertJUnit.assertTrue(illegalState);231232illegalState = false;233try {234ccs.unconstructedCS.getTarget();235} catch(IllegalStateException e) {236illegalState = true;237}238239AssertJUnit.assertTrue(illegalState);240241illegalState = false;242try {243ccs.unconstructedCS.type();244} catch(IllegalStateException e) {245illegalState = true;246}247248AssertJUnit.assertFalse(illegalState);249}250251public MethodHandle hook(ConstantCallSite cs) {252unconstructedCS = cs;253throw new NullPointerException();254}255256/**257* Subclass of ConstantCallSite where protected ConstantCallSite(MethodType targetType,MethodHandle createTargetHook) is invoked258*/259private class MyConstantCallSite extends ConstantCallSite {260public MyConstantCallSite(MethodType target, MethodHandle createTargetHook) throws Throwable {261super(target,createTargetHook);262}263}264265/**266* This method is used to produce the final target method handle that will be hooked to the constant call site267* @param c268* @return269* @throws Throwable270*/271public static MethodHandle createTargetHook(ConstantCallSite c) throws Throwable {272MethodHandle targetHook = MethodHandles.lookup().findStatic(ConstantCallSiteTest.class, "getOne", MethodType.methodType(int.class));273return targetHook;274}275276/**277* This method is used to produce the null target method handle that will be hooked to the constant call site278* @param c279* @return280* @throws Throwable281*/282public static MethodHandle createTargetHook_Null(ConstantCallSite c) throws Throwable {283return null;284}285286/**287* This method is used to produce the null target method handle that will be hooked to the constant call site288* @param c289* @return290* @throws Throwable291*/292public static ConstantCallSiteTest createTargetHook_NonMH(ConstantCallSite c) throws Throwable {293return new ConstantCallSiteTest();294}295296297/**298* Target method to be hooked to the call site299* @return always returns 1300*/301public static int getOne() {302return 1;303}304305/**306* Test for ConstantCallSite.type()307* @throws Throwable308*/309@Test(groups = { "level.extended" })310public void testType_ConstantCallSite() throws Throwable {311MethodType mt = MethodType.methodType(int.class,int.class,int.class);312MethodHandle mh = MethodHandles.lookup().findStatic(SamePackageExample.class, "addPublicStatic",mt);313ConstantCallSite ccs = new ConstantCallSite(mh);314AssertJUnit.assertEquals(mt,ccs.type());315}316}317318319