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