1 /*
  2  * Copyright (c) 2019, 2021, 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.
  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 package compiler.valhalla.inlinetypes;
 25 
 26 import jdk.test.lib.Asserts;
 27 import compiler.lib.ir_framework.*;
 28 
 29 import static compiler.valhalla.inlinetypes.InlineTypes.rI;
 30 import static compiler.valhalla.inlinetypes.InlineTypes.rL;
 31 
 32 /*
 33  * @test
 34  * @key randomness
 35  * @summary Test calling native methods with inline type arguments from compiled code.
 36  * @library /test/lib /
 37  * @requires (os.simpleArch == "x64" | os.simpleArch == "aarch64")
 38  * @run driver/timeout=300 compiler.valhalla.inlinetypes.TestJNICalls
 39  */
 40 
 41 @ForceCompileClassInitializer
 42 public class TestJNICalls {
 43 
 44     public static void main(String[] args) {
 45         Scenario[] scenarios = InlineTypes.DEFAULT_SCENARIOS;
 46 
 47         InlineTypes.getFramework()
 48                    .addScenarios(scenarios)
 49                    .addHelperClasses(MyValue1.class)
 50                    .start();
 51     }
 52 
 53     static {
 54         System.loadLibrary("TestJNICalls");
 55     }
 56 
 57     public native Object testMethod1(MyValue1 o);
 58     public native long testMethod2(MyValue1 o);
 59 
 60     // Pass an inline type to a native method that calls back into Java code and returns an inline type
 61     @Test
 62     public MyValue1 test1(MyValue1 vt, boolean callback) {
 63         if (!callback) {
 64           return (MyValue1)testMethod1(vt);
 65         } else {
 66           return vt;
 67         }
 68     }
 69 
 70     @Run(test = "test1")
 71     @Warmup(10000) // Make sure native method is compiled
 72     public void test1_verifier() {
 73         MyValue1 vt = MyValue1.createWithFieldsInline(rI, rL);
 74         MyValue1 result = test1(vt, false);
 75         Asserts.assertEQ(result.hash(), vt.hash());
 76         result = test1(vt, true);
 77         Asserts.assertEQ(result.hash(), vt.hash());
 78     }
 79 
 80     // Pass an inline type to a native method that calls the hash method and returns the result
 81     @Test
 82     public long test2(MyValue1 vt) {
 83         return testMethod2(vt);
 84     }
 85 
 86     @Run(test = "test2")
 87     @Warmup(10000) // Make sure native method is compiled
 88     public void test2_verifier() {
 89         MyValue1 vt = MyValue1.createWithFieldsInline(rI, rL);
 90         long result = test2(vt);
 91         Asserts.assertEQ(result, vt.hash());
 92     }
 93 
 94     static primitive class MyValueWithNative {
 95         public final int x;
 96 
 97         private MyValueWithNative(int x) {
 98             this.x = x;
 99         }
100 
101         public native int testMethod3();
102     }
103 
104     // Call a native method with an inline type receiver
105     @Test
106     public int test3(MyValueWithNative vt) {
107         return vt.testMethod3();
108     }
109 
110     @Run(test = "test3")
111     @Warmup(10000) // Make sure native method is compiled
112     public void test3_verifier() {
113         MyValueWithNative vt = new MyValueWithNative(rI);
114         int result = test3(vt);
115         Asserts.assertEQ(result, rI);
116     }
117 }