jdk-24/test/hotspot/jtreg/runtime/jni/FastGetField/FastGetField.java
Axel Boldt-Christmas c7056737e3 8299089: Instrument global jni handles with tag to make them distinguishable
Co-authored-by: Stefan Karlsson <stefank@openjdk.org>
Co-authored-by: Martin Doerr <mdoerr@openjdk.org>
Co-authored-by: Leslie Zhai <lzhai@openjdk.org>
Reviewed-by: eosterlund, stefank, ayang
2023-01-18 09:21:08 +00:00

166 lines
5.8 KiB
Java

/*
* Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2019 SAP SE and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/**
* @test
* @bug 8227680
* @summary Tests that all FieldAccess notifications for Get*Field
with primitive type are generated.
* @requires vm.jvmti
* @compile FastGetField.java
* @run main/othervm/native -agentlib:FastGetField -XX:+IgnoreUnrecognizedVMOptions -XX:-VerifyJNIFields FastGetField 0
* @run main/othervm/native -agentlib:FastGetField -XX:+IgnoreUnrecognizedVMOptions -XX:-VerifyJNIFields FastGetField 1
* @run main/othervm/native -agentlib:FastGetField -XX:+IgnoreUnrecognizedVMOptions -XX:-VerifyJNIFields FastGetField 2
* @run main/othervm/native -agentlib:FastGetField -XX:+IgnoreUnrecognizedVMOptions -XX:-VerifyJNIFields -XX:+UnlockDiagnosticVMOptions -XX:+ForceUnreachable -XX:+SafepointALot -XX:GuaranteedSafepointInterval=1 FastGetField 0
* @run main/othervm/native -agentlib:FastGetField -XX:+IgnoreUnrecognizedVMOptions -XX:-VerifyJNIFields -XX:+UnlockDiagnosticVMOptions -XX:+ForceUnreachable -XX:+SafepointALot -XX:GuaranteedSafepointInterval=1 FastGetField 1
* @run main/othervm/native -agentlib:FastGetField -XX:+IgnoreUnrecognizedVMOptions -XX:-VerifyJNIFields -XX:+UnlockDiagnosticVMOptions -XX:+ForceUnreachable -XX:+SafepointALot -XX:GuaranteedSafepointInterval=1 FastGetField 2
*/
import java.lang.reflect.Field;
public class FastGetField {
private static final String agentLib = "FastGetField";
private native boolean initFieldIDs(Class c);
private native boolean initWatchers(Class c);
public native void registerGlobal(MyItem i);
public native void registerWeak(MyItem i);
public native long accessFields(MyItem i);
public native long accessFieldsViaHandle();
public static native long getFieldAccessCount();
static final int loop_cnt = 10000;
class MyItem {
// Names should match JNI types.
boolean Z;
byte B;
short S;
char C;
int I;
long J;
float F;
double D;
public void change_values() {
Z = true;
B = 1;
C = 1;
S = 1;
I = 1;
J = 1l;
F = 1.0f;
D = 1.0;
}
public void reset_values() {
Z = false;
B = 0;
C = 0;
S = 0;
I = 0;
J = 0l;
F = 0.0f;
D = 0.0;
}
}
// Static initialization.
static {
try {
System.loadLibrary(agentLib);
} catch (UnsatisfiedLinkError ex) {
System.err.println("Failed to load " + agentLib + " lib");
System.err.println("java.library.path: " + System.getProperty("java.library.path"));
throw ex;
}
}
private int mode;
private MyItem obj;
private FastGetField(int mode) {
this.mode = mode;
this.obj = new MyItem();
if (mode == 0) {
// Direct
} else if (mode == 1) {
registerGlobal(this.obj);
} else if ( mode == 2) {
registerWeak(this.obj);
} else {
throw new IllegalArgumentException("Unexpected mode");
}
}
private long accessFields() {
if (mode == 0) {
return accessFields(obj);
}
// Otherwise through a handle
return accessFieldsViaHandle();
}
public void TestFieldAccess() throws Exception {
if (!initFieldIDs(MyItem.class)) throw new RuntimeException("FieldID initialization failed!");
long duration = System.nanoTime();
for (int c = 0; c < loop_cnt; ++c) {
if (accessFields() != 0l) throw new RuntimeException("Wrong initial result!");
obj.change_values();
if (accessFields() != 8l) throw new RuntimeException("Wrong result after changing!");
obj.reset_values();
}
duration = System.nanoTime() - duration;
System.out.println(loop_cnt + " iterations took " + duration + "ns.");
if (getFieldAccessCount() != 0) throw new RuntimeException("Watch not yet active!");
// Install watchers.
if (!initWatchers(MyItem.class)) throw new RuntimeException("JVMTI missing!");
// Try again with watchers.
if (accessFields() != 0l) throw new RuntimeException("Wrong initial result!");
obj.change_values();
if (accessFields() != 8l) throw new RuntimeException("Wrong result after changing!");
if (getFieldAccessCount() != 16) throw new RuntimeException("Unexpected event count!");
}
public static void main(String[] args) throws Exception {
if (args.length != 1) {
throw new IllegalArgumentException("Expected one argument");
}
int mode = Integer.parseInt(args[0]);
FastGetField inst = new FastGetField(mode);
inst.TestFieldAccess();
}
}