[PATCH 1 of 2] Add tapset tests
Mark Wielaard
mjw at redhat.com
Fri Mar 23 15:49:53 PDT 2012
ChangeLog | 30 +
Makefile.am | 29 +-
tapset/hotspot_jni.stp.in | 20 +-
test/tapset/ClassUnloadedProbeTester.java | 38 +
test/tapset/JNIStapTest.c | 2107 +++++++++++++++++++++++++++++
test/tapset/JNITestClass.c | 7 +
test/tapset/JNITestClass.h | 21 +
test/tapset/JNITestClass.java | 121 +
test/tapset/RunWrapper.java | 21 +
test/tapset/StapJNIClassLoader.java | 64 +
test/tapset/StapURLClassLoader.java | 24 +
test/tapset/SystemtapTester.java | 202 ++
test/tapset/TestingRunner.java | 82 +
test/tapset/jstaptest.pl | 954 +++++++++++++
14 files changed, 3712 insertions(+), 8 deletions(-)
# HG changeset patch
# User Jon VanAlten <jon.vanalten at redhat.com>
# Date 1332508260 -3600
# Node ID 55b21736fe194ce377bfe99b9a06f7f6e9107521
# Parent 2ec7673965579347cd63bddaba5b207f08be2e07
Add tapset tests.
* Makefile.am:
Add target to run tapset tests.
* tapset/hotspot_jni.stp.in:
Add notes regarding required JVM option to Get<PrimitiveType>Field
family of probe aliases.
* test/tapset/ClassUnloadedProbeTester.java:
Part of test coverage for hotspot.stp and hotspot_jni.stp tapsets.
* test/tapset/JNIStapTest.c:
Likewise.
* test/tapset/JNITestClass.c:
Likewise.
* test/tapset/JNITestClass.h:
Likewise.
* test/tapset/JNITestClass.java:
Likewise.
* test/tapset/RunWrapper.java:
Likewise.
* test/tapset/StapJNIClassLoader.java:
Likewise.
* test/tapset/StapURLClassLoader.java:
Likewise.
* test/tapset/SystemtapTester.java:
Likewise.
* test/tapset/TestingRunner.java:
Likewise.
* test/tapset/jstaptest.pl:
Wrapper script, compiles and runs tests for tapsets.
diff -r 2ec767396557 -r 55b21736fe19 ChangeLog
--- a/ChangeLog Tue Mar 20 13:48:29 2012 +0100
+++ b/ChangeLog Fri Mar 23 14:11:00 2012 +0100
@@ -1,3 +1,33 @@
+2012-03-23 Jon VanAlten <jon.vanalten at redhat.com>
+
+ * Makefile.am:
+ Add target to run tapset tests.
+ * tapset/hotspot_jni.stp.in:
+ Add notes regarding required JVM option to Get<PrimitiveType>Field
+ family of probe aliases.
+ * test/tapset/ClassUnloadedProbeTester.java:
+ Part of test coverage for hotspot.stp and hotspot_jni.stp tapsets.
+ * test/tapset/JNIStapTest.c:
+ Likewise.
+ * test/tapset/JNITestClass.c:
+ Likewise.
+ * test/tapset/JNITestClass.h:
+ Likewise.
+ * test/tapset/JNITestClass.java:
+ Likewise.
+ * test/tapset/RunWrapper.java:
+ Likewise.
+ * test/tapset/StapJNIClassLoader.java:
+ Likewise.
+ * test/tapset/StapURLClassLoader.java:
+ Likewise.
+ * test/tapset/SystemtapTester.java:
+ Likewise.
+ * test/tapset/TestingRunner.java:
+ Likewise.
+ * test/tapset/jstaptest.pl:
+ Wrapper script, compiles and runs tests for tapsets.
+
2012-03-20 Mark Wielaard <mjw at redhat.com>
* Makefile.am (clean-jtreg): Depend on clean-jtreg-reports.
diff -r 2ec767396557 -r 55b21736fe19 Makefile.am
--- a/Makefile.am Tue Mar 20 13:48:29 2012 +0100
+++ b/Makefile.am Fri Mar 23 14:11:00 2012 +0100
@@ -654,9 +654,16 @@
all-local: icedtea-against-icedtea
-check-local: jtregcheck
+check-local: jtregcheck check-tapset
-clean-local: clean-jtreg clean-jtreg-reports $(PULSE_JAVA_CLEAN_TARGET) \
+clean-tests: clean-jtreg clean-tapset-report
+ if [ $(abs_top_srcdir) != $(abs_top_builddir) ] ; then \
+ if [ -e test ] ; then \
+ rmdir test ; \
+ fi \
+ fi
+
+clean-local: clean-tests $(PULSE_JAVA_CLEAN_TARGET) \
clean-icedtea clean-icedtea-debug clean-icedtea-ecj clean-extract clean-ports \
clean-overlay clean-native-ecj clean-icedtea-against-icedtea clean-icedtea-debug-against-icedtea \
clean-icedtea-against-ecj clean-extract-ecj clean-generated clean-replace-hotspot \
@@ -700,7 +707,7 @@
clean-add-pulseaudio clean-add-pulseaudio-debug clean-add-nss clean-add-nss-debug \
clean-add-tzdata-support clean-add-tzdata-support-debug clean-add-systemtap-ecj \
clean-add-pulseaudio-ecj clean-add-nss-ecj clean-add-tzdata-support-ecj clean-fonts \
- clean-download-hotspot jtregcheck
+ clean-download-hotspot clean-tests clean-tapset-report jtregcheck
env:
@echo 'unset JAVA_HOME'
@@ -2163,9 +2170,6 @@
rmdir test/jtreg ; \
fi
rm -f test/jtreg.jar
- if [ -e test ] ; then \
- rmdir test ; \
- fi
rm -f stamps/jtreg.stamp
check-hotspot: stamps/jtreg.stamp
@@ -2246,6 +2250,19 @@
$(jtreg_processes); \
fi
+check-tapset:
+if ENABLE_SYSTEMTAP
+ $(abs_top_srcdir)/test/tapset/jstaptest.pl \
+ -B $(BUILD_OUTPUT_DIR) -A $(BUILD_ARCH_DIR) \
+ -S $(abs_top_srcdir)/test/tapset \
+ -o test/check-stap.log
+endif
+
+clean-tapset-report:
+if ENABLE_SYSTEMTAP
+ rm -f test/check-stap.log
+endif
+
# Support classes for non-OpenJDK bootstraps
# rt.jar additional class files.
diff -r 2ec767396557 -r 55b21736fe19 tapset/hotspot_jni.stp.in
--- a/tapset/hotspot_jni.stp.in Tue Mar 20 13:48:29 2012 +0100
+++ b/tapset/hotspot_jni.stp.in Fri Mar 23 14:11:00 2012 +0100
@@ -3532,6 +3532,7 @@
/* hotspot.jni.GetBooleanField
* Get non-static jboolean field value.
+ * NEEDS: -XX:-UseFastJNIAccessors
*
* env - JNIEnv pointer.
* obj - jobject.
@@ -3550,6 +3551,7 @@
/* hotspot.jni.GetBooleanField.return
* Get non-static jboolean field value. Return.
+ * NEEDS: -XX:-UseFastJNIAccessors
*
* ret - jboolean value.
*/
@@ -3629,6 +3631,7 @@
/* hotspot.jni.GetByteField
* Get non-static jbyte field value.
+ * NEEDS: -XX:-UseFastJNIAccessors
*
* env - JNIEnv pointer.
* obj - jobject.
@@ -3647,6 +3650,7 @@
/* hotspot.jni.GetByteField.return
* Get non-static jbyte field value. Return.
+ * NEEDS: -XX:-UseFastJNIAccessors
*
* ret - jbyte value.
*/
@@ -3726,6 +3730,7 @@
/* hotspot.jni.GetCharField
* Get non-static jchar field value.
+ * NEEDS: -XX:-UseFastJNIAccessors
*
* env - JNIEnv pointer.
* obj - jobject.
@@ -3744,6 +3749,7 @@
/* hotspot.jni.GetCharField.return
* Get non-static jchar field value. Return.
+ * NEEDS: -XX:-UseFastJNIAccessors
*
* ret - jchar value.
*/
@@ -3761,7 +3767,7 @@
*
* vmbuf - Pointer to JavaVM pointer.
* buflen - Max number of vms returned.
- * nvms - Number of JavaVMs returned.
+ * nvms - Pointer to where the number of created JavaVMs will be returned.
*/
probe hotspot.jni.GetCreatedJavaVMs =
process("@ABS_CLIENT_LIBJVM_SO@").mark("GetCreatedJavaVMs__entry"),
@@ -3771,7 +3777,7 @@
vmbuf = $arg1
buflen = $arg2
nvms = $arg3
- probestr = sprintf("%s(vmbuf=0x%x,buflen=%d,nvms=%d)", name, vmbuf, buflen, nvms)
+ probestr = sprintf("%s(vmbuf=0x%x,buflen=%d,nvms=0x%x)", name, vmbuf, buflen, nvms)
}
/* hotspot.jni.GetCreatedJavaVMs.return
@@ -3943,6 +3949,7 @@
/* hotspot.jni.GetDoubleField
* Get non-static jdouble field value.
+ * NEEDS: -XX:-UseFastJNIAccessors
*
* env - JNIEnv pointer.
* obj - jobject.
@@ -3961,6 +3968,7 @@
/* hotspot.jni.GetDoubleField.return
* Get non-static jdouble field value. Return.
+ * NEEDS: -XX:-UseFastJNIAccessors
*/
probe hotspot.jni.GetDoubleField.return =
process("@ABS_CLIENT_LIBJVM_SO@").mark("GetDoubleField__return"),
@@ -4103,6 +4111,7 @@
/* hotspot.jni.GetFloatField
* Get non-static jfloat field value.
+ * NEEDS: -XX:-UseFastJNIAccessors
*
* env - JNIEnv pointer.
* obj - jobject.
@@ -4121,6 +4130,7 @@
/* hotspot.jni.GetFloatField.return
* Get non-static jfloat field value. Return.
+ * NEEDS: -XX:-UseFastJNIAccessors
*/
probe hotspot.jni.GetFloatField.return =
process("@ABS_CLIENT_LIBJVM_SO@").mark("GetFloatField__return"),
@@ -4197,6 +4207,7 @@
/* hotspot.jni.GetIntField
* Get non-static jint field value.
+ * NEEDS: -XX:-UseFastJNIAccessors
*
* env - JNIEnv pointer.
* obj - jobject.
@@ -4215,6 +4226,7 @@
/* hotspot.jni.GetIntField.return
* Get non-static jint field value. Return.
+ * NEEDS: -XX:-UseFastJNIAccessors
*
* ret - jint value.
*/
@@ -4324,6 +4336,7 @@
/* hotspot.jni.GetLongField
* Get non-static jlong field value.
+ * NEEDS: -XX:-UseFastJNIAccessors
*
* env - JNIEnv pointer.
* obj - jobject.
@@ -4342,6 +4355,7 @@
/* hotspot.jni.GetLongField.return
* Get non-static jlong field value. Return.
+ * NEEDS: -XX:-UseFastJNIAccessors
*
* ret - jlong value.
*/
@@ -4611,6 +4625,7 @@
/* hotspot.jni.GetShortField
* Get non-static jshort field value.
+ * NEEDS: -XX:-UseFastJNIAccessors
*
* env - JNIEnv pointer.
* obj - jobject.
@@ -4629,6 +4644,7 @@
/* hotspot.jni.GetShortField.return
* Get non-static jshort field value. Return.
+ * NEEDS: -XX:-UseFastJNIAccessors
*
* ret - jshort value.
*/
diff -r 2ec767396557 -r 55b21736fe19 test/tapset/ClassUnloadedProbeTester.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tapset/ClassUnloadedProbeTester.java Fri Mar 23 14:11:00 2012 +0100
@@ -0,0 +1,38 @@
+package staptest;
+
+class ClassUnloadedProbeTester {
+ private int myField;
+ long total;
+ static ClassUnloadedProbeTester tester;
+
+ public static void main(String[] args) {
+ long total = 0;
+ for (int i = 1; i < 105; i++) {
+ tester = new ClassUnloadedProbeTester();
+ tester.runner(tester, i);
+ if (total != tester.total)
+ total += tester.getField();
+ }
+ }
+
+ void runner(ClassUnloadedProbeTester run, int j) {
+ for (int i = 1; i < 105; i++) {
+ run.setField(i);
+ total += tester.getField();
+ }
+ total += j;
+ }
+
+ public ClassUnloadedProbeTester() {
+ myField = 500;
+ }
+
+ public int getField() {
+ return myField;
+ }
+
+ public void setField(int newValue) {
+ myField = newValue;
+ }
+}
+
diff -r 2ec767396557 -r 55b21736fe19 test/tapset/JNIStapTest.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tapset/JNIStapTest.c Fri Mar 23 14:11:00 2012 +0100
@@ -0,0 +1,2107 @@
+#include <errno.h>
+#include <fcntl.h>
+#include <pthread.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include "jni.h"
+#include "JNITestClass.h"
+
+/* Longer than any known good argument. */
+#define MAX_ARG_LEN 128
+/* Arbitrary length. Some arrays are assigned with literals, so do not change
+ * this without examining the source carefully.
+ */
+#define TEST_ARRAY_LEN 5
+
+/* Arguments for run_attach_current_thread. */
+#define DAEMON 1
+#define NOT_DAEMON 2
+
+/* Avoiding repeated inline string constants. */
+char* const ALLOC_OBJECT = "AllocObject";
+char* const ATTACH_CURRENT_THREAD_AS_DAEMON = "AttachCurrentThreadAsDaemon";
+char* const ATTACH_CURRENT_THREAD = "AttachCurrentThread";
+char* const CALL = "Call";
+char* const CREATE_JAVA_VM = "CreateJavaVM";
+char* const DEFINE_CLASS = "DefineClass";
+char* const DELETE_GLOBAL_REF = "DeleteGlobalRef";
+char* const DELETE_LOCAL_REF = "DeleteLocalRef";
+char* const DELETE_WEAK_GLOBAL_REF = "DeleteWeakGlobalRef";
+char* const DESTROY_JAVA_VM = "DestroyJavaVM";
+char* const DETACH_CURRENT_THREAD = "DetachCurrentThread";
+char* const ENSURE_LOCAL_CAPACITY = "EnsureLocalCapacity";
+char* const EXCEPTION_CHECK = "ExceptionCheck";
+char* const EXCEPTION_CLEAR = "ExceptionClear";
+char* const EXCEPTION_DESCRIBE = "ExceptionDescribe";
+char* const EXCEPTION_OCCURRED = "ExceptionOccurred";
+char* const FATAL_ERROR = "FatalError";
+char* const FIND_CLASS = "FindClass";
+char* const FROM_REFLECTED_FIELD = "FromReflectedField";
+char* const FROM_REFLECTED_METHOD = "FromReflectedMethod";
+char* const GET_ARRAY_LENGTH = "GetArrayLength";
+char* const GET_CREATED_JAVA_VMS = "GetCreatedJavaVMs";
+char* const GET_DEFAULT_JAVA_VM_INIT_ARGS = "GetDefaultJavaVMInitArgs";
+char* const GET_DIRECT_BUFFER_ADDRESS = "GetDirectBufferAddress";
+char* const GET_DIRECT_BUFFER_CAPACITY = "GetDirectBufferCapacity";
+char* const GET = "Get";
+char* const GET_ENV = "GetEnv";
+char* const GET_FIELD_ID = "GetFieldID";
+char* const GET_JAVA_VM = "GetJavaVM";
+char* const GET_METHOD_ID = "GetMethodID";
+char* const GET_OBJECT_CLASS = "GetObjectClass";
+char* const GET_OBJECT_REF_TYPE = "GetObjectRefType";
+char* const GET_PRIMITIVE_ARRAY_CRITICAL = "GetPrimitiveArrayCritical";
+char* const GET_STATIC_FIELD_ID = "GetStaticFieldID";
+char* const GET_STATIC_METHOD_ID = "GetStaticMethodID";
+char* const GET_STRING = "GetString";
+char* const GET_STRING_UTF = "GetStringUTF";
+char* const GET_SUPERCLASS = "GetSuperclass";
+char* const GET_VERSION = "GetVersion";
+char* const IS_ASSIGNABLE_FROM = "IsAssignableFrom";
+char* const IS_INSTANCE_OF = "IsInstanceOf";
+char* const IS_SAME_OBJECT = "IsSameObject";
+char* const MONITOR = "Monitor";
+char* const NEW = "New";
+char* const NEW_DIRECT_BYTE_BUFFER = "NewDirectByteBuffer";
+char* const NEW_GLOBAL_REF = "NewGlobalRef";
+char* const NEW_LOCAL_REF = "NewLocalRef";
+char* const NEW_OBJECT_A = "NewObjectA";
+char* const NEW_OBJECT = "NewObject";
+char* const NEW_OBJECT_V = "NewObjectV";
+char* const NEW_STRING = "NewString";
+char* const NEW_STRING_UTF = "NewStringUTF";
+char* const NEW_WEAK_GLOBAL_REF = "NewWeakGlobalRef";
+char* const POP_LOCAL_FRAME = "PopLocalFrame";
+char* const PUSH_LOCAL_FRAME = "PushLocalFrame";
+char* const REGISTER_NATIVES = "RegisterNatives";
+char* const RELEASE = "Release";
+char* const RELEASE_PRIMITIVE_ARRAY_CRITICAL = "ReleasePrimitiveArrayCritical";
+char* const RELEASE_STRING_CHARS = "ReleaseStringChars";
+char* const RELEASE_STRING_CRITICAL = "ReleaseStringCritical";
+char* const RELEASE_STRING_UTF_CHARS = "ReleaseStringUTFChars";
+char* const SET = "Set";
+char* const THROW = "Throw";
+char* const THROW_NEW = "ThrowNew";
+char* const TO_REFLECTED_FIELD = "ToReflectedField";
+char* const TO_REFLECTED_METHOD = "ToReflectedMethod";
+char* const UNREGISTER_NATIVES = "UnregisterNatives";
+
+char* const FIELD = "Field";
+char* const ARRAY = "Array";
+char* const STATIC = "Static";
+char* const NONVIRTUAL = "Nonvirtual";
+char* const DIRECT = "Direct";
+char* const BOOLEAN = "Boolean";
+char* const BYTE = "Byte";
+char* const CHAR = "Char";
+char* const DOUBLE = "Double";
+char* const FLOAT = "Float";
+char* const INT = "Int";
+char* const LONG = "Long";
+char* const OBJECT = "Object";
+char* const SHORT = "Short";
+char* const VOID = "Void";
+
+char* const TEST_CLASS = "staptest/JNITestClass";
+
+/* These functions defined below. */
+void bad_usage();
+void* run_attach_current_thread(void* style);
+
+int get_type_and_modifier(char* arg, char** type_p, char** mod_p);
+
+jboolean is_field_op(char* arg);
+jboolean is_array_op(char* arg);
+
+jint create_java_vm_wrap(JavaVMInitArgs* args);
+
+jobject new_object_v_wrap(JNIEnv* env_, jclass* class_p,
+ jmethodID* construct, ...);
+
+jboolean boolean_v_wrap(JNIEnv** env_p, jobject* obj_p,
+ jmethodID* method_p, ...);
+jbyte byte_v_wrap(JNIEnv** env_p, jobject* obj_p,
+ jmethodID* method_p, ...);
+jchar char_v_wrap(JNIEnv** env_p, jobject* obj_p,
+ jmethodID* method_p, ...);
+jdouble double_v_wrap(JNIEnv** env_p, jobject* obj_p,
+ jmethodID* method_p, ...);
+jfloat float_v_wrap(JNIEnv** env_p, jobject* obj_p,
+ jmethodID* method_p, ...);
+jint int_v_wrap(JNIEnv** env_p, jobject* obj_p,
+ jmethodID* method_p, ...);
+jlong long_v_wrap(JNIEnv** env_p, jobject* obj_p,
+ jmethodID* method_p, ...);
+jobject object_v_wrap(JNIEnv** env_p, jobject* obj_p,
+ jmethodID* method_p, ...);
+jshort short_v_wrap(JNIEnv** env_p, jobject* obj_p,
+ jmethodID* method_p, ...);
+void void_v_wrap(JNIEnv** env_p, jobject* obj_p,
+ jmethodID* method_p, ...);
+
+jboolean nonvirtual_boolean_v_wrap(JNIEnv** env_p, jobject* obj_p,
+ jclass* jclass_p, jmethodID* method_p, ...);
+jbyte nonvirtual_byte_v_wrap(JNIEnv** env_p, jobject* obj_p,
+ jclass* jclass_p, jmethodID* method_p, ...);
+jchar nonvirtual_char_v_wrap(JNIEnv** env_p, jobject* obj_p,
+ jclass* jclass_p, jmethodID* method_p, ...);
+jdouble nonvirtual_double_v_wrap(JNIEnv** env_p, jobject* obj_p,
+ jclass* jclass_p, jmethodID* method_p, ...);
+jfloat nonvirtual_float_v_wrap(JNIEnv** env_p, jobject* obj_p,
+ jclass* jclass_p, jmethodID* method_p, ...);
+jint nonvirtual_int_v_wrap(JNIEnv** env_p, jobject* obj_p,
+ jclass* jclass_p, jmethodID* method_p, ...);
+jlong nonvirtual_long_v_wrap(JNIEnv** env_p, jobject* obj_p,
+ jclass* jclass_p, jmethodID* method_p, ...);
+jobject nonvirtual_object_v_wrap(JNIEnv** env_p, jobject* obj_p,
+ jclass* jclass_p, jmethodID* method_p, ...);
+jshort nonvirtual_short_v_wrap(JNIEnv** env_p, jobject* obj_p,
+ jclass* jclass_p, jmethodID* method_p, ...);
+void nonvirtual_void_v_wrap(JNIEnv** env_p, jobject* obj_p,
+ jclass* jclass_p, jmethodID* method_p, ...);
+
+jboolean static_boolean_v_wrap(JNIEnv** env_p, jclass* jclass_p,
+ jmethodID* method_p, ...);
+jbyte static_byte_v_wrap(JNIEnv** env_p, jclass* jclass_p,
+ jmethodID* method_p, ...);
+jchar static_char_v_wrap(JNIEnv** env_p, jclass* jclass_p,
+ jmethodID* method_p, ...);
+jdouble static_double_v_wrap(JNIEnv** env_p, jclass* jclass_p,
+ jmethodID* method_p, ...);
+jfloat static_float_v_wrap(JNIEnv** env_p, jclass* jclass_p,
+ jmethodID* method_p, ...);
+jint static_int_v_wrap(JNIEnv** env_p, jclass* jclass_p,
+ jmethodID* method_p, ...);
+jlong static_long_v_wrap(JNIEnv** env_p, jclass* jclass_p,
+ jmethodID* method_p, ...);
+jobject static_object_v_wrap(JNIEnv** env_p, jclass* jclass_p,
+ jmethodID* method_p, ...);
+jshort static_short_v_wrap(JNIEnv** env_p, jclass* jclass_p,
+ jmethodID* method_p, ...);
+void static_void_v_wrap(JNIEnv** env_p, jclass* jclass_p,
+ jmethodID* method_p, ...);
+
+/* We don't want to have to pass these around all the time, so make them global.
+ * This would probably be a Very Bad Idea in real JNI code.
+ */
+JavaVM* jvm;
+JNIEnv *env;
+
+int main(int argc, char *argv[]) {
+
+ pthread_t attach_thread;
+
+ if (argc != 2) {
+ bad_usage("No argument specified.");
+ exit(1);
+ }
+ int arglen = (int) strlen(argv[1]);
+ if (arglen > MAX_ARG_LEN) {
+ bad_usage("Argument too long.");
+ exit(1);
+ }
+ char* safe_arg = (char*) malloc(sizeof(char)*(MAX_ARG_LEN + 1));
+ strncpy(safe_arg, argv[1], MAX_ARG_LEN);
+ /* Copy into a larger array so we can strncmp to our string constants
+ * without the risk of running past the end of the string.
+ */
+/* This is a gigantic if-else if-else block. Each JNI function (or, where
+ * appropriate, groups of related JNI functions) are called independently, as
+ * determined by the argument to this program, in order to trigger the
+ * corresponding systemtap/dtrace probes.
+ */
+ if ((strncmp(safe_arg, CREATE_JAVA_VM,
+ strlen(CREATE_JAVA_VM)) == 0) ||
+ (strncmp(safe_arg, DESTROY_JAVA_VM,
+ strlen(DESTROY_JAVA_VM)) == 0)) {
+ jint created = create_java_vm_wrap(NULL);
+ if (created != 0) {
+ exit(-1);
+ }
+ /* No further action needed. */
+ goto end_vm;
+ } else if (strncmp(safe_arg, FATAL_ERROR, strlen(FATAL_ERROR)) == 0) {
+ jint created = create_java_vm_wrap(NULL);
+ if (created != 0) {
+ exit(-1);
+ }
+ (*env)->FatalError(env, "Intentional Crash: Ignore.");
+ exit(-1);
+ } else if (strncmp(safe_arg, GET_VERSION, strlen(GET_VERSION)) == 0) {
+ jint created = create_java_vm_wrap(NULL);
+ if (created != 0) {
+ exit(-1);
+ }
+ (*env)->GetVersion(env);
+ } else if (strncmp(safe_arg, GET_ENV, strlen(GET_ENV)) == 0) {
+ jint created = create_java_vm_wrap(NULL);
+ if (created != 0) {
+ exit(-1);
+ }
+ JNIEnv *tmp_env;
+ (*jvm)->GetEnv(jvm, (void**)&tmp_env, JNI_VERSION_1_6);
+ } else if (strncmp(safe_arg, GET_DEFAULT_JAVA_VM_INIT_ARGS,
+ strlen(GET_DEFAULT_JAVA_VM_INIT_ARGS)) == 0) {
+ JavaVMInitArgs vm_args;
+ vm_args.version = JNI_VERSION_1_6;
+ JNI_GetDefaultJavaVMInitArgs(&vm_args);
+ if (safe_arg != NULL) {
+ free(safe_arg);
+ safe_arg = NULL;
+ }
+ exit(0);
+ } else if (strncmp(safe_arg, GET_JAVA_VM,
+ strlen(GET_JAVA_VM)) == 0) {
+ jint created = create_java_vm_wrap(NULL);
+ if (created != 0) {
+ exit(-1);
+ }
+ JavaVM* vm_pointer;
+ (*env)->GetJavaVM(env, &vm_pointer);
+ } else if (strncmp(safe_arg, DEFINE_CLASS, strlen(DEFINE_CLASS)) == 0) {
+ jint created = create_java_vm_wrap(NULL);
+ if (created != 0) {
+ exit(-1);
+ }
+ jclass loaderClass = (*env)->FindClass(env, "staptest/StapJNIClassLoader");
+ if (loaderClass == NULL) {
+ /* Bail out, cannot find class. */
+ goto end_vm;
+ }
+ jmethodID loadConstructor = (*env)->GetMethodID(env, loaderClass,
+ "<init>", "()V");
+ if (loadConstructor == NULL) {
+ /* Bail out, cannot find constructor. */
+ goto end_vm;
+ }
+ jobject loader = (*env)->NewObject(env, loaderClass, loadConstructor);
+ if (loader == NULL) {
+ /* Bail out, cannot create loader. */
+ goto end_vm;
+ }
+ int class_fildes = open("./staptest/JNITestClass.class", O_RDONLY|O_NONBLOCK);
+ if (class_fildes == -1) {
+ /* Bail out, cannot open class file. */
+ goto end_vm;
+ }
+ struct stat classfile_stats;
+ int r_val = fstat(class_fildes, &classfile_stats);
+ if (r_val != 0) {
+ /* Bail out, cannot determine classfile size. */
+ goto end_vm;
+ }
+ ssize_t classfile_size = (ssize_t) classfile_stats.st_size;
+ jbyte* classfile_buf = malloc(sizeof(jbyte)*classfile_size);
+ ssize_t total_bytes_read = 0;
+ /* Ensure entire file is read in case of interrupts. */
+ while (total_bytes_read < classfile_size) {
+ size_t bytes_needed = (size_t) classfile_size - (size_t) total_bytes_read;
+ void* buf_start = (void*) classfile_buf + total_bytes_read;
+ ssize_t bytes_read = pread(class_fildes, buf_start,
+ bytes_needed, (off_t) total_bytes_read);
+ if (bytes_read <= 0) {
+ /* Bail out, reading from file blocked or unexpected EOF */
+ if (classfile_buf != NULL) {
+ free(classfile_buf);
+ classfile_buf = NULL;
+ }
+ goto end_vm;
+ }
+ total_bytes_read += bytes_read;
+ }
+ jclass testClass = (*env)->DefineClass(env, TEST_CLASS, loader,
+ classfile_buf, (jsize) classfile_size);
+ if (classfile_buf != NULL) {
+ free(classfile_buf);
+ classfile_buf = NULL;
+ }
+ } else if ((strncmp(safe_arg, ENSURE_LOCAL_CAPACITY,
+ strlen(ENSURE_LOCAL_CAPACITY)) == 0) ||
+ (strncmp(safe_arg, PUSH_LOCAL_FRAME,
+ strlen(PUSH_LOCAL_FRAME)) == 0) ||
+ (strncmp(safe_arg, POP_LOCAL_FRAME,
+ strlen(POP_LOCAL_FRAME)) == 0)) {
+ jint created = create_java_vm_wrap(NULL);
+ if (created != 0) {
+ exit(-1);
+ }
+ jint rval = (*env)->PushLocalFrame(env, (jint) 10);
+ if (rval == JNI_OK) {
+ (*env)->EnsureLocalCapacity(env, (jint) 10);
+ (*env)->PopLocalFrame(env, NULL);
+ }
+ } else if ((strncmp(safe_arg, NEW_OBJECT, strlen(NEW_OBJECT)) == 0) &&
+ (strlen(safe_arg) == strlen(NEW_OBJECT))) {
+ jint created = create_java_vm_wrap(NULL);
+ if (created != 0) {
+ exit(-1);
+ }
+ jclass testClass = (*env)->FindClass(env, TEST_CLASS);
+ if (testClass == NULL) {
+ /* Bail out, cannot find class. */
+ goto end_vm;
+ }
+ jmethodID constructor = (*env)->GetMethodID(env, testClass,
+ "<init>", "()V");
+ if (constructor == NULL) {
+ /* Bail out, cannot find constructor. */
+ goto end_vm;
+ }
+ jobject testInstance = (*env)->NewObject(env, testClass, constructor);
+ } else if ((strncmp(safe_arg, NEW_OBJECT_A, strlen(NEW_OBJECT_A)) == 0) &&
+ (strlen(safe_arg) == strlen(NEW_OBJECT_A))) {
+ jint created = create_java_vm_wrap(NULL);
+ if (created != 0) {
+ exit(-1);
+ }
+ jclass testClass = (*env)->FindClass(env, TEST_CLASS);
+ if (testClass == NULL) {
+ /* Bail out, cannot find class. */
+ goto end_vm;
+ }
+ jmethodID constructor = (*env)->GetMethodID(env, testClass,
+ "<init>", "()V");
+ if (constructor == NULL) {
+ /* Bail out, cannot find constructor. */
+ goto end_vm;
+ }
+ jobject testInstance = (*env)->NewObjectA(env, testClass,
+ constructor, NULL);
+ } else if (strncmp(safe_arg, NEW_OBJECT_V, strlen(NEW_OBJECT_V)) == 0) {
+ jint created = create_java_vm_wrap(NULL);
+ if (created != 0) {
+ exit(-1);
+ }
+ jclass testClass = (*env)->FindClass(env, TEST_CLASS);
+ if (testClass == NULL) {
+ /* Bail out, cannot find class. */
+ goto end_vm;
+ }
+ jmethodID constructor = (*env)->GetMethodID(env, testClass,
+ "<init>", "()V");
+ if (constructor == NULL) {
+ /* Bail out, cannot find constructor. */
+ goto end_vm;
+ }
+ jobject testInstance = new_object_v_wrap(env, &testClass, &constructor);
+ } else if ((strncmp(safe_arg, GET_ARRAY_LENGTH,
+ strlen(GET_ARRAY_LENGTH)) == 0) ||
+ (strncmp(safe_arg, GET_PRIMITIVE_ARRAY_CRITICAL,
+ strlen(GET_PRIMITIVE_ARRAY_CRITICAL)) == 0) ||
+ (strncmp(safe_arg, RELEASE_PRIMITIVE_ARRAY_CRITICAL,
+ strlen(RELEASE_PRIMITIVE_ARRAY_CRITICAL)) == 0)) {
+ jint created = create_java_vm_wrap(NULL);
+ if (created != 0) {
+ exit(-1);
+ }
+ jbyteArray byte_array = (*env)->NewByteArray(env, (jsize) TEST_ARRAY_LEN);
+ jsize byte_array_len = (*env)->GetArrayLength(env, (jarray) byte_array);
+ void* primitive_array = (*env)->GetPrimitiveArrayCritical(env,
+ (jarray) byte_array, NULL);
+ if (primitive_array == NULL) {
+ /* JVM out of memory, don't try to release. */
+ goto end_vm;
+ }
+ (*env)->ReleasePrimitiveArrayCritical(env, (jarray) byte_array,
+ primitive_array, JNI_ABORT);
+ } else if (strncmp(safe_arg+3, DIRECT, strlen(DIRECT)) == 0) {
+ jint created = create_java_vm_wrap(NULL);
+ if (created != 0) {
+ exit(-1);
+ }
+ void* some_space = malloc((size_t) MAX_ARG_LEN);
+ jobject byte_buffer = (*env)->NewDirectByteBuffer(env, some_space,
+ (jlong) MAX_ARG_LEN);
+ void* pointer_to_some_space = (*env)->GetDirectBufferAddress(env,
+ byte_buffer);
+ jlong some_space_capacity = (*env)->GetDirectBufferCapacity(env,
+ byte_buffer);
+ if (some_space != NULL) {
+ free(some_space);
+ some_space = NULL;
+ }
+ } else if ((strncmp(safe_arg, THROW, strlen(THROW)) == 0) ||
+ (strncmp(safe_arg, EXCEPTION_CHECK,
+ strlen(EXCEPTION_CHECK)) == 0) ||
+ (strncmp(safe_arg, EXCEPTION_CLEAR,
+ strlen(EXCEPTION_CLEAR)) == 0) ||
+ (strncmp(safe_arg, EXCEPTION_DESCRIBE,
+ strlen(EXCEPTION_DESCRIBE)) == 0) ||
+ (strncmp(safe_arg, EXCEPTION_OCCURRED,
+ strlen(EXCEPTION_OCCURRED)) == 0)) {
+ jint created = create_java_vm_wrap(NULL);
+ if (created != 0) {
+ exit(-1);
+ }
+ jclass exceptionClass = (*env)->FindClass(env, "java/lang/Exception");
+ if (exceptionClass == NULL) {
+ /* Bail out, cannot find class. */
+ goto end_vm;
+ }
+ jmethodID constructor = (*env)->GetMethodID(env, exceptionClass,
+ "<init>", "()V");
+ if (constructor == NULL) {
+ /* Bail out, cannot find constructor. */
+ goto end_vm;
+ }
+ jthrowable anException = (jthrowable) (*env)->NewObject(env,
+ exceptionClass, constructor);
+ if (anException == NULL) {
+ /* Bail out, cannot create exception. */
+ goto end_vm;
+ }
+ jint r_val = (*env)->Throw(env, anException);
+ if (r_val != 0) {
+ /* Bail out, couldn't throw exception. */
+ goto end_vm;
+ }
+ jboolean exception_thrown = (*env)->ExceptionCheck(env);
+ if (exception_thrown == JNI_FALSE) {
+ /* Huh? Should be true. */
+ goto end_vm;
+ }
+ (*env)->ExceptionClear(env);
+ r_val = (*env)->ThrowNew(env, exceptionClass, "This exception is for testing purposes only.");
+ anException = (*env)->ExceptionOccurred(env);
+ if (anException == NULL) {
+ goto end_vm;
+ }
+ (*env)->ExceptionClear(env);
+ /* We don't actually want to see output, so we clear exception first. */
+ (*env)->ExceptionDescribe(env);
+ } else if ((strncmp(safe_arg, REGISTER_NATIVES,
+ strlen(REGISTER_NATIVES)) == 0) ||
+ (strncmp(safe_arg, UNREGISTER_NATIVES,
+ strlen(UNREGISTER_NATIVES)) == 0)) {
+ jint created = create_java_vm_wrap(NULL);
+ if (created != 0) {
+ exit(-1);
+ }
+ jclass testClass = (*env)->FindClass(env, TEST_CLASS);
+ if (testClass == NULL) {
+ /* Bail out, cannot find class. */
+ goto end_vm;
+ }
+ JNINativeMethod jni_method;
+ jni_method.name = "doNothing";
+ jni_method.signature = "()V";
+ jni_method.fnPtr = &Java_JNITestClass_doNothing;
+ jint r_val = (*env)->RegisterNatives(env, testClass, &jni_method, (jint) 1);
+ if (r_val != 0) {
+ goto end_vm;
+ }
+ r_val = (*env)->UnregisterNatives(env, testClass);
+ } else if ((strncmp(safe_arg, ATTACH_CURRENT_THREAD_AS_DAEMON,
+ strlen(ATTACH_CURRENT_THREAD_AS_DAEMON)) == 0) ||
+ (strncmp(safe_arg, GET_CREATED_JAVA_VMS,
+ strlen(GET_CREATED_JAVA_VMS)) == 0)) {
+ jint created = create_java_vm_wrap(NULL);
+ if (created != 0) {
+ exit(-1);
+ }
+ int rval;
+ int style = (int) DAEMON;
+ rval = pthread_create(&attach_thread, NULL,
+ run_attach_current_thread, &style);
+ if (rval == 0) {
+ pthread_join(attach_thread, NULL);
+ }
+ } else if ((strncmp(safe_arg, ATTACH_CURRENT_THREAD,
+ strlen(ATTACH_CURRENT_THREAD)) == 0) ||
+ (strncmp(safe_arg, DETACH_CURRENT_THREAD,
+ strlen(DETACH_CURRENT_THREAD)) == 0)) {
+ jint created = create_java_vm_wrap(NULL);
+ if (created != 0) {
+ exit(-1);
+ }
+ int rval;
+ int style = (int) NOT_DAEMON;
+ rval = pthread_create(&attach_thread, NULL,
+ run_attach_current_thread, &style);
+ if (rval == 0) {
+ pthread_join(attach_thread, NULL);
+ }
+ } else if ((strncmp(safe_arg, ALLOC_OBJECT,
+ strlen(ALLOC_OBJECT)) == 0) ||
+/* A bunch of jni functions having to do with classes and references. */
+ (strncmp(safe_arg, DELETE_GLOBAL_REF,
+ strlen(DELETE_GLOBAL_REF)) == 0) ||
+ (strncmp(safe_arg, DELETE_LOCAL_REF,
+ strlen(DELETE_LOCAL_REF)) == 0) ||
+ (strncmp(safe_arg, DELETE_WEAK_GLOBAL_REF,
+ strlen(DELETE_WEAK_GLOBAL_REF)) == 0) ||
+ (strncmp(safe_arg, FIND_CLASS,
+ strlen(FIND_CLASS)) == 0) ||
+ (strncmp(safe_arg, GET_FIELD_ID,
+ strlen(GET_FIELD_ID)) == 0) ||
+ (strncmp(safe_arg, GET_METHOD_ID,
+ strlen(GET_METHOD_ID)) == 0) ||
+ (strncmp(safe_arg, GET_OBJECT_CLASS,
+ strlen(GET_OBJECT_CLASS)) == 0) ||
+ (strncmp(safe_arg, GET_OBJECT_REF_TYPE,
+ strlen(GET_OBJECT_REF_TYPE)) == 0) ||
+ (strncmp(safe_arg, GET_STATIC_FIELD_ID,
+ strlen(GET_STATIC_FIELD_ID)) == 0) ||
+ (strncmp(safe_arg, GET_STATIC_METHOD_ID,
+ strlen(GET_STATIC_METHOD_ID)) == 0) ||
+ (strncmp(safe_arg, GET_SUPERCLASS,
+ strlen(GET_SUPERCLASS)) == 0) ||
+ (strncmp(safe_arg, IS_ASSIGNABLE_FROM,
+ strlen(IS_ASSIGNABLE_FROM)) == 0) ||
+ (strncmp(safe_arg, IS_INSTANCE_OF,
+ strlen(IS_INSTANCE_OF)) == 0) ||
+ (strncmp(safe_arg, IS_SAME_OBJECT,
+ strlen(IS_SAME_OBJECT)) == 0) ||
+ (strncmp(safe_arg, NEW_GLOBAL_REF,
+ strlen(NEW_GLOBAL_REF)) == 0) ||
+ (strncmp(safe_arg, NEW_LOCAL_REF,
+ strlen(NEW_LOCAL_REF)) == 0) ||
+ (strncmp(safe_arg, NEW_WEAK_GLOBAL_REF,
+ strlen(NEW_WEAK_GLOBAL_REF)) == 0) ||
+ (strncmp(safe_arg, TO_REFLECTED_FIELD,
+ strlen(TO_REFLECTED_FIELD)) == 0) ||
+ (strncmp(safe_arg, FROM_REFLECTED_FIELD,
+ strlen(FROM_REFLECTED_FIELD)) == 0) ||
+ (strncmp(safe_arg, TO_REFLECTED_METHOD,
+ strlen(TO_REFLECTED_METHOD)) == 0) ||
+ (strncmp(safe_arg, FROM_REFLECTED_METHOD,
+ strlen(FROM_REFLECTED_METHOD)) == 0)) {
+ jint created = create_java_vm_wrap(NULL);
+ if (created != 0) {
+ exit(-1);
+ }
+ jclass testClass = (*env)->FindClass(env, TEST_CLASS);
+ if (testClass == NULL) {
+ /* Bail out, cannot find class. */
+ goto end_vm;
+ }
+ jobject testClassInstance = (*env)->AllocObject(env, testClass);
+ jclass aClass = (*env)->GetObjectClass(env, testClassInstance);
+ jclass superClass = (*env)->GetSuperclass(env, aClass);
+ jboolean jboolrval = (*env)->IsAssignableFrom(env, testClass, aClass);
+ jboolrval = (*env)->IsInstanceOf(env, testClassInstance, testClass);
+ jfieldID myBoolean = (*env)->GetFieldID(env, testClass, "myBoolean", "Z");
+ jobject myBooleanRef = (*env)->ToReflectedField(env, testClass, myBoolean,
+ (jboolean) JNI_FALSE);
+ jfieldID myBoolean2 = (*env)->FromReflectedField(env, myBooleanRef);
+ jmethodID getBoolean = (*env)->GetMethodID(env, testClass,
+ "getBoolean", "()Z");
+ jobject getBooleanRef = (*env)->ToReflectedMethod(env, testClass,
+ getBoolean, (jboolean) JNI_FALSE);
+ jmethodID getBoolean2 = (*env)->FromReflectedMethod(env, getBooleanRef);
+ jfieldID myStaticBoolean = (*env)->GetStaticFieldID(env, testClass,
+ "myStaticBoolean", "Z");
+ jmethodID getStaticBoolean = (*env)->GetStaticMethodID(env, testClass,
+ "getStaticBoolean", "()Z");
+ jobject testClassLocal = (*env)->NewLocalRef(env, testClassInstance);
+ jobject testClassGlobal = (*env)->NewGlobalRef(env, testClassInstance);
+ jobject testClassWeakGlobal = (*env)->NewWeakGlobalRef(env,
+ testClassInstance);
+ jboolrval = (*env)->IsSameObject(env, testClassGlobal, testClassWeakGlobal);
+ jobjectRefType refType = (*env)->GetObjectRefType(env, testClassGlobal);
+ (*env)->DeleteGlobalRef(env, testClassGlobal);
+ (*env)->DeleteWeakGlobalRef(env, testClassWeakGlobal);
+ (*env)->DeleteLocalRef(env, testClassLocal);
+ } else if (strncmp(safe_arg, MONITOR, strlen(MONITOR)) == 0) {
+ jint created = create_java_vm_wrap(NULL);
+ if (created != 0) {
+ exit(-1);
+ }
+ jclass testClass = (*env)->FindClass(env, TEST_CLASS);
+ if (testClass == NULL) {
+ /* Bail out, cannot find class. */
+ goto end_vm;
+ }
+ jmethodID constructor = (*env)->GetMethodID(env, testClass,
+ "<init>", "()V");
+ if (constructor == NULL) {
+ /* Bail out, cannot find constructor. */
+ goto end_vm;
+ }
+ jobject testInstance = (*env)->NewObject(env, testClass, constructor);
+ (*env)->MonitorEnter(env, testInstance);
+ (*env)->MonitorExit(env, testInstance);
+ } else if ((strncmp(safe_arg, GET_STRING_UTF,
+ strlen(GET_STRING_UTF)) == 0) ||
+ (strncmp(safe_arg, NEW_STRING_UTF,
+ strlen(NEW_STRING_UTF)) == 0) ||
+ (strncmp(safe_arg, RELEASE_STRING_UTF_CHARS,
+ strlen(RELEASE_STRING_UTF_CHARS)) == 0)) {
+ jint created = create_java_vm_wrap(NULL);
+ if (created != 0) {
+ exit(-1);
+ }
+ char string_chars[6] = {0x57,0x4F,0x52,0x44,0xC0,0x80};
+ jstring aString = (*env)->NewStringUTF(env, string_chars);
+ jsize str_len = (*env)->GetStringUTFLength(env, aString);
+ char string_buf[2];
+ (*env)->GetStringUTFRegion(env, aString, (jsize) 1, (jsize) 2, string_buf);
+ const jbyte* str_pointer = (*env)->GetStringUTFChars(env, aString, NULL);
+ (*env)->ReleaseStringUTFChars(env, aString, (char*) str_pointer);
+ } else if ((strncmp(safe_arg, GET_STRING,
+ strlen(GET_STRING)) == 0) ||
+ (strncmp(safe_arg, NEW_STRING,
+ strlen(NEW_STRING)) == 0) ||
+ (strncmp(safe_arg, RELEASE_STRING_CHARS,
+ strlen(RELEASE_STRING_CHARS)) == 0) ||
+ (strncmp(safe_arg, RELEASE_STRING_CRITICAL,
+ strlen(RELEASE_STRING_CRITICAL)) == 0)) {
+ jint created = create_java_vm_wrap(NULL);
+ if (created != 0) {
+ exit(-1);
+ }
+ /* Long way to say "WORD" in Unicode: */
+ jchar string_chars[4] = {(jchar)0x57,(jchar)0x4F,(jchar)0x52,(jchar)0x44};
+ jstring aString = (*env)->NewString(env, string_chars, (jsize) 4);
+ jsize str_len = (*env)->GetStringLength(env, aString);
+ jchar string_buf[2];
+ (*env)->GetStringRegion(env, aString, (jsize) 1, (jsize) 2, string_buf);
+ const jchar* str_pointer = (*env)->GetStringChars(env, aString, NULL);
+ (*env)->ReleaseStringChars(env, aString, str_pointer);
+ str_pointer = (*env)->GetStringCritical(env, aString, NULL);
+ (*env)->ReleaseStringCritical(env, aString, str_pointer);
+
+ } else if (strncmp(safe_arg, CALL, strlen(CALL)) == 0) {
+ jint created = create_java_vm_wrap(NULL);
+ if (created != 0) {
+ exit(-1);
+ }
+ char* type = NULL;
+ char* modifier = NULL;
+ char* method_sig = malloc(MAX_ARG_LEN);
+ char* method_name = malloc(MAX_ARG_LEN);
+ if ((method_sig == NULL) || (method_name == NULL)) {
+ goto cannot_call;
+ }
+ int rval = get_type_and_modifier(safe_arg+4, &type, &modifier);
+ if (rval == -1) {
+ goto cannot_call;
+ }
+ int arg_len = strlen(safe_arg);
+ jclass testClass = (*env)->FindClass(env, TEST_CLASS);
+ if (testClass == NULL) {
+ /* Bail out, cannot find class. */
+ goto cannot_call;
+ }
+ if ((modifier != NULL) && (strncmp(modifier, STATIC,
+ strlen(STATIC)) == 0)) {
+ snprintf(method_name, MAX_ARG_LEN, "get%s%s", modifier, type);
+ if (strncmp(type, BOOLEAN, strlen(type)) == 0) {
+ strncpy(method_sig, "()Z", MAX_ARG_LEN-1);
+ jmethodID method = (*env)->GetStaticMethodID(env, testClass,
+ method_name, method_sig);
+ if (method == NULL) {
+ /* Bail out, cannot find method. */
+ goto cannot_call;
+ }
+ if (safe_arg[arg_len - 1] == 'V') {
+ static_boolean_v_wrap(&env, &testClass, &method);
+ } else if (safe_arg[arg_len - 1] == 'A') {
+ (*env)->CallStaticBooleanMethodA(env, testClass, method, NULL);
+ } else {
+ (*env)->CallStaticBooleanMethod(env, testClass, method);
+ }
+ } else if (strncmp(type, BYTE, strlen(type)) == 0) {
+ strncpy(method_sig, "()B", MAX_ARG_LEN-1);
+ jmethodID method = (*env)->GetStaticMethodID(env, testClass,
+ method_name, method_sig);
+ if (method == NULL) {
+ /* Bail out, cannot find method. */
+ goto cannot_call;
+ }
+ if (safe_arg[arg_len - 1] == 'V') {
+ static_byte_v_wrap(&env, &testClass, &method);
+ } else if (safe_arg[arg_len - 1] == 'A') {
+ (*env)->CallStaticByteMethodA(env, testClass, method, NULL);
+ } else {
+ (*env)->CallStaticByteMethod(env, testClass, method);
+ }
+ } else if (strncmp(type, CHAR, strlen(type)) == 0) {
+ strncpy(method_sig, "()C", MAX_ARG_LEN-1);
+ jmethodID method = (*env)->GetStaticMethodID(env, testClass,
+ method_name, method_sig);
+ if (method == NULL) {
+ /* Bail out, cannot find method. */
+ goto cannot_call;
+ }
+ if (safe_arg[arg_len - 1] == 'V') {
+ static_char_v_wrap(&env, &testClass, &method);
+ } else if (safe_arg[arg_len - 1] == 'A') {
+ (*env)->CallStaticCharMethodA(env, testClass, method, NULL);
+ } else {
+ (*env)->CallStaticCharMethod(env, testClass, method);
+ }
+ } else if (strncmp(type, DOUBLE, strlen(type)) == 0) {
+ strncpy(method_sig, "()D", MAX_ARG_LEN-1);
+ jmethodID method = (*env)->GetStaticMethodID(env, testClass,
+ method_name, method_sig);
+ if (method == NULL) {
+ /* Bail out, cannot find method. */
+ goto cannot_call;
+ }
+ if (safe_arg[arg_len - 1] == 'V') {
+ static_double_v_wrap(&env, &testClass, &method);
+ } else if (safe_arg[arg_len - 1] == 'A') {
+ (*env)->CallStaticDoubleMethodA(env, testClass, method, NULL);
+ } else {
+ (*env)->CallStaticDoubleMethod(env, testClass, method);
+ }
+ } else if (strncmp(type, FLOAT, strlen(type)) == 0) {
+ strncpy(method_sig, "()F", MAX_ARG_LEN-1);
+ jmethodID method = (*env)->GetStaticMethodID(env, testClass,
+ method_name, method_sig);
+ if (method == NULL) {
+ /* Bail out, cannot find method. */
+ goto cannot_call;
+ }
+ if (safe_arg[arg_len - 1] == 'V') {
+ static_float_v_wrap(&env, &testClass, &method);
+ } else if (safe_arg[arg_len - 1] == 'A') {
+ (*env)->CallStaticFloatMethodA(env, testClass, method, NULL);
+ } else {
+ (*env)->CallStaticFloatMethod(env, testClass, method);
+ }
+ } else if (strncmp(type, INT, strlen(type)) == 0) {
+ strncpy(method_sig, "()I", MAX_ARG_LEN-1);
+ jmethodID method = (*env)->GetStaticMethodID(env, testClass,
+ method_name, method_sig);
+ if (method == NULL) {
+ /* Bail out, cannot find method. */
+ goto cannot_call;
+ }
+ if (safe_arg[arg_len - 1] == 'V') {
+ static_int_v_wrap(&env, &testClass, &method);
+ } else if (safe_arg[arg_len - 1] == 'A') {
+ (*env)->CallStaticIntMethodA(env, testClass, method, NULL);
+ } else {
+ (*env)->CallStaticIntMethod(env, testClass, method);
+ }
+ } else if (strncmp(type, LONG, strlen(type)) == 0) {
+ strncpy(method_sig, "()J", MAX_ARG_LEN-1);
+ jmethodID method = (*env)->GetStaticMethodID(env, testClass,
+ method_name, method_sig);
+ if (method == NULL) {
+ /* Bail out, cannot find method. */
+ goto cannot_call;
+ }
+ if (safe_arg[arg_len - 1] == 'V') {
+ static_long_v_wrap(&env, &testClass, &method);
+ } else if (safe_arg[arg_len - 1] == 'A') {
+ (*env)->CallStaticLongMethodA(env, testClass, method, NULL);
+ } else {
+ (*env)->CallStaticLongMethod(env, testClass, method);
+ }
+ } else if (strncmp(type, OBJECT, strlen(type)) == 0) {
+ strncpy(method_sig, "()Ljava/lang/Object;", MAX_ARG_LEN-1);
+ jmethodID method = (*env)->GetStaticMethodID(env, testClass,
+ method_name, method_sig);
+ if (method == NULL) {
+ /* Bail out, cannot find method. */
+ goto cannot_call;
+ }
+ if (safe_arg[arg_len - 1] == 'V') {
+ static_object_v_wrap(&env, &testClass, &method);
+ } else if (safe_arg[arg_len - 1] == 'A') {
+ (*env)->CallStaticObjectMethodA(env, testClass, method, NULL);
+ } else {
+ (*env)->CallStaticObjectMethod(env, testClass, method);
+ }
+ } else if (strncmp(type, SHORT, strlen(type)) == 0) {
+ strncpy(method_sig, "()S", MAX_ARG_LEN-1);
+ jmethodID method = (*env)->GetStaticMethodID(env, testClass,
+ method_name, method_sig);
+ if (method == NULL) {
+ /* Bail out, cannot find method. */
+ goto cannot_call;
+ }
+ if (safe_arg[arg_len - 1] == 'V') {
+ static_short_v_wrap(&env, &testClass, &method);
+ } else if (safe_arg[arg_len - 1] == 'A') {
+ (*env)->CallStaticShortMethodA(env, testClass, method, NULL);
+ } else {
+ (*env)->CallStaticShortMethod(env, testClass, method);
+ }
+ } else if (strncmp(type, VOID, strlen(type)) == 0) {
+ strncpy(method_sig, "()V", MAX_ARG_LEN-1);
+ jmethodID method = (*env)->GetStaticMethodID(env, testClass,
+ method_name, method_sig);
+ if (method == NULL) {
+ /* Bail out, cannot find method. */
+ goto cannot_call;
+ }
+ if (safe_arg[arg_len - 1] == 'V') {
+ static_void_v_wrap(&env, &testClass, &method);
+ } else if (safe_arg[arg_len - 1] == 'A') {
+ (*env)->CallStaticVoidMethodA(env, testClass, method, NULL);
+ } else {
+ (*env)->CallStaticVoidMethod(env, testClass, method);
+ }
+ } else {
+ /* Type not recognized. */
+ goto cannot_call;
+ }
+ } else {
+ jmethodID constructor = (*env)->GetMethodID(env, testClass,
+ "<init>", "()V");
+ if (constructor == NULL) {
+ /* Bail out, cannot find constructor. */
+ goto cannot_call;
+ }
+ jobject testInstance = (*env)->NewObject(env, testClass, constructor);
+ if (testInstance == NULL) {
+ /* Bail out, cannot create object. */
+ goto cannot_call;
+ }
+ snprintf(method_name, MAX_ARG_LEN, "get%s", type);
+ if ((modifier != NULL) && (strncmp(modifier, NONVIRTUAL,
+ strlen(NONVIRTUAL)) == 0)) {
+ if (strncmp(type, BOOLEAN, strlen(type)) == 0) {
+ strncpy(method_sig, "()Z", MAX_ARG_LEN-1);
+ jmethodID method = (*env)->GetMethodID(env, testClass,
+ method_name, method_sig);
+ if (method == NULL) {
+ /* Bail out, cannot find method. */
+ goto cannot_call;
+ }
+ if (safe_arg[arg_len - 1] == 'V') {
+ nonvirtual_boolean_v_wrap(&env, &testInstance, &testClass, &method);
+ } else if (safe_arg[arg_len - 1] == 'A') {
+ (*env)->CallNonvirtualBooleanMethodA(env, testInstance, testClass,
+ method, NULL);
+ } else {
+ (*env)->CallNonvirtualBooleanMethod(env, testInstance, testClass,
+ method);
+ }
+ } else if (strncmp(type, BYTE, strlen(type)) == 0) {
+ strncpy(method_sig, "()B", MAX_ARG_LEN-1);
+ jmethodID method = (*env)->GetMethodID(env, testClass,
+ method_name, method_sig);
+ if (method == NULL) {
+ /* Bail out, cannot find method. */
+ goto cannot_call;
+ }
+ if (safe_arg[arg_len - 1] == 'V') {
+ nonvirtual_byte_v_wrap(&env, &testInstance, &testClass, &method);
+ } else if (safe_arg[arg_len - 1] == 'A') {
+ (*env)->CallNonvirtualByteMethodA(env, testInstance, testClass,
+ method, NULL);
+ } else {
+ (*env)->CallNonvirtualByteMethod(env, testInstance, testClass,
+ method);
+ }
+ } else if (strncmp(type, CHAR, strlen(type)) == 0) {
+ strncpy(method_sig, "()C", MAX_ARG_LEN-1);
+ jmethodID method = (*env)->GetMethodID(env, testClass,
+ method_name, method_sig);
+ if (method == NULL) {
+ /* Bail out, cannot find method. */
+ goto cannot_call;
+ }
+ if (safe_arg[arg_len - 1] == 'V') {
+ nonvirtual_char_v_wrap(&env, &testInstance, &testClass, &method);
+ } else if (safe_arg[arg_len - 1] == 'A') {
+ (*env)->CallNonvirtualCharMethodA(env, testInstance, testClass,
+ method, NULL);
+ } else {
+ (*env)->CallNonvirtualCharMethod(env, testInstance, testClass,
+ method);
+ }
+ } else if (strncmp(type, DOUBLE, strlen(type)) == 0) {
+ strncpy(method_sig, "()D", MAX_ARG_LEN-1);
+ jmethodID method = (*env)->GetMethodID(env, testClass,
+ method_name, method_sig);
+ if (method == NULL) {
+ /* Bail out, cannot find method. */
+ goto cannot_call;
+ }
+ if (safe_arg[arg_len - 1] == 'V') {
+ nonvirtual_double_v_wrap(&env, &testInstance, &testClass, &method);
+ } else if (safe_arg[arg_len - 1] == 'A') {
+ (*env)->CallNonvirtualDoubleMethodA(env, testInstance, testClass,
+ method, NULL);
+ } else {
+ (*env)->CallNonvirtualDoubleMethod(env, testInstance, testClass,
+ method);
+ }
+ } else if (strncmp(type, FLOAT, strlen(type)) == 0) {
+ strncpy(method_sig, "()F", MAX_ARG_LEN-1);
+ jmethodID method = (*env)->GetMethodID(env, testClass,
+ method_name, method_sig);
+ if (method == NULL) {
+ /* Bail out, cannot find method. */
+ goto cannot_call;
+ }
+ if (safe_arg[arg_len - 1] == 'V') {
+ nonvirtual_float_v_wrap(&env, &testInstance, &testClass, &method);
+ } else if (safe_arg[arg_len - 1] == 'A') {
+ (*env)->CallNonvirtualFloatMethodA(env, testInstance, testClass,
+ method, NULL);
+ } else {
+ (*env)->CallNonvirtualFloatMethod(env, testInstance, testClass,
+ method);
+ }
+ } else if (strncmp(type, INT, strlen(type)) == 0) {
+ strncpy(method_sig, "()I", MAX_ARG_LEN-1);
+ jmethodID method = (*env)->GetMethodID(env, testClass,
+ method_name, method_sig);
+ if (method == NULL) {
+ /* Bail out, cannot find method. */
+ goto cannot_call;
+ }
+ if (safe_arg[arg_len - 1] == 'V') {
+ nonvirtual_int_v_wrap(&env, &testInstance, &testClass, &method);
+ } else if (safe_arg[arg_len - 1] == 'A') {
+ (*env)->CallNonvirtualIntMethodA(env, testInstance, testClass,
+ method, NULL);
+ } else {
+ (*env)->CallNonvirtualIntMethod(env, testInstance, testClass,
+ method);
+ }
+ } else if (strncmp(type, LONG, strlen(type)) == 0) {
+ strncpy(method_sig, "()J", MAX_ARG_LEN-1);
+ jmethodID method = (*env)->GetMethodID(env, testClass,
+ method_name, method_sig);
+ if (method == NULL) {
+ /* Bail out, cannot find method. */
+ goto cannot_call;
+ }
+ if (safe_arg[arg_len - 1] == 'V') {
+ nonvirtual_long_v_wrap(&env, &testInstance, &testClass, &method);
+ } else if (safe_arg[arg_len - 1] == 'A') {
+ (*env)->CallNonvirtualLongMethodA(env, testInstance, testClass,
+ method, NULL);
+ } else {
+ (*env)->CallNonvirtualLongMethod(env, testInstance, testClass,
+ method);
+ }
+ } else if (strncmp(type, OBJECT, strlen(type)) == 0) {
+ strncpy(method_sig, "()Ljava/lang/Object;", 21);
+ jmethodID method = (*env)->GetMethodID(env, testClass,
+ method_name, method_sig);
+ if (method == NULL) {
+ /* Bail out, cannot find method. */
+ goto cannot_call;
+ }
+ if (safe_arg[arg_len - 1] == 'V') {
+ nonvirtual_object_v_wrap(&env, &testInstance, &testClass, &method);
+ } else if (safe_arg[arg_len - 1] == 'A') {
+ (*env)->CallNonvirtualObjectMethodA(env, testInstance, testClass,
+ method, NULL);
+ } else {
+ (*env)->CallNonvirtualObjectMethod(env, testInstance, testClass,
+ method);
+ }
+ } else if (strncmp(type, SHORT, strlen(type)) == 0) {
+ strncpy(method_sig, "()S", MAX_ARG_LEN-1);
+ jmethodID method = (*env)->GetMethodID(env, testClass,
+ method_name, method_sig);
+ if (method == NULL) {
+ /* Bail out, cannot find method. */
+ goto cannot_call;
+ }
+ if (safe_arg[arg_len - 1] == 'V') {
+ nonvirtual_short_v_wrap(&env, &testInstance, &testClass, &method);
+ } else if (safe_arg[arg_len - 1] == 'A') {
+ (*env)->CallNonvirtualShortMethodA(env, testInstance, testClass,
+ method, NULL);
+ } else {
+ (*env)->CallNonvirtualShortMethod(env, testInstance, testClass,
+ method);
+ }
+ } else if (strncmp(type, VOID, strlen(type)) == 0) {
+ strncpy(method_sig, "()V", MAX_ARG_LEN-1);
+ jmethodID method = (*env)->GetMethodID(env, testClass,
+ method_name, method_sig);
+ if (method == NULL) {
+ /* Bail out, cannot find method. */
+ goto cannot_call;
+ }
+ if (safe_arg[arg_len - 1] == 'V') {
+ nonvirtual_void_v_wrap(&env, &testInstance, &testClass, &method);
+ } else if (safe_arg[arg_len - 1] == 'A') {
+ (*env)->CallNonvirtualVoidMethodA(env, testInstance, testClass,
+ method, NULL);
+ } else {
+ (*env)->CallNonvirtualVoidMethod(env, testInstance, testClass,
+ method);
+ }
+ } else {
+ /* Type not recognized. */
+ goto cannot_call;
+ }
+ } else {
+ if (strncmp(type, BOOLEAN, strlen(type)) == 0) {
+ strncpy(method_sig, "()Z", MAX_ARG_LEN-1);
+ jmethodID method = (*env)->GetMethodID(env, testClass,
+ method_name, method_sig);
+ if (method == NULL) {
+ /* Bail out, cannot find method. */
+ goto cannot_call;
+ }
+ if (safe_arg[arg_len - 1] == 'V') {
+ boolean_v_wrap(&env, &testInstance, &method);
+ } else if (safe_arg[arg_len - 1] == 'A') {
+ (*env)->CallBooleanMethodA(env, testInstance, method, NULL);
+ } else {
+ (*env)->CallBooleanMethod(env, testInstance, method);
+ }
+ } else if (strncmp(type, BYTE, strlen(type)) == 0) {
+ strncpy(method_sig, "()B", MAX_ARG_LEN-1);
+ jmethodID method = (*env)->GetMethodID(env, testClass,
+ method_name, method_sig);
+ if (method == NULL) {
+ /* Bail out, cannot find method. */
+ goto cannot_call;
+ }
+ if (safe_arg[arg_len - 1] == 'V') {
+ byte_v_wrap(&env, &testInstance, &method);
+ } else if (safe_arg[arg_len - 1] == 'A') {
+ (*env)->CallByteMethodA(env, testInstance, method, NULL);
+ } else {
+ (*env)->CallByteMethod(env, testInstance, method);
+ }
+ } else if (strncmp(type, CHAR, strlen(type)) == 0) {
+ strncpy(method_sig, "()C", MAX_ARG_LEN-1);
+ jmethodID method = (*env)->GetMethodID(env, testClass,
+ method_name, method_sig);
+ if (method == NULL) {
+ /* Bail out, cannot find method. */
+ goto cannot_call;
+ }
+ if (safe_arg[arg_len - 1] == 'V') {
+ char_v_wrap(&env, &testInstance, &method);
+ } else if (safe_arg[arg_len - 1] == 'A') {
+ (*env)->CallCharMethodA(env, testInstance, method, NULL);
+ } else {
+ (*env)->CallCharMethod(env, testInstance, method);
+ }
+ } else if (strncmp(type, DOUBLE, strlen(type)) == 0) {
+ strncpy(method_sig, "()D", MAX_ARG_LEN-1);
+ jmethodID method = (*env)->GetMethodID(env, testClass,
+ method_name, method_sig);
+ if (method == NULL) {
+ /* Bail out, cannot find method. */
+ goto cannot_call;
+ }
+ if (safe_arg[arg_len - 1] == 'V') {
+ double_v_wrap(&env, &testInstance, &method);
+ } else if (safe_arg[arg_len - 1] == 'A') {
+ (*env)->CallDoubleMethodA(env, testInstance, method, NULL);
+ } else {
+ (*env)->CallDoubleMethod(env, testInstance, method);
+ }
+ } else if (strncmp(type, FLOAT, strlen(type)) == 0) {
+ strncpy(method_sig, "()F", MAX_ARG_LEN-1);
+ jmethodID method = (*env)->GetMethodID(env, testClass,
+ method_name, method_sig);
+ if (method == NULL) {
+ /* Bail out, cannot find method. */
+ goto cannot_call;
+ }
+ if (safe_arg[arg_len - 1] == 'V') {
+ float_v_wrap(&env, &testInstance, &method);
+ } else if (safe_arg[arg_len - 1] == 'A') {
+ (*env)->CallFloatMethodA(env, testInstance, method, NULL);
+ } else {
+ (*env)->CallFloatMethod(env, testInstance, method);
+ }
+ } else if (strncmp(type, INT, strlen(type)) == 0) {
+ strncpy(method_sig, "()I", MAX_ARG_LEN-1);
+ jmethodID method = (*env)->GetMethodID(env, testClass,
+ method_name, method_sig);
+ if (method == NULL) {
+ /* Bail out, cannot find method. */
+ goto cannot_call;
+ }
+ if (safe_arg[arg_len - 1] == 'V') {
+ int_v_wrap(&env, &testInstance, &method);
+ } else if (safe_arg[arg_len - 1] == 'A') {
+ (*env)->CallIntMethodA(env, testInstance, method, NULL);
+ } else {
+ (*env)->CallIntMethod(env, testInstance, method);
+ }
+ } else if (strncmp(type, LONG, strlen(type)) == 0) {
+ strncpy(method_sig, "()J", MAX_ARG_LEN-1);
+ jmethodID method = (*env)->GetMethodID(env, testClass,
+ method_name, method_sig);
+ if (method == NULL) {
+ /* Bail out, cannot find method. */
+ goto cannot_call;
+ }
+ if (safe_arg[arg_len - 1] == 'V') {
+ long_v_wrap(&env, &testInstance, &method);
+ } else if (safe_arg[arg_len - 1] == 'A') {
+ (*env)->CallLongMethodA(env, testInstance, method, NULL);
+ } else {
+ (*env)->CallLongMethod(env, testInstance, method);
+ }
+ } else if (strncmp(type, OBJECT, strlen(type)) == 0) {
+ strncpy(method_sig, "()Ljava/lang/Object;", MAX_ARG_LEN-1);
+ jmethodID method = (*env)->GetMethodID(env, testClass,
+ method_name, method_sig);
+ if (method == NULL) {
+ /* Bail out, cannot find method. */
+ goto cannot_call;
+ }
+ if (safe_arg[arg_len - 1] == 'V') {
+ object_v_wrap(&env, &testInstance, &method);
+ } else if (safe_arg[arg_len - 1] == 'A') {
+ (*env)->CallObjectMethodA(env, testInstance, method, NULL);
+ } else {
+ (*env)->CallObjectMethod(env, testInstance, method);
+ }
+ } else if (strncmp(type, SHORT, strlen(type)) == 0) {
+ strncpy(method_sig, "()S", MAX_ARG_LEN-1);
+ jmethodID method = (*env)->GetMethodID(env, testClass,
+ method_name, method_sig);
+ if (method == NULL) {
+ /* Bail out, cannot find method. */
+ goto cannot_call;
+ }
+ if (safe_arg[arg_len - 1] == 'V') {
+ short_v_wrap(&env, &testInstance, &method);
+ } else if (safe_arg[arg_len - 1] == 'A') {
+ (*env)->CallShortMethodA(env, testInstance, method, NULL);
+ } else {
+ (*env)->CallShortMethod(env, testInstance, method);
+ }
+ } else if (strncmp(type, VOID, strlen(type)) == 0) {
+ strncpy(method_sig, "()V", MAX_ARG_LEN-1);
+ jmethodID method = (*env)->GetMethodID(env, testClass,
+ method_name, method_sig);
+ if (method == NULL) {
+ /* Bail out, cannot find method. */
+ goto cannot_call;
+ }
+ if (safe_arg[arg_len - 1] == 'V') {
+ void_v_wrap(&env, &testInstance, &method);
+ } else if (safe_arg[arg_len - 1] == 'A') {
+ (*env)->CallVoidMethodA(env, testInstance, method, NULL);
+ } else {
+ (*env)->CallVoidMethod(env, testInstance, method);
+ }
+ } else {
+ /* Type not recognized. */
+ goto cannot_call;
+ }
+ }
+ }
+cannot_call:
+ if (type != NULL) {
+ free(type);
+ type = NULL;
+ }
+ if (modifier != NULL) {
+ free(modifier);
+ modifier = NULL;
+ }
+ if (method_sig != NULL) {
+ free(method_sig);
+ method_sig = NULL;
+ }
+ if (method_name != NULL) {
+ free(method_name);
+ method_name = NULL;
+ }
+ } else if ((strncmp(safe_arg, GET, strlen(GET)) == 0) ||
+ (strncmp(safe_arg, NEW, strlen(NEW)) == 0) ||
+ (strncmp(safe_arg, SET, strlen(SET)) == 0) ||
+ (strncmp(safe_arg, RELEASE, strlen(RELEASE)) == 0)) {
+ char* type;
+ char* modifier;
+ char* field_name = malloc(MAX_ARG_LEN);
+ char* field_sig = malloc(MAX_ARG_LEN);
+ if ((field_name == NULL) || (field_sig == NULL)) {
+ goto done_or_error;
+ }
+ int rval;
+ if (strncmp(safe_arg, RELEASE, strlen(RELEASE)) == 0) {
+ rval = get_type_and_modifier(safe_arg+7, &type, &modifier);
+ } else {
+ rval = get_type_and_modifier(safe_arg+3, &type, &modifier);
+ }
+ if (rval == -1) {
+ goto done_or_error;
+ }
+ jboolean check_static = JNI_FALSE;
+ jboolean check_boolean = JNI_FALSE;
+ jboolean check_byte = JNI_FALSE;
+ jboolean check_char = JNI_FALSE;
+ jboolean check_double = JNI_FALSE;
+ jboolean check_float = JNI_FALSE;
+ jboolean check_int = JNI_FALSE;
+ jboolean check_long = JNI_FALSE;
+ jboolean check_object = JNI_FALSE;
+ jboolean check_short = JNI_FALSE;
+ jboolean check_field = is_field_op(safe_arg);
+ jboolean check_array = is_array_op(safe_arg);
+ if (strncmp(type, BOOLEAN, strlen(type)) == 0) {
+ check_boolean = JNI_TRUE;
+ snprintf(field_sig, MAX_ARG_LEN-1, "Z");
+ } else if (strncmp(type, BYTE, strlen(type)) == 0) {
+ check_byte = JNI_TRUE;
+ snprintf(field_sig, MAX_ARG_LEN-1, "B");
+ } else if (strncmp(type, CHAR, strlen(type)) == 0) {
+ check_char = JNI_TRUE;
+ snprintf(field_sig, MAX_ARG_LEN-1, "C");
+ } else if (strncmp(type, DOUBLE, strlen(type)) == 0) {
+ check_double = JNI_TRUE;
+ snprintf(field_sig, MAX_ARG_LEN-1, "D");
+ } else if (strncmp(type, FLOAT, strlen(type)) == 0) {
+ check_float = JNI_TRUE;
+ snprintf(field_sig, MAX_ARG_LEN-1, "F");
+ } else if (strncmp(type, INT, strlen(type)) == 0) {
+ check_int = JNI_TRUE;
+ snprintf(field_sig, MAX_ARG_LEN-1, "I");
+ } else if (strncmp(type, LONG, strlen(type)) == 0) {
+ check_long = JNI_TRUE;
+ snprintf(field_sig, MAX_ARG_LEN-1, "J");
+ } else if (strncmp(type, OBJECT, strlen(type)) == 0) {
+ check_object = JNI_TRUE;
+ snprintf(field_sig, MAX_ARG_LEN-1, "Ljava/lang/String;");
+ } else if (strncmp(type, SHORT, strlen(type)) == 0) {
+ check_short = JNI_TRUE;
+ snprintf(field_sig, MAX_ARG_LEN-1, "S");
+ } else {
+ goto done_or_error;
+ }
+ if (modifier == NULL) {
+ snprintf(field_name, MAX_ARG_LEN-1, "my%s", type);
+ } else {
+ if (strncmp(modifier, STATIC, strlen(modifier)) == 0) {
+ check_static = JNI_TRUE;
+ snprintf(field_name, MAX_ARG_LEN-1, "my%s%s", modifier, type);
+ } else {
+ goto done_or_error;
+ }
+ }
+ if ((check_static == JNI_FALSE) &&
+ (strncmp(safe_arg, GET, strlen(GET)) == 0)) {
+ /* Get<PrimitiveType>Field() functions are optimized by default,
+ * bypassing the probe locations.
+ */
+ JavaVMOption options[1];
+ options[0].optionString = "-XX:-UseFastJNIAccessors";
+ JavaVMInitArgs vm_args;
+ vm_args.version = JNI_VERSION_1_6;
+ vm_args.nOptions = 1;
+ vm_args.options = options;
+ jint created = create_java_vm_wrap(&vm_args);
+ if (created != 0) {
+ exit(-1);
+ }
+ } else {
+ jint created = create_java_vm_wrap(NULL);
+ if (created != 0) {
+ exit(-1);
+ }
+ }
+ if (check_field == JNI_TRUE) {
+ /* Field */
+ jclass testClass = (*env)->FindClass(env, TEST_CLASS);
+ if (testClass == NULL) {
+ /* Bail out, cannot find class. */
+ goto done_or_error;
+ }
+ jobject testInstance = NULL;
+ jfieldID theFieldID = NULL;
+ if (check_static == JNI_TRUE) {
+ theFieldID = (*env)->GetStaticFieldID(env, testClass, field_name,
+ field_sig);
+ } else {
+ jmethodID constructor = (*env)->GetMethodID(env, testClass,
+ "<init>", "()V");
+ if (constructor == NULL) {
+ /* Bail out, cannot find constructor. */
+ goto done_or_error;
+ }
+ testInstance = (*env)->NewObject(env, testClass, constructor);
+ if (testInstance == NULL) {
+ /* Bail out, cannot create object. */
+ goto done_or_error;
+ }
+ theFieldID = (*env)->GetFieldID(env, testClass, field_name, field_sig);
+ }
+ if (theFieldID == NULL) {
+ /* Bail out, cannot access field. */
+ goto done_or_error;
+ }
+ if (check_boolean == JNI_TRUE) {
+ if (strncmp(safe_arg, GET, strlen(GET)) == 0) {
+ if (check_static == JNI_TRUE) {
+ jboolean aBool = (*env)->GetStaticBooleanField(env, testClass,
+ theFieldID);
+ } else {
+ jboolean aBool = (*env)->GetBooleanField(env, testInstance,
+ theFieldID);
+ }
+ } else if (strncmp(safe_arg, SET, strlen(SET)) == 0) {
+ jboolean aBool = JNI_TRUE;
+ if (check_static == JNI_TRUE) {
+ (*env)->SetStaticBooleanField(env, testClass, theFieldID, aBool);
+ } else {
+ (*env)->SetBooleanField(env, testInstance, theFieldID, aBool);
+ }
+ }
+ } else if (check_byte == JNI_TRUE) {
+ if (strncmp(safe_arg, GET, strlen(GET)) == 0) {
+ if (check_static == JNI_TRUE) {
+ jbyte aByte = (*env)->GetStaticByteField(env, testClass,
+ theFieldID);
+ } else {
+ jbyte aByte = (*env)->GetByteField(env, testInstance, theFieldID);
+ }
+ } else if (strncmp(safe_arg, SET, strlen(SET)) == 0) {
+ jbyte aByte = (jbyte) 2;
+ if (check_static == JNI_TRUE) {
+ (*env)->SetStaticByteField(env, testClass, theFieldID, aByte);
+ } else {
+ (*env)->SetByteField(env, testInstance, theFieldID, aByte);
+ }
+ }
+ } else if (check_char == JNI_TRUE) {
+ if (strncmp(safe_arg, GET, strlen(GET)) == 0) {
+ if (check_static == JNI_TRUE) {
+ jchar aChar = (*env)->GetStaticCharField(env, testClass,
+ theFieldID);
+ } else {
+ jchar aChar = (*env)->GetCharField(env, testInstance, theFieldID);
+ }
+ } else if (strncmp(safe_arg, SET, strlen(SET)) == 0) {
+ jchar aChar = 'A';
+ if (check_static == JNI_TRUE) {
+ (*env)->SetStaticCharField(env, testClass, theFieldID, aChar);
+ } else {
+ (*env)->SetCharField(env, testInstance, theFieldID, aChar);
+ }
+ }
+ } else if (check_double == JNI_TRUE) {
+ if (strncmp(safe_arg, GET, strlen(GET)) == 0) {
+ if (check_static == JNI_TRUE) {
+ jdouble aDouble = (*env)->GetStaticDoubleField(env, testClass,
+ theFieldID);
+ } else {
+ jdouble aDouble = (*env)->GetDoubleField(env, testInstance,
+ theFieldID);
+ }
+ } else if (strncmp(safe_arg, SET, strlen(SET)) == 0) {
+ jdouble aDouble = (jdouble) 2.5;
+ if (check_static == JNI_TRUE) {
+ (*env)->SetStaticDoubleField(env, testClass, theFieldID, aDouble);
+ } else {
+ (*env)->SetDoubleField(env, testInstance, theFieldID, aDouble);
+ }
+ }
+ } else if (check_float == JNI_TRUE) {
+ if (strncmp(safe_arg, GET, strlen(GET)) == 0) {
+ if (check_static == JNI_TRUE) {
+ jfloat aFloat = (*env)->GetStaticFloatField(env, testClass,
+ theFieldID);
+ } else {
+ jfloat aFloat = (*env)->GetFloatField(env, testInstance,
+ theFieldID);
+ }
+ } else if (strncmp(safe_arg, SET, strlen(SET)) == 0) {
+ jfloat aFloat = (jfloat) 3.5;
+ if (check_static == JNI_TRUE) {
+ (*env)->SetStaticFloatField(env, testClass, theFieldID, aFloat);
+ } else {
+ (*env)->SetFloatField(env, testInstance, theFieldID, aFloat);
+ }
+ }
+ } else if (check_int == JNI_TRUE) {
+ if (strncmp(safe_arg, GET, strlen(GET)) == 0) {
+ if (check_static == JNI_TRUE) {
+ jint aInt = (*env)->GetStaticIntField(env, testClass, theFieldID);
+ } else {
+ jint aInt = (*env)->GetIntField(env, testInstance, theFieldID);
+ }
+ } else if (strncmp(safe_arg, SET, strlen(SET)) == 0) {
+ jint aInt = (jint) 7;
+ if (check_static == JNI_TRUE) {
+ (*env)->SetStaticIntField(env, testClass, theFieldID, aInt);
+ } else {
+ (*env)->SetIntField(env, testInstance, theFieldID, aInt);
+ }
+ }
+ } else if (check_long == JNI_TRUE) {
+ if (strncmp(safe_arg, GET, strlen(GET)) == 0) {
+ if (check_static == JNI_TRUE) {
+ jlong aLong = (*env)->GetStaticLongField(env, testClass,
+ theFieldID);
+ } else {
+ jlong aLong = (*env)->GetLongField(env, testInstance, theFieldID);
+ }
+ } else if (strncmp(safe_arg, SET, strlen(SET)) == 0) {
+ jlong aLong = (jlong) 13;
+ if (check_static == JNI_TRUE) {
+ (*env)->SetStaticLongField(env, testClass, theFieldID, aLong);
+ } else {
+ (*env)->SetLongField(env, testInstance, theFieldID, aLong);
+ }
+ }
+ } else if (check_object == JNI_TRUE) {
+ if (strncmp(safe_arg, GET, strlen(GET)) == 0) {
+ if (check_static == JNI_TRUE) {
+ jobject aObject = (*env)->GetStaticObjectField(env, testClass,
+ theFieldID);
+ } else {
+ jobject aObject = (*env)->GetObjectField(env, testInstance,
+ theFieldID);
+ }
+ } else if (strncmp(safe_arg, SET, strlen(SET)) == 0) {
+ jchar string_chars[4] =
+ { (jchar) 0x57, (jchar) 0x4F, (jchar) 0x52, (jchar) 0x44 };
+ jobject aObject = (jobject) (*env)->NewString(env, string_chars,
+ (jsize) 4);
+ if (aObject == NULL) {
+ goto done_or_error;
+ }
+ if (check_static == JNI_TRUE) {
+ (*env)->SetStaticObjectField(env, testClass, theFieldID, aObject);
+ } else {
+ (*env)->SetObjectField(env, testInstance, theFieldID, aObject);
+ }
+ }
+ } else if (check_short == JNI_TRUE) {
+ if (strncmp(safe_arg, GET, strlen(GET)) == 0) {
+ if (check_static == JNI_TRUE) {
+ jshort aShort = (*env)->GetStaticShortField(env, testClass,
+ theFieldID);
+ } else {
+ jshort aShort = (*env)->GetShortField(env, testInstance,
+ theFieldID);
+ }
+ } else if (strncmp(safe_arg, SET, strlen(SET)) == 0) {
+ jshort aShort = (jshort) 11;
+ if (check_static == JNI_TRUE) {
+ (*env)->SetStaticShortField(env, testClass, theFieldID, aShort);
+ } else {
+ (*env)->SetShortField(env, testInstance, theFieldID, aShort);
+ }
+ }
+ }
+ } else if (check_array == JNI_TRUE) {
+ /* Array */
+ if (check_boolean == JNI_TRUE) {
+ jbooleanArray jboolean_array = (*env)->NewBooleanArray(env,
+ TEST_ARRAY_LEN);
+ if (jboolean_array == NULL) {
+ goto done_or_error;
+ }
+ jboolean boolean_array[TEST_ARRAY_LEN] = { JNI_TRUE, JNI_TRUE, JNI_TRUE,
+ JNI_TRUE, JNI_TRUE };
+ (*env)->SetBooleanArrayRegion(env, jboolean_array, 0, TEST_ARRAY_LEN,
+ boolean_array);
+ jboolean* boolean_buf = malloc(sizeof(jboolean) * TEST_ARRAY_LEN);
+ if (boolean_buf == NULL) {
+ goto done_or_error;
+ }
+ (*env)->GetBooleanArrayRegion(env, jboolean_array, 0, TEST_ARRAY_LEN,
+ boolean_buf);
+ jboolean* jbool_p = (*env)->GetBooleanArrayElements(env,
+ jboolean_array, NULL);
+ if (jbool_p == NULL) {
+ goto done_or_error;
+ }
+ (*env)->ReleaseBooleanArrayElements(env, jboolean_array, jbool_p,
+ JNI_ABORT);
+ } else if (check_byte == JNI_TRUE) {
+ jbyteArray jbyte_array = (*env)->NewByteArray(env, TEST_ARRAY_LEN);
+ if (jbyte_array == NULL) {
+ goto done_or_error;
+ }
+ jbyte byte_array[TEST_ARRAY_LEN] = { 0, 0, 0, 0, 0 };
+ (*env)->SetByteArrayRegion(env, jbyte_array, 0, TEST_ARRAY_LEN,
+ byte_array);
+ jbyte* byte_buf = malloc(sizeof(jbyte) * TEST_ARRAY_LEN);
+ if (byte_buf == NULL) {
+ goto done_or_error;
+ }
+ (*env)->GetByteArrayRegion(env, jbyte_array, 0, TEST_ARRAY_LEN,
+ byte_buf);
+ jbyte* jbyte_p = (*env)->GetByteArrayElements(env,
+ jbyte_array, NULL);
+ if (jbyte_p == NULL) {
+ goto done_or_error;
+ }
+ (*env)->ReleaseByteArrayElements(env, jbyte_array, jbyte_p, JNI_ABORT);
+ } else if (check_char == JNI_TRUE) {
+ jcharArray jchar_array = (*env)->NewCharArray(env, TEST_ARRAY_LEN);
+ if (jchar_array == NULL) {
+ goto done_or_error;
+ }
+ jchar char_array[TEST_ARRAY_LEN] = { (jchar) 'a', (jchar) 'b',
+ (jchar) 'c', (jchar) 'd', (jchar) 'e' };
+ (*env)->SetCharArrayRegion(env, jchar_array, 0, TEST_ARRAY_LEN,
+ char_array);
+ jchar* char_buf = malloc(sizeof(jchar) * TEST_ARRAY_LEN);
+ if (char_buf == NULL) {
+ goto done_or_error;
+ }
+ (*env)->GetCharArrayRegion(env, jchar_array, 0, TEST_ARRAY_LEN,
+ char_buf);
+ jchar* jchar_p = (*env)->GetCharArrayElements(env, jchar_array, NULL);
+ if (jchar_p == NULL) {
+ goto done_or_error;
+ }
+ (*env)->ReleaseCharArrayElements(env, jchar_array, jchar_p, JNI_ABORT);
+ } else if (check_double == JNI_TRUE) {
+ jdoubleArray jdouble_array = (*env)->NewDoubleArray(env, TEST_ARRAY_LEN);
+ if (jdouble_array == NULL) {
+ goto done_or_error;
+ }
+ jdouble double_array[TEST_ARRAY_LEN] = { (jdouble) 1, (jdouble) 2,
+ (jdouble) 3, (jdouble) 4, (jdouble) 5 };
+ (*env)->SetDoubleArrayRegion(env, jdouble_array, 0, TEST_ARRAY_LEN,
+ double_array);
+ jdouble* double_buf = malloc(sizeof(jdouble) * TEST_ARRAY_LEN);
+ if (double_buf == NULL) {
+ goto done_or_error;
+ }
+ (*env)->GetDoubleArrayRegion(env, jdouble_array, 0, TEST_ARRAY_LEN,
+ double_buf);
+ jdouble* jdouble_p = (*env)->GetDoubleArrayElements(env,
+ jdouble_array, NULL);
+ if (jdouble_p == NULL) {
+ goto done_or_error;
+ }
+ (*env)->ReleaseDoubleArrayElements(env, jdouble_array, jdouble_p,
+ JNI_ABORT);
+ } else if (check_float == JNI_TRUE) {
+ jfloatArray jfloat_array = (*env)->NewFloatArray(env, TEST_ARRAY_LEN);
+ if (jfloat_array == NULL) {
+ goto done_or_error;
+ }
+ jfloat float_array[TEST_ARRAY_LEN] = { (jfloat) 2.5, (jfloat) 6.7,
+ (jfloat) 11.2, (jfloat) 4.8, (jfloat) 8.4 };
+ (*env)->SetFloatArrayRegion(env, jfloat_array, 0, TEST_ARRAY_LEN,
+ float_array);
+ jfloat* float_buf = malloc(sizeof(jfloat) * TEST_ARRAY_LEN);
+ if (float_buf == NULL) {
+ goto done_or_error;
+ }
+ (*env)->GetFloatArrayRegion(env, jfloat_array, 0, TEST_ARRAY_LEN,
+ float_buf);
+ jfloat* jfloat_p = (*env)->GetFloatArrayElements(env, jfloat_array,
+ NULL);
+ if (jfloat_p == NULL) {
+ goto done_or_error;
+ }
+ (*env)->ReleaseFloatArrayElements(env, jfloat_array, jfloat_p,
+ JNI_ABORT);
+ } else if (check_int == JNI_TRUE) {
+ jintArray jint_array = (*env)->NewIntArray(env, TEST_ARRAY_LEN);
+ if (jint_array == NULL) {
+ goto done_or_error;
+ }
+ jint int_array[TEST_ARRAY_LEN] = { (jint) 1, (jint) 2, (jint) 3,
+ (jint) 4, (jint) 5 };
+ (*env)->SetIntArrayRegion(env, jint_array, 0, TEST_ARRAY_LEN,
+ int_array);
+ jint* int_buf = malloc(sizeof(jint) * TEST_ARRAY_LEN);
+ if (int_buf == NULL) {
+ goto done_or_error;
+ }
+ (*env)->GetIntArrayRegion(env, jint_array, 0, TEST_ARRAY_LEN, int_buf);
+ jint* jint_p = (*env)->GetIntArrayElements(env, jint_array, NULL);
+ if (jint_p == NULL) {
+ goto done_or_error;
+ }
+ (*env)->ReleaseIntArrayElements(env, jint_array, jint_p, JNI_ABORT);
+ } else if (check_long == JNI_TRUE) {
+ jlongArray jlong_array = (*env)->NewLongArray(env, TEST_ARRAY_LEN);
+ if (jlong_array == NULL) {
+ goto done_or_error;
+ }
+ jlong long_array[TEST_ARRAY_LEN] = { (jlong) 1, (jlong) 2, (jlong) 3,
+ (jlong) 4, (jlong) 5 };
+ (*env)->SetLongArrayRegion(env, jlong_array, 0, TEST_ARRAY_LEN,
+ long_array);
+ jlong* long_buf = malloc(sizeof(jlong) * TEST_ARRAY_LEN);
+ if (long_buf == NULL) {
+ goto done_or_error;
+ }
+ (*env)->GetLongArrayRegion(env, jlong_array, 0, TEST_ARRAY_LEN,
+ long_buf);
+ jlong* jlong_p = (*env)->GetLongArrayElements(env, jlong_array, NULL);
+ if (jlong_p == NULL) {
+ goto done_or_error;
+ }
+ (*env)->ReleaseLongArrayElements(env, jlong_array, jlong_p, JNI_ABORT);
+ } else if (check_object == JNI_TRUE) {
+ jchar string_chars[4] =
+ { (jchar) 0x57, (jchar) 0x4F, (jchar) 0x52, (jchar) 0x44 };
+ jstring aString = (*env)->NewString(env, string_chars, (jsize) 4);
+ if (aString == NULL) {
+ goto done_or_error;
+ }
+ jclass stringClass = (*env)->GetObjectClass(env, (jobject) aString);
+ if (stringClass == NULL) {
+ goto done_or_error;
+ }
+ jobjectArray oArray = (*env)->NewObjectArray(env, 5, stringClass, NULL);
+ if (oArray == NULL) {
+ goto done_or_error;
+ }
+ (*env)->SetObjectArrayElement(env, oArray, 1, (jobject) aString);
+ if ((*env)->ExceptionCheck(env) == JNI_TRUE) {
+ goto done_or_error;
+ }
+ jobject bString = (*env)->GetObjectArrayElement(env, oArray, 1);
+ } else if (check_short == JNI_TRUE) {
+ jshortArray jshort_array = (*env)->NewShortArray(env, TEST_ARRAY_LEN);
+ if (jshort_array == NULL) {
+ goto done_or_error;
+ }
+ jshort short_array[TEST_ARRAY_LEN] = { (jshort) 1, (jshort) 2,
+ (jshort) 3, (jshort) 4, (jshort) 5 };
+ (*env)->SetShortArrayRegion(env, jshort_array, 0, TEST_ARRAY_LEN,
+ short_array);
+ jshort* short_buf = malloc(sizeof(jshort) * TEST_ARRAY_LEN);
+ if (short_buf == NULL) {
+ goto done_or_error;
+ }
+ (*env)->GetShortArrayRegion(env, jshort_array, 0, TEST_ARRAY_LEN,
+ short_buf);
+ jshort* jshort_p = (*env)->GetShortArrayElements(env, jshort_array,
+ NULL);
+ if (jshort_p == NULL) {
+ goto done_or_error;
+ }
+ (*env)->ReleaseShortArrayElements(env, jshort_array, jshort_p,
+ JNI_ABORT);
+ }
+ }
+done_or_error:
+ if (type != NULL) {
+ free(type);
+ type = NULL;
+ }
+ if (modifier != NULL) {
+ free(modifier);
+ modifier = NULL;
+ }
+ if (field_name != NULL) {
+ free(field_name);
+ field_name = NULL;
+ }
+ if (field_sig != NULL) {
+ free(field_sig);
+ field_sig = NULL;
+ }
+ } else {
+/* bad_usage("Probe specified not found.");*/
+ exit(-1);
+ }
+
+/* Goto labels are ugly, but we use one anyways to provide a way to
+ * jump out of a series of JNI operations if an unsafe operation is reached,
+ * while still ensuring the JVM gets shut down.
+ */
+end_vm:
+ if (safe_arg != NULL) {
+ free(safe_arg);
+ safe_arg = NULL;
+ }
+ (*jvm)->DestroyJavaVM(jvm);
+}
+
+void bad_usage(char* error_msg) {
+ fprintf(stderr, "Error: %s\nThis program requires a single argument.\nThe argument should specify a probe alias in the hotspot_jni tapset.\nThese probes aliases are of the form \"hotspot.jni.<name>\".\nThe argument should consist of the <name>.\n", error_msg);
+}
+
+void* run_attach_current_thread(void* style) {
+ jint r_val;
+ JavaVM* javavm = NULL;
+ jsize returned_count = 0;
+ r_val = JNI_GetCreatedJavaVMs(&javavm, (jsize) 1, &returned_count);
+ if ((r_val != JNI_OK) || (returned_count < 1)) {
+ pthread_exit(NULL);
+ }
+ struct JavaVMAttachArgs attach_args;
+ attach_args.version = (jint) JNI_VERSION_1_6;
+ attach_args.name = "Attached Thread";
+ attach_args.group = (jobject) NULL;
+ JNIEnv *attach_env;
+ if (*(int*)style == (int) DAEMON) {
+ r_val = (*javavm)->AttachCurrentThreadAsDaemon(javavm,
+ (void **) &attach_env, (void *) &attach_args);
+ } else if (*(int*)style == (int) NOT_DAEMON) {
+ r_val = (*javavm)->AttachCurrentThread(javavm,
+ (void **) &attach_env, (void *) &attach_args);
+ } else {
+ pthread_exit(NULL);
+ }
+ if (r_val != JNI_OK) {
+ pthread_exit(NULL);
+ }
+ (*javavm)->DetachCurrentThread(javavm);
+ pthread_exit(NULL);
+}
+
+int get_type_and_modifier(char* arg, char** type_p, char** mod_p) {
+ char* type = arg;
+ if (strncmp(type, STATIC, strlen(STATIC)) == 0) {
+ *mod_p = malloc(strlen(STATIC) + 1);
+ if (*mod_p == NULL) {
+ *type_p = NULL;
+ return -1;
+ }
+ strncpy(*mod_p, type, strlen(STATIC));
+ type += strlen(STATIC);
+ } else if (strncmp(type, NONVIRTUAL, strlen(NONVIRTUAL)) == 0) {
+ *mod_p = malloc(strlen(NONVIRTUAL) + 1);
+ if (*mod_p == NULL) {
+ *type_p = NULL;
+ return -1;
+ }
+ strncpy(*mod_p, type, strlen(NONVIRTUAL));
+ type += strlen(NONVIRTUAL);
+ } else {
+ *mod_p = NULL;
+ }
+ char* char_after_type = strchr(type, (int) 'M');
+ /* 'M' targets "Method" in argument. */
+ if (char_after_type == NULL) {
+ char_after_type = strchr(type, (int) 'A');
+ /* 'A' targets "Array<Elements|Region>" in argument. */
+ if (char_after_type == NULL) {
+ /* 'F' targets "Field" in argument. */
+ char_after_type = strrchr(type, (int) 'F');
+ }
+ }
+ int type_len = char_after_type - type;
+ if (type_len <= 0) {
+ /* char_after_type doesn't point at 'M', 'A', or 'F', or the special case
+ * where it points at the 'F' in "Float". */
+ *type_p = NULL;
+ return -1;
+ }
+ *type_p = malloc(type_len + 1);
+ if (*type_p == NULL) {
+ return -1;
+ }
+ strncpy(*type_p, type, (size_t) type_len);
+ return 0;
+}
+
+jboolean is_field_op(char* arg) {
+ char* poss_field = strrchr(arg, (int) 'F');
+ if (poss_field != NULL) {
+ if (strncmp(poss_field, FIELD, strlen(FIELD)) == 0) {
+ return JNI_TRUE;
+ }
+ }
+ return JNI_FALSE;
+}
+
+jboolean is_array_op(char* arg) {
+ char* poss_array = strrchr(arg, (int) 'A');
+ if (poss_array != NULL) {
+ if (strncmp(poss_array, ARRAY, strlen(ARRAY)) == 0) {
+ return JNI_TRUE;
+ }
+ }
+ return JNI_FALSE;
+}
+
+jint create_java_vm_wrap(JavaVMInitArgs* args) {
+ JavaVMInitArgs def_vm_args;
+ JavaVMInitArgs* vm_args_p;
+ if (args == NULL) {
+ def_vm_args.version = JNI_VERSION_1_6;
+ def_vm_args.nOptions = 0;
+ def_vm_args.options = NULL;
+ vm_args_p = &def_vm_args;
+ } else {
+ vm_args_p = args;
+ }
+
+ return JNI_CreateJavaVM(&jvm, (void **) &env, vm_args_p);
+}
+
+jobject new_object_v_wrap(JNIEnv* env_, jclass* class_p,
+ jmethodID* construct, ...) {
+ va_list var_args;
+ va_start(var_args, construct);
+ jobject instance = (*env_)->NewObjectV(env_, *class_p, *construct, var_args);
+ va_end(var_args);
+ return instance;
+}
+
+jboolean boolean_v_wrap(JNIEnv** env_p, jobject* obj_p,
+ jmethodID* method_p, ...) {
+ va_list var_args;
+ va_start(var_args, method_p);
+ jboolean to_return = (**env_p)->CallBooleanMethodV(*env_p, *obj_p,
+ *method_p, var_args);
+ va_end(var_args);
+ return to_return;
+}
+jbyte byte_v_wrap(JNIEnv** env_p, jobject* obj_p,
+ jmethodID* method_p, ...) {
+ va_list var_args;
+ va_start(var_args, method_p);
+ jbyte to_return = (**env_p)->CallByteMethodV(*env_p, *obj_p,
+ *method_p, var_args);
+ va_end(var_args);
+ return to_return;
+}
+jchar char_v_wrap(JNIEnv** env_p, jobject* obj_p,
+ jmethodID* method_p, ...) {
+ va_list var_args;
+ va_start(var_args, method_p);
+ jchar to_return = (**env_p)->CallCharMethodV(*env_p, *obj_p,
+ *method_p, var_args);
+ va_end(var_args);
+ return to_return;
+}
+jdouble double_v_wrap(JNIEnv** env_p, jobject* obj_p,
+ jmethodID* method_p, ...) {
+ va_list var_args;
+ va_start(var_args, method_p);
+ jdouble to_return = (**env_p)->CallDoubleMethodV(*env_p, *obj_p,
+ *method_p, var_args);
+ va_end(var_args);
+ return to_return;
+}
+jfloat float_v_wrap(JNIEnv** env_p, jobject* obj_p,
+ jmethodID* method_p, ...) {
+ va_list var_args;
+ va_start(var_args, method_p);
+ jfloat to_return = (**env_p)->CallFloatMethodV(*env_p, *obj_p,
+ *method_p, var_args);
+ va_end(var_args);
+ return to_return;
+}
+jint int_v_wrap(JNIEnv** env_p, jobject* obj_p,
+ jmethodID* method_p, ...) {
+ va_list var_args;
+ va_start(var_args, method_p);
+ jint to_return = (**env_p)->CallIntMethodV(*env_p, *obj_p,
+ *method_p, var_args);
+ va_end(var_args);
+ return to_return;
+}
+jlong long_v_wrap(JNIEnv** env_p, jobject* obj_p,
+ jmethodID* method_p, ...) {
+ va_list var_args;
+ va_start(var_args, method_p);
+ jlong to_return = (**env_p)->CallLongMethodV(*env_p, *obj_p,
+ *method_p, var_args);
+ va_end(var_args);
+ return to_return;
+}
+jobject object_v_wrap(JNIEnv** env_p, jobject* obj_p,
+ jmethodID* method_p, ...) {
+ va_list var_args;
+ va_start(var_args, method_p);
+ jobject to_return = (**env_p)->CallObjectMethodV(*env_p, *obj_p,
+ *method_p, var_args);
+ va_end(var_args);
+ return to_return;
+}
+jshort short_v_wrap(JNIEnv** env_p, jobject* obj_p,
+ jmethodID* method_p, ...) {
+ va_list var_args;
+ va_start(var_args, method_p);
+ jshort to_return = (**env_p)->CallShortMethodV(*env_p, *obj_p,
+ *method_p, var_args);
+ va_end(var_args);
+ return to_return;
+}
+void void_v_wrap(JNIEnv** env_p, jobject* obj_p,
+ jmethodID* method_p, ...) {
+ va_list var_args;
+ va_start(var_args, method_p);
+ (**env_p)->CallVoidMethodV(*env_p, *obj_p, *method_p, var_args);
+ va_end(var_args);
+ return;
+}
+
+jboolean nonvirtual_boolean_v_wrap(JNIEnv** env_p, jobject* obj_p,
+ jclass* jclass_p, jmethodID* method_p, ...) {
+ va_list var_args;
+ va_start(var_args, method_p);
+ jboolean to_return = (**env_p)->CallNonvirtualBooleanMethodV(*env_p, *obj_p,
+ *jclass_p, *method_p, var_args);
+ va_end(var_args);
+ return to_return;
+}
+jbyte nonvirtual_byte_v_wrap(JNIEnv** env_p, jobject* obj_p,
+ jclass* jclass_p, jmethodID* method_p, ...) {
+ va_list var_args;
+ va_start(var_args, method_p);
+ jbyte to_return = (**env_p)->CallNonvirtualByteMethodV(*env_p, *obj_p,
+ *jclass_p, *method_p, var_args);
+ va_end(var_args);
+ return to_return;
+}
+jchar nonvirtual_char_v_wrap(JNIEnv** env_p, jobject* obj_p,
+ jclass* jclass_p, jmethodID* method_p, ...) {
+ va_list var_args;
+ va_start(var_args, method_p);
+ jchar to_return = (**env_p)->CallNonvirtualCharMethodV(*env_p, *obj_p,
+ *jclass_p, *method_p, var_args);
+ va_end(var_args);
+ return to_return;
+}
+jdouble nonvirtual_double_v_wrap(JNIEnv** env_p, jobject* obj_p,
+ jclass* jclass_p, jmethodID* method_p, ...) {
+ va_list var_args;
+ va_start(var_args, method_p);
+ jdouble to_return = (**env_p)->CallNonvirtualDoubleMethodV(*env_p, *obj_p,
+ *jclass_p, *method_p, var_args);
+ va_end(var_args);
+ return to_return;
+}
+jfloat nonvirtual_float_v_wrap(JNIEnv** env_p, jobject* obj_p,
+ jclass* jclass_p, jmethodID* method_p, ...) {
+ va_list var_args;
+ va_start(var_args, method_p);
+ jfloat to_return = (**env_p)->CallNonvirtualFloatMethodV(*env_p, *obj_p,
+ *jclass_p, *method_p, var_args);
+ va_end(var_args);
+ return to_return;
+}
+jint nonvirtual_int_v_wrap(JNIEnv** env_p, jobject* obj_p,
+ jclass* jclass_p, jmethodID* method_p, ...) {
+ va_list var_args;
+ va_start(var_args, method_p);
+ jint to_return = (**env_p)->CallNonvirtualIntMethodV(*env_p, *obj_p,
+ *jclass_p, *method_p, var_args);
+ va_end(var_args);
+ return to_return;
+}
+jlong nonvirtual_long_v_wrap(JNIEnv** env_p, jobject* obj_p,
+ jclass* jclass_p, jmethodID* method_p, ...) {
+ va_list var_args;
+ va_start(var_args, method_p);
+ jlong to_return = (**env_p)->CallNonvirtualLongMethodV(*env_p, *obj_p,
+ *jclass_p, *method_p, var_args);
+ va_end(var_args);
+ return to_return;
+}
+jobject nonvirtual_object_v_wrap(JNIEnv** env_p, jobject* obj_p,
+ jclass* jclass_p, jmethodID* method_p, ...) {
+ va_list var_args;
+ va_start(var_args, method_p);
+ jobject to_return = (**env_p)->CallNonvirtualObjectMethodV(*env_p, *obj_p,
+ *jclass_p, *method_p, var_args);
+ va_end(var_args);
+ return to_return;
+}
+jshort nonvirtual_short_v_wrap(JNIEnv** env_p, jobject* obj_p,
+ jclass* jclass_p, jmethodID* method_p, ...) {
+ va_list var_args;
+ va_start(var_args, method_p);
+ jshort to_return = (**env_p)->CallNonvirtualShortMethodV(*env_p, *obj_p,
+ *jclass_p, *method_p, var_args);
+ va_end(var_args);
+ return to_return;
+}
+void nonvirtual_void_v_wrap(JNIEnv** env_p, jobject* obj_p,
+ jclass* jclass_p, jmethodID* method_p, ...) {
+ va_list var_args;
+ va_start(var_args, method_p);
+ (**env_p)->CallNonvirtualVoidMethodV(*env_p, *obj_p,
+ *jclass_p, *method_p, var_args);
+ va_end(var_args);
+ return;
+}
+
+jboolean static_boolean_v_wrap(JNIEnv** env_p, jclass* jclass_p,
+ jmethodID* method_p, ...) {
+ va_list var_args;
+ va_start(var_args, method_p);
+ jboolean to_return = (**env_p)->CallStaticBooleanMethodV(*env_p, *jclass_p,
+ *method_p, var_args);
+ va_end(var_args);
+ return to_return;
+}
+jbyte static_byte_v_wrap(JNIEnv** env_p, jclass* jclass_p,
+ jmethodID* method_p, ...) {
+ va_list var_args;
+ va_start(var_args, method_p);
+ jbyte to_return = (**env_p)->CallStaticByteMethodV(*env_p, *jclass_p,
+ *method_p, var_args);
+ va_end(var_args);
+ return to_return;
+}
+jchar static_char_v_wrap(JNIEnv** env_p, jclass* jclass_p,
+ jmethodID* method_p, ...) {
+ va_list var_args;
+ va_start(var_args, method_p);
+ jchar to_return = (**env_p)->CallStaticCharMethodV(*env_p, *jclass_p,
+ *method_p, var_args);
+ va_end(var_args);
+ return to_return;
+}
+jdouble static_double_v_wrap(JNIEnv** env_p, jclass* jclass_p,
+ jmethodID* method_p, ...) {
+ va_list var_args;
+ va_start(var_args, method_p);
+ jdouble to_return = (**env_p)->CallStaticDoubleMethodV(*env_p, *jclass_p,
+ *method_p, var_args);
+ va_end(var_args);
+ return to_return;
+}
+jfloat static_float_v_wrap(JNIEnv** env_p, jclass* jclass_p,
+ jmethodID* method_p, ...) {
+ va_list var_args;
+ va_start(var_args, method_p);
+ jfloat to_return = (**env_p)->CallStaticFloatMethodV(*env_p, *jclass_p,
+ *method_p, var_args);
+ va_end(var_args);
+ return to_return;
+}
+jint static_int_v_wrap(JNIEnv** env_p, jclass* jclass_p,
+ jmethodID* method_p, ...) {
+ va_list var_args;
+ va_start(var_args, method_p);
+ jint to_return = (**env_p)->CallStaticIntMethodV(*env_p, *jclass_p,
+ *method_p, var_args);
+ va_end(var_args);
+ return to_return;
+}
+jlong static_long_v_wrap(JNIEnv** env_p, jclass* jclass_p,
+ jmethodID* method_p, ...) {
+ va_list var_args;
+ va_start(var_args, method_p);
+ jlong to_return = (**env_p)->CallStaticLongMethodV(*env_p, *jclass_p,
+ *method_p, var_args);
+ va_end(var_args);
+ return to_return;
+}
+jobject static_object_v_wrap(JNIEnv** env_p, jclass* jclass_p,
+ jmethodID* method_p, ...) {
+ va_list var_args;
+ va_start(var_args, method_p);
+ jobject to_return = (**env_p)->CallStaticObjectMethodV(*env_p, *jclass_p,
+ *method_p, var_args);
+ va_end(var_args);
+ return to_return;
+}
+jshort static_short_v_wrap(JNIEnv** env_p, jclass* jclass_p,
+ jmethodID* method_p, ...) {
+ va_list var_args;
+ va_start(var_args, method_p);
+ jshort to_return = (**env_p)->CallStaticShortMethodV(*env_p, *jclass_p,
+ *method_p, var_args);
+ va_end(var_args);
+ return to_return;
+}
+void static_void_v_wrap(JNIEnv** env_p, jclass* jclass_p,
+ jmethodID* method_p, ...) {
+ va_list var_args;
+ va_start(var_args, method_p);
+ (**env_p)->CallStaticVoidMethodV(*env_p, *jclass_p, *method_p, var_args);
+ va_end(var_args);
+ return;
+}
+
diff -r 2ec767396557 -r 55b21736fe19 test/tapset/JNITestClass.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tapset/JNITestClass.c Fri Mar 23 14:11:00 2012 +0100
@@ -0,0 +1,7 @@
+#include "jni.h"
+#include "JNITestClass.h"
+
+JNIEXPORT void JNICALL Java_JNITestClass_doNothing
+ (JNIEnv * env, jobject this) {
+ return;
+}
diff -r 2ec767396557 -r 55b21736fe19 test/tapset/JNITestClass.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tapset/JNITestClass.h Fri Mar 23 14:11:00 2012 +0100
@@ -0,0 +1,21 @@
+/* DO NOT EDIT THIS FILE - it is machine generated */
+#include "jni.h"
+/* Header for class JNITestClass */
+
+#ifndef _Included_JNITestClass
+#define _Included_JNITestClass
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*
+ * Class: JNITestClass
+ * Method: doNothing
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_JNITestClass_doNothing
+ (JNIEnv *, jobject);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff -r 2ec767396557 -r 55b21736fe19 test/tapset/JNITestClass.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tapset/JNITestClass.java Fri Mar 23 14:11:00 2012 +0100
@@ -0,0 +1,121 @@
+package staptest;
+
+public class JNITestClass {
+ public boolean myBoolean;
+ public byte myByte;
+ public char myChar;
+ public double myDouble;
+ public float myFloat;
+ public int myInt;
+ public long myLong;
+ public String myObject;
+ public short myShort;
+
+ public static boolean myStaticBoolean = false;
+ public static byte myStaticByte = 1;
+ public static char myStaticChar = 'b';
+ public static double myStaticDouble = 5.5;
+ public static float myStaticFloat = (float) 2.75;
+ public static int myStaticInt = 32;
+ public static long myStaticLong = 64;
+ public static String myStaticObject = "aString";
+ public static short myStaticShort = 16;
+
+ public JNITestClass() {
+ myBoolean = true;
+ myByte = 0;
+ myChar = 'a';
+ myDouble = 1.5;
+ myFloat = (float) 0.75;
+ myInt = 4;
+ myLong = 8;
+ myObject = "myString";
+ myShort = 2;
+ }
+
+ private native void doNothing();
+
+ public boolean getBoolean() {
+ return myBoolean;
+ }
+
+ public byte getByte() {
+ return myByte;
+ }
+
+ public char getChar() {
+ return myChar;
+ }
+
+ public double getDouble() {
+ return myDouble;
+ }
+
+ public float getFloat() {
+ return myFloat;
+ }
+
+ public int getInt() {
+ return myInt;
+ }
+
+ public long getLong() {
+ return myLong;
+ }
+
+ public Object getObject() {
+ return (Object) new String(myObject);
+ }
+
+ public short getShort() {
+ return myShort;
+ }
+
+ /* Ridiculous name and useless method, but this removes needing a
+ * special case for testing CallVoidMethod[A|V] probes. */
+ public void getVoid() {
+ return;
+ }
+
+ public static boolean getStaticBoolean() {
+ return myStaticBoolean;
+ }
+
+ public static byte getStaticByte() {
+ return myStaticByte;
+ }
+
+ public static char getStaticChar() {
+ return myStaticChar;
+ }
+
+ public static double getStaticDouble() {
+ return myStaticDouble;
+ }
+
+ public static float getStaticFloat() {
+ return myStaticFloat;
+ }
+
+ public static int getStaticInt() {
+ return myStaticInt;
+ }
+
+ public static long getStaticLong() {
+ return myStaticLong;
+ }
+
+ public static Object getStaticObject() {
+ return (Object) new String(myStaticObject);
+ }
+
+ public static short getStaticShort() {
+ return myStaticShort;
+ }
+
+ /* Ridiculous name and useless method, but this removes needing a
+ * special case for testing CallStaticVoidMethod[A|V] probes. */
+ public static void getStaticVoid() {
+ return;
+ }
+}
diff -r 2ec767396557 -r 55b21736fe19 test/tapset/RunWrapper.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tapset/RunWrapper.java Fri Mar 23 14:11:00 2012 +0100
@@ -0,0 +1,21 @@
+package staptest;
+
+import java.lang.reflect.Method;
+
+public class RunWrapper {
+ public static void main(String[] args) {
+ if (args.length >= 1) {
+ try {
+ Class<?> mainClass = RunWrapper.class.
+ getClassLoader().loadClass(args[0]);
+ Class[] types = new Class[] { args.getClass() };
+ Method main = mainClass.getDeclaredMethod(
+ "main", types);
+ String[] runArgs = new String[args.length-1];
+ System.arraycopy(args, 1, runArgs, 0,
+ runArgs.length);
+ main.invoke(null, new Object[] { runArgs });
+ } catch (Exception ignore) {}
+ }
+ }
+}
diff -r 2ec767396557 -r 55b21736fe19 test/tapset/StapJNIClassLoader.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tapset/StapJNIClassLoader.java Fri Mar 23 14:11:00 2012 +0100
@@ -0,0 +1,64 @@
+package staptest;
+
+import java.io.ByteArrayOutputStream;
+import java.io.InputStream;
+import java.io.IOException;
+
+/* Loads classes only in default package in working directory, must be
+ * under 4096 bytes. Intentionally breaks classloader hierarchy.
+ */
+public class StapJNIClassLoader extends ClassLoader {
+
+ public StapJNIClassLoader() {
+ super();
+ }
+
+ public StapJNIClassLoader(ClassLoader parent) {
+ super(parent);
+ }
+
+ private static final int BUF_LEN = 4096;
+
+ protected synchronized Class loadClass(String className,
+ boolean resolve) throws ClassNotFoundException {
+ Class aClass = findLoadedClass(className);
+
+ if (aClass != null) {
+ return aClass;
+ }
+
+ String fileName = className.replace('.', '/').concat(".class");
+ byte[] classBytes = null;
+ try {
+ InputStream classIn = getResourceAsStream(fileName);
+ byte[] buffer = new byte[BUF_LEN];
+ ByteArrayOutputStream temp = new ByteArrayOutputStream();
+ int bytes_read = -1;
+ while ((bytes_read = classIn.read(buffer, 0, BUF_LEN)) != -1) {
+ temp.write(buffer, 0, bytes_read);
+ }
+ classBytes = temp.toByteArray();
+ } catch (IOException ignore) {
+ // Possible error condition(s) resulting from thrown
+ // exception checked after.
+ }
+
+ if (classBytes == null) {
+ throw new ClassNotFoundException("Could not load class: " + className);
+ }
+
+ try {
+ aClass = defineClass(className, classBytes, 0, classBytes.length);
+ if (aClass == null) {
+ System.out.println("Gaah!");
+ }
+ if (resolve) {
+ resolveClass(aClass);
+ }
+ } catch (SecurityException ex) {
+ aClass = super.loadClass(className, resolve);
+ }
+
+ return aClass;
+ }
+}
diff -r 2ec767396557 -r 55b21736fe19 test/tapset/StapURLClassLoader.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tapset/StapURLClassLoader.java Fri Mar 23 14:11:00 2012 +0100
@@ -0,0 +1,24 @@
+package staptest;
+
+import java.io.File;
+import java.net.URL;
+import java.net.URLClassLoader;
+
+/* Let superclass handle everything, we just need a separate Classloader that
+ * will be unloaded (along with classes and their associated hot-compiled
+ * methods) while testing the hotspot.compiled_method_unload probe.
+ */
+public class StapURLClassLoader extends URLClassLoader {
+ public StapURLClassLoader(URL[] urls, ClassLoader parent) {
+ super(urls, parent);
+ }
+
+ public Class loadClass(String name) throws ClassNotFoundException {
+ return super.loadClass(name);
+ }
+
+ protected Class findClass(String name) throws ClassNotFoundException {
+ return super.findClass(name);
+ }
+}
+
diff -r 2ec767396557 -r 55b21736fe19 test/tapset/SystemtapTester.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tapset/SystemtapTester.java Fri Mar 23 14:11:00 2012 +0100
@@ -0,0 +1,202 @@
+package staptest;
+
+import java.io.File;
+import java.lang.reflect.Method;
+import java.net.URL;
+import java.net.URLClassLoader;
+
+public class SystemtapTester {
+ static String throwAwayString;
+ public static void main(String[] args) {
+ SystemtapTester tester = new SystemtapTester();
+ throwAwayString = (args.length < 1 ? "NOTHING"
+ : ("ARG: " + args[0]));
+ System.out.println(throwAwayString);
+ if (args.length < 1) {
+ System.exit(1);
+ } else if (args[0].equals("vm_init_begin") ||
+ args[0].equals("vm_init_end") ||
+ args[0].equals("vm_shutdown") ||
+ args[0].equals("object_alloc") ||
+ args[0].equals("method_entry") ||
+ args[0].equals("method_return")) {
+ // In this case, hotspot has already triggered these
+ // probes (or will shortly). No need to continue.
+ System.exit(0);
+ } else if (args[0].equals("gc_begin") ||
+ args[0].equals("gc_end") ||
+ args[0].equals("mem_pool_gc_begin") ||
+ args[0].equals("mem_pool_gc_end")) {
+ tester.triggerGarbageCollect();
+ } else if (args[0].equals("method_compile_begin") ||
+ args[0].equals("method_compile_end") ||
+ args[0].equals("compiled_method_load")) {
+ tester.triggerCompileMethod();
+ // The jit compiler might be working in the background
+ // wait a little to make sure it is finished. Then
+ // repeat the test with a "hot jit".
+ try {
+ Thread.sleep(1000);
+ } catch (InterruptedException ie) { }
+ tester.triggerCompileMethod();
+ } else if (args[0].equals("compiled_method_unload")) {
+ tester.triggerUnloadMethod();
+ // The jit compiler might be working in the background
+ // wait a little to make sure it is finished. Then
+ // repeat the test with a "hot jit".
+ try {
+ Thread.sleep(1000);
+ } catch (InterruptedException ie) { }
+ tester.triggerUnloadMethod();
+ } else if (args[0].equals("thread_start") ||
+ args[0].equals("thread_stop")) {
+ tester.triggerThread();
+ } else if (args[0].equals("class_loaded") ||
+ args[0].equals("class_unloaded")) {
+ tester.triggerClassLoader();
+ tester.triggerGarbageCollect();
+ } else if (args[0].equals("monitor_contended_enter") ||
+ args[0].equals("monitor_contended_entered") ||
+ args[0].equals("monitor_contended_exit")) {
+ tester.triggerContended();
+ } else if (args[0].equals("monitor_wait") ||
+ args[0].equals("monitor_waited") ||
+ args[0].equals("monitor_notify")) {
+ tester.triggerWait(TestingRunner.NOTIFY);
+ } else if (args[0].equals("monitor_notifyAll")) {
+ tester.triggerWait(TestingRunner.NOTIFYALL);
+ }
+ System.out.println(throwAwayString);
+ }
+
+ public void triggerGarbageCollect() {
+ for (int i = 0; i < 1000; i++) {
+ throwAwayString = allocateForNoReason(i);
+ }
+ forceGarbageCollect();
+ }
+
+ public void triggerThread() {
+ Thread basicThread = new Thread(
+ new TestingRunner(TestingRunner.NOOP));
+ basicThread.start();
+ while (basicThread.isAlive()) {
+ try {
+ basicThread.join();
+ } catch (Exception ignore) {}
+ }
+ }
+
+ public void triggerCompileMethod() {
+ for (int i = 0; i < 105; i++) {
+ Integer iobj = new Integer(i);
+ throwAwayString = triggerCompileMethodLoop(iobj);
+ }
+ }
+
+ public String triggerCompileMethodLoop(Integer iobj) {
+ for (int i = 0; i < 105; i++) {
+ throwAwayString = allocateForNoReason(iobj.intValue());
+ }
+ return throwAwayString;
+ }
+
+ public void triggerUnloadMethod() {
+ try {
+ ClassLoader base = ClassLoader.getSystemClassLoader();
+ URL[] urls;
+ if (base instanceof URLClassLoader) {
+ urls = ((URLClassLoader) base).getURLs();
+ } else {
+ urls = new URL[] {
+ new File(".").toURI().toURL() };
+ }
+ StapURLClassLoader loader = new StapURLClassLoader(
+ urls, base.getParent());
+ Class<?> runClass = loader.loadClass("staptest.RunWrapper");
+ String[] aargs = new String[] { "staptest.RunWrapper",
+ "staptest.ClassUnloadedProbeTester"};
+ Class[] argTypes = new Class[] { aargs.getClass() };
+ Method main = runClass.getDeclaredMethod("main", argTypes);
+ String[] bargs = new String[1];
+ bargs[0] = new String(aargs[1]);
+ Thread.currentThread().setContextClassLoader(loader);
+ main.invoke(null, new Object[] { bargs });
+ Thread.currentThread().setContextClassLoader(base);
+ loader = null;
+ runClass = null;
+ } catch (Exception ex) {
+ ex.printStackTrace();
+ }
+ triggerGarbageCollect();
+ }
+
+ public void triggerClassLoader() {
+ ThreadGroup aThreadGroup = new ThreadGroup("CustomClassLoadingThreadGroup");
+ Thread classLoadingThread = new Thread(aThreadGroup,
+ new TestingRunner(TestingRunner.LOADER));
+ classLoadingThread.start();
+ while (classLoadingThread.isAlive()) {
+ try {
+ classLoadingThread.join();
+ } catch (Exception ignore) {}
+ }
+ aThreadGroup.destroy();
+ }
+
+ public void triggerContended() {
+ Thread contendThread1 =
+ new Thread(new TestingRunner(TestingRunner.CONTENDER));
+ Thread contendThread2 =
+ new Thread(new TestingRunner(TestingRunner.CONTENDER));
+ contendThread1.start();
+ contendThread2.start();
+ while (contendThread1.isAlive() || contendThread2.isAlive()) {
+ try {
+ contendThread1.join();
+ contendThread2.join();
+ } catch (Exception ignore) {}
+ }
+ }
+
+ public void triggerWait(int whichNotify) {
+ TestingRunner myRunner = new TestingRunner(whichNotify);
+ Thread target = new Thread(myRunner);
+ synchronized (myRunner) {
+ target.start();
+ try {
+ myRunner.wait();
+ } catch (Exception ex) {
+ ex.printStackTrace();
+ }
+ }
+ while (target.isAlive()) {
+ try {
+ target.join();
+ } catch (Exception ignore) {
+ }
+ }
+ }
+
+ private void forceGarbageCollect() {
+ Runtime rt = Runtime.getRuntime();
+ long memFree = rt.freeMemory();
+ long beginTime = System.currentTimeMillis();
+ long currentTime = beginTime;
+ do {
+ rt.gc();
+ try {
+ Thread.sleep(1000);
+ } catch (Exception ignore) {}
+ currentTime = System.currentTimeMillis();
+ } while ((memFree <= rt.freeMemory()) &&
+ ((currentTime - beginTime) < 5000));
+ }
+
+ String allocateForNoReason(int i) {
+ String aString = new String("sometextinastring" + i);
+ return aString;
+ }
+
+}
+
diff -r 2ec767396557 -r 55b21736fe19 test/tapset/TestingRunner.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tapset/TestingRunner.java Fri Mar 23 14:11:00 2012 +0100
@@ -0,0 +1,82 @@
+package staptest;
+
+import java.io.File;
+import java.net.URL;
+import java.net.URLClassLoader;
+
+public class TestingRunner implements Runnable {
+ public static int NOOP = 0;
+ public static int LOADER = 1;
+ public static int CONTENDER = 2;
+ public static int NOTIFY = 3;
+ public static int NOTIFYALL = 4;
+
+ private int myType;
+
+ public TestingRunner(int type) {
+ myType = type;
+ }
+
+ public void run() {
+ if (myType == LOADER) {
+ doLoadClass();
+ } else if (myType == CONTENDER) {
+ doSynchronized();
+ } else if (myType == NOTIFY) {
+ doNotify();
+ } else if (myType == NOTIFYALL) {
+ doNotifyAll();
+ }
+ }
+
+ private void doLoadClass() {
+ /* We really just want to load the class and then let it
+ * get garbage collected.
+ */
+ try {
+ ClassLoader base = ClassLoader.getSystemClassLoader();
+ URL[] urls;
+ if (base instanceof URLClassLoader) {
+ urls = ((URLClassLoader) base).getURLs();
+ } else {
+ urls = new URL[] {
+ new File(".").toURI().toURL() };
+ }
+ StapURLClassLoader loader = new StapURLClassLoader(
+ urls, base.getParent());
+ Class testClass = Class.forName("staptest.ClassUnloadedProbeTester", true, loader);
+ testClass = null;
+ loader = null;
+ } catch (Exception ignore) {
+ ignore.printStackTrace();
+ }
+ }
+
+ private void doNotify() {
+ synchronized (this) {
+ waitFiveSeconds();
+ notify();
+ }
+ }
+
+ private void doNotifyAll() {
+ synchronized (this) {
+ waitFiveSeconds();
+ notifyAll();
+ }
+ }
+
+ private static synchronized void doSynchronized() {
+ int anInt = 5;
+ for (int i = 0; i < 10; i++) {
+ anInt += i;
+ }
+ waitFiveSeconds();
+ }
+
+ private static void waitFiveSeconds() {
+ try {
+ Thread.sleep(5000);
+ } catch (Exception ignore) {}
+ }
+}
diff -r 2ec767396557 -r 55b21736fe19 test/tapset/jstaptest.pl
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tapset/jstaptest.pl Fri Mar 23 14:11:00 2012 +0100
@@ -0,0 +1,954 @@
+#!/usr/bin/perl
+
+use strict;
+use warnings;
+
+use Config;
+# For log file.
+use File::Basename;
+use File::Path;
+my $log_file;
+my $logfile_name;
+
+# For parsing options.
+use Getopt::Std;
+$Getopt::Std::OUTPUT_HELP_VERSION = 1;
+# sub main::HELP_MESSAGE defined below.
+our($opt_B, $opt_A, $opt_o, $opt_a, $opt_S, $opt_J);
+
+# Gigantic nested array.
+# Each element in outer array should be of the form:
+# ["<NAME>", "<PRINTARG>", "<TARGET>"]
+# NAME is the name of a probe alias.
+# PRINTARG is a (quoted, escaped) format string along with additional variable
+# arguments, separated by commas, that will be inserted as the arguments to
+# a printf() call in a systemtap script.
+# TARGET is the expected output of the probe firing in a test, or (where exact
+# output is not known) a matching regex.
+my @probestrings = (["hotspot.gc_begin", "\"%s\\n\",name", "^gc_begin\$"],
+ ["hotspot.gc_end", "\"%s\\n\",name", "^gc_end\$"],
+ ["hotspot.mem_pool_gc_begin", "\"%s\\n\",name", "^mem_pool_gc_begin\$"],
+ ["hotspot.mem_pool_gc_end", "\"%s\\n\",name", "^mem_pool_gc_end\$"],
+ ["hotspot.object_alloc", "\"%stid=%dclass=%s\\n\",name,thread_id,class", "^object_alloctid=1class=staptest/SystemtapTester\$"],
+ ["hotspot.vm_init_begin", "\"%s\\n\",name", "^vm_init_begin\$"],
+ ["hotspot.vm_init_end", "\"%s\\n\",name", "^vm_init_end\$"],
+ ["hotspot.vm_shutdown", "\"%s\\n\",name", "^vm_shutdown\$"],
+ ["hotspot.thread_start", "\"%sname=%stid=%dd=%d\\n\",name,thread_name,id,is_daemon", "^thread_startname=Thread-0tid=8d=0\$"],
+ ["hotspot.thread_stop", "\"%sname=%stid=%dd=%d\\n\",name,thread_name,id,is_daemon", "^thread_stopname=Thread-0tid=8d=0\$"],
+ ["hotspot.class_loaded", "\"%sclass=%ssh=%d\\n\",name,class,is_shared", "class_loadedclass=staptest/ClassUnloadedProbeTestersh=0"],
+ ["hotspot.class_unloaded", "\"%sclass=%ssh=%d\\n\",name,class,is_shared", "class_unloadedclass=staptest/ClassUnloadedProbeTestersh=0"],
+ ["hotspot.method_compile_begin", "\"%sclass=%smethod=%ssig=%s\\n\",name,class,method,sig", "method_compile_beginclass=staptest/SystemtapTestermethod=allocateForNoReasonsig=(I)Ljava/lang/String;"],
+ ["hotspot.method_compile_end", "\"%sclass=%smethod=%ssig=%s\\n\",name,class,method,sig", "method_compile_endclass=staptest/SystemtapTestermethod=allocateForNoReasonsig=(I)Ljava/lang/String;"],
+ ["hotspot.monitor_wait", "\"%sclass=%sto=%d\\n\",name,class,timeout", "monitor_waitclass=staptest/TestingRunnerto=0"],
+ ["hotspot.monitor_waited", "\"%sclass=%s\\n\",name,class", "monitor_waitedclass=staptest/TestingRunner"],
+ ["hotspot.monitor_notify", "\"%sclass=%s\\n\",name,class", "monitor_notifyclass=staptest/TestingRunner"],
+ ["hotspot.monitor_notifyAll", "\"%sclass=%s\\n\",name,class", "monitor_notifyAllclass=staptest/TestingRunner"],
+ ["hotspot.monitor_contended_enter", "\"%sclass=%s\\n\",name,class", "monitor_contended_enterclass=java/lang/Class"],
+ ["hotspot.monitor_contended_entered", "\"%sclass=%s\\n\",name,class", "monitor_contended_enteredclass=java/lang/Class"],
+ ["hotspot.monitor_contended_exit", "\"%sclass=%s\\n\",name,class", "monitor_contended_exitclass=java/lang/Class"],
+ ["hotspot.method_entry", "\"%sclass=%smethod=%ssig=%s\\n\",name,class,method,sig", "method_entryclass=staptest/SystemtapTestermethod=<init>sig=()V"],
+ ["hotspot.method_return", "\"%sclass=%smethod=%ssig=%s\\n\",name,class,method,sig", "method_returnclass=staptest/SystemtapTestermethod=<init>sig=()V"],
+ ["hotspot.compiled_method_load", "\"%sclass=%smethod=%ssig=%s\\n\",name,class,method,sig", "compiled_method_loadclass=staptest/SystemtapTestermethod=allocateForNoReasonsig=(I)Ljava/lang/String;"],
+ ["hotspot.compiled_method_unload", "\"%sclass=%smethod=%ssig=%s\\n\",name,class,method,sig", "compiled_method_unloadclass=staptest/ClassUnloadedProbeTestermethod=setFieldsig=(I)V"],
+ ["hotspot.jni.AllocObject", "\"%s\\n\",name", "AllocObject"],
+ ["hotspot.jni.AllocObject.return", "\"%sret=%d\\n\",name,ret", "AllocObjectret=[^0]"],
+ ["hotspot.jni.AttachCurrentThreadAsDaemon", "\"%s\\n\",name", "AttachCurrentThreadAsDaemon"],
+ ["hotspot.jni.AttachCurrentThreadAsDaemon.return", "\"%sret=%d\\n\",name,ret", "AttachCurrentThreadAsDaemonret=0"],
+ ["hotspot.jni.AttachCurrentThread", "\"%s\\n\",name", "AttachCurrentThread"],
+ ["hotspot.jni.AttachCurrentThread.return", "\"%sret=%d\\n\",name,ret", "AttachCurrentThreadret=0"],
+ ["hotspot.jni.CallBooleanMethodA", "\"%s\\n\",name", "CallBooleanMethodA"],
+ ["hotspot.jni.CallBooleanMethodA.return", "\"%sret=%d\\n\",name,ret", "CallBooleanMethodAret=1"],
+ ["hotspot.jni.CallBooleanMethod", "\"%s\\n\",name", "CallBooleanMethod"],
+ ["hotspot.jni.CallBooleanMethod.return", "\"%sret=%d\\n\",name,ret", "CallBooleanMethodret=1"],
+ ["hotspot.jni.CallBooleanMethodV", "\"%s\\n\",name", "CallBooleanMethodV"],
+ ["hotspot.jni.CallBooleanMethodV.return", "\"%sret=%d\\n\",name,ret", "CallBooleanMethodVret=1"],
+ ["hotspot.jni.CallByteMethodA", "\"%s\\n\",name", "CallByteMethodA"],
+ ["hotspot.jni.CallByteMethodA.return", "\"%sret=%d\\n\",name,ret", "CallByteMethodAret=0"],
+ ["hotspot.jni.CallByteMethod", "\"%s\\n\",name", "CallByteMethod"],
+ ["hotspot.jni.CallByteMethod.return", "\"%sret=%d\\n\",name,ret", "CallByteMethodret=0"],
+ ["hotspot.jni.CallByteMethodV", "\"%s\\n\",name", "CallByteMethodV"],
+ ["hotspot.jni.CallByteMethodV.return", "\"%sret=%d\\n\",name,ret", "CallByteMethodVret=0"],
+ ["hotspot.jni.CallCharMethodA", "\"%s\\n\",name", "CallCharMethodA"],
+ ["hotspot.jni.CallCharMethodA.return", "\"%sret=%d\\n\",name,ret", "CallCharMethodAret=97"],
+ ["hotspot.jni.CallCharMethod", "\"%s\\n\",name", "CallCharMethod"],
+ ["hotspot.jni.CallCharMethod.return", "\"%sret=%d\\n\",name,ret", "CallCharMethodret=97"],
+ ["hotspot.jni.CallCharMethodV", "\"%s\\n\",name", "CallCharMethodV"],
+ ["hotspot.jni.CallCharMethodV.return", "\"%sret=%d\\n\",name,ret", "CallCharMethodVret=97"],
+ ["hotspot.jni.CallDoubleMethodA", "\"%s\\n\",name", "CallDoubleMethodA"],
+ ["hotspot.jni.CallDoubleMethodA.return", "\"%s\\n\",name", "CallDoubleMethodA"],
+ ["hotspot.jni.CallDoubleMethod", "\"%s\\n\",name", "CallDoubleMethod"],
+ ["hotspot.jni.CallDoubleMethod.return", "\"%s\\n\",name", "CallDoubleMethod"],
+ ["hotspot.jni.CallDoubleMethodV", "\"%s\\n\",name", "CallDoubleMethodV"],
+ ["hotspot.jni.CallDoubleMethodV.return", "\"%s\\n\",name", "CallDoubleMethodV"],
+ ["hotspot.jni.CallFloatMethodA", "\"%s\\n\",name", "CallFloatMethodA"],
+ ["hotspot.jni.CallFloatMethodA.return", "\"%s\\n\",name", "CallFloatMethodA"],
+ ["hotspot.jni.CallFloatMethod", "\"%s\\n\",name", "CallFloatMethod"],
+ ["hotspot.jni.CallFloatMethod.return", "\"%s\\n\",name", "CallFloatMethod"],
+ ["hotspot.jni.CallFloatMethodV", "\"%s\\n\",name", "CallFloatMethodV"],
+ ["hotspot.jni.CallFloatMethodV.return", "\"%s\\n\",name", "CallFloatMethodV"],
+ ["hotspot.jni.CallIntMethodA", "\"%s\\n\",name", "CallIntMethodA"],
+ ["hotspot.jni.CallIntMethodA.return", "\"%sret=%d\\n\",name,ret", "CallIntMethodAret=4"],
+ ["hotspot.jni.CallIntMethod", "\"%s\\n\",name", "CallIntMethod"],
+ ["hotspot.jni.CallIntMethod.return", "\"%sret=%d\\n\",name,ret", "CallIntMethodret=4"],
+ ["hotspot.jni.CallIntMethodV", "\"%s\\n\",name", "CallIntMethodV"],
+ ["hotspot.jni.CallIntMethodV.return", "\"%sret=%d\\n\",name,ret", "CallIntMethodVret=4"],
+ ["hotspot.jni.CallLongMethodA", "\"%s\\n\",name", "CallLongMethodA"],
+ ["hotspot.jni.CallLongMethodA.return", "\"%sret=%d\\n\",name,ret", "CallLongMethodAret=8"],
+ ["hotspot.jni.CallLongMethod", "\"%s\\n\",name", "CallLongMethod"],
+ ["hotspot.jni.CallLongMethod.return", "\"%sret=%d\\n\",name,ret", "CallLongMethodret=8"],
+ ["hotspot.jni.CallLongMethodV", "\"%s\\n\",name", "CallLongMethodV"],
+ ["hotspot.jni.CallLongMethodV.return", "\"%sret=%d\\n\",name,ret", "CallLongMethodVret=8"],
+ ["hotspot.jni.CallObjectMethodA", "\"%s\\n\",name", "CallObjectMethodA"],
+ ["hotspot.jni.CallObjectMethodA.return", "\"%s\\n\",name", "CallObjectMethodA"],
+ ["hotspot.jni.CallObjectMethod", "\"%s\\n\",name", "CallObjectMethod"],
+ ["hotspot.jni.CallObjectMethod.return", "\"%s\\n\",name", "CallObjectMethod"],
+ ["hotspot.jni.CallObjectMethodV", "\"%s\\n\",name", "CallObjectMethodV"],
+ ["hotspot.jni.CallObjectMethodV.return", "\"%s\\n\",name", "CallObjectMethodV"],
+ ["hotspot.jni.CallShortMethodA", "\"%s\\n\",name", "CallShortMethodA"],
+ ["hotspot.jni.CallShortMethodA.return", "\"%sret=%d\\n\",name,ret", "CallShortMethodAret=2"],
+ ["hotspot.jni.CallShortMethod", "\"%s\\n\",name", "CallShortMethod"],
+ ["hotspot.jni.CallShortMethod.return", "\"%sret=%d\\n\",name,ret", "CallShortMethodret=2"],
+ ["hotspot.jni.CallShortMethodV", "\"%s\\n\",name", "CallShortMethodV"],
+ ["hotspot.jni.CallShortMethodV.return", "\"%sret=%d\\n\",name,ret", "CallShortMethodVret=2"],
+ ["hotspot.jni.CallVoidMethodA", "\"%s\\n\",name", "CallVoidMethodA"],
+ ["hotspot.jni.CallVoidMethodA.return", "\"%s\\n\",name", "CallVoidMethodA"],
+ ["hotspot.jni.CallVoidMethod", "\"%s\\n\",name", "CallVoidMethod"],
+ ["hotspot.jni.CallVoidMethod.return", "\"%s\\n\",name", "CallVoidMethod"],
+ ["hotspot.jni.CallVoidMethodV", "\"%s\\n\",name", "CallVoidMethodV"],
+ ["hotspot.jni.CallVoidMethodV.return", "\"%s\\n\",name", "CallVoidMethodV"],
+ ["hotspot.jni.CallNonvirtualBooleanMethodA", "\"%s\\n\",name", "CallNonvirtualBooleanMethodA"],
+ ["hotspot.jni.CallNonvirtualBooleanMethodA.return", "\"%sret=%d\\n\",name,ret", "CallNonvirtualBooleanMethodAret=1"],
+ ["hotspot.jni.CallNonvirtualBooleanMethod", "\"%s\\n\",name", "CallNonvirtualBooleanMethod"],
+ ["hotspot.jni.CallNonvirtualBooleanMethod.return", "\"%sret=%d\\n\",name,ret", "CallNonvirtualBooleanMethodret=1"],
+ ["hotspot.jni.CallNonvirtualBooleanMethodV", "\"%s\\n\",name", "CallNonvirtualBooleanMethodV"],
+ ["hotspot.jni.CallNonvirtualBooleanMethodV.return", "\"%sret=%d\\n\",name,ret", "CallNonvirtualBooleanMethodVret=1"],
+ ["hotspot.jni.CallNonvirtualByteMethodA", "\"%s\\n\",name", "CallNonvirtualByteMethodA"],
+ ["hotspot.jni.CallNonvirtualByteMethodA.return", "\"%sret=%d\\n\",name,ret", "CallNonvirtualByteMethodAret=0"],
+ ["hotspot.jni.CallNonvirtualByteMethod", "\"%s\\n\",name", "CallNonvirtualByteMethod"],
+ ["hotspot.jni.CallNonvirtualByteMethod.return", "\"%sret=%d\\n\",name,ret", "CallNonvirtualByteMethodret=0"],
+ ["hotspot.jni.CallNonvirtualByteMethodV", "\"%s\\n\",name", "CallNonvirtualByteMethodV"],
+ ["hotspot.jni.CallNonvirtualByteMethodV.return", "\"%sret=%d\\n\",name,ret", "CallNonvirtualByteMethodVret=0"],
+ ["hotspot.jni.CallNonvirtualCharMethodA", "\"%s\\n\",name", "CallNonvirtualCharMethodA"],
+ ["hotspot.jni.CallNonvirtualCharMethodA.return", "\"%sret=%d\\n\",name,ret", "CallNonvirtualCharMethodAret=97"],
+ ["hotspot.jni.CallNonvirtualCharMethod", "\"%s\\n\",name", "CallNonvirtualCharMethod"],
+ ["hotspot.jni.CallNonvirtualCharMethod.return", "\"%sret=%d\\n\",name,ret", "CallNonvirtualCharMethodret=97"],
+ ["hotspot.jni.CallNonvirtualCharMethodV", "\"%s\\n\",name", "CallNonvirtualCharMethodV"],
+ ["hotspot.jni.CallNonvirtualCharMethodV.return", "\"%sret=%d\\n\",name,ret", "CallNonvirtualCharMethodVret=97"],
+ ["hotspot.jni.CallNonvirtualDoubleMethodA", "\"%s\\n\",name", "CallNonvirtualDoubleMethodA"],
+ ["hotspot.jni.CallNonvirtualDoubleMethodA.return", "\"%s\\n\",name", "CallNonvirtualDoubleMethodA"],
+ ["hotspot.jni.CallNonvirtualDoubleMethod", "\"%s\\n\",name", "CallNonvirtualDoubleMethod"],
+ ["hotspot.jni.CallNonvirtualDoubleMethod.return", "\"%s\\n\",name", "CallNonvirtualDoubleMethod"],
+ ["hotspot.jni.CallNonvirtualDoubleMethodV", "\"%s\\n\",name", "CallNonvirtualDoubleMethodV"],
+ ["hotspot.jni.CallNonvirtualDoubleMethodV.return", "\"%s\\n\",name", "CallNonvirtualDoubleMethodV"],
+ ["hotspot.jni.CallNonvirtualFloatMethodA", "\"%s\\n\",name", "CallNonvirtualFloatMethodA"],
+ ["hotspot.jni.CallNonvirtualFloatMethodA.return", "\"%s\\n\",name", "CallNonvirtualFloatMethodA"],
+ ["hotspot.jni.CallNonvirtualFloatMethod", "\"%s\\n\",name", "CallNonvirtualFloatMethod"],
+ ["hotspot.jni.CallNonvirtualFloatMethod.return", "\"%s\\n\",name", "CallNonvirtualFloatMethod"],
+ ["hotspot.jni.CallNonvirtualFloatMethodV", "\"%s\\n\",name", "CallNonvirtualFloatMethodV"],
+ ["hotspot.jni.CallNonvirtualFloatMethodV.return", "\"%s\\n\",name", "CallNonvirtualFloatMethodV"],
+ ["hotspot.jni.CallNonvirtualIntMethodA", "\"%s\\n\",name", "CallNonvirtualIntMethodA"],
+ ["hotspot.jni.CallNonvirtualIntMethodA.return", "\"%sret=%d\\n\",name,ret", "CallNonvirtualIntMethodAret=4"],
+ ["hotspot.jni.CallNonvirtualIntMethod", "\"%s\\n\",name", "CallNonvirtualIntMethod"],
+ ["hotspot.jni.CallNonvirtualIntMethod.return", "\"%sret=%d\\n\",name,ret", "CallNonvirtualIntMethodret=4"],
+ ["hotspot.jni.CallNonvirtualIntMethodV", "\"%s\\n\",name", "CallNonvirtualIntMethodV"],
+ ["hotspot.jni.CallNonvirtualIntMethodV.return", "\"%sret=%d\\n\",name,ret", "CallNonvirtualIntMethodVret=4"],
+ ["hotspot.jni.CallNonvirtualLongMethodA", "\"%s\\n\",name", "CallNonvirtualLongMethodA"],
+ ["hotspot.jni.CallNonvirtualLongMethodA.return", "\"%sret=%d\\n\",name,ret", "CallNonvirtualLongMethodAret=8"],
+ ["hotspot.jni.CallNonvirtualLongMethod", "\"%s\\n\",name", "CallNonvirtualLongMethod"],
+ ["hotspot.jni.CallNonvirtualLongMethod.return", "\"%sret=%d\\n\",name,ret", "CallNonvirtualLongMethodret=8"],
+ ["hotspot.jni.CallNonvirtualLongMethodV", "\"%s\\n\",name", "CallNonvirtualLongMethodV"],
+ ["hotspot.jni.CallNonvirtualLongMethodV.return", "\"%sret=%d\\n\",name,ret", "CallNonvirtualLongMethodVret=8"],
+ ["hotspot.jni.CallNonvirtualObjectMethodA", "\"%s\\n\",name", "CallNonvirtualObjectMethodA"],
+ ["hotspot.jni.CallNonvirtualObjectMethodA.return", "\"%s\\n\",name", "CallNonvirtualObjectMethodA"],
+ ["hotspot.jni.CallNonvirtualObjectMethod", "\"%s\\n\",name", "CallNonvirtualObjectMethod"],
+ ["hotspot.jni.CallNonvirtualObjectMethod.return", "\"%s\\n\",name", "CallNonvirtualObjectMethod"],
+ ["hotspot.jni.CallNonvirtualObjectMethodV", "\"%s\\n\",name", "CallNonvirtualObjectMethodV"],
+ ["hotspot.jni.CallNonvirtualObjectMethodV.return", "\"%s\\n\",name", "CallNonvirtualObjectMethodV"],
+ ["hotspot.jni.CallNonvirtualShortMethodA", "\"%s\\n\",name", "CallNonvirtualShortMethodA"],
+ ["hotspot.jni.CallNonvirtualShortMethodA.return", "\"%sret=%d\\n\",name,ret", "CallNonvirtualShortMethodAret=2"],
+ ["hotspot.jni.CallNonvirtualShortMethod", "\"%s\\n\",name", "CallNonvirtualShortMethod"],
+ ["hotspot.jni.CallNonvirtualShortMethod.return", "\"%sret=%d\\n\",name,ret", "CallNonvirtualShortMethodret=2"],
+ ["hotspot.jni.CallNonvirtualShortMethodV", "\"%s\\n\",name", "CallNonvirtualShortMethodV"],
+ ["hotspot.jni.CallNonvirtualShortMethodV.return", "\"%sret=%d\\n\",name,ret", "CallNonvirtualShortMethodVret=2"],
+ ["hotspot.jni.CallNonvirtualVoidMethodA", "\"%s\\n\",name", "CallNonvirtualVoidMethodA"],
+ ["hotspot.jni.CallNonvirtualVoidMethodA.return", "\"%s\\n\",name", "CallNonvirtualVoidMethodA"],
+ ["hotspot.jni.CallNonvirtualVoidMethod", "\"%s\\n\",name", "CallNonvirtualVoidMethod"],
+ ["hotspot.jni.CallNonvirtualVoidMethod.return", "\"%s\\n\",name", "CallNonvirtualVoidMethod"],
+ ["hotspot.jni.CallNonvirtualVoidMethodV", "\"%s\\n\",name", "CallNonvirtualVoidMethodV"],
+ ["hotspot.jni.CallNonvirtualVoidMethodV.return", "\"%s\\n\",name", "CallNonvirtualVoidMethodV"],
+ ["hotspot.jni.CallStaticBooleanMethodA", "\"%s\\n\",name", "CallStaticBooleanMethodA"],
+ ["hotspot.jni.CallStaticBooleanMethodA.return", "\"%sret=%d\\n\",name,ret", "CallStaticBooleanMethodAret=0"],
+ ["hotspot.jni.CallStaticBooleanMethod", "\"%s\\n\",name", "CallStaticBooleanMethod"],
+ ["hotspot.jni.CallStaticBooleanMethod.return", "\"%sret=%d\\n\",name,ret", "CallStaticBooleanMethodret=0"],
+ ["hotspot.jni.CallStaticBooleanMethodV", "\"%s\\n\",name", "CallStaticBooleanMethodV"],
+ ["hotspot.jni.CallStaticBooleanMethodV.return", "\"%sret=%d\\n\",name,ret", "CallStaticBooleanMethodVret=0"],
+ ["hotspot.jni.CallStaticByteMethodA", "\"%s\\n\",name", "CallStaticByteMethodA"],
+ ["hotspot.jni.CallStaticByteMethodA.return", "\"%sret=%d\\n\",name,ret", "CallStaticByteMethodAret=1"],
+ ["hotspot.jni.CallStaticByteMethod", "\"%s\\n\",name", "CallStaticByteMethod"],
+ ["hotspot.jni.CallStaticByteMethod.return", "\"%sret=%d\\n\",name,ret", "CallStaticByteMethodret=1"],
+ ["hotspot.jni.CallStaticByteMethodV", "\"%s\\n\",name", "CallStaticByteMethodV"],
+ ["hotspot.jni.CallStaticByteMethodV.return", "\"%sret=%d\\n\",name,ret", "CallStaticByteMethodVret=1"],
+ ["hotspot.jni.CallStaticCharMethodA", "\"%s\\n\",name", "CallStaticCharMethodA"],
+ ["hotspot.jni.CallStaticCharMethodA.return", "\"%sret=%d\\n\",name,ret", "CallStaticCharMethodAret=98"],
+ ["hotspot.jni.CallStaticCharMethod", "\"%s\\n\",name", "CallStaticCharMethod"],
+ ["hotspot.jni.CallStaticCharMethod.return", "\"%sret=%d\\n\",name,ret", "CallStaticCharMethodret=98"],
+ ["hotspot.jni.CallStaticCharMethodV", "\"%s\\n\",name", "CallStaticCharMethodV"],
+ ["hotspot.jni.CallStaticCharMethodV.return", "\"%sret=%d\\n\",name,ret", "CallStaticCharMethodVret=98"],
+ ["hotspot.jni.CallStaticDoubleMethodA", "\"%s\\n\",name", "CallStaticDoubleMethodA"],
+ ["hotspot.jni.CallStaticDoubleMethodA.return", "\"%s\\n\",name", "CallStaticDoubleMethodA"],
+ ["hotspot.jni.CallStaticDoubleMethod", "\"%s\\n\",name", "CallStaticDoubleMethod"],
+ ["hotspot.jni.CallStaticDoubleMethod.return", "\"%s\\n\",name", "CallStaticDoubleMethod"],
+ ["hotspot.jni.CallStaticDoubleMethodV", "\"%s\\n\",name", "CallStaticDoubleMethodV"],
+ ["hotspot.jni.CallStaticDoubleMethodV.return", "\"%s\\n\",name", "CallStaticDoubleMethodV"],
+ ["hotspot.jni.CallStaticFloatMethodA", "\"%s\\n\",name", "CallStaticFloatMethodA"],
+ ["hotspot.jni.CallStaticFloatMethodA.return", "\"%s\\n\",name", "CallStaticFloatMethodA"],
+ ["hotspot.jni.CallStaticFloatMethod", "\"%s\\n\",name", "CallStaticFloatMethod"],
+ ["hotspot.jni.CallStaticFloatMethod.return", "\"%s\\n\",name", "CallStaticFloatMethod"],
+ ["hotspot.jni.CallStaticFloatMethodV", "\"%s\\n\",name", "CallStaticFloatMethodV"],
+ ["hotspot.jni.CallStaticFloatMethodV.return", "\"%s\\n\",name", "CallStaticFloatMethodV"],
+ ["hotspot.jni.CallStaticIntMethodA", "\"%s\\n\",name", "CallStaticIntMethodA"],
+ ["hotspot.jni.CallStaticIntMethodA.return", "\"%sret=%d\\n\",name,ret", "CallStaticIntMethodAret=32"],
+ ["hotspot.jni.CallStaticIntMethod", "\"%s\\n\",name", "CallStaticIntMethod"],
+ ["hotspot.jni.CallStaticIntMethod.return", "\"%sret=%d\\n\",name,ret", "CallStaticIntMethodret=32"],
+ ["hotspot.jni.CallStaticIntMethodV", "\"%s\\n\",name", "CallStaticIntMethodV"],
+ ["hotspot.jni.CallStaticIntMethodV.return", "\"%sret=%d\\n\",name,ret", "CallStaticIntMethodVret=32"],
+ ["hotspot.jni.CallStaticLongMethodA", "\"%s\\n\",name", "CallStaticLongMethodA"],
+ ["hotspot.jni.CallStaticLongMethodA.return", "\"%sret=%d\\n\",name,ret", "CallStaticLongMethodAret=64"],
+ ["hotspot.jni.CallStaticLongMethod", "\"%s\\n\",name", "CallStaticLongMethod"],
+ ["hotspot.jni.CallStaticLongMethod.return", "\"%sret=%d\\n\",name,ret", "CallStaticLongMethodret=64"],
+ ["hotspot.jni.CallStaticLongMethodV", "\"%s\\n\",name", "CallStaticLongMethodV"],
+ ["hotspot.jni.CallStaticLongMethodV.return", "\"%sret=%d\\n\",name,ret", "CallStaticLongMethodVret=64"],
+ ["hotspot.jni.CallStaticObjectMethodA", "\"%s\\n\",name", "CallStaticObjectMethodA"],
+ ["hotspot.jni.CallStaticObjectMethodA.return", "\"%s\\n\",name", "CallStaticObjectMethodA"],
+ ["hotspot.jni.CallStaticObjectMethod", "\"%s\\n\",name", "CallStaticObjectMethod"],
+ ["hotspot.jni.CallStaticObjectMethod.return", "\"%s\\n\",name", "CallStaticObjectMethod"],
+ ["hotspot.jni.CallStaticObjectMethodV", "\"%s\\n\",name", "CallStaticObjectMethodV"],
+ ["hotspot.jni.CallStaticObjectMethodV.return", "\"%s\\n\",name", "CallStaticObjectMethodV"],
+ ["hotspot.jni.CallStaticShortMethodA", "\"%s\\n\",name", "CallStaticShortMethodA"],
+ ["hotspot.jni.CallStaticShortMethodA.return", "\"%sret=%d\\n\",name,ret", "CallStaticShortMethodAret=16"],
+ ["hotspot.jni.CallStaticShortMethod", "\"%s\\n\",name", "CallStaticShortMethod"],
+ ["hotspot.jni.CallStaticShortMethod.return", "\"%sret=%d\\n\",name,ret", "CallStaticShortMethodret=16"],
+ ["hotspot.jni.CallStaticShortMethodV", "\"%s\\n\",name", "CallStaticShortMethodV"],
+ ["hotspot.jni.CallStaticShortMethodV.return", "\"%sret=%d\\n\",name,ret", "CallStaticShortMethodVret=16"],
+ ["hotspot.jni.CallStaticVoidMethodA", "\"%s\\n\",name", "CallStaticVoidMethodA"],
+ ["hotspot.jni.CallStaticVoidMethodA.return", "\"%s\\n\",name", "CallStaticVoidMethodA"],
+ ["hotspot.jni.CallStaticVoidMethod", "\"%s\\n\",name", "CallStaticVoidMethod"],
+ ["hotspot.jni.CallStaticVoidMethod.return", "\"%s\\n\",name", "CallStaticVoidMethod"],
+ ["hotspot.jni.CallStaticVoidMethodV", "\"%s\\n\",name", "CallStaticVoidMethodV"],
+ ["hotspot.jni.CallStaticVoidMethodV.return", "\"%s\\n\",name", "CallStaticVoidMethodV"],
+ ["hotspot.jni.CreateJavaVM", "\"%s\\n\",name", "CreateJavaVM"],
+ ["hotspot.jni.CreateJavaVM.return", "\"%sret=%d\\n\",name,ret", "CreateJavaVMret=0"],
+ ["hotspot.jni.DefineClass", "\"%sclass=%s\\n\",name,clazz", "DefineClassclass=staptest/JNITestClass"],
+ ["hotspot.jni.DefineClass.return", "\"%sret=%d\\n\",name,ret", "DefineClassret=[^0]"],
+ ["hotspot.jni.DeleteGlobalRef", "\"%s\\n\",name", "DeleteGlobalRef"],
+ ["hotspot.jni.DeleteGlobalRef.return", "\"%s\\n\",name", "DeleteGlobalRef"],
+ ["hotspot.jni.DeleteLocalRef", "\"%s\\n\",name", "DeleteLocalRef"],
+ ["hotspot.jni.DeleteLocalRef.return", "\"%s\\n\",name", "DeleteLocalRef"],
+ ["hotspot.jni.DeleteWeakGlobalRef", "\"%s\\n\",name", "DeleteWeakGlobalRef"],
+ ["hotspot.jni.DeleteWeakGlobalRef.return", "\"%s\\n\",name", "DeleteWeakGlobalRef"],
+ ["hotspot.jni.DestroyJavaVM", "\"%s\\n\",name", "DestroyJavaVM"],
+ ["hotspot.jni.DestroyJavaVM.return", "\"%sret=%d\\n\",name,ret", "DestroyJavaVMret=0"],
+ ["hotspot.jni.DetachCurrentThread", "\"%s\\n\",name", "DetachCurrentThread"],
+ ["hotspot.jni.DetachCurrentThread.return", "\"%sret=%d\\n\",name,ret", "DetachCurrentThreadret=0"],
+ ["hotspot.jni.EnsureLocalCapacity", "\"%scap=%d\\n\",name,capacity", "EnsureLocalCapacitycap=10"],
+ ["hotspot.jni.EnsureLocalCapacity.return", "\"%sret=%d\\n\",name,ret", "EnsureLocalCapacityret=0"],
+ ["hotspot.jni.ExceptionCheck", "\"%s\\n\",name", "ExceptionCheck"],
+ ["hotspot.jni.ExceptionCheck.return", "\"%sret=%d\\n\",name,ret", "ExceptionCheckret=1"],
+ ["hotspot.jni.ExceptionClear", "\"%s\\n\",name", "ExceptionClear"],
+ ["hotspot.jni.ExceptionClear.return", "\"%s\\n\",name", "ExceptionClear"],
+ ["hotspot.jni.ExceptionDescribe", "\"%s\\n\",name", "ExceptionDescribe"],
+ ["hotspot.jni.ExceptionDescribe.return", "\"%s\\n\",name", "ExceptionDescribe"],
+ ["hotspot.jni.ExceptionOccurred", "\"%s\\n\",name", "ExceptionOccurred"],
+ ["hotspot.jni.ExceptionOccurred.return", "\"%sret=%d\\n\",name,ret", "ExceptionOccurredret=[^0]"],
+ ["hotspot.jni.FatalError", "\"%smsg=%s\\n\",name,msg", "FatalErrormsg=Intentional Crash: Ignore."],
+ ["hotspot.jni.FindClass", "\"%sclass=%s\\n\",name,clazz", "FindClassclass=staptest/JNITestClass"],
+ ["hotspot.jni.FindClass.return", "\"%sret=%d\\n\",name,ret", "FindClassret=[^0]"],
+ ["hotspot.jni.FromReflectedField", "\"%s\\n\",name", "FromReflectedField"],
+ ["hotspot.jni.FromReflectedField.return", "\"%s\\n\",name", "FromReflectedField"],
+ ["hotspot.jni.FromReflectedMethod", "\"%s\\n\",name", "FromReflectedMethod"],
+ ["hotspot.jni.FromReflectedMethod.return", "\"%s\\n\",name", "FromReflectedMethod"],
+ ["hotspot.jni.GetArrayLength", "\"%s\\n\",name", "GetArrayLength"],
+ ["hotspot.jni.GetArrayLength.return", "\"%sret=%d\\n\",name,ret", "GetArrayLengthret=5"],
+ ["hotspot.jni.GetBooleanArrayElements", "\"%scp=%d\\n\",name,iscopy", "GetBooleanArrayElementscp=0"],
+ ["hotspot.jni.GetBooleanArrayElements.return", "\"%sret=%d\\n\",name,ret", "GetBooleanArrayElementsret=[^0]"],
+ ["hotspot.jni.GetBooleanArrayRegion", "\"%sstart=%dlen=%d\\n\",name,start,len", "GetBooleanArrayRegionstart=0len=5"],
+ ["hotspot.jni.GetBooleanArrayRegion.return", "\"%s\\n\",name", "GetBooleanArrayRegion"],
+ ["hotspot.jni.GetBooleanField", "\"%s\\n\",name", "GetBooleanField"],
+ ["hotspot.jni.GetBooleanField.return", "\"%sret=%d\\n\",name,ret", "GetBooleanFieldret=1"],
+ ["hotspot.jni.GetByteArrayElements", "\"%scp=%d\\n\",name,iscopy", "GetByteArrayElementscp=0"],
+ ["hotspot.jni.GetByteArrayElements.return", "\"%sret=%d\\n\",name,ret", "GetByteArrayElementsret=[^0]"],
+ ["hotspot.jni.GetByteArrayRegion", "\"%sstart=%dlen=%d\\n\",name,start,len", "GetByteArrayRegionstart=0len=5"],
+ ["hotspot.jni.GetByteArrayRegion.return", "\"%s\\n\",name", "GetByteArrayRegion"],
+ ["hotspot.jni.GetByteField", "\"%s\\n\",name", "GetByteField"],
+ ["hotspot.jni.GetByteField.return", "\"%sret=%d\\n\",name,ret", "GetByteFieldret=0"],
+ ["hotspot.jni.GetCharArrayElements", "\"%scp=%d\\n\",name,iscopy", "GetCharArrayElementscp=0"],
+ ["hotspot.jni.GetCharArrayElements.return", "\"%sret=%d\\n\",name,ret", "GetCharArrayElementsret=[^0]"],
+ ["hotspot.jni.GetCharArrayRegion", "\"%sstart=%dlen=%d\\n\",name,start,len", "GetCharArrayRegionstart=0len=5"],
+ ["hotspot.jni.GetCharArrayRegion.return", "\"%s\\n\",name", "GetCharArrayRegion"],
+ ["hotspot.jni.GetCharField", "\"%s\\n\",name", "GetCharField"],
+ ["hotspot.jni.GetCharField.return", "\"%sret=%d\\n\",name,ret", "GetCharFieldret=97"],
+ ["hotspot.jni.GetCreatedJavaVMs", "\"%sbuflen=%d\\n\",name,buflen", "GetCreatedJavaVMsbuflen=1"],
+ ["hotspot.jni.GetCreatedJavaVMs.return", "\"%sret=%d\\n\",name,ret", "GetCreatedJavaVMsret=0"],
+ ["hotspot.jni.GetDefaultJavaVMInitArgs", "\"%s\\n\",name", "GetDefaultJavaVMInitArgs"],
+ ["hotspot.jni.GetDefaultJavaVMInitArgs.return", "\"%sret=%d\\n\",name,ret", "GetDefaultJavaVMInitArgsret=0"],
+ ["hotspot.jni.GetDirectBufferAddress", "\"%s\\n\",name", "GetDirectBufferAddress"],
+ ["hotspot.jni.GetDirectBufferAddress.return", "\"%sret=%d\\n\",name,ret", "GetDirectBufferAddressret=[^0]"],
+ ["hotspot.jni.GetDirectBufferCapacity", "\"%s\\n\",name", "GetDirectBufferCapacity"],
+ ["hotspot.jni.GetDirectBufferCapacity.return", "\"%sret=%d\\n\",name,ret", "GetDirectBufferCapacityret=128"],
+ ["hotspot.jni.GetDoubleArrayElements", "\"%scp=%d\\n\",name,iscopy", "GetDoubleArrayElementscp=0"],
+ ["hotspot.jni.GetDoubleArrayElements.return", "\"%sret=%d\\n\",name,ret", "GetDoubleArrayElementsret=[^0]"],
+ ["hotspot.jni.GetDoubleArrayRegion", "\"%sstart=%dlen=%d\\n\",name,start,len", "GetDoubleArrayRegionstart=0len=5"],
+ ["hotspot.jni.GetDoubleArrayRegion.return", "\"%s\\n\",name", "GetDoubleArrayRegion"],
+ ["hotspot.jni.GetDoubleField", "\"%s\\n\",name", "GetDoubleField"],
+ ["hotspot.jni.GetDoubleField.return", "\"%s\\n\",name", "GetDoubleField"],
+ ["hotspot.jni.GetEnv", "\"%sver=%x\\n\",name,version", "GetEnvver=10006"],
+ ["hotspot.jni.GetEnv.return", "\"%sret=%d\\n\",name,ret", "GetEnvret=0"],
+ ["hotspot.jni.GetFieldID", "\"%sfield=%ssig=%s\\n\",name,field,sig", "GetFieldIDfield=myBooleansig=Z"],
+ ["hotspot.jni.GetFieldID.return", "\"%sret=%d\\n\",name,ret", "GetFieldIDret=[^0]"],
+ ["hotspot.jni.GetFloatArrayElements", "\"%scp=%d\\n\",name,iscopy", "GetFloatArrayElementscp=0"],
+ ["hotspot.jni.GetFloatArrayElements.return", "\"%sret=%d\\n\",name,ret", "GetFloatArrayElementsret=[^0]"],
+ ["hotspot.jni.GetFloatArrayRegion", "\"%sstart=%dlen=%d\\n\",name,start,len", "GetFloatArrayRegionstart=0len=5"],
+ ["hotspot.jni.GetFloatArrayRegion.return", "\"%s\\n\",name", "GetFloatArrayRegion"],
+ ["hotspot.jni.GetFloatField", "\"%s\\n\",name", "GetFloatField"],
+ ["hotspot.jni.GetFloatField.return", "\"%s\\n\",name", "GetFloatField"],
+ ["hotspot.jni.GetIntArrayElements", "\"%scp=%d\\n\",name,iscopy", "GetIntArrayElementscp=0"],
+ ["hotspot.jni.GetIntArrayElements.return", "\"%sret=%d\\n\",name,ret", "GetIntArrayElementsret=[^0]"],
+ ["hotspot.jni.GetIntArrayRegion", "\"%sstart=%dlen=%d\\n\",name,start,len", "GetIntArrayRegionstart=0len=5"],
+ ["hotspot.jni.GetIntArrayRegion.return", "\"%s\\n\",name", "GetIntArrayRegion"],
+ ["hotspot.jni.GetIntField", "\"%s\\n\",name", "GetIntField"],
+ ["hotspot.jni.GetIntField.return", "\"%sret=%d\\n\",name,ret", "GetIntFieldret=4"],
+ ["hotspot.jni.GetJavaVM", "\"%s\\n\",name", "GetJavaVM"],
+ ["hotspot.jni.GetJavaVM.return", "\"%sret=%d\\n\",name,ret", "GetJavaVMret=0"],
+ ["hotspot.jni.GetLongArrayElements", "\"%scp=%d\\n\",name,iscopy", "GetLongArrayElementscp=0"],
+ ["hotspot.jni.GetLongArrayElements.return", "\"%sret=%d\\n\",name,ret", "GetLongArrayElementsret=[^0]"],
+ ["hotspot.jni.GetLongArrayRegion", "\"%sstart=%dlen=%d\\n\",name,start,len", "GetLongArrayRegionstart=0len=5"],
+ ["hotspot.jni.GetLongArrayRegion.return", "\"%s\\n\",name", "GetLongArrayRegion"],
+ ["hotspot.jni.GetLongField", "\"%s\\n\",name", "GetLongField"],
+ ["hotspot.jni.GetLongField.return", "\"%sret=%d\\n\",name,ret", "GetLongFieldret=8"],
+ ["hotspot.jni.GetMethodID", "\"%smethod=%ssig=%s\\n\",name,method,sig", "GetMethodIDmethod=getBooleansig=()Z"],
+ ["hotspot.jni.GetMethodID.return", "\"%sret=%d\\n\",name,ret", "GetMethodIDret=[^0]"],
+ ["hotspot.jni.GetObjectArrayElement", "\"%si=%d\\n\",name,index", "GetObjectArrayElementi=1"],
+ ["hotspot.jni.GetObjectArrayElement.return", "\"%sret=%d\\n\",name,ret", "GetObjectArrayElementret=[^0]"],
+ ["hotspot.jni.GetObjectClass", "\"%s\\n\",name", "GetObjectClass"],
+ ["hotspot.jni.GetObjectClass.return", "\"%sret=%d\\n\",name,ret", "GetObjectClassret=[^0]"],
+ ["hotspot.jni.GetObjectField", "\"%s\\n\",name", "GetObjectField"],
+ ["hotspot.jni.GetObjectField.return", "\"%sret=%d\\n\",name,ret", "GetObjectFieldret=[^0]"],
+ ["hotspot.jni.GetObjectRefType", "\"%s\\n\",name", "GetObjectRefType"],
+ ["hotspot.jni.GetObjectRefType.return", "\"%sret=%d\\n\",name,ret", "GetObjectRefTyperet=2"],
+ ["hotspot.jni.GetPrimitiveArrayCritical", "\"%s\\n\",name", "GetPrimitiveArrayCritical"],
+ ["hotspot.jni.GetPrimitiveArrayCritical.return", "\"%sret=%d\\n\",name,ret", "GetPrimitiveArrayCriticalret=[^0]"],
+ ["hotspot.jni.GetShortArrayElements", "\"%scp=%d\\n\",name,iscopy", "GetShortArrayElementscp=0"],
+ ["hotspot.jni.GetShortArrayElements.return", "\"%sret=%d\\n\",name,ret", "GetShortArrayElementsret=[^0]"],
+ ["hotspot.jni.GetShortArrayRegion", "\"%sstart=%dlen=%d\\n\",name,start,len", "GetShortArrayRegionstart=0len=5"],
+ ["hotspot.jni.GetShortArrayRegion.return", "\"%s\\n\",name", "GetShortArrayRegion"],
+ ["hotspot.jni.GetShortField", "\"%s\\n\",name", "GetShortField"],
+ ["hotspot.jni.GetShortField.return", "\"%sret=%d\\n\",name,ret", "GetShortFieldret=2"],
+ ["hotspot.jni.GetStaticBooleanField", "\"%s\\n\",name", "GetStaticBooleanField"],
+ ["hotspot.jni.GetStaticBooleanField.return", "\"%sret=%d\\n\",name,ret", "GetStaticBooleanFieldret=0"],
+ ["hotspot.jni.GetStaticByteField", "\"%s\\n\",name", "GetStaticByteField"],
+ ["hotspot.jni.GetStaticByteField.return", "\"%sret=%d\\n\",name,ret", "GetStaticByteFieldret=1"],
+ ["hotspot.jni.GetStaticCharField", "\"%s\\n\",name", "GetStaticCharField"],
+ ["hotspot.jni.GetStaticCharField.return", "\"%sret=%d\\n\",name,ret", "GetStaticCharFieldret=98"],
+ ["hotspot.jni.GetStaticDoubleField", "\"%s\\n\",name", "GetStaticDoubleField"],
+ ["hotspot.jni.GetStaticDoubleField.return", "\"%s\\n\",name", "GetStaticDoubleField"],
+ ["hotspot.jni.GetStaticFieldID", "\"%sfield=%ssig=%s\\n\",name,field,sig", "GetStaticFieldIDfield=myStaticBooleansig=Z"],
+ ["hotspot.jni.GetStaticFieldID.return", "\"%sret=%d\\n\",name,ret", "GetStaticFieldIDret=[^0]"],
+ ["hotspot.jni.GetStaticFloatField", "\"%s\\n\",name", "GetStaticFloatField"],
+ ["hotspot.jni.GetStaticFloatField.return", "\"%s\\n\",name", "GetStaticFloatField"],
+ ["hotspot.jni.GetStaticIntField", "\"%s\\n\",name", "GetStaticIntField"],
+ ["hotspot.jni.GetStaticIntField.return", "\"%sret=%d\\n\",name,ret", "GetStaticIntFieldret=32"],
+ ["hotspot.jni.GetStaticLongField", "\"%s\\n\",name", "GetStaticLongField"],
+ ["hotspot.jni.GetStaticLongField.return", "\"%sret=%d\\n\",name,ret", "GetStaticLongFieldret=64"],
+ ["hotspot.jni.GetMethodID", "\"%smethod=%ssig=%s\\n\",name,method,sig", "GetMethodIDmethod=getBooleansig=()Z"],
+ ["hotspot.jni.GetStaticMethodID.return", "\"%sret=%d\\n\",name,ret", "GetStaticMethodIDret=[^0]"],
+ ["hotspot.jni.GetStaticObjectField", "\"%s\\n\",name", "GetStaticObjectField"],
+ ["hotspot.jni.GetStaticObjectField.return", "\"%sret=%d\\n\",name,ret", "GetStaticObjectFieldret=[^0]"],
+ ["hotspot.jni.GetStaticShortField", "\"%s\\n\",name", "GetStaticShortField"],
+ ["hotspot.jni.GetStaticShortField.return", "\"%sret=%d\\n\",name,ret", "GetStaticShortFieldret=16"],
+ ["hotspot.jni.GetStringChars", "\"%scp=%d\\n\",name,iscopy", "GetStringCharscp=0"],
+ ["hotspot.jni.GetStringChars.return", "\"%sret=%d\\n\",name,ret", "GetStringCharsret=[^0]"],
+ ["hotspot.jni.GetStringCritical", "\"%scp=%d\\n\",name,iscopy", "GetStringCriticalcp=0"],
+ ["hotspot.jni.GetStringCritical.return", "\"%sret=%d\\n\",name,ret", "GetStringCriticalret=[^0]"],
+ ["hotspot.jni.GetStringLength", "\"%s\\n\",name", "GetStringLength"],
+ ["hotspot.jni.GetStringLength.return", "\"%sret=%d\\n\",name,ret", "GetStringLengthret=4"],
+ ["hotspot.jni.GetStringRegion", "\"%sst=%dlen=%d\\n\",name,start,len", "GetStringRegionst=1len=2"],
+ ["hotspot.jni.GetStringRegion.return", "\"%s\\n\",name", "GetStringRegion"],
+ ["hotspot.jni.GetStringUTFChars", "\"%scp=%d\\n\",name,iscopy", "GetStringUTFCharscp=0"],
+ ["hotspot.jni.GetStringUTFChars.return", "\"%sret=%s\\n\",name,ret", "GetStringUTFCharsret=WORD"],
+ ["hotspot.jni.GetStringUTFLength", "\"%s\\n\",name", "GetStringUTFLength"],
+ ["hotspot.jni.GetStringUTFLength.return", "\"%sret=%d\\n\",name,ret", "GetStringUTFLengthret=6"],
+ ["hotspot.jni.GetStringUTFRegion", "\"%sst=%dlen=%d\\n\",name,start,len", "GetStringUTFRegionst=1len=2"],
+ ["hotspot.jni.GetStringUTFRegion.return", "\"%s\\n\",name", "GetStringUTFRegion"],
+ ["hotspot.jni.GetSuperclass", "\"%s\\n\",name", "GetSuperclass"],
+ ["hotspot.jni.GetSuperclass.return", "\"%sret=%d\\n\",name,ret", "GetSuperclassret=[^0]"],
+ ["hotspot.jni.GetVersion", "\"%s\\n\",name", "GetVersion"],
+ ["hotspot.jni.GetVersion.return", "\"%sret=%x\\n\",name,ret", "GetVersionret=10006"],
+ ["hotspot.jni.IsAssignableFrom", "\"%s\\n\",name", "IsAssignableFrom"],
+ ["hotspot.jni.IsAssignableFrom.return", "\"%sret=%d\\n\",name,ret", "IsAssignableFromret=1"],
+ ["hotspot.jni.IsInstanceOf", "\"%s\\n\",name", "IsInstanceOf"],
+ ["hotspot.jni.IsInstanceOf.return", "\"%sret=%d\\n\",name,ret", "IsInstanceOfret=1"],
+ ["hotspot.jni.IsSameObject", "\"%s\\n\",name", "IsSameObject"],
+ ["hotspot.jni.IsSameObject.return", "\"%sret=%d\\n\",name,ret", "IsSameObjectret=1"],
+ ["hotspot.jni.MonitorEnter", "\"%s\\n\",name", "MonitorEnter"],
+ ["hotspot.jni.MonitorEnter.return", "\"%sret=%d\\n\",name,ret", "MonitorEnterret=0"],
+ ["hotspot.jni.MonitorExit", "\"%s\\n\",name", "MonitorExit"],
+ ["hotspot.jni.MonitorExit.return", "\"%sret=%d\\n\",name,ret", "MonitorExitret=0"],
+ ["hotspot.jni.NewBooleanArray", "\"%slen=%d\\n\",name,length", "NewBooleanArraylen=5"],
+ ["hotspot.jni.NewBooleanArray.return", "\"%sret=%d\\n\",name,ret", "NewBooleanArrayret=[^0]"],
+ ["hotspot.jni.NewByteArray", "\"%slen=%d\\n\",name,length", "NewByteArraylen=5"],
+ ["hotspot.jni.NewByteArray.return", "\"%sret=%d\\n\",name,ret", "NewByteArrayret=[^0]"],
+ ["hotspot.jni.NewCharArray", "\"%slen=%d\\n\",name,length", "NewCharArraylen=5"],
+ ["hotspot.jni.NewCharArray.return", "\"%sret=%d\\n\",name,ret", "NewCharArrayret=[^0]"],
+ ["hotspot.jni.NewDirectByteBuffer", "\"%ssize=%d\\n\",name,size", "NewDirectByteBuffersize=128"],
+ ["hotspot.jni.NewDirectByteBuffer.return", "\"%sret=%d\\n\",name,ret", "NewDirectByteBufferret=[^0]"],
+ ["hotspot.jni.NewDoubleArray", "\"%slen=%d\\n\",name,length", "NewDoubleArraylen=5"],
+ ["hotspot.jni.NewDoubleArray.return", "\"%sret=%d\\n\",name,ret", "NewDoubleArrayret=[^0]"],
+ ["hotspot.jni.NewFloatArray", "\"%slen=%d\\n\",name,length", "NewFloatArraylen=5"],
+ ["hotspot.jni.NewFloatArray.return", "\"%sret=%d\\n\",name,ret", "NewFloatArrayret=[^0]"],
+ ["hotspot.jni.NewGlobalRef", "\"%s\\n\",name", "NewGlobalRef"],
+ ["hotspot.jni.NewGlobalRef.return", "\"%sret=%d\\n\",name,ret", "NewGlobalRefret=[^0]"],
+ ["hotspot.jni.NewIntArray", "\"%slen=%d\\n\",name,length", "NewIntArraylen=5"],
+ ["hotspot.jni.NewIntArray.return", "\"%sret=%d\\n\",name,ret", "NewIntArrayret=[^0]"],
+ ["hotspot.jni.NewLocalRef", "\"%s\\n\",name", "NewLocalRef"],
+ ["hotspot.jni.NewLocalRef.return", "\"%sret=%d\\n\",name,ret", "NewLocalRefret=[^0]"],
+ ["hotspot.jni.NewLongArray", "\"%slen=%d\\n\",name,length", "NewLongArraylen=5"],
+ ["hotspot.jni.NewLongArray.return", "\"%sret=%d\\n\",name,ret", "NewLongArrayret=[^0]"],
+ ["hotspot.jni.NewObjectA", "\"%s\\n\",name", "NewObjectA"],
+ ["hotspot.jni.NewObjectA.return", "\"%sret=%d\\n\",name,ret", "NewObjectAret=0"],
+ ["hotspot.jni.NewObjectArray", "\"%slen=%dinit=%d\\n\",name,length,initial", "NewObjectArraylen=5init=0"],
+ ["hotspot.jni.NewObjectArray.return", "\"%sret=%d\\n\",name,ret", "NewObjectArrayret=[^0]"],
+ ["hotspot.jni.NewObject", "\"%s\\n\",name", "NewObject"],
+ ["hotspot.jni.NewObject.return", "\"%sret=%d\\n\",name,ret", "NewObjectret=[^0]"],
+ ["hotspot.jni.NewObjectV", "\"%s\\n\",name", "NewObjectV"],
+ ["hotspot.jni.NewObjectV.return", "\"%sret=%d\\n\",name,ret", "NewObjectVret=[^0]"],
+ ["hotspot.jni.NewShortArray", "\"%slen=%d\\n\",name,length", "NewShortArraylen=5"],
+ ["hotspot.jni.NewShortArray.return", "\"%sret=%d\\n\",name,ret", "NewShortArrayret=[^0]"],
+ ["hotspot.jni.NewString", "\"%slen=%d\\n\",name,len", "NewStringlen=4"],
+ ["hotspot.jni.NewString.return", "\"%sret=%d\\n\",name,ret", "NewStringret=[^0]"],
+ ["hotspot.jni.NewStringUTF", "\"%sbytes=%s\\n\",name,bytes", "NewStringUTFbytes=WORD"],
+ ["hotspot.jni.NewStringUTF.return", "\"%sret=%d\\n\",name,ret", "NewStringUTFret=[^0]"],
+ ["hotspot.jni.NewWeakGlobalRef", "\"%s\\n\",name", "NewWeakGlobalRef"],
+ ["hotspot.jni.NewWeakGlobalRef.return", "\"%sret=%d\\n\",name,ret", "NewWeakGlobalRefret=[^0]"],
+ ["hotspot.jni.PopLocalFrame", "\"%s\\n\",name", "PopLocalFrame"],
+ ["hotspot.jni.PopLocalFrame.return", "\"%sret=%d\\n\",name,ret", "PopLocalFrameret=0"],
+ ["hotspot.jni.PushLocalFrame", "\"%scap=%d\\n\",name,capacity", "PushLocalFramecap=10"],
+ ["hotspot.jni.PushLocalFrame.return", "\"%sret=%d\\n\",name,ret", "PushLocalFrameret=0"],
+ ["hotspot.jni.RegisterNatives", "\"%s\\n\",name", "RegisterNatives"],
+ ["hotspot.jni.RegisterNatives.return", "\"%sret=%d\\n\",name,ret", "RegisterNativesret=0"],
+ ["hotspot.jni.ReleaseBooleanArrayElements", "\"%smode=%d\\n\",name,mode", "ReleaseBooleanArrayElementsmode=2"],
+ ["hotspot.jni.ReleaseBooleanArrayElements.return", "\"%s\\n\",name", "ReleaseBooleanArrayElements"],
+ ["hotspot.jni.ReleaseByteArrayElements", "\"%smode=%d\\n\",name,mode", "ReleaseByteArrayElementsmode=2"],
+ ["hotspot.jni.ReleaseByteArrayElements.return", "\"%s\\n\",name", "ReleaseByteArrayElements"],
+ ["hotspot.jni.ReleaseCharArrayElements", "\"%smode=%d\\n\",name,mode", "ReleaseCharArrayElementsmode=2"],
+ ["hotspot.jni.ReleaseCharArrayElements.return", "\"%s\\n\",name", "ReleaseCharArrayElements"],
+ ["hotspot.jni.ReleaseDoubleArrayElements", "\"%smode=%d\\n\",name,mode", "ReleaseDoubleArrayElementsmode=2"],
+ ["hotspot.jni.ReleaseDoubleArrayElements.return", "\"%s\\n\",name", "ReleaseDoubleArrayElements"],
+ ["hotspot.jni.ReleaseFloatArrayElements", "\"%smode=%d\\n\",name,mode", "ReleaseFloatArrayElementsmode=2"],
+ ["hotspot.jni.ReleaseFloatArrayElements.return", "\"%s\\n\",name", "ReleaseFloatArrayElements"],
+ ["hotspot.jni.ReleaseIntArrayElements", "\"%smode=%d\\n\",name,mode", "ReleaseIntArrayElementsmode=2"],
+ ["hotspot.jni.ReleaseIntArrayElements.return", "\"%s\\n\",name", "ReleaseIntArrayElements"],
+ ["hotspot.jni.ReleaseLongArrayElements", "\"%smode=%d\\n\",name,mode", "ReleaseLongArrayElementsmode=2"],
+ ["hotspot.jni.ReleaseLongArrayElements.return", "\"%s\\n\",name", "ReleaseLongArrayElements"],
+ ["hotspot.jni.ReleasePrimitiveArrayCritical", "\"%smode=%d\\n\",name,mode", "ReleasePrimitiveArrayCriticalmode=2"],
+ ["hotspot.jni.ReleasePrimitiveArrayCritical.return", "\"%s\\n\",name", "ReleasePrimitiveArrayCritical"],
+ ["hotspot.jni.ReleaseShortArrayElements", "\"%smode=%d\\n\",name,mode", "ReleaseShortArrayElementsmode=2"],
+ ["hotspot.jni.ReleaseShortArrayElements.return", "\"%s\\n\",name", "ReleaseShortArrayElements"],
+ ["hotspot.jni.ReleaseStringChars", "\"%s\\n\",name", "ReleaseStringChars"],
+ ["hotspot.jni.ReleaseStringChars.return", "\"%s\\n\",name", "ReleaseStringChars"],
+ ["hotspot.jni.ReleaseStringCritical", "\"%s\\n\",name", "ReleaseStringCritical"],
+ ["hotspot.jni.ReleaseStringCritical.return", "\"%s\\n\",name", "ReleaseStringCritical"],
+ ["hotspot.jni.ReleaseStringUTFChars", "\"%sutf=%s\\n\",name,utf", "ReleaseStringUTFCharsutf=WORD"],
+ ["hotspot.jni.ReleaseStringUTFChars.return", "\"%s\\n\",name", "ReleaseStringUTFChars"],
+ ["hotspot.jni.SetBooleanArrayRegion", "\"%sstart=%dlen=%d\\n\",name,start,len", "SetBooleanArrayRegionstart=0len=5"],
+ ["hotspot.jni.SetBooleanArrayRegion.return", "\"%s\\n\",name", "SetBooleanArrayRegion"],
+ ["hotspot.jni.SetBooleanField", "\"%sval=%d\\n\",name,value", "SetBooleanFieldval=1"],
+ ["hotspot.jni.SetBooleanField.return", "\"%s\\n\",name", "SetBooleanField"],
+ ["hotspot.jni.SetByteArrayRegion", "\"%sstart=%dlen=%d\\n\",name,start,len", "SetByteArrayRegionstart=0len=5"],
+ ["hotspot.jni.SetByteArrayRegion.return", "\"%s\\n\",name", "SetByteArrayRegion"],
+ ["hotspot.jni.SetByteField", "\"%sval=%d\\n\",name,value", "SetByteFieldval=2"],
+ ["hotspot.jni.SetByteField.return", "\"%s\\n\",name", "SetByteField"],
+ ["hotspot.jni.SetCharArrayRegion", "\"%sstart=%dlen=%d\\n\",name,start,len", "SetCharArrayRegionstart=0len=5"],
+ ["hotspot.jni.SetCharArrayRegion.return", "\"%s\\n\",name", "SetCharArrayRegion"],
+ ["hotspot.jni.SetCharField", "\"%sval=%d\\n\",name,value", "SetCharFieldval=65"],
+ ["hotspot.jni.SetCharField.return", "\"%s\\n\",name", "SetCharField"],
+ ["hotspot.jni.SetDoubleArrayRegion", "\"%sstart=%dlen=%d\\n\",name,start,len", "SetDoubleArrayRegionstart=0len=5"],
+ ["hotspot.jni.SetDoubleArrayRegion.return", "\"%s\\n\",name", "SetDoubleArrayRegion"],
+ ["hotspot.jni.SetDoubleField", "\"%s\\n\",name", "SetDoubleField"],
+ ["hotspot.jni.SetDoubleField.return", "\"%s\\n\",name", "SetDoubleField"],
+ ["hotspot.jni.SetFloatArrayRegion", "\"%sstart=%dlen=%d\\n\",name,start,len", "SetFloatArrayRegionstart=0len=5"],
+ ["hotspot.jni.SetFloatArrayRegion.return", "\"%s\\n\",name", "SetFloatArrayRegion"],
+ ["hotspot.jni.SetFloatField", "\"%s\\n\",name", "SetFloatField"],
+ ["hotspot.jni.SetFloatField.return", "\"%s\\n\",name", "SetFloatField"],
+ ["hotspot.jni.SetIntArrayRegion", "\"%sstart=%dlen=%d\\n\",name,start,len", "SetIntArrayRegionstart=0len=5"],
+ ["hotspot.jni.SetIntArrayRegion.return", "\"%s\\n\",name", "SetIntArrayRegion"],
+ ["hotspot.jni.SetIntField", "\"%sval=%d\\n\",name,value", "SetIntFieldval=7"],
+ ["hotspot.jni.SetIntField.return", "\"%s\\n\",name", "SetIntField"],
+ ["hotspot.jni.SetLongArrayRegion", "\"%sstart=%dlen=%d\\n\",name,start,len", "SetLongArrayRegionstart=0len=5"],
+ ["hotspot.jni.SetLongArrayRegion.return", "\"%s\\n\",name", "SetLongArrayRegion"],
+ ["hotspot.jni.SetLongField", "\"%sval=%d\\n\",name,value", "SetLongFieldval=13"],
+ ["hotspot.jni.SetLongField.return", "\"%s\\n\",name", "SetLongField"],
+ ["hotspot.jni.SetObjectArrayElement", "\"%s\\n\",name", "SetObjectArrayElement"],
+ ["hotspot.jni.SetObjectArrayElement.return", "\"%s\\n\",name", "SetObjectArrayElement"],
+ ["hotspot.jni.SetObjectField", "\"%s\\n\",name", "SetObjectField"],
+ ["hotspot.jni.SetObjectField.return", "\"%s\\n\",name", "SetObjectField"],
+ ["hotspot.jni.SetShortArrayRegion", "\"%sstart=%dlen=%d\\n\",name,start,len", "SetShortArrayRegionstart=0len=5"],
+ ["hotspot.jni.SetShortArrayRegion.return", "\"%s\\n\",name", "SetShortArrayRegion"],
+ ["hotspot.jni.SetShortField", "\"%sval=%d\\n\",name,value", "SetShortFieldval=11"],
+ ["hotspot.jni.SetShortField.return", "\"%s\\n\",name", "SetShortField"],
+ ["hotspot.jni.SetStaticBooleanField", "\"%sval=%d\\n\",name,value", "SetStaticBooleanFieldval=1"],
+ ["hotspot.jni.SetStaticBooleanField.return", "\"%s\\n\",name", "SetStaticBooleanField"],
+ ["hotspot.jni.SetStaticByteField", "\"%sval=%d\\n\",name,value", "SetStaticByteFieldval=2"],
+ ["hotspot.jni.SetStaticByteField.return", "\"%s\\n\",name", "SetStaticByteField"],
+ ["hotspot.jni.SetStaticCharField", "\"%sval=%d\\n\",name,value", "SetStaticCharFieldval=65"],
+ ["hotspot.jni.SetStaticCharField.return", "\"%s\\n\",name", "SetStaticCharField"],
+ ["hotspot.jni.SetStaticDoubleField", "\"%s\\n\",name", "SetStaticDoubleField"],
+ ["hotspot.jni.SetStaticDoubleField.return", "\"%s\\n\",name", "SetStaticDoubleField"],
+ ["hotspot.jni.SetStaticFloatField", "\"%s\\n\",name", "SetStaticFloatField"],
+ ["hotspot.jni.SetStaticFloatField.return", "\"%s\\n\",name", "SetStaticFloatField"],
+ ["hotspot.jni.SetStaticIntField", "\"%sval=%d\\n\",name,value", "SetStaticIntFieldval=7"],
+ ["hotspot.jni.SetStaticIntField.return", "\"%s\\n\",name", "SetStaticIntField"],
+ ["hotspot.jni.SetStaticLongField", "\"%sval=%d\\n\",name,value", "SetStaticLongFieldval=13"],
+ ["hotspot.jni.SetStaticLongField.return", "\"%s\\n\",name", "SetStaticLongField"],
+ ["hotspot.jni.SetStaticObjectField", "\"%s\\n\",name", "SetStaticObjectField"],
+ ["hotspot.jni.SetStaticObjectField.return", "\"%s\\n\",name", "SetStaticObjectField"],
+ ["hotspot.jni.SetStaticShortField", "\"%sval=%d\\n\",name,value", "SetStaticShortFieldval=11"],
+ ["hotspot.jni.SetStaticShortField.return", "\"%s\\n\",name", "SetStaticShortField"],
+ ["hotspot.jni.Throw", "\"%s\\n\",name", "Throw"],
+ ["hotspot.jni.Throw.return", "\"%sret=%d\\n\",name,ret", "Throwret=0"],
+ ["hotspot.jni.ThrowNew", "\"%smsg=%s\\n\",name,msg", "ThrowNewmsg=This exception is for testing purposes only."],
+ ["hotspot.jni.ThrowNew.return", "\"%sret=%d\\n\",name,ret", "ThrowNewret=0"],
+ ["hotspot.jni.ToReflectedField", "\"%s\\n\",name", "ToReflectedField"],
+ ["hotspot.jni.ToReflectedField.return", "\"%sret=%d\\n\",name,ret", "ToReflectedFieldret=[^0]"],
+ ["hotspot.jni.ToReflectedMethod", "\"%s\\n\",name", "ToReflectedMethod"],
+ ["hotspot.jni.ToReflectedMethod.return", "\"%sret=%d\\n\",name,ret", "ToReflectedMethodret=[^0]"],
+ ["hotspot.jni.UnregisterNatives", "\"%s\\n\",name", "UnregisterNatives"],
+ ["hotspot.jni.UnregisterNatives.return", "\"%sret=%d\\n\",name,ret", "UnregisterNativesret=0"]);
+
+# To test for known probe prefix. Determines main type of test run.
+my $hs_regex = "^hotspot\.";
+my $jni_regex = "^hotspot\.jni\.";
+
+# Status of test run.
+my $working_count = 0;
+my $undetected_count = 0;
+my $broken_count = 0;
+
+# Stuffed based on argument(s), used as argument to stap executable.
+my @tapset_dirs = ();
+
+# Set based on arguments, used to during compilation and/or running of tests.
+my $ignore_system_tapset = "";
+my $java_exec = "";
+my $javac_exec = "";
+my $jvm_dir = "";
+my $jvm_so = "";
+my $test_sourcedir = ".";
+my @include_dirs = ();
+
+
+### MAIN BODY
+# Short and sweet.
+process_args();
+log_preamble();
+build_tests();
+my @detected_probes = detect_probes(@probestrings);
+if (can_run_probes()) {
+ test_probes(@detected_probes);
+}
+summarize();
+log_postamble();
+clean_up();
+exit($broken_count | $undetected_count);
+
+### PRIMARY SUBROUTINES
+# These are called by the main body of the script.
+
+# Uses Getopt::Std::getopts() to grab user arguments, then performs further
+# processing to ensure valid combination of args and set several variables
+# based on args.
+sub process_args {
+ die "Try \"jstaptest.pl --help\" for usage information.\n"
+ if (!getopts('B:A:J:o:a:S:') || ($opt_o && $opt_a));
+ # -o and -a are mutually exclusive.
+ if ($opt_B && $opt_A) {
+ die "Directory $opt_B not found." unless (-d $opt_B);
+ die "Directory $opt_B/j2sdk-image/tapset not found.\nTry rebuilding Icedtea with systemtap support.\n"
+ unless (-d "$opt_B/j2sdk-image/tapset");
+ push(@tapset_dirs, "-I$opt_B/j2sdk-image/tapset");
+ set_java_vars("$opt_B/j2sdk-image", $opt_A);
+ $ignore_system_tapset = "SYSTEMTAP_TAPSET=\"\"";
+ }
+ elsif ($opt_J) {
+ set_java_vars($opt_J, get_arch_dir());
+
+ }
+ else {
+ die "Try \"./jstaptest.pl --help\" for usage information.\n";
+ }
+
+ if ($opt_S) {
+ die "Directory $opt_S not found." unless (-d $opt_S);
+ $test_sourcedir = "$opt_S";
+ }
+
+ if ($opt_o) {
+ $logfile_name = $opt_o;
+ mkpath(dirname($opt_o)) or
+ die "Couldn't make enclosing directory for $opt_o\n$!"
+ unless (-d dirname($opt_o));
+ open($log_file, '>', $opt_o) or
+ die "Couldn't open log file: $opt_a\n$!";
+ }
+ if ($opt_a) {
+ $logfile_name = $opt_a;
+ mkpath(dirname($opt_a)) or
+ die "Couldn't make enclosing directory for $opt_a\n$!"
+ unless (-d dirname($opt_a));
+ open($log_file, '>>', $opt_a) or
+ die "Couldn't open log file: $opt_a\n$!";
+ }
+}
+
+# Any text that should precede a test run in the log file goes here.
+sub log_preamble {
+ just_log("###############################################################");
+ just_log("Start of test run.\n" . gmtime());
+}
+
+# Tests consist of a number of C and Java files. These need to be compiled.
+sub build_tests {
+ log_and_print("Compiling tests.");
+ my $compile_command = "$javac_exec -d ./ $test_sourcedir/*.java";
+ just_log($compile_command);
+ system($compile_command);
+ if ($? != 0) {
+ log_and_print("Error compiling one or more .java files.");
+ clean_up();
+ die "Cannot compile tests.\n";
+ }
+ $compile_command = "gcc " . join(' ', @include_dirs) .
+ " -c -fPIC $test_sourcedir/JNITestClass.c -o JNITestClass.o";
+ just_log($compile_command);
+ system($compile_command);
+ if ($? != 0) {
+ log_and_print("Error compiling JNITestClass.o");
+ clean_up();
+ die "Cannot compile tests.\n";
+ }
+ $compile_command = "gcc -shared -o libJNITestClass.so -fPIC JNITestClass.o";
+ just_log($compile_command);
+ system($compile_command);
+ if ($? != 0) {
+ log_and_print("Error building libJNITestClass.so");
+ clean_up();
+ die "Cannot compile tests.\n";
+ }
+ $compile_command = "gcc " . join(' ', @include_dirs) .
+ " -pthread -L$jvm_dir -L. -lJNITestClass $jvm_so" .
+ " -o JNIStapTest $test_sourcedir/JNIStapTest.c";
+ just_log($compile_command);
+ system($compile_command);
+ if ($? != 0) {
+ log_and_print("Error compiling JNIStapTest");
+ clean_up();
+ die "Cannot compile tests.\n";
+ }
+}
+
+# Filter out the list of probes. If Systemtap cannot locate a probe using the
+# -l argument, it makes little sense to try to run a script based on it.
+# This also means we can detect this case as a distinct failure mode.
+sub detect_probes {
+ log_and_print("Testing if systemtap can match probes.");
+ my @probes_detected = ();
+ my ($probe_name, $probe_printargs, $probe_output, $stap_pre, $stap_command,
+ @sysargs);
+ $stap_pre = "$ignore_system_tapset stap " . join(' ', @tapset_dirs);
+ foreach my $probe_index (0..$#_) {
+ $probe_name = $_[$probe_index][0];
+ $probe_printargs = $_[$probe_index][1];
+ $probe_output = $_[$probe_index][2];
+ $stap_command = "$stap_pre -L $probe_name 2>&1 | grep -q \"^$probe_name\"";
+ just_log($stap_command);
+ print(".");
+ system($stap_command);
+ if ($? != 0) {
+ print("\n");
+ log_and_print("Probe $probe_name not found.");
+ $undetected_count++;
+ }
+ else {
+ just_log("Probe $probe_name found.");
+ push(@probes_detected, [$probe_name, $probe_printargs,
+ $probe_output]);
+ }
+ }
+ print("\n");
+ return @probes_detected;
+}
+
+# Check whether we can run stap while probing.
+# This needs extra user privs. If not, we only run the detect_probes()
+# test, but not the test_probes() test.
+sub can_run_probes {
+ log_and_print("Check whether we have enough privs to run systemtap script...");
+ my $stap_command = "stap -e 'probe begin { log(\"Hello World\"); exit(); }'";
+ just_log($stap_command);
+ my $result = `$stap_command 2>&1`;
+ if ($? != 0) {
+ # First few error lines give a hint...
+ print(join("\n", (split /\n/, $result)[0..5]), "\n");
+ just_log($result);
+ log_and_print("Cannot run simple stap script, skipping probe tests.");
+ return 0;
+ }
+ print("OK\n");
+ return 1;
+}
+
+# For each probe, run a stap script using the -c command to have it load
+# and unload automatically around the execution of a single command. This
+# command will be the running of a java program (in the case of probes
+# from the hotspot.stp tapset) or a C program which uses the JNI
+# Invocation API (in the case of probes from the hotspot_jni.stp tapset),
+# which is designed to trigger the named probe in as minimal of a test
+# case as possible. Associated with each probe is a format string (with
+# variables) that is called in a printf statement within the stap script,
+# and a regex designed to resemble the expected output of said printf
+# statement.
+sub test_probes {
+ log_and_print("Testing if detected probes work as expected. This may take a while...");
+ my ($probe_name, $probe_suffix, $probe_printargs, $probe_output,
+ $stap_pre, $stap_command, $jvm_xxarg);
+ $stap_pre = "stap " . join(' ', @tapset_dirs);
+ foreach my $probe_index (0..$#_) {
+ $jvm_xxarg = "";
+ $probe_name = $_[$probe_index][0];
+ $probe_suffix = $probe_name;
+ $probe_printargs = $_[$probe_index][1];
+ $probe_output = $_[$probe_index][2];
+ $stap_command = "$stap_pre -e 'probe $probe_name { printf($probe_printargs) }' -c";
+ if ($probe_name =~ m/($jni_regex)/) {
+ # JNI probes are triggered by calling a C program which uses the
+ # invocation API on which the probes are based.
+ $probe_suffix =~ s/($jni_regex)//;
+ # The test against the jni function entry and return probes are
+ # identical.
+ $probe_suffix =~ s/\.return$//;
+ $stap_command = "$stap_command 'export LD_LIBRARY_PATH=.:$jvm_dir && ./JNIStapTest $probe_suffix'";
+ if ($probe_suffix =~ m/^FatalError$/) {
+ # This test intentionally crashes the JVM, generating output
+ # on stderr. We don't want to see this noise.
+ $stap_command = "$stap_command 2>&1";
+ }
+ }
+ elsif ($probe_name =~ m/($hs_regex)/) {
+ # Hotspot probes are triggered by calling a Java program which sets
+ # up appropriate conditions in the JVM to hit the probe points.
+ $probe_suffix =~ s/($hs_regex)//;
+ # Some probes are optimized out in the default JVM configuration, so
+ # we need some special arguments.
+ if ($probe_suffix =~ m/^monitor/) {
+ $jvm_xxarg = "-XX:+DTraceMonitorProbes";
+ }
+ elsif ($probe_suffix =~ m/^method_(entry|return)$/) {
+ $jvm_xxarg = "-XX:+DTraceMethodProbes";
+ }
+ elsif ($probe_suffix =~ m/^object_alloc$/) {
+ $jvm_xxarg = "-XX:+DTraceAllocProbes";
+ }
+ elsif ($probe_suffix =~ m/^(method_compile|compiled_method)/) {
+ # Default here is much larger, this way our test doesn't need to
+ # run as long.
+ $jvm_xxarg = "-XX:CompileThreshold=100";
+ }
+ $stap_command = "$stap_command '$java_exec $jvm_xxarg staptest.SystemtapTester $probe_suffix'";
+ }
+ else {
+ just_log("Probe $probe_name has no test defined.");
+ $broken_count++;
+ next;
+ }
+ $stap_command = "$stap_command | grep \"$probe_output\" 2>&1 >> /dev/null";
+ print(".");
+ just_log($stap_command);
+ system($stap_command);
+ if ($? == 0) {
+ just_log("Probe $probe_name working.");
+ $working_count++;
+ }
+ else {
+ print("\n");
+ log_and_print("Probe $probe_name failed.");
+ $broken_count++;
+ }
+ }
+ print("\n");
+}
+
+# Output a tally of test results.
+sub summarize {
+ if ($working_count) {
+ log_and_print("Working probes: $working_count");
+ }
+ if ($broken_count) {
+ log_and_print("Broken probes: $broken_count");
+ }
+ if ($undetected_count) {
+ log_and_print("Undetected probes: $undetected_count");
+ }
+
+}
+
+# Any text that should follow a test run in the log file goes here.
+sub log_postamble {
+ if ($broken_count | $undetected_count) {
+ log_and_print("Some tests did not work as expected. See file " .
+ $logfile_name . " for details.");
+ }
+ just_log("End of test run");
+}
+
+# Remove compiled files and close file handle(s). Any other cleanup needed
+# should be added here.
+sub clean_up {
+ log_and_print("Removing compiled test files.");
+ rmtree('staptest');
+ unlink <*.o>;
+ unlink <*.so>;
+ unlink "JNIStapTest";
+ if ($log_file) {
+ close($log_file);
+ }
+}
+
+
+# HELPER SUBROUTINES
+# Subroutines other than top-level.
+
+# Used when processing arguments to set a number of variables that refer to
+# files/directories within $JAVA_HOME.
+sub set_java_vars {
+ my ($_java_home, $_arch_dir) = @_;
+ $java_exec = "$_java_home/jre/bin/java";
+ $javac_exec = "$_java_home/bin/javac";
+ $jvm_dir = "$_java_home/jre/lib/$_arch_dir/server";
+ $jvm_so = "$jvm_dir/libjvm.so";
+ push(@include_dirs, "-I$_java_home/include");
+ push(@include_dirs, "-I$_java_home/include/linux");
+ die "Java executable not found: $java_exec\n" unless (-x $java_exec);
+ die "Javac executable not found: $javac_exec\n" unless (-x $javac_exec);
+ die "Directory not found: $jvm_dir\n" unless (-d $jvm_dir);
+ die "File not found: $jvm_so\n" unless (-r $jvm_so);
+ die "jni.h or jni_md.h headers not found within directory: $_java_home/j2sdk-image/include"
+ unless ((-r "$_java_home/include/jni.h") &&
+ (-r "$_java_home/include/linux/jni_md.h"));
+}
+
+# When testing against an installed jdk, we need to know the current
+# architecture to find libjvm.so within the jdk directory tree.
+sub get_arch_dir {
+ my $sys_arch = $Config{archname};
+ if ($sys_arch =~ m/x86_64/) {
+ return "amd64";
+ }
+ elsif ($sys_arch =~ m/i.86/) {
+ return "i586";
+ }
+ elsif ($sys_arch =~ m/alpha/) {
+ return "alpha";
+ }
+ elsif ($sys_arch =~ m/arm/) {
+ return "arm";
+ }
+ elsif ($sys_arch =~ m/mips-/) {
+ return "mips";
+ }
+ elsif ($sys_arch =~ m/mipsel/) {
+ return "mipsel";
+ }
+ elsif ($sys_arch =~ m/powerpc-/) {
+ return "ppc";
+ }
+ elsif ($sys_arch =~ m/powerpc64/) {
+ return "ppc64";
+ }
+ elsif ($sys_arch =~ m/sparc64/) {
+ return "sparcv9";
+ }
+ elsif ($sys_arch =~ m/s390/) {
+ return "s390";
+ }
+ else {
+ die "Unknown arch: $sys_arch\n";
+ }
+}
+
+# If we are logging, send arguments as lines to log file.
+sub just_log {
+ if ($log_file) {
+ foreach my $line (@_) {
+ print $log_file "$line\n";
+ }
+ }
+}
+
+# This is sort of like a "tee $logfile".
+sub log_and_print {
+ just_log(@_);
+ foreach my $line (@_) {
+ print("$line\n");
+ }
+}
+
+
+# OVERRIDDEN FUNCTIONS
+
+# Runs when --help option is passed, thanks to hooks in Getopt::Std::getopts();
+sub main::HELP_MESSAGE {
+ print("\n");
+ print("To run test suite:\n");
+ print("\n");
+ print(" $ ./jstaptest.sh [[--help] | [<[-B <DIR> -A <ARCH>] | [-J <DIR>]> [-S <DIR>] [-<o|a> <LOGFILE>]]]\n");
+ print("\n");
+ print("--help will display this help message.\n");
+ print("\n");
+ print("\n");
+ print("One of -BA or -J *must* be used.\n");
+ print("\n");
+ print("-J can be used to specify the location of the icedtea install on\n");
+ print(" the system. Specifically, this directory should contain the\n");
+ print(" directories bin, jre, lib, and include. Only the tapsets in\n");
+ print(" systemtap's default directory will be tested. Arch-specific\n");
+ print(" directories will be determined from the system's arch.\n");
+ print("\n");
+ print("\n");
+ print("-BA can be used to specify a local icedtea build.\n");
+ print(" -B should be equivalent to the \$(BUILD_OUTPUT_DIR) in the\n");
+ print(" icedtea Makefile.\n");
+ print(" For example:\n");
+ print(" ./jstaptest.sh -B \\\n");
+ print(" /path/to/icedtea6/openjdk/build/<OS-ARCH>/\n");
+ print("\n");
+ print(" -A must also be used when -B is used, to specify the \n");
+ print(" architecture of the icedtea build, \$(BUILD_ARCH_DIR) from\n");
+ print(" the icedtea Makefile.\n");
+ print("\n");
+ print("\n");
+ print("-S can be used to specify the directory where the test source\n");
+ print(" code can be found. If it is omitted, the current working\n");
+ print(" directory is assumed.\n");
+ print("\n");
+ print("\n");
+ print("-o or -a specify a log file for more detailed output.\n");
+ print(" Using -o will replace the existing file if present, while -a\n");
+ print(" will append. These two options are mutually exclusive. The\n");
+ print(" log file will contain specifics of which probes pass, fail,\n");
+ print(" or are not detected by systemtap, along with a record of\n");
+ print(" the arguments passed to the script and the command executed\n");
+ print(" for each test\n");
+ print("\n");
+}
+
+#######################################################################
+
More information about the distro-pkg-dev
mailing list