8199384: [TESTBUG] Open source VM testbase MLVM tests
Reviewed-by: erikj, mseledtsov, vlivanov
This commit is contained in:
parent
12a799b4e1
commit
01b0f9ea7d
make/test
test/hotspot/jtreg
ProblemList-graal.txtProblemList.txtTEST.groups
vmTestbase
nsk/share/jvmti
Injector.cInjector.hJVMTITools.cJVMTITools.h
agent_common
agent_tools.cjvmti_FollowRefObjects.cjvmti_FollowRefObjects.hjvmti_tools.cjvmti_tools.hvm/mlvm
anonloader
func
castToGrandparent
castToParent
classNameInStackTrace
finalSuperclass
findByName
invalidSuperclass
isGarbageCollected
uniqueClassAndObject
share
stress
byteMutation
oome
parallelLoad
randomBytecodes
cp
share
GenCPFullOfMH.javaGenCPFullOfMT.javaGenFullCP.javaGenManyIndyCorrectBootstrap.javaGenManyIndyIncorrectBootstrap.javaGenManyIndyOneCPX.javaHandleType.java
stress/classfmt
correctBootstrap
incorrectBootstrap
manyIndyOneCPX
mh
mt
indy/func
java
rawRetypes
thisAsArgument
verifyStackTrace
jdi
jvmti
mergeCP_indy2manyDiff_a
mergeCP_indy2manyDiff_b
mergeCP_indy2manySame_a
mergeCP_indy2manySame_b
mergeCP_indy2none_a
mergeCP_indy2none_b
mergeCP_indy2same_a
mergeCP_indy2same_b
mergeCP_none2indy_a
mergeCP_none2indy_b
@ -78,6 +78,17 @@ NSK_SHARE_LOCKS_INCLUDES := \
|
||||
-I$(VM_TESTBASE_DIR)/nsk/share/native \
|
||||
-I$(VM_TESTBASE_DIR)/nsk/share/locks
|
||||
|
||||
MLVM_JVMTI_INCLUDES := \
|
||||
-I$(VM_TESTBASE_DIR)/nsk/share/native \
|
||||
-I$(VM_TESTBASE_DIR)/nsk/share/jni \
|
||||
-I$(VM_TESTBASE_DIR)/nsk/share/jvmti \
|
||||
-I$(VM_TESTBASE_DIR)/nsk/share/jvmti/agent_common \
|
||||
-I$(VM_TESTBASE_DIR)/vm/mlvm/share
|
||||
|
||||
MLVM_STRESS_INCLUDES := \
|
||||
-I$(VM_TESTBASE_DIR)/nsk/share/native \
|
||||
-I$(VM_TESTBASE_DIR)/nsk/share/jni
|
||||
|
||||
BUILD_HOTSPOT_JTREG_LIBRARIES_CFLAGS_libProcessUtils := $(VM_SHARE_INCLUDES)
|
||||
|
||||
BUILD_HOTSPOT_JTREG_LIBRARIES_CFLAGS_libThreadController := $(NSK_MONITORING_INCLUDES)
|
||||
@ -95,6 +106,11 @@ BUILD_HOTSPOT_JTREG_LIBRARIES_CFLAGS_libJNIreferences := $(NSK_SHARE_JNI_INCLUDE
|
||||
BUILD_HOTSPOT_JTREG_LIBRARIES_CFLAGS_libLockingThread := $(NSK_SHARE_LOCKS_INCLUDES)
|
||||
BUILD_HOTSPOT_JTREG_LIBRARIES_CFLAGS_libJNIMonitorLocker := $(NSK_SHARE_LOCKS_INCLUDES)
|
||||
|
||||
BUILD_HOTSPOT_JTREG_LIBRARIES_CFLAGS_libstepBreakPopReturn := $(MLVM_JVMTI_INCLUDES)
|
||||
BUILD_HOTSPOT_JTREG_LIBRARIES_CFLAGS_libIndyRedefineClass := $(MLVM_JVMTI_INCLUDES)
|
||||
|
||||
BUILD_HOTSPOT_JTREG_LIBRARIES_CFLAGS_libnativeAndMH := $(MLVM_STRESS_INCLUDES)
|
||||
|
||||
################################################################################
|
||||
|
||||
# Platform specific setup
|
||||
@ -105,6 +121,8 @@ endif
|
||||
ifeq ($(OPENJDK_TARGET_OS), linux)
|
||||
BUILD_HOTSPOT_JTREG_LIBRARIES_LDFLAGS_libtest-rw := -z noexecstack
|
||||
BUILD_HOTSPOT_JTREG_LIBRARIES_LDFLAGS_libtest-rwx := -z execstack
|
||||
BUILD_HOTSPOT_JTREG_LIBRARIES_LIBS_libstepBreakPopReturn := -lpthread
|
||||
BUILD_HOTSPOT_JTREG_LIBRARIES_LIBS_libIndyRedefineClass := -lpthread
|
||||
BUILD_HOTSPOT_JTREG_EXECUTABLES_LIBS_exeinvoke := -ljvm -lpthread
|
||||
BUILD_HOTSPOT_JTREG_EXECUTABLES_LIBS_exestack-gap := -ljvm -lpthread
|
||||
BUILD_TEST_exeinvoke_exeinvoke.c_OPTIMIZATION := NONE
|
||||
|
@ -135,3 +135,6 @@ vmTestbase/nsk/jdi/VirtualMachine/redefineClasses/redefineclasses026/TestDescrip
|
||||
vmTestbase/nsk/jdi/VirtualMachine/redefineClasses/redefineclasses028/TestDescription.java 8195627 generic-all
|
||||
vmTestbase/nsk/jdi/VirtualMachine/redefineClasses/redefineclasses030/TestDescription.java 8195627 generic-all
|
||||
|
||||
vmTestbase/vm/mlvm/anonloader/stress/oome/heap/Test.java 8186299 generic-all
|
||||
vmTestbase/vm/mlvm/anonloader/stress/oome/metaspace/Test.java 8186299 generic-all
|
||||
|
||||
|
@ -123,6 +123,25 @@ vmTestbase/nsk/jdi/VirtualMachine/redefineClasses/redefineclasses023/TestDescrip
|
||||
vmTestbase/nsk/jdi/EventQueue/remove_l/remove_l005/TestDescription.java 8068225 generic-all
|
||||
vmTestbase/nsk/jdi/stress/ClassPrepareEvents/ClassPrepareEvents001/ClassPrepareEvents001.java 6426321 generic-all
|
||||
|
||||
vmTestbase/vm/mlvm/indy/func/jdi/breakpointOtherStratum/Test.java 8199578 generic-all
|
||||
vmTestbase/vm/mlvm/indy/func/jdi/breakpoint/Test.java 8199578 generic-all
|
||||
vmTestbase/vm/mlvm/indy/func/jvmti/redefineClassInBootstrap/TestDescription.java 8013267 generic-all
|
||||
vmTestbase/vm/mlvm/indy/stress/java/relinkMutableCallSite/Test.java 8079664 generic-all
|
||||
vmTestbase/vm/mlvm/indy/stress/java/relinkVolatileCallSite/Test.java 8079664 generic-all
|
||||
vmTestbase/vm/mlvm/meth/func/java/throwException/Test.java 8079714 generic-all
|
||||
vmTestbase/vm/mlvm/meth/func/jdi/breakpointOtherStratum/Test.java 8079713,8079714 generic-all
|
||||
vmTestbase/vm/mlvm/meth/stress/compiler/deoptimize/Test.java 8079642,8079714 generic-all
|
||||
vmTestbase/vm/mlvm/meth/stress/compiler/i2c_c2i/Test.java 8079714 generic-all
|
||||
vmTestbase/vm/mlvm/meth/stress/compiler/sequences/Test.java 8079714 generic-all
|
||||
vmTestbase/vm/mlvm/meth/stress/gc/callSequencesDuringGC/Test.java 8079714 generic-all
|
||||
vmTestbase/vm/mlvm/meth/stress/java/sequences/Test.java 8079714 generic-all
|
||||
vmTestbase/vm/mlvm/meth/stress/jdi/breakpointInCompiledCode/Test.java 8079714 generic-all
|
||||
vmTestbase/vm/mlvm/mixed/stress/java/findDeadlock/TestDescription.java 8055376 generic-all
|
||||
vmTestbase/vm/mlvm/mixed/stress/regression/b6969574/INDIFY_Test.java 8079650 generic-all
|
||||
vmTestbase/vm/mlvm/indy/func/jvmti/mergeCP_indy2none_a/TestDescription.java 8013267 generic-all
|
||||
vmTestbase/vm/mlvm/indy/func/jvmti/mergeCP_indy2manyDiff_b/TestDescription.java 8013267 generic-all
|
||||
vmTestbase/vm/mlvm/indy/func/jvmti/mergeCP_indy2manySame_b/TestDescription.java 8013267 generic-all
|
||||
|
||||
vmTestbase/heapdump/JMapHeapCore/TestDescription.java 8023376,8001227,8051445 generic-all
|
||||
vmTestbase/heapdump/JMapMetaspaceCore/TestDescription.java 8023376,8001227,8051445 generic-all
|
||||
|
||||
|
@ -1157,6 +1157,9 @@ vmTestbase_nsk_jdi_quick = \
|
||||
vmTestbase/nsk/jdi/StackFrame/getArgumentValues/getArgumentValues002/getArgumentValues002.java \
|
||||
vmTestbase/nsk/jdi/StackFrame/getArgumentValues/getArgumentValues003/getArgumentValues003.java
|
||||
|
||||
# JSR292 tests (invokedynamic AKA Multi-Language VM AKA Da Vinci Machine)
|
||||
vmTestbase_vm_mlvm = \
|
||||
vmTestbase/vm/mlvm
|
||||
# Heap dump tests
|
||||
vmTestbase_vm_heapdump = \
|
||||
vmTestbase/heapdump/
|
||||
|
1207
test/hotspot/jtreg/vmTestbase/nsk/share/jvmti/Injector.c
Normal file
1207
test/hotspot/jtreg/vmTestbase/nsk/share/jvmti/Injector.c
Normal file
File diff suppressed because it is too large
Load Diff
312
test/hotspot/jtreg/vmTestbase/nsk/share/jvmti/Injector.h
Normal file
312
test/hotspot/jtreg/vmTestbase/nsk/share/jvmti/Injector.h
Normal file
@ -0,0 +1,312 @@
|
||||
/*
|
||||
* Copyright (c) 2004, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
#ifndef _NSK_SHARE_JVMTI_INJECTOR_H_
|
||||
#define _NSK_SHARE_JVMTI_INJECTOR_H_
|
||||
|
||||
/* Class File Format Constants
|
||||
*/
|
||||
|
||||
typedef unsigned char u1;
|
||||
typedef unsigned short u2;
|
||||
typedef unsigned int u4;
|
||||
|
||||
/* Constant table */
|
||||
enum {
|
||||
CONSTANT_Utf8 = 1,
|
||||
CONSTANT_Integer = 3,
|
||||
CONSTANT_Float = 4,
|
||||
CONSTANT_Long = 5,
|
||||
CONSTANT_Double = 6,
|
||||
CONSTANT_Class = 7,
|
||||
CONSTANT_String = 8,
|
||||
CONSTANT_Fieldref = 9,
|
||||
CONSTANT_Methodref = 10,
|
||||
CONSTANT_InterfaceMethodref = 11,
|
||||
CONSTANT_NameAndType = 12,
|
||||
CONSTANT_MethodHandle = 15,
|
||||
CONSTANT_MethodType = 16,
|
||||
CONSTANT_InvokeDynamic = 18
|
||||
};
|
||||
|
||||
/* Access and modifier flags */
|
||||
enum {
|
||||
ACC_PUBLIC = 0x00000001,
|
||||
ACC_PRIVATE = 0x00000002,
|
||||
ACC_PROTECTED = 0x00000004,
|
||||
ACC_STATIC = 0x00000008,
|
||||
ACC_FINAL = 0x00000010,
|
||||
ACC_SYNCHRONIZED = 0x00000020,
|
||||
ACC_VOLATILE = 0x00000040,
|
||||
ACC_TRANSIENT = 0x00000080,
|
||||
ACC_NATIVE = 0x00000100,
|
||||
ACC_INTERFACE = 0x00000200,
|
||||
ACC_ABSTRACT = 0x00000400,
|
||||
ACC_SUPER = 0x00000020,
|
||||
ACC_STRICT = 0x00000800
|
||||
};
|
||||
|
||||
/* Opcodes */
|
||||
enum {
|
||||
opc_nop = 0,
|
||||
opc_aconst_null = 1,
|
||||
opc_iconst_m1 = 2,
|
||||
opc_iconst_0 = 3,
|
||||
opc_iconst_1 = 4,
|
||||
opc_iconst_2 = 5,
|
||||
opc_iconst_3 = 6,
|
||||
opc_iconst_4 = 7,
|
||||
opc_iconst_5 = 8,
|
||||
opc_lconst_0 = 9,
|
||||
opc_lconst_1 = 10,
|
||||
opc_fconst_0 = 11,
|
||||
opc_fconst_1 = 12,
|
||||
opc_fconst_2 = 13,
|
||||
opc_dconst_0 = 14,
|
||||
opc_dconst_1 = 15,
|
||||
opc_bipush = 16,
|
||||
opc_sipush = 17,
|
||||
opc_ldc = 18,
|
||||
opc_ldc_w = 19,
|
||||
opc_ldc2_w = 20,
|
||||
opc_iload = 21,
|
||||
opc_lload = 22,
|
||||
opc_fload = 23,
|
||||
opc_dload = 24,
|
||||
opc_aload = 25,
|
||||
opc_iload_0 = 26,
|
||||
opc_iload_1 = 27,
|
||||
opc_iload_2 = 28,
|
||||
opc_iload_3 = 29,
|
||||
opc_lload_0 = 30,
|
||||
opc_lload_1 = 31,
|
||||
opc_lload_2 = 32,
|
||||
opc_lload_3 = 33,
|
||||
opc_fload_0 = 34,
|
||||
opc_fload_1 = 35,
|
||||
opc_fload_2 = 36,
|
||||
opc_fload_3 = 37,
|
||||
opc_dload_0 = 38,
|
||||
opc_dload_1 = 39,
|
||||
opc_dload_2 = 40,
|
||||
opc_dload_3 = 41,
|
||||
opc_aload_0 = 42,
|
||||
opc_aload_1 = 43,
|
||||
opc_aload_2 = 44,
|
||||
opc_aload_3 = 45,
|
||||
opc_iaload = 46,
|
||||
opc_laload = 47,
|
||||
opc_faload = 48,
|
||||
opc_daload = 49,
|
||||
opc_aaload = 50,
|
||||
opc_baload = 51,
|
||||
opc_caload = 52,
|
||||
opc_saload = 53,
|
||||
opc_istore = 54,
|
||||
opc_lstore = 55,
|
||||
opc_fstore = 56,
|
||||
opc_dstore = 57,
|
||||
opc_astore = 58,
|
||||
opc_istore_0 = 59,
|
||||
opc_istore_1 = 60,
|
||||
opc_istore_2 = 61,
|
||||
opc_istore_3 = 62,
|
||||
opc_lstore_0 = 63,
|
||||
opc_lstore_1 = 64,
|
||||
opc_lstore_2 = 65,
|
||||
opc_lstore_3 = 66,
|
||||
opc_fstore_0 = 67,
|
||||
opc_fstore_1 = 68,
|
||||
opc_fstore_2 = 69,
|
||||
opc_fstore_3 = 70,
|
||||
opc_dstore_0 = 71,
|
||||
opc_dstore_1 = 72,
|
||||
opc_dstore_2 = 73,
|
||||
opc_dstore_3 = 74,
|
||||
opc_astore_0 = 75,
|
||||
opc_astore_1 = 76,
|
||||
opc_astore_2 = 77,
|
||||
opc_astore_3 = 78,
|
||||
opc_iastore = 79,
|
||||
opc_lastore = 80,
|
||||
opc_fastore = 81,
|
||||
opc_dastore = 82,
|
||||
opc_aastore = 83,
|
||||
opc_bastore = 84,
|
||||
opc_castore = 85,
|
||||
opc_sastore = 86,
|
||||
opc_pop = 87,
|
||||
opc_pop2 = 88,
|
||||
opc_dup = 89,
|
||||
opc_dup_x1 = 90,
|
||||
opc_dup_x2 = 91,
|
||||
opc_dup2 = 92,
|
||||
opc_dup2_x1 = 93,
|
||||
opc_dup2_x2 = 94,
|
||||
opc_swap = 95,
|
||||
opc_iadd = 96,
|
||||
opc_ladd = 97,
|
||||
opc_fadd = 98,
|
||||
opc_dadd = 99,
|
||||
opc_isub = 100,
|
||||
opc_lsub = 101,
|
||||
opc_fsub = 102,
|
||||
opc_dsub = 103,
|
||||
opc_imul = 104,
|
||||
opc_lmul = 105,
|
||||
opc_fmul = 106,
|
||||
opc_dmul = 107,
|
||||
opc_idiv = 108,
|
||||
opc_ldiv = 109,
|
||||
opc_fdiv = 110,
|
||||
opc_ddiv = 111,
|
||||
opc_irem = 112,
|
||||
opc_lrem = 113,
|
||||
opc_frem = 114,
|
||||
opc_drem = 115,
|
||||
opc_ineg = 116,
|
||||
opc_lneg = 117,
|
||||
opc_fneg = 118,
|
||||
opc_dneg = 119,
|
||||
opc_ishl = 120,
|
||||
opc_lshl = 121,
|
||||
opc_ishr = 122,
|
||||
opc_lshr = 123,
|
||||
opc_iushr = 124,
|
||||
opc_lushr = 125,
|
||||
opc_iand = 126,
|
||||
opc_land = 127,
|
||||
opc_ior = 128,
|
||||
opc_lor = 129,
|
||||
opc_ixor = 130,
|
||||
opc_lxor = 131,
|
||||
opc_iinc = 132,
|
||||
opc_i2l = 133,
|
||||
opc_i2f = 134,
|
||||
opc_i2d = 135,
|
||||
opc_l2i = 136,
|
||||
opc_l2f = 137,
|
||||
opc_l2d = 138,
|
||||
opc_f2i = 139,
|
||||
opc_f2l = 140,
|
||||
opc_f2d = 141,
|
||||
opc_d2i = 142,
|
||||
opc_d2l = 143,
|
||||
opc_d2f = 144,
|
||||
opc_i2b = 145,
|
||||
opc_i2c = 146,
|
||||
opc_i2s = 147,
|
||||
opc_lcmp = 148,
|
||||
opc_fcmpl = 149,
|
||||
opc_fcmpg = 150,
|
||||
opc_dcmpl = 151,
|
||||
opc_dcmpg = 152,
|
||||
opc_ifeq = 153,
|
||||
opc_ifne = 154,
|
||||
opc_iflt = 155,
|
||||
opc_ifge = 156,
|
||||
opc_ifgt = 157,
|
||||
opc_ifle = 158,
|
||||
opc_if_icmpeq = 159,
|
||||
opc_if_icmpne = 160,
|
||||
opc_if_icmplt = 161,
|
||||
opc_if_icmpge = 162,
|
||||
opc_if_icmpgt = 163,
|
||||
opc_if_icmple = 164,
|
||||
opc_if_acmpeq = 165,
|
||||
opc_if_acmpne = 166,
|
||||
opc_goto = 167,
|
||||
opc_jsr = 168,
|
||||
opc_ret = 169,
|
||||
opc_tableswitch = 170,
|
||||
opc_lookupswitch = 171,
|
||||
opc_ireturn = 172,
|
||||
opc_lreturn = 173,
|
||||
opc_freturn = 174,
|
||||
opc_dreturn = 175,
|
||||
opc_areturn = 176,
|
||||
opc_return = 177,
|
||||
opc_getstatic = 178,
|
||||
opc_putstatic = 179,
|
||||
opc_getfield = 180,
|
||||
opc_putfield = 181,
|
||||
opc_invokevirtual = 182,
|
||||
opc_invokespecial = 183,
|
||||
opc_invokestatic = 184,
|
||||
opc_invokeinterface = 185,
|
||||
opc_invokedynamic = 186,
|
||||
opc_new = 187,
|
||||
opc_newarray = 188,
|
||||
opc_anewarray = 189,
|
||||
opc_arraylength = 190,
|
||||
opc_athrow = 191,
|
||||
opc_checkcast = 192,
|
||||
opc_instanceof = 193,
|
||||
opc_monitorenter = 194,
|
||||
opc_monitorexit = 195,
|
||||
opc_wide = 196,
|
||||
opc_multianewarray = 197,
|
||||
opc_ifnull = 198,
|
||||
opc_ifnonnull = 199,
|
||||
opc_goto_w = 200,
|
||||
opc_jsr_w = 201,
|
||||
opc_breakpoint = 202
|
||||
};
|
||||
|
||||
enum {
|
||||
BCI_MODE_EMCP = 0,
|
||||
BCI_MODE_CALL = 1,
|
||||
BCI_MODE_ALLOC = 2
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Class file transformer. Transforms a classfile image from old_bytes
|
||||
* to a new classfile image new_bytes according to value of bci_mode.
|
||||
* The new classfile image is allocated with malloc(), and should be
|
||||
* freed by the caller. The possible bci_mode values:
|
||||
*
|
||||
* BCI_MODE_EMCP
|
||||
* dummy, without injection any bytecodes
|
||||
*
|
||||
* BCI_MODE_CALL
|
||||
* inject invokestatic call to ProfileCollector.callTracker()
|
||||
* at the beginning of all methods
|
||||
*
|
||||
* BCI_MODE_ALLOC
|
||||
* inject invokestatic call to ProfileCollector.allocTracker()
|
||||
* immediately following new/newarray opcodes.
|
||||
*
|
||||
*/
|
||||
|
||||
int Inject(const u1* old_bytes, const jint old_length,
|
||||
u1** new_bytes, jint* new_length, int bci_mode);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _NSK_SHARE_JVMTI_INJECTOR_H_ */
|
331
test/hotspot/jtreg/vmTestbase/nsk/share/jvmti/JVMTITools.c
Normal file
331
test/hotspot/jtreg/vmTestbase/nsk/share/jvmti/JVMTITools.c
Normal file
@ -0,0 +1,331 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "JVMTITools.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
const char* TranslateState(jint flags) {
|
||||
static char str[15 * 20];
|
||||
|
||||
if (flags == 0)
|
||||
return "<none>";
|
||||
|
||||
str[0] = '\0';
|
||||
|
||||
if (flags & JVMTI_THREAD_STATE_ALIVE) {
|
||||
strcat(str, " ALIVE");
|
||||
}
|
||||
|
||||
if (flags & JVMTI_THREAD_STATE_TERMINATED) {
|
||||
strcat(str, " TERMINATED");
|
||||
}
|
||||
|
||||
if (flags & JVMTI_THREAD_STATE_RUNNABLE) {
|
||||
strcat(str, " RUNNABLE");
|
||||
}
|
||||
|
||||
if (flags & JVMTI_THREAD_STATE_WAITING) {
|
||||
strcat(str, " WAITING");
|
||||
}
|
||||
|
||||
if (flags & JVMTI_THREAD_STATE_WAITING_INDEFINITELY) {
|
||||
strcat(str, " WAITING_INDEFINITELY");
|
||||
}
|
||||
|
||||
if (flags & JVMTI_THREAD_STATE_WAITING_WITH_TIMEOUT) {
|
||||
strcat(str, " WAITING_WITH_TIMEOUT");
|
||||
}
|
||||
|
||||
if (flags & JVMTI_THREAD_STATE_SLEEPING) {
|
||||
strcat(str, " SLEEPING");
|
||||
}
|
||||
|
||||
if (flags & JVMTI_THREAD_STATE_IN_OBJECT_WAIT) {
|
||||
strcat(str, " IN_OBJECT_WAIT");
|
||||
}
|
||||
|
||||
if (flags & JVMTI_THREAD_STATE_PARKED) {
|
||||
strcat(str, " PARKED");
|
||||
}
|
||||
|
||||
if (flags & JVMTI_THREAD_STATE_BLOCKED_ON_MONITOR_ENTER) {
|
||||
strcat(str, " BLOCKED_ON_MONITOR_ENTER");
|
||||
}
|
||||
|
||||
if (flags & JVMTI_THREAD_STATE_SUSPENDED) {
|
||||
strcat(str, " SUSPENDED");
|
||||
}
|
||||
|
||||
if (flags & JVMTI_THREAD_STATE_INTERRUPTED) {
|
||||
strcat(str, " INTERRUPTED");
|
||||
}
|
||||
|
||||
if (flags & JVMTI_THREAD_STATE_IN_NATIVE) {
|
||||
strcat(str, " IN_NATIVE");
|
||||
}
|
||||
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
const char* TranslateEvent(jvmtiEvent event_type) {
|
||||
switch (event_type) {
|
||||
case JVMTI_EVENT_VM_INIT:
|
||||
return ("JVMTI_EVENT_VM_INIT");
|
||||
case JVMTI_EVENT_VM_DEATH:
|
||||
return ("JVMTI_EVENT_VM_DEATH");
|
||||
case JVMTI_EVENT_THREAD_START:
|
||||
return ("JVMTI_EVENT_THREAD_START");
|
||||
case JVMTI_EVENT_THREAD_END:
|
||||
return ("JVMTI_EVENT_THREAD_END");
|
||||
case JVMTI_EVENT_CLASS_FILE_LOAD_HOOK:
|
||||
return ("JVMTI_EVENT_CLASS_FILE_LOAD_HOOK");
|
||||
case JVMTI_EVENT_CLASS_LOAD:
|
||||
return ("JVMTI_EVENT_CLASS_LOAD");
|
||||
case JVMTI_EVENT_CLASS_PREPARE:
|
||||
return ("JVMTI_EVENT_CLASS_PREPARE");
|
||||
case JVMTI_EVENT_VM_START:
|
||||
return ("JVMTI_EVENT_VM_START");
|
||||
case JVMTI_EVENT_EXCEPTION:
|
||||
return ("JVMTI_EVENT_EXCEPTION");
|
||||
case JVMTI_EVENT_EXCEPTION_CATCH:
|
||||
return ("JVMTI_EVENT_EXCEPTION_CATCH");
|
||||
case JVMTI_EVENT_SINGLE_STEP:
|
||||
return ("JVMTI_EVENT_SINGLE_STEP");
|
||||
case JVMTI_EVENT_FRAME_POP:
|
||||
return ("JVMTI_EVENT_FRAME_POP");
|
||||
case JVMTI_EVENT_BREAKPOINT:
|
||||
return ("JVMTI_EVENT_BREAKPOINT");
|
||||
case JVMTI_EVENT_FIELD_ACCESS:
|
||||
return ("JVMTI_EVENT_FIELD_ACCESS");
|
||||
case JVMTI_EVENT_FIELD_MODIFICATION:
|
||||
return ("JVMTI_EVENT_FIELD_MODIFICATION");
|
||||
case JVMTI_EVENT_METHOD_ENTRY:
|
||||
return ("JVMTI_EVENT_METHOD_ENTRY");
|
||||
case JVMTI_EVENT_METHOD_EXIT:
|
||||
return ("JVMTI_EVENT_METHOD_EXIT");
|
||||
case JVMTI_EVENT_NATIVE_METHOD_BIND:
|
||||
return ("JVMTI_EVENT_NATIVE_METHOD_BIND");
|
||||
case JVMTI_EVENT_COMPILED_METHOD_LOAD:
|
||||
return ("JVMTI_EVENT_COMPILED_METHOD_LOAD");
|
||||
case JVMTI_EVENT_COMPILED_METHOD_UNLOAD:
|
||||
return ("JVMTI_EVENT_COMPILED_METHOD_UNLOAD");
|
||||
case JVMTI_EVENT_DYNAMIC_CODE_GENERATED:
|
||||
return ("JVMTI_EVENT_DYNAMIC_CODE_GENERATED");
|
||||
case JVMTI_EVENT_DATA_DUMP_REQUEST:
|
||||
return ("JVMTI_EVENT_DATA_DUMP_REQUEST");
|
||||
case JVMTI_EVENT_MONITOR_WAIT:
|
||||
return ("JVMTI_EVENT_MONITOR_WAIT");
|
||||
case JVMTI_EVENT_MONITOR_WAITED:
|
||||
return ("JVMTI_EVENT_MONITOR_WAITED");
|
||||
case JVMTI_EVENT_MONITOR_CONTENDED_ENTER:
|
||||
return ("JVMTI_EVENT_MONITOR_CONTENDED_ENTER");
|
||||
case JVMTI_EVENT_MONITOR_CONTENDED_ENTERED:
|
||||
return ("JVMTI_EVENT_MONITOR_CONTENDED_ENTERED");
|
||||
case JVMTI_EVENT_GARBAGE_COLLECTION_START:
|
||||
return ("JVMTI_EVENT_GARBAGE_COLLECTION_START");
|
||||
case JVMTI_EVENT_GARBAGE_COLLECTION_FINISH:
|
||||
return ("JVMTI_EVENT_GARBAGE_COLLECTION_FINISH");
|
||||
case JVMTI_EVENT_OBJECT_FREE:
|
||||
return ("JVMTI_EVENT_OBJECT_FREE");
|
||||
case JVMTI_EVENT_VM_OBJECT_ALLOC:
|
||||
return ("JVMTI_EVENT_VM_OBJECT_ALLOC");
|
||||
default:
|
||||
return ("<unknown event>");
|
||||
}
|
||||
}
|
||||
|
||||
const char* TranslateError(jvmtiError err) {
|
||||
switch (err) {
|
||||
case JVMTI_ERROR_NONE:
|
||||
return ("JVMTI_ERROR_NONE");
|
||||
case JVMTI_ERROR_INVALID_THREAD:
|
||||
return ("JVMTI_ERROR_INVALID_THREAD");
|
||||
case JVMTI_ERROR_INVALID_THREAD_GROUP:
|
||||
return ("JVMTI_ERROR_INVALID_THREAD_GROUP");
|
||||
case JVMTI_ERROR_INVALID_PRIORITY:
|
||||
return ("JVMTI_ERROR_INVALID_PRIORITY");
|
||||
case JVMTI_ERROR_THREAD_NOT_SUSPENDED:
|
||||
return ("JVMTI_ERROR_THREAD_NOT_SUSPENDED");
|
||||
case JVMTI_ERROR_THREAD_SUSPENDED:
|
||||
return ("JVMTI_ERROR_THREAD_SUSPENDED");
|
||||
case JVMTI_ERROR_THREAD_NOT_ALIVE:
|
||||
return ("JVMTI_ERROR_THREAD_NOT_ALIVE");
|
||||
case JVMTI_ERROR_INVALID_OBJECT:
|
||||
return ("JVMTI_ERROR_INVALID_OBJECT");
|
||||
case JVMTI_ERROR_INVALID_CLASS:
|
||||
return ("JVMTI_ERROR_INVALID_CLASS");
|
||||
case JVMTI_ERROR_CLASS_NOT_PREPARED:
|
||||
return ("JVMTI_ERROR_CLASS_NOT_PREPARED");
|
||||
case JVMTI_ERROR_INVALID_METHODID:
|
||||
return ("JVMTI_ERROR_INVALID_METHODID");
|
||||
case JVMTI_ERROR_INVALID_LOCATION:
|
||||
return ("JVMTI_ERROR_INVALID_LOCATION");
|
||||
case JVMTI_ERROR_INVALID_FIELDID:
|
||||
return ("JVMTI_ERROR_INVALID_FIELDID");
|
||||
case JVMTI_ERROR_NO_MORE_FRAMES:
|
||||
return ("JVMTI_ERROR_NO_MORE_FRAMES");
|
||||
case JVMTI_ERROR_OPAQUE_FRAME:
|
||||
return ("JVMTI_ERROR_OPAQUE_FRAME");
|
||||
case JVMTI_ERROR_TYPE_MISMATCH:
|
||||
return ("JVMTI_ERROR_TYPE_MISMATCH");
|
||||
case JVMTI_ERROR_INVALID_SLOT:
|
||||
return ("JVMTI_ERROR_INVALID_SLOT");
|
||||
case JVMTI_ERROR_DUPLICATE:
|
||||
return ("JVMTI_ERROR_DUPLICATE");
|
||||
case JVMTI_ERROR_NOT_FOUND:
|
||||
return ("JVMTI_ERROR_NOT_FOUND");
|
||||
case JVMTI_ERROR_INVALID_MONITOR:
|
||||
return ("JVMTI_ERROR_INVALID_MONITOR");
|
||||
case JVMTI_ERROR_NOT_MONITOR_OWNER:
|
||||
return ("JVMTI_ERROR_NOT_MONITOR_OWNER");
|
||||
case JVMTI_ERROR_INTERRUPT:
|
||||
return ("JVMTI_ERROR_INTERRUPT");
|
||||
case JVMTI_ERROR_INVALID_CLASS_FORMAT:
|
||||
return ("JVMTI_ERROR_INVALID_CLASS_FORMAT");
|
||||
case JVMTI_ERROR_CIRCULAR_CLASS_DEFINITION:
|
||||
return ("JVMTI_ERROR_CIRCULAR_CLASS_DEFINITION");
|
||||
case JVMTI_ERROR_FAILS_VERIFICATION:
|
||||
return ("JVMTI_ERROR_FAILS_VERIFICATION");
|
||||
case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_ADDED:
|
||||
return ("JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_ADDED");
|
||||
case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_SCHEMA_CHANGED:
|
||||
return ("JVMTI_ERROR_UNSUPPORTED_REDEFINITION_SCHEMA_CHANGED");
|
||||
case JVMTI_ERROR_INVALID_TYPESTATE:
|
||||
return ("JVMTI_ERROR_INVALID_TYPESTATE");
|
||||
case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_HIERARCHY_CHANGED:
|
||||
return ("JVMTI_ERROR_UNSUPPORTED_REDEFINITION_HIERARCHY_CHANGED");
|
||||
case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_DELETED:
|
||||
return ("JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_DELETED");
|
||||
case JVMTI_ERROR_UNSUPPORTED_VERSION:
|
||||
return ("JVMTI_ERROR_UNSUPPORTED_VERSION");
|
||||
case JVMTI_ERROR_NAMES_DONT_MATCH:
|
||||
return ("JVMTI_ERROR_NAMES_DONT_MATCH");
|
||||
case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_CLASS_MODIFIERS_CHANGED:
|
||||
return ("JVMTI_ERROR_UNSUPPORTED_REDEFINITION_CLASS_MODIFIERS_CHANGED");
|
||||
case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_MODIFIERS_CHANGED:
|
||||
return ("JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_MODIFIERS_CHANGED");
|
||||
case JVMTI_ERROR_UNMODIFIABLE_CLASS:
|
||||
return ("JVMTI_ERROR_UNMODIFIABLE_CLASS");
|
||||
case JVMTI_ERROR_NOT_AVAILABLE:
|
||||
return ("JVMTI_ERROR_NOT_AVAILABLE");
|
||||
case JVMTI_ERROR_MUST_POSSESS_CAPABILITY:
|
||||
return ("JVMTI_ERROR_MUST_POSSESS_CAPABILITY");
|
||||
case JVMTI_ERROR_NULL_POINTER:
|
||||
return ("JVMTI_ERROR_NULL_POINTER");
|
||||
case JVMTI_ERROR_ABSENT_INFORMATION:
|
||||
return ("JVMTI_ERROR_ABSENT_INFORMATION");
|
||||
case JVMTI_ERROR_INVALID_EVENT_TYPE:
|
||||
return ("JVMTI_ERROR_INVALID_EVENT_TYPE");
|
||||
case JVMTI_ERROR_ILLEGAL_ARGUMENT:
|
||||
return ("JVMTI_ERROR_ILLEGAL_ARGUMENT");
|
||||
case JVMTI_ERROR_NATIVE_METHOD:
|
||||
return ("JVMTI_ERROR_NATIVE_METHOD");
|
||||
case JVMTI_ERROR_OUT_OF_MEMORY:
|
||||
return ("JVMTI_ERROR_OUT_OF_MEMORY");
|
||||
case JVMTI_ERROR_ACCESS_DENIED:
|
||||
return ("JVMTI_ERROR_ACCESS_DENIED");
|
||||
case JVMTI_ERROR_WRONG_PHASE:
|
||||
return ("JVMTI_ERROR_WRONG_PHASE");
|
||||
case JVMTI_ERROR_INTERNAL:
|
||||
return ("JVMTI_ERROR_INTERNAL");
|
||||
case JVMTI_ERROR_UNATTACHED_THREAD:
|
||||
return ("JVMTI_ERROR_UNATTACHED_THREAD");
|
||||
case JVMTI_ERROR_INVALID_ENVIRONMENT:
|
||||
return ("JVMTI_ERROR_INVALID_ENVIRONMENT");
|
||||
default:
|
||||
return ("<unknown error>");
|
||||
}
|
||||
}
|
||||
|
||||
const char* TranslatePhase(jvmtiPhase phase) {
|
||||
switch (phase) {
|
||||
case JVMTI_PHASE_ONLOAD:
|
||||
return ("JVMTI_PHASE_ONLOAD");
|
||||
case JVMTI_PHASE_PRIMORDIAL:
|
||||
return ("JVMTI_PHASE_PRIMORDIAL");
|
||||
case JVMTI_PHASE_START:
|
||||
return ("JVMTI_PHASE_START");
|
||||
case JVMTI_PHASE_LIVE:
|
||||
return ("JVMTI_PHASE_LIVE");
|
||||
case JVMTI_PHASE_DEAD:
|
||||
return ("JVMTI_PHASE_DEAD");
|
||||
default:
|
||||
return ("<unknown phase>");
|
||||
}
|
||||
}
|
||||
|
||||
const char* TranslateRootKind(jvmtiHeapRootKind root) {
|
||||
switch (root) {
|
||||
case JVMTI_HEAP_ROOT_JNI_GLOBAL:
|
||||
return ("JVMTI_HEAP_ROOT_JNI_GLOBAL");
|
||||
case JVMTI_HEAP_ROOT_JNI_LOCAL:
|
||||
return ("JVMTI_HEAP_ROOT_JNI_LOCAL");
|
||||
case JVMTI_HEAP_ROOT_SYSTEM_CLASS:
|
||||
return ("JVMTI_HEAP_ROOT_SYSTEM_CLASS");
|
||||
case JVMTI_HEAP_ROOT_MONITOR:
|
||||
return ("JVMTI_HEAP_ROOT_MONITOR");
|
||||
case JVMTI_HEAP_ROOT_STACK_LOCAL:
|
||||
return ("JVMTI_HEAP_ROOT_STACK_LOCAL");
|
||||
case JVMTI_HEAP_ROOT_THREAD:
|
||||
return ("JVMTI_HEAP_ROOT_THREAD");
|
||||
case JVMTI_HEAP_ROOT_OTHER:
|
||||
return ("JVMTI_HEAP_ROOT_OTHER");
|
||||
default:
|
||||
return ("<unknown root kind>");
|
||||
}
|
||||
}
|
||||
|
||||
const char* TranslateObjectRefKind(jvmtiObjectReferenceKind ref) {
|
||||
switch (ref) {
|
||||
case JVMTI_REFERENCE_CLASS:
|
||||
return ("JVMTI_REFERENCE_CLASS");
|
||||
case JVMTI_REFERENCE_FIELD:
|
||||
return ("JVMTI_REFERENCE_FIELD");
|
||||
case JVMTI_REFERENCE_ARRAY_ELEMENT:
|
||||
return ("JVMTI_REFERENCE_ARRAY_ELEMENT");
|
||||
case JVMTI_REFERENCE_CLASS_LOADER:
|
||||
return ("JVMTI_REFERENCE_CLASS_LOADER");
|
||||
case JVMTI_REFERENCE_SIGNERS:
|
||||
return ("JVMTI_REFERENCE_SIGNERS");
|
||||
case JVMTI_REFERENCE_PROTECTION_DOMAIN:
|
||||
return ("JVMTI_REFERENCE_PROTECTION_DOMAIN");
|
||||
case JVMTI_REFERENCE_INTERFACE:
|
||||
return ("JVMTI_REFERENCE_INTERFACE");
|
||||
case JVMTI_REFERENCE_STATIC_FIELD:
|
||||
return ("JVMTI_REFERENCE_STATIC_FIELD");
|
||||
case JVMTI_REFERENCE_CONSTANT_POOL:
|
||||
return ("JVMTI_REFERENCE_CONSTANT_POOL");
|
||||
default:
|
||||
return ("<unknown reference kind>");
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
67
test/hotspot/jtreg/vmTestbase/nsk/share/jvmti/JVMTITools.h
Normal file
67
test/hotspot/jtreg/vmTestbase/nsk/share/jvmti/JVMTITools.h
Normal file
@ -0,0 +1,67 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
#ifndef _NSK_SHARE_JVMTI_JVMTITOOLS_H_
|
||||
#define _NSK_SHARE_JVMTI_JVMTITOOLS_H_
|
||||
|
||||
#include "jvmti.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Return string representation of given JVMTI event constant.
|
||||
*/
|
||||
const char* TranslateEvent(jvmtiEvent event_type);
|
||||
|
||||
/**
|
||||
* Return string representation of given JVMTI thread state constant.
|
||||
*/
|
||||
const char* TranslateState(jint flags);
|
||||
|
||||
/**
|
||||
* Return string representation of given JVMTI error code.
|
||||
*/
|
||||
const char* TranslateError(jvmtiError err);
|
||||
|
||||
/**
|
||||
* Return string representation of given phase of VM execution.
|
||||
*/
|
||||
const char* TranslatePhase(jvmtiPhase phase);
|
||||
|
||||
/**
|
||||
* Return string representation of given heap root kind.
|
||||
*/
|
||||
const char* TranslateRootKind(jvmtiHeapRootKind root);
|
||||
|
||||
/**
|
||||
* Return string representation of given heap root kind.
|
||||
*/
|
||||
const char* TranslateObjectRefKind(jvmtiObjectReferenceKind ref);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _NSK_SHARE_JVMTI_JVMTITOOLS_H_ */
|
@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright (c) 2008, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
#include "jvmti.h"
|
||||
#include "agent_common.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
JNIEXPORT jint JNICALL Agent_OnLoad(JavaVM *jvm, char *options, void *reserved) {
|
||||
return Agent_Initialize(jvm, options, reserved);
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL Agent_OnAttach(JavaVM *jvm, char *options, void *reserved) {
|
||||
return Agent_Initialize(jvm, options, reserved);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright (c) 2008, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
#ifndef NSK_JVMTI_AGENT_COMMON_DEFINED
|
||||
#define NSK_JVMTI_AGENT_COMMON_DEFINED
|
||||
|
||||
#include "jvmti.h"
|
||||
#include "../jvmti_tools.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
JNIEXPORT jint JNICALL Agent_OnLoad(JavaVM *jvm, char *options, void *reserved);
|
||||
|
||||
JNIEXPORT jint JNICALL Agent_OnAttach(JavaVM *jvm, char *options, void *reserved);
|
||||
|
||||
jint Agent_Initialize(JavaVM *vm, char *options, void *reserved);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
815
test/hotspot/jtreg/vmTestbase/nsk/share/jvmti/agent_tools.c
Normal file
815
test/hotspot/jtreg/vmTestbase/nsk/share/jvmti/agent_tools.c
Normal file
@ -0,0 +1,815 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "native_thread.h"
|
||||
#include "jni_tools.h"
|
||||
#include "jvmti_tools.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* ============================================================================= */
|
||||
|
||||
/* Be careful: do not build shared library which will be linked with different
|
||||
* agent libs while global variables are used
|
||||
* Now the same source is used to build different agent libs, so these
|
||||
* variables are not shared between agents */
|
||||
|
||||
static jthread agentThread = NULL;
|
||||
static jvmtiStartFunction agentThreadProc = NULL;
|
||||
static void* agentThreadArg = NULL;
|
||||
|
||||
|
||||
typedef enum {NEW, RUNNABLE, WAITING, SUSPENDED, TERMINATED} thread_state_t;
|
||||
|
||||
typedef struct agent_data_t {
|
||||
volatile thread_state_t thread_state;
|
||||
int last_debuggee_status;
|
||||
jrawMonitorID monitor;
|
||||
} agent_data_t;
|
||||
|
||||
static agent_data_t agent_data;
|
||||
|
||||
static jvmtiEnv* jvmti_env = NULL;
|
||||
static JavaVM* jvm = NULL;
|
||||
static JNIEnv* jni_env = NULL;
|
||||
|
||||
static volatile int currentAgentStatus = NSK_STATUS_PASSED;
|
||||
|
||||
/* ============================================================================= */
|
||||
|
||||
void nsk_jvmti_setFailStatus() {
|
||||
currentAgentStatus = NSK_STATUS_FAILED;
|
||||
}
|
||||
|
||||
int nsk_jvmti_isFailStatus() {
|
||||
return (nsk_jvmti_getStatus() != NSK_STATUS_PASSED);
|
||||
}
|
||||
|
||||
jint nsk_jvmti_getStatus() {
|
||||
return currentAgentStatus;
|
||||
}
|
||||
|
||||
/* ============================================================================= */
|
||||
static jvmtiError init_agent_data(jvmtiEnv *jvmti_env, agent_data_t *data) {
|
||||
data->thread_state = NEW;
|
||||
data->last_debuggee_status = NSK_STATUS_PASSED;
|
||||
|
||||
return NSK_CPP_STUB3(CreateRawMonitor, jvmti_env, "agent_data_monitor", &data->monitor);
|
||||
}
|
||||
|
||||
/** Reset agent data to prepare for another run. */
|
||||
void nsk_jvmti_resetAgentData() {
|
||||
rawMonitorEnter(jvmti_env, agent_data.monitor);
|
||||
/* wait for agentThreadWrapper() to finish */
|
||||
while (agent_data.thread_state != TERMINATED) {
|
||||
rawMonitorWait(jvmti_env, agent_data.monitor, 10);
|
||||
}
|
||||
agent_data.thread_state = NEW;
|
||||
agent_data.last_debuggee_status = NSK_STATUS_PASSED;
|
||||
rawMonitorExit(jvmti_env, agent_data.monitor);
|
||||
}
|
||||
|
||||
static jvmtiError free_agent_data(jvmtiEnv *jvmti_env, agent_data_t *data) {
|
||||
return NSK_CPP_STUB2(DestroyRawMonitor, jvmti_env, data->monitor);
|
||||
}
|
||||
|
||||
/** Create JVMTI environment. */
|
||||
jvmtiEnv* nsk_jvmti_createJVMTIEnv(JavaVM* javaVM, void* reserved) {
|
||||
jvm = javaVM;
|
||||
if (!NSK_VERIFY(
|
||||
NSK_CPP_STUB3(GetEnv, javaVM, (void **)&jvmti_env, JVMTI_VERSION_1_1) == JNI_OK)) {
|
||||
nsk_jvmti_setFailStatus();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!NSK_JVMTI_VERIFY(init_agent_data(jvmti_env, &agent_data))) {
|
||||
nsk_jvmti_setFailStatus();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return jvmti_env;
|
||||
}
|
||||
|
||||
/** Dispose JVMTI environment */
|
||||
static int nsk_jvmti_disposeJVMTIEnv(jvmtiEnv* jvmti_env) {
|
||||
if (jvmti_env != NULL) {
|
||||
if (!NSK_JVMTI_VERIFY(
|
||||
NSK_CPP_STUB1(DisposeEnvironment, jvmti_env))) {
|
||||
nsk_jvmti_setFailStatus();
|
||||
return NSK_FALSE;
|
||||
}
|
||||
|
||||
if (!NSK_JVMTI_VERIFY(free_agent_data(jvmti_env, &agent_data))) {
|
||||
nsk_jvmti_setFailStatus();
|
||||
return NSK_FALSE;
|
||||
}
|
||||
}
|
||||
return NSK_TRUE;
|
||||
}
|
||||
|
||||
/** Get JNI environment for agent thread. */
|
||||
JNIEnv* nsk_jvmti_getAgentJNIEnv() {
|
||||
return jni_env;
|
||||
}
|
||||
|
||||
/** Get JVMTI environment for agent */
|
||||
jvmtiEnv* nsk_jvmti_getAgentJVMTIEnv() {
|
||||
return jvmti_env;
|
||||
}
|
||||
|
||||
/* ============================================================================= */
|
||||
static void set_agent_thread_state(thread_state_t value) {
|
||||
rawMonitorEnter(jvmti_env, agent_data.monitor);
|
||||
agent_data.thread_state = value;
|
||||
rawMonitorNotify(jvmti_env, agent_data.monitor);
|
||||
rawMonitorExit(jvmti_env, agent_data.monitor);
|
||||
}
|
||||
|
||||
/** Wrapper for user agent thread. */
|
||||
static void JNICALL
|
||||
agentThreadWrapper(jvmtiEnv* jvmti_env, JNIEnv* agentJNI, void* arg) {
|
||||
jni_env = agentJNI;
|
||||
|
||||
/* run user agent proc */
|
||||
{
|
||||
set_agent_thread_state(RUNNABLE);
|
||||
|
||||
NSK_TRACE((*agentThreadProc)(jvmti_env, agentJNI, agentThreadArg));
|
||||
|
||||
set_agent_thread_state(TERMINATED);
|
||||
}
|
||||
|
||||
/* finalize agent thread */
|
||||
{
|
||||
/* gelete global ref for agent thread */
|
||||
NSK_CPP_STUB2(DeleteGlobalRef, agentJNI, agentThread);
|
||||
agentThread = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/** Start wrapper for user agent thread. */
|
||||
static jthread startAgentThreadWrapper(JNIEnv *jni_env, jvmtiEnv* jvmti_env) {
|
||||
const jint THREAD_PRIORITY = JVMTI_THREAD_MAX_PRIORITY;
|
||||
const char* THREAD_NAME = "JVMTI agent thread";
|
||||
const char* THREAD_CLASS_NAME = "java/lang/Thread";
|
||||
const char* THREAD_CTOR_NAME = "<init>";
|
||||
const char* THREAD_CTOR_SIGNATURE = "(Ljava/lang/String;)V";
|
||||
|
||||
jobject threadName = NULL;
|
||||
jclass threadClass = NULL;
|
||||
jmethodID threadCtor = NULL;
|
||||
jobject threadObject = NULL;
|
||||
jobject threadGlobalRef = NULL;
|
||||
|
||||
if (!NSK_JNI_VERIFY(jni_env, (threadClass =
|
||||
NSK_CPP_STUB2(FindClass, jni_env, THREAD_CLASS_NAME)) != NULL)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!NSK_JNI_VERIFY(jni_env, (threadCtor =
|
||||
NSK_CPP_STUB4(GetMethodID, jni_env, threadClass, THREAD_CTOR_NAME, THREAD_CTOR_SIGNATURE)) != NULL))
|
||||
return NULL;
|
||||
|
||||
if (!NSK_JNI_VERIFY(jni_env, (threadName =
|
||||
NSK_CPP_STUB2(NewStringUTF, jni_env, THREAD_NAME)) != NULL))
|
||||
return NULL;
|
||||
|
||||
if (!NSK_JNI_VERIFY(jni_env, (threadObject =
|
||||
NSK_CPP_STUB4(NewObject, jni_env, threadClass, threadCtor, threadName)) != NULL))
|
||||
return NULL;
|
||||
|
||||
if (!NSK_JNI_VERIFY(jni_env, (threadGlobalRef =
|
||||
NSK_CPP_STUB2(NewGlobalRef, jni_env, threadObject)) != NULL)) {
|
||||
NSK_CPP_STUB2(DeleteLocalRef, jni_env, threadObject);
|
||||
return NULL;
|
||||
}
|
||||
agentThread = (jthread)threadGlobalRef;
|
||||
|
||||
if (!NSK_JVMTI_VERIFY(
|
||||
NSK_CPP_STUB5(RunAgentThread, jvmti_env, agentThread,
|
||||
&agentThreadWrapper, agentThreadArg, THREAD_PRIORITY))) {
|
||||
NSK_CPP_STUB2(DeleteGlobalRef, jni_env, threadGlobalRef);
|
||||
NSK_CPP_STUB2(DeleteLocalRef, jni_env, threadObject);
|
||||
return NULL;
|
||||
}
|
||||
return agentThread;
|
||||
}
|
||||
|
||||
/** Register user agent thread with arg. */
|
||||
int nsk_jvmti_setAgentProc(jvmtiStartFunction proc, void* arg) {
|
||||
agentThreadProc = proc;
|
||||
agentThreadArg = arg;
|
||||
return NSK_TRUE;
|
||||
}
|
||||
|
||||
/** Get agent thread ref. */
|
||||
jthread nsk_jvmti_getAgentThread() {
|
||||
return agentThread;
|
||||
}
|
||||
|
||||
/** Run registered user agent thread via wrapper. */
|
||||
static jthread nsk_jvmti_runAgentThread(JNIEnv *jni_env, jvmtiEnv* jvmti_env) {
|
||||
/* start agent thread wrapper */
|
||||
jthread thread = startAgentThreadWrapper(jni_env, jvmti_env);
|
||||
if (thread == NULL) {
|
||||
nsk_jvmti_setFailStatus();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return thread;
|
||||
}
|
||||
|
||||
/* ============================================================================= */
|
||||
|
||||
/** Sleep current thread. */
|
||||
void nsk_jvmti_sleep(jlong timeout) {
|
||||
int seconds = (int)((timeout + 999) / 1000);
|
||||
THREAD_sleep(seconds);
|
||||
}
|
||||
|
||||
/** Sync point called from Java code. */
|
||||
static jint syncDebuggeeStatus(JNIEnv* jni_env, jvmtiEnv* jvmti_env, jint debuggeeStatus) {
|
||||
jint result = NSK_STATUS_FAILED;
|
||||
|
||||
rawMonitorEnter(jvmti_env, agent_data.monitor);
|
||||
|
||||
/* save last debugee status */
|
||||
agent_data.last_debuggee_status = debuggeeStatus;
|
||||
|
||||
/* we don't enter if-stmt in second call */
|
||||
if (agent_data.thread_state == NEW) {
|
||||
if (nsk_jvmti_runAgentThread(jni_env, jvmti_env) == NULL)
|
||||
goto monitor_exit_and_return;
|
||||
|
||||
/* SP2.2-w - wait for agent thread */
|
||||
while (agent_data.thread_state == NEW) {
|
||||
rawMonitorWait(jvmti_env, agent_data.monitor, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/* wait for sync permit */
|
||||
/* we don't enter loop in first call */
|
||||
while (agent_data.thread_state != WAITING && agent_data.thread_state != TERMINATED) {
|
||||
/* SP4.2-w - second wait for agent thread */
|
||||
rawMonitorWait(jvmti_env, agent_data.monitor, 0);
|
||||
}
|
||||
|
||||
if (agent_data.thread_state != TERMINATED) {
|
||||
agent_data.thread_state = SUSPENDED;
|
||||
/* SP3.2-n - notify to start test */
|
||||
/* SP6.2-n - notify to end test */
|
||||
rawMonitorNotify(jvmti_env, agent_data.monitor);
|
||||
}
|
||||
else {
|
||||
NSK_COMPLAIN0("Debuggee status sync aborted because agent thread has finished\n");
|
||||
goto monitor_exit_and_return;
|
||||
}
|
||||
|
||||
/* update status from debuggee */
|
||||
if (debuggeeStatus != NSK_STATUS_PASSED) {
|
||||
nsk_jvmti_setFailStatus();
|
||||
}
|
||||
|
||||
while (agent_data.thread_state == SUSPENDED) {
|
||||
/* SP5.2-w - wait while testing */
|
||||
/* SP7.2 - wait for agent end */
|
||||
rawMonitorWait(jvmti_env, agent_data.monitor, 0);
|
||||
}
|
||||
|
||||
agent_data.last_debuggee_status = nsk_jvmti_getStatus();
|
||||
result = agent_data.last_debuggee_status;
|
||||
|
||||
monitor_exit_and_return:
|
||||
rawMonitorExit(jvmti_env, agent_data.monitor);
|
||||
return result;
|
||||
}
|
||||
|
||||
/** Wait for sync point with Java code. */
|
||||
int nsk_jvmti_waitForSync(jlong timeout) {
|
||||
static const int inc_timeout = 1000;
|
||||
|
||||
jlong t = 0;
|
||||
int result = NSK_TRUE;
|
||||
|
||||
rawMonitorEnter(jvmti_env, agent_data.monitor);
|
||||
|
||||
agent_data.thread_state = WAITING;
|
||||
|
||||
/* SP2.2-n - notify agent is waiting and wait */
|
||||
/* SP4.1-n - notify agent is waiting and wait */
|
||||
rawMonitorNotify(jvmti_env, agent_data.monitor);
|
||||
|
||||
while (agent_data.thread_state == WAITING) {
|
||||
/* SP3.2-w - wait to start test */
|
||||
/* SP6.2-w - wait to end test */
|
||||
rawMonitorWait(jvmti_env, agent_data.monitor, inc_timeout);
|
||||
|
||||
if (timeout == 0) continue;
|
||||
|
||||
t += inc_timeout;
|
||||
|
||||
if (t >= timeout) break;
|
||||
}
|
||||
|
||||
if (agent_data.thread_state == WAITING) {
|
||||
NSK_COMPLAIN1("No status sync occured for timeout: %"LL"d ms\n", timeout);
|
||||
nsk_jvmti_setFailStatus();
|
||||
result = NSK_FALSE;
|
||||
}
|
||||
|
||||
rawMonitorExit(jvmti_env, agent_data.monitor);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/** Resume java code suspended on sync point. */
|
||||
int nsk_jvmti_resumeSync() {
|
||||
int result;
|
||||
rawMonitorEnter(jvmti_env, agent_data.monitor);
|
||||
|
||||
if (agent_data.thread_state == SUSPENDED) {
|
||||
result = NSK_TRUE;
|
||||
agent_data.thread_state = RUNNABLE;
|
||||
/* SP5.2-n - notify suspend done */
|
||||
/* SP7.2-n - notify agent end */
|
||||
rawMonitorNotify(jvmti_env, agent_data.monitor);
|
||||
}
|
||||
else {
|
||||
NSK_COMPLAIN0("Debuggee was not suspended on status sync\n");
|
||||
nsk_jvmti_setFailStatus();
|
||||
result = NSK_FALSE;
|
||||
}
|
||||
|
||||
rawMonitorExit(jvmti_env, agent_data.monitor);
|
||||
return NSK_TRUE;
|
||||
}
|
||||
|
||||
/** Native function for Java code to provide sync point. */
|
||||
JNIEXPORT jint JNICALL
|
||||
Java_nsk_share_jvmti_DebugeeClass_checkStatus(JNIEnv* jni_env, jclass cls, jint debuggeeStatus) {
|
||||
jint status;
|
||||
NSK_TRACE(status = syncDebuggeeStatus(jni_env, jvmti_env, debuggeeStatus));
|
||||
return status;
|
||||
}
|
||||
|
||||
/** Native function for Java code to reset agent data. */
|
||||
JNIEXPORT void JNICALL
|
||||
Java_nsk_share_jvmti_DebugeeClass_resetAgentData(JNIEnv* jni_env, jclass cls) {
|
||||
NSK_TRACE(nsk_jvmti_resetAgentData());
|
||||
}
|
||||
|
||||
/* ============================================================================= */
|
||||
|
||||
/** Find loaded class by signature. */
|
||||
jclass nsk_jvmti_classBySignature(const char signature[]) {
|
||||
jclass* classes = NULL;
|
||||
jint count = 0;
|
||||
jclass foundClass = NULL;
|
||||
int i;
|
||||
|
||||
if (!NSK_VERIFY(signature != NULL)) {
|
||||
nsk_jvmti_setFailStatus();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!NSK_JVMTI_VERIFY(
|
||||
NSK_CPP_STUB3(GetLoadedClasses, jvmti_env, &count, &classes))) {
|
||||
nsk_jvmti_setFailStatus();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
char* sig = NULL;
|
||||
char* generic = NULL;
|
||||
|
||||
if (!NSK_JVMTI_VERIFY(
|
||||
NSK_CPP_STUB4(GetClassSignature, jvmti_env, classes[i], &sig, &generic))) {
|
||||
nsk_jvmti_setFailStatus();
|
||||
break;
|
||||
}
|
||||
|
||||
if (sig != NULL && strcmp(signature, sig) == 0) {
|
||||
foundClass = classes[i];
|
||||
}
|
||||
|
||||
if (!(NSK_JVMTI_VERIFY(
|
||||
NSK_CPP_STUB2(Deallocate, jvmti_env, (unsigned char*)sig))
|
||||
&& NSK_JVMTI_VERIFY(
|
||||
NSK_CPP_STUB2(Deallocate, jvmti_env, (unsigned char*)generic)))) {
|
||||
nsk_jvmti_setFailStatus();
|
||||
break;
|
||||
}
|
||||
|
||||
if (foundClass != NULL)
|
||||
break;
|
||||
}
|
||||
|
||||
if (!NSK_JVMTI_VERIFY(
|
||||
NSK_CPP_STUB2(Deallocate, jvmti_env, (unsigned char*)classes))) {
|
||||
nsk_jvmti_setFailStatus();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!NSK_JNI_VERIFY(jni_env, (foundClass = (jclass)
|
||||
NSK_CPP_STUB2(NewGlobalRef, jni_env, foundClass)) != NULL)) {
|
||||
nsk_jvmti_setFailStatus();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return foundClass;
|
||||
}
|
||||
|
||||
/** Find alive thread by name. */
|
||||
jthread nsk_jvmti_threadByName(const char name[]) {
|
||||
jthread* threads = NULL;
|
||||
jint count = 0;
|
||||
jthread foundThread = NULL;
|
||||
int i;
|
||||
|
||||
if (!NSK_VERIFY(name != NULL)) {
|
||||
nsk_jvmti_setFailStatus();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!NSK_JVMTI_VERIFY(
|
||||
NSK_CPP_STUB3(GetAllThreads, jvmti_env, &count, &threads))) {
|
||||
nsk_jvmti_setFailStatus();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
jvmtiThreadInfo info;
|
||||
|
||||
if (!NSK_JVMTI_VERIFY(
|
||||
NSK_CPP_STUB3(GetThreadInfo, jvmti_env, threads[i], &info))) {
|
||||
nsk_jvmti_setFailStatus();
|
||||
break;
|
||||
}
|
||||
|
||||
if (info.name != NULL && strcmp(name, info.name) == 0) {
|
||||
foundThread = threads[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!NSK_JVMTI_VERIFY(
|
||||
NSK_CPP_STUB2(Deallocate, jvmti_env, (unsigned char*)threads))) {
|
||||
nsk_jvmti_setFailStatus();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!NSK_JNI_VERIFY(jni_env, (foundThread = (jthread)
|
||||
NSK_CPP_STUB2(NewGlobalRef, jni_env, foundThread)) != NULL)) {
|
||||
nsk_jvmti_setFailStatus();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return foundThread;
|
||||
}
|
||||
|
||||
|
||||
/* ============================================================================= */
|
||||
|
||||
/** Add all capabilities for finding line locations. */
|
||||
int nsk_jvmti_addLocationCapabilities() {
|
||||
jvmtiCapabilities caps;
|
||||
|
||||
memset(&caps, 0, sizeof(caps));
|
||||
caps.can_get_line_numbers = 1;
|
||||
if (!NSK_JVMTI_VERIFY(
|
||||
NSK_CPP_STUB2(AddCapabilities, jvmti_env, &caps)))
|
||||
return NSK_FALSE;
|
||||
|
||||
return NSK_TRUE;
|
||||
}
|
||||
|
||||
/** Add all capabilities for using breakpoints. */
|
||||
int nsk_jvmti_addBreakpointCapabilities() {
|
||||
jvmtiCapabilities caps;
|
||||
|
||||
if (!nsk_jvmti_addLocationCapabilities())
|
||||
return NSK_FALSE;
|
||||
|
||||
memset(&caps, 0, sizeof(caps));
|
||||
caps.can_generate_breakpoint_events = 1;
|
||||
if (!NSK_JVMTI_VERIFY(
|
||||
NSK_CPP_STUB2(AddCapabilities, jvmti_env, &caps)))
|
||||
return NSK_FALSE;
|
||||
|
||||
return NSK_TRUE;
|
||||
}
|
||||
|
||||
/** Find line location. */
|
||||
jlocation nsk_jvmti_getLineLocation(jclass cls, jmethodID method, int line) {
|
||||
jint count = 0;
|
||||
jvmtiLineNumberEntry* table = NULL;
|
||||
jlocation location = NSK_JVMTI_INVALID_JLOCATION;
|
||||
int i;
|
||||
|
||||
if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB4(GetLineNumberTable, jvmti_env, method, &count, &table)))
|
||||
return NSK_JVMTI_INVALID_JLOCATION;
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
if (table[i].line_number == line) {
|
||||
location = table[i].start_location;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB2(Deallocate, jvmti_env, (unsigned char*)table)))
|
||||
return NSK_JVMTI_INVALID_JLOCATION;
|
||||
|
||||
return location;
|
||||
}
|
||||
|
||||
/** Set breakpoint to a line. */
|
||||
jlocation nsk_jvmti_setLineBreakpoint(jclass cls, jmethodID method, int line) {
|
||||
jlocation location = NSK_JVMTI_INVALID_JLOCATION;
|
||||
|
||||
if (!NSK_VERIFY((location =
|
||||
nsk_jvmti_getLineLocation(cls, method, line)) != NSK_JVMTI_INVALID_JLOCATION))
|
||||
return NSK_JVMTI_INVALID_JLOCATION;
|
||||
|
||||
if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB3(SetBreakpoint, jvmti_env, method, location)))
|
||||
return NSK_JVMTI_INVALID_JLOCATION;
|
||||
|
||||
return location;
|
||||
}
|
||||
|
||||
/** Remove breakpoint from a line. */
|
||||
jlocation nsk_jvmti_clearLineBreakpoint(jclass cls, jmethodID method, int line) {
|
||||
jlocation location = NSK_JVMTI_INVALID_JLOCATION;
|
||||
|
||||
if (!NSK_VERIFY((location =
|
||||
nsk_jvmti_getLineLocation(cls, method, line)) != NSK_JVMTI_INVALID_JLOCATION))
|
||||
return NSK_JVMTI_INVALID_JLOCATION;
|
||||
|
||||
if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB3(ClearBreakpoint, jvmti_env, method, location)))
|
||||
return NSK_JVMTI_INVALID_JLOCATION;
|
||||
|
||||
return location;
|
||||
}
|
||||
|
||||
/* ============================================================================= */
|
||||
|
||||
/** Enable or disable given events. */
|
||||
int nsk_jvmti_enableEvents(jvmtiEventMode enable, int size, jvmtiEvent list[], jthread thread) {
|
||||
int i;
|
||||
|
||||
for (i = 0; i < size; i++) {
|
||||
if (!NSK_JVMTI_VERIFY(
|
||||
NSK_CPP_STUB4(SetEventNotificationMode, jvmti_env, enable,
|
||||
list[i], thread))) {
|
||||
nsk_jvmti_setFailStatus();
|
||||
return NSK_FALSE;
|
||||
}
|
||||
}
|
||||
return NSK_TRUE;
|
||||
}
|
||||
|
||||
/* ============================================================================= */
|
||||
|
||||
typedef jint (JNICALL *checkStatus_type)(JNIEnv* jni_env, jclass cls, jint debuggeeStatus);
|
||||
|
||||
static checkStatus_type checkStatus_func = NULL;
|
||||
|
||||
/**
|
||||
* Proxy function to gain sequential access to checkStatus of each agent
|
||||
*/
|
||||
JNIEXPORT jint JNICALL
|
||||
MA_checkStatus(JNIEnv* jni_env, jclass cls, jint debuggeeStatus) {
|
||||
jint status;
|
||||
|
||||
NSK_TRACE(status = syncDebuggeeStatus(jni_env, jvmti_env, debuggeeStatus));
|
||||
return (*checkStatus_func)(jni_env, cls, status);
|
||||
}
|
||||
|
||||
/**
|
||||
* nativeMethodBind callback:
|
||||
* if needed, redirects checkStatus native method call
|
||||
*/
|
||||
static void JNICALL nativeMethodBind(jvmtiEnv* jvmti_env, JNIEnv *jni_env,
|
||||
jthread thread, jmethodID mid,
|
||||
void* address, void** new_address_ptr) {
|
||||
const char* BIND_CLASS_NAME = "Lnsk/share/jvmti/DebugeeClass;";
|
||||
const char* BIND_METHOD_NAME = "checkStatus";
|
||||
const char* BIND_METHOD_SIGNATURE = "(I)I";
|
||||
|
||||
jvmtiPhase phase;
|
||||
jclass cls;
|
||||
char *class_sig = NULL;
|
||||
char *name = NULL;
|
||||
char *sig = NULL;
|
||||
|
||||
if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB2(GetPhase, jvmti_env, &phase))) {
|
||||
nsk_jvmti_setFailStatus();
|
||||
return;
|
||||
}
|
||||
|
||||
if (phase != JVMTI_PHASE_START && phase != JVMTI_PHASE_LIVE)
|
||||
return;
|
||||
|
||||
if (NSK_JVMTI_VERIFY(
|
||||
NSK_CPP_STUB5(GetMethodName, jvmti_env, mid, &name, &sig, NULL))) {
|
||||
if (strcmp(name, BIND_METHOD_NAME) == 0 &&
|
||||
strcmp(sig, BIND_METHOD_SIGNATURE) == 0) {
|
||||
|
||||
if (NSK_JVMTI_VERIFY(
|
||||
NSK_CPP_STUB3(GetMethodDeclaringClass, jvmti_env, mid, &cls))
|
||||
&& NSK_JVMTI_VERIFY(
|
||||
NSK_CPP_STUB4(GetClassSignature, jvmti_env, cls, &class_sig, NULL))
|
||||
&& strcmp(class_sig, BIND_CLASS_NAME) == 0
|
||||
&& address != (void*)Java_nsk_share_jvmti_DebugeeClass_checkStatus) {
|
||||
checkStatus_func = (checkStatus_type)address;
|
||||
NSK_TRACE(*new_address_ptr = (void*)MA_checkStatus);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (name != NULL)
|
||||
NSK_CPP_STUB2(Deallocate, jvmti_env, (unsigned char*)name);
|
||||
|
||||
if (sig != NULL)
|
||||
NSK_CPP_STUB2(Deallocate, jvmti_env, (unsigned char*)sig);
|
||||
|
||||
if (class_sig != NULL)
|
||||
NSK_CPP_STUB2(Deallocate, jvmti_env, (unsigned char*)class_sig);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize multiple agent:
|
||||
* establish processing of nativeMethodBind events
|
||||
*/
|
||||
int nsk_jvmti_init_MA(jvmtiEventCallbacks* callbacks) {
|
||||
|
||||
if (callbacks == NULL) {
|
||||
NSK_COMPLAIN0("callbacks should not be NULL\n");
|
||||
nsk_jvmti_setFailStatus();
|
||||
return NSK_FALSE;
|
||||
}
|
||||
|
||||
if (callbacks->NativeMethodBind != NULL) {
|
||||
NSK_COMPLAIN0("callbacks.NativeMethodBind should be NULL\n");
|
||||
nsk_jvmti_setFailStatus();
|
||||
return NSK_FALSE;
|
||||
}
|
||||
|
||||
{
|
||||
jvmtiCapabilities caps;
|
||||
memset(&caps, 0, sizeof(caps));
|
||||
caps.can_generate_native_method_bind_events = 1;
|
||||
if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB2(AddCapabilities, jvmti_env, &caps)))
|
||||
return NSK_FALSE;
|
||||
}
|
||||
|
||||
callbacks->NativeMethodBind = nativeMethodBind;
|
||||
if (!NSK_JVMTI_VERIFY(
|
||||
NSK_CPP_STUB3(SetEventCallbacks, jvmti_env, callbacks,
|
||||
sizeof(jvmtiEventCallbacks))))
|
||||
return NSK_FALSE;
|
||||
|
||||
if (!NSK_JVMTI_VERIFY(
|
||||
NSK_CPP_STUB4(SetEventNotificationMode, jvmti_env, JVMTI_ENABLE,
|
||||
JVMTI_EVENT_NATIVE_METHOD_BIND, NULL)))
|
||||
return NSK_FALSE;
|
||||
|
||||
return NSK_TRUE;
|
||||
}
|
||||
|
||||
/* ============================================================================= */
|
||||
|
||||
int nsk_jvmti_isOptionalEvent(jvmtiEvent event) {
|
||||
|
||||
return (event == JVMTI_EVENT_EXCEPTION)
|
||||
|| (event == JVMTI_EVENT_EXCEPTION_CATCH)
|
||||
|| (event == JVMTI_EVENT_SINGLE_STEP)
|
||||
|| (event == JVMTI_EVENT_FRAME_POP)
|
||||
|| (event == JVMTI_EVENT_BREAKPOINT)
|
||||
|| (event == JVMTI_EVENT_FIELD_ACCESS)
|
||||
|| (event == JVMTI_EVENT_FIELD_MODIFICATION)
|
||||
|| (event == JVMTI_EVENT_METHOD_ENTRY)
|
||||
|| (event == JVMTI_EVENT_METHOD_EXIT)
|
||||
|| (event == JVMTI_EVENT_NATIVE_METHOD_BIND)
|
||||
|| (event == JVMTI_EVENT_COMPILED_METHOD_LOAD)
|
||||
|| (event == JVMTI_EVENT_COMPILED_METHOD_UNLOAD)
|
||||
|| (event == JVMTI_EVENT_MONITOR_WAIT)
|
||||
|| (event == JVMTI_EVENT_MONITOR_WAITED)
|
||||
|| (event == JVMTI_EVENT_MONITOR_CONTENDED_ENTER)
|
||||
|| (event == JVMTI_EVENT_MONITOR_CONTENDED_ENTERED)
|
||||
|| (event == JVMTI_EVENT_GARBAGE_COLLECTION_START)
|
||||
|| (event == JVMTI_EVENT_GARBAGE_COLLECTION_FINISH)
|
||||
|| (event == JVMTI_EVENT_OBJECT_FREE)
|
||||
|| (event == JVMTI_EVENT_VM_OBJECT_ALLOC);
|
||||
}
|
||||
|
||||
/* ============================================================================= */
|
||||
|
||||
void nsk_jvmti_showPossessedCapabilities(jvmtiEnv *jvmti_env) {
|
||||
|
||||
jvmtiCapabilities caps;
|
||||
|
||||
if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB2(GetCapabilities, jvmti_env, &caps))) {
|
||||
return;
|
||||
}
|
||||
|
||||
NSK_DISPLAY0("\n");
|
||||
NSK_DISPLAY0("Possessed capabilities:\n");
|
||||
NSK_DISPLAY0("-----------------------\n");
|
||||
if (caps.can_tag_objects)
|
||||
NSK_DISPLAY0("\tcan_tag_objects\n");
|
||||
if (caps.can_generate_field_modification_events)
|
||||
NSK_DISPLAY0("\tcan_generate_field_modification_events\n");
|
||||
if (caps.can_generate_field_access_events)
|
||||
NSK_DISPLAY0("\tcan_generate_field_access_events\n");
|
||||
if (caps.can_get_bytecodes)
|
||||
NSK_DISPLAY0("\tcan_get_bytecodes\n");
|
||||
if (caps.can_get_synthetic_attribute)
|
||||
NSK_DISPLAY0("\tcan_get_synthetic_attribute\n");
|
||||
if (caps.can_get_owned_monitor_info)
|
||||
NSK_DISPLAY0("\tcan_get_owned_monitor_info\n");
|
||||
if (caps.can_get_current_contended_monitor)
|
||||
NSK_DISPLAY0("\tcan_get_current_contended_monitor\n");
|
||||
if (caps.can_get_monitor_info)
|
||||
NSK_DISPLAY0("\tcan_get_monitor_info\n");
|
||||
if (caps.can_pop_frame)
|
||||
NSK_DISPLAY0("\tcan_pop_frame\n");
|
||||
if (caps.can_redefine_classes)
|
||||
NSK_DISPLAY0("\tcan_redefine_classes\n");
|
||||
if (caps.can_signal_thread)
|
||||
NSK_DISPLAY0("\tcan_signal_thread\n");
|
||||
if (caps.can_get_source_file_name)
|
||||
NSK_DISPLAY0("\tcan_get_source_file_name\n");
|
||||
if (caps.can_get_line_numbers)
|
||||
NSK_DISPLAY0("\tcan_get_line_numbers\n");
|
||||
if (caps.can_get_source_debug_extension)
|
||||
NSK_DISPLAY0("\tcan_get_source_debug_extension\n");
|
||||
if (caps.can_access_local_variables)
|
||||
NSK_DISPLAY0("\tcan_access_local_variables\n");
|
||||
if (caps.can_maintain_original_method_order)
|
||||
NSK_DISPLAY0("\tcan_maintain_original_method_order\n");
|
||||
if (caps.can_generate_single_step_events)
|
||||
NSK_DISPLAY0("\tcan_generate_single_step_events\n");
|
||||
if (caps.can_generate_exception_events)
|
||||
NSK_DISPLAY0("\tcan_generate_exception_events\n");
|
||||
if (caps.can_generate_frame_pop_events)
|
||||
NSK_DISPLAY0("\tcan_generate_frame_pop_events\n");
|
||||
if (caps.can_generate_breakpoint_events)
|
||||
NSK_DISPLAY0("\tcan_generate_breakpoint_events\n");
|
||||
if (caps.can_suspend)
|
||||
NSK_DISPLAY0("\tcan_suspend\n");
|
||||
if (caps.can_get_current_thread_cpu_time)
|
||||
NSK_DISPLAY0("\tcan_get_current_thread_cpu_time\n");
|
||||
if (caps.can_get_thread_cpu_time)
|
||||
NSK_DISPLAY0("\tcan_get_thread_cpu_time\n");
|
||||
if (caps.can_generate_method_entry_events)
|
||||
NSK_DISPLAY0("\tcan_generate_method_entry_events\n");
|
||||
if (caps.can_generate_method_exit_events)
|
||||
NSK_DISPLAY0("\tcan_generate_method_exit_events\n");
|
||||
if (caps.can_generate_all_class_hook_events)
|
||||
NSK_DISPLAY0("\tcan_generate_all_class_hook_events\n");
|
||||
if (caps.can_generate_compiled_method_load_events)
|
||||
NSK_DISPLAY0("\tcan_generate_compiled_method_load_events\n");
|
||||
if (caps.can_generate_monitor_events)
|
||||
NSK_DISPLAY0("\tcan_generate_monitor_events\n");
|
||||
if (caps.can_generate_vm_object_alloc_events)
|
||||
NSK_DISPLAY0("\tcan_generate_vm_object_alloc_events\n");
|
||||
if (caps.can_generate_native_method_bind_events)
|
||||
NSK_DISPLAY0("\tcan_generate_native_method_bind_events\n");
|
||||
if (caps.can_generate_garbage_collection_events)
|
||||
NSK_DISPLAY0("\tcan_generate_garbage_collection_events\n");
|
||||
if (caps.can_generate_object_free_events)
|
||||
NSK_DISPLAY0("\tcan_generate_object_free_events\n");
|
||||
|
||||
NSK_DISPLAY0("\n");
|
||||
}
|
||||
|
||||
/* ============================================================================= */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@ -0,0 +1,397 @@
|
||||
/*
|
||||
* Copyright (c) 2006, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <jvmti.h>
|
||||
#include "jni_tools.h"
|
||||
#include "jvmti_tools.h"
|
||||
#include "jvmti_FollowRefObjects.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* ============================================================================= */
|
||||
|
||||
int g_fakeUserData = 0;
|
||||
int g_userDataError = 0;
|
||||
jvmtiHeapCallbacks g_wrongHeapCallbacks = { 0 };
|
||||
|
||||
/* This array has to be up-to-date with the jvmtiHeapReferenceKind enum */
|
||||
const char * const g_refKindStr[28] = {
|
||||
"unknown_0",
|
||||
"JVMTI_HEAP_REFERENCE_CLASS",
|
||||
"JVMTI_HEAP_REFERENCE_FIELD",
|
||||
"JVMTI_HEAP_REFERENCE_ARRAY_ELEMENT",
|
||||
"JVMTI_HEAP_REFERENCE_CLASS_LOADER",
|
||||
"JVMTI_HEAP_REFERENCE_SIGNERS",
|
||||
"JVMTI_HEAP_REFERENCE_PROTECTION_DOMAIN",
|
||||
"JVMTI_HEAP_REFERENCE_INTERFACE",
|
||||
"JVMTI_HEAP_REFERENCE_STATIC_FIELD",
|
||||
"JVMTI_HEAP_REFERENCE_CONSTANT_POOL",
|
||||
"JVMTI_HEAP_REFERENCE_SUPERCLASS",
|
||||
"unknown_11", "unknown_12", "unknown_13", "unknown_14", "unknown_15",
|
||||
"unknown_16", "unknown_17", "unknown_18", "unknown_19", "unknown_20",
|
||||
"JVMTI_HEAP_REFERENCE_JNI_GLOBAL",
|
||||
"JVMTI_HEAP_REFERENCE_SYSTEM_CLASS",
|
||||
"JVMTI_HEAP_REFERENCE_MONITOR",
|
||||
"JVMTI_HEAP_REFERENCE_STACK_LOCAL",
|
||||
"JVMTI_HEAP_REFERENCE_JNI_LOCAL",
|
||||
"JVMTI_HEAP_REFERENCE_THREAD",
|
||||
"JVMTI_HEAP_REFERENCE_OTHER"
|
||||
};
|
||||
|
||||
/* ============================================================================= */
|
||||
|
||||
char * g_szTagInfo[MAX_TAG];
|
||||
char g_tagFlags[MAX_TAG];
|
||||
int g_tagVisitCount[MAX_TAG];
|
||||
|
||||
/* ============================================================================= */
|
||||
|
||||
void markTagSet(jlong tag_val)
|
||||
{
|
||||
if ( tag_val > 0 && tag_val < MAX_TAG )
|
||||
g_tagFlags[tag_val] |= FLAG_TAG_SET;
|
||||
}
|
||||
|
||||
void markTagVisited(jlong tag_val)
|
||||
{
|
||||
if ( tag_val > 0 && tag_val < MAX_TAG ) {
|
||||
g_tagVisitCount[tag_val]++;
|
||||
}
|
||||
}
|
||||
|
||||
jboolean checkThatAllTagsVisited()
|
||||
{
|
||||
jboolean ok = JNI_TRUE;
|
||||
jlong i;
|
||||
|
||||
NSK_DISPLAY0("Checking that all set tags have been visited\n");
|
||||
|
||||
for ( i = 1; i < MAX_TAG; i++ ) {
|
||||
char flags = g_tagFlags[i];
|
||||
|
||||
if ( (g_tagFlags[i] & FLAG_TAG_SET) ) {
|
||||
if ( g_tagVisitCount[i] == 0 ) {
|
||||
NSK_COMPLAIN1("Tag %" LL "d has not been visited: %x\n", i);
|
||||
ok = JNI_FALSE;
|
||||
}
|
||||
|
||||
DBG(printf(">>> Tag %" LL "d has been visited %i times: %s\n", i, g_tagVisitCount[i], g_szTagInfo[i]));
|
||||
}
|
||||
}
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL Java_nsk_jvmti_unit_FollowReferences_FollowRefObjects_resetTags(JNIEnv* jni, jclass klass)
|
||||
{
|
||||
memset(g_szTagInfo, 0, sizeof(g_szTagInfo));
|
||||
memset(g_tagFlags, 0, sizeof(g_tagFlags));
|
||||
memset(g_tagVisitCount, 0, sizeof(g_tagVisitCount));
|
||||
}
|
||||
|
||||
JNIEXPORT jboolean JNICALL Java_nsk_jvmti_unit_FollowReferences_FollowRefObjects_setTag(JNIEnv* jni, jclass klass, jobject o, jlong tag, jstring sInfo)
|
||||
{
|
||||
jvmtiEnv * jvmti = nsk_jvmti_getAgentJVMTIEnv();
|
||||
jint hashCode;
|
||||
|
||||
if ( ! NSK_VERIFY(NSK_CPP_STUB3(SetTag, jvmti, o, tag) == JVMTI_ERROR_NONE) ) {
|
||||
NSK_COMPLAIN2("Can't set tag %li for object %lx\n", tag, o);
|
||||
return JNI_FALSE;
|
||||
}
|
||||
|
||||
if ( ! NSK_VERIFY(NSK_CPP_STUB3(GetObjectHashCode, jvmti, o, &hashCode) == JVMTI_ERROR_NONE) ) {
|
||||
NSK_COMPLAIN1("Can't get hash object %lx\n", o);
|
||||
return JNI_FALSE;
|
||||
}
|
||||
|
||||
NSK_DISPLAY2("setTag: %08x <- % 3li", hashCode, tag);
|
||||
|
||||
if ( tag > 0 && tag < MAX_TAG ) {
|
||||
jboolean fCopy;
|
||||
const char * s;
|
||||
|
||||
if ( ! NSK_VERIFY((s = NSK_CPP_STUB3(GetStringUTFChars, jni, sInfo, &fCopy)) != NULL) ) {
|
||||
NSK_COMPLAIN1("Can't get string at %#p\n", sInfo);
|
||||
return JNI_FALSE;
|
||||
}
|
||||
|
||||
if ( ! s ) {
|
||||
NSK_COMPLAIN1("Can't get string at %#p: NULL\n", sInfo);
|
||||
return JNI_FALSE;
|
||||
}
|
||||
|
||||
g_szTagInfo[tag] = strdup(s);
|
||||
|
||||
NSK_CPP_STUB3(ReleaseStringUTFChars, jni, sInfo, s);
|
||||
|
||||
NSK_DISPLAY1(" // %s", g_szTagInfo[tag]);
|
||||
|
||||
}
|
||||
|
||||
markTagSet(tag);
|
||||
|
||||
return JNI_TRUE;
|
||||
}
|
||||
|
||||
JNIEXPORT jlong JNICALL Java_nsk_jvmti_unit_FollowReferences_FollowRefObjects_getTag(JNIEnv* jni, jclass klass, jobject o)
|
||||
{
|
||||
jvmtiEnv * jvmti = nsk_jvmti_getAgentJVMTIEnv();
|
||||
|
||||
jlong tag;
|
||||
jvmtiError r;
|
||||
if ( ! NSK_VERIFY((r = NSK_CPP_STUB3(GetTag, jvmti, o, &tag)) == JVMTI_ERROR_NONE) ) {
|
||||
NSK_COMPLAIN2("Can't GetTag for object %lx. Return code: %i\n", o, r);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return tag;
|
||||
}
|
||||
|
||||
/* ============================================================================= */
|
||||
|
||||
int g_refsToVerifyCnt;
|
||||
|
||||
RefToVerify g_refsToVerify[MAX_REFS];
|
||||
|
||||
/* ============================================================================= */
|
||||
|
||||
JNIEXPORT void JNICALL Java_nsk_jvmti_unit_FollowReferences_FollowRefObjects_resetRefsToVerify(JNIEnv* jni, jclass klass)
|
||||
{
|
||||
g_refsToVerifyCnt = 0;
|
||||
}
|
||||
|
||||
static RefToVerify * findRefToVerify(jlong tagFrom, jlong tagTo, jint refKind)
|
||||
{
|
||||
int i;
|
||||
RefToVerify * pRefRec = g_refsToVerify;
|
||||
|
||||
for ( i = g_refsToVerifyCnt; i > 0; i--, pRefRec++ ) {
|
||||
pRefRec = &g_refsToVerify[i];
|
||||
if ( pRefRec->_tagFrom == tagFrom && pRefRec->_tagTo == tagTo && pRefRec->_refKind == refKind ) {
|
||||
return pRefRec;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static jboolean addRefToVerify(jlong tagFrom, jlong tagTo, jint refKind, int expectedCount, int actualCount)
|
||||
{
|
||||
RefToVerify * pRefRec;
|
||||
|
||||
if ( g_refsToVerifyCnt >= MAX_REFS ) {
|
||||
NSK_COMPLAIN0("TEST_BUG: Max. number of refs reached!");
|
||||
nsk_jvmti_setFailStatus();
|
||||
return JNI_FALSE;
|
||||
}
|
||||
|
||||
pRefRec = &g_refsToVerify[g_refsToVerifyCnt++];
|
||||
|
||||
pRefRec->_tagFrom = tagFrom;
|
||||
pRefRec->_tagTo = tagTo;
|
||||
pRefRec->_refKind = refKind;
|
||||
pRefRec->_expectedCount = expectedCount;
|
||||
pRefRec->_actualCount = actualCount;
|
||||
|
||||
return JNI_TRUE;
|
||||
}
|
||||
|
||||
JNIEXPORT jboolean JNICALL Java_nsk_jvmti_unit_FollowReferences_FollowRefObjects_addRefToVerify(JNIEnv* jni, jclass klass, jobject from, jobject to, jint refKind, jint count)
|
||||
{
|
||||
jvmtiEnv * jvmti = nsk_jvmti_getAgentJVMTIEnv();
|
||||
jvmtiError r;
|
||||
jlong tagFrom, tagTo;
|
||||
RefToVerify * pRefRec;
|
||||
|
||||
if ( ! NSK_VERIFY((r = NSK_CPP_STUB3(GetTag, jvmti, from, &tagFrom)) == JVMTI_ERROR_NONE) ) {
|
||||
NSK_COMPLAIN2("TEST_BUG: Can't GetTag for object %lx. Return code: %i\n", from, r);
|
||||
nsk_jvmti_setFailStatus();
|
||||
return JNI_FALSE;
|
||||
}
|
||||
|
||||
|
||||
if ( ! NSK_VERIFY((r = NSK_CPP_STUB3(GetTag, jvmti, to, &tagTo)) == JVMTI_ERROR_NONE) ) {
|
||||
NSK_COMPLAIN2("TEST_BUG: Can't GetTag for object %lx. Return code: %i\n", to, r);
|
||||
nsk_jvmti_setFailStatus();
|
||||
return JNI_FALSE;
|
||||
}
|
||||
|
||||
if ( (pRefRec = findRefToVerify(tagFrom, tagTo, refKind)) != NULL ) {
|
||||
pRefRec->_expectedCount += count;
|
||||
return JNI_TRUE;
|
||||
}
|
||||
|
||||
return addRefToVerify(tagFrom, tagTo, refKind, count, 0);
|
||||
}
|
||||
|
||||
jboolean markRefToVerify(jlong tagFrom, jlong tagTo, int refKind)
|
||||
{
|
||||
RefToVerify * pRefRec;
|
||||
|
||||
if ( (pRefRec = findRefToVerify(tagFrom, tagTo, refKind)) != NULL ) {
|
||||
pRefRec->_actualCount++;
|
||||
return JNI_TRUE;
|
||||
}
|
||||
|
||||
return addRefToVerify(tagFrom, tagTo, refKind, 0, 1);
|
||||
}
|
||||
|
||||
/* ============================================================================= */
|
||||
|
||||
void checkUserData(const char * szFile, const int line, void * user_data)
|
||||
{
|
||||
if (user_data != &g_fakeUserData && !g_userDataError) {
|
||||
NSK_COMPLAIN4("%s, %i: Unexpected user_data is passed"
|
||||
" to heapReferenceCallback:\n"
|
||||
" expected: 0x%p\n"
|
||||
" actual: 0x%p\n",
|
||||
szFile, line,
|
||||
&g_fakeUserData,
|
||||
user_data);
|
||||
g_userDataError++;
|
||||
}
|
||||
}
|
||||
|
||||
#define CHECK_USER_DATA(p) checkUserData(__FILE__, __LINE__, (p))
|
||||
|
||||
void printHeapRefCallbackInfo(
|
||||
jvmtiHeapReferenceKind reference_kind,
|
||||
const jvmtiHeapReferenceInfo* reference_info,
|
||||
jlong class_tag,
|
||||
jlong referrer_class_tag,
|
||||
jlong size,
|
||||
jlong* tag_ptr,
|
||||
jlong* referrer_tag_ptr,
|
||||
jint length)
|
||||
{
|
||||
const char * szInfo, * szRefInfo;
|
||||
jlong tag_val = tag_ptr ? *tag_ptr : 0;
|
||||
|
||||
NSK_DISPLAY1("heapReferenceCallback: %s", g_refKindStr[reference_kind]);
|
||||
|
||||
NSK_DISPLAY3(" reference_info: %#lx, class_tag: %#" LL "d, referrer_class_tag: %#" LL "d\n",
|
||||
reference_info, class_tag, referrer_class_tag);
|
||||
|
||||
NSK_DISPLAY4(" size: %" LL "d, tag_ptr: %p, referrer_tag_ptr: %p, length: %-ld\n",
|
||||
size, tag_ptr, referrer_tag_ptr, length);
|
||||
|
||||
NSK_DISPLAY2(" tag: %" LL "d, referrer_tag: %" LL "d\n",
|
||||
tag_val, DEREF(referrer_tag_ptr));
|
||||
|
||||
szInfo = ( tag_val > 0 && tag_val < MAX_TAG ) ? g_szTagInfo[tag_val] : "<none>";
|
||||
szRefInfo = ( referrer_tag_ptr && *referrer_tag_ptr > 0 && *referrer_tag_ptr < MAX_TAG ) ? g_szTagInfo[*referrer_tag_ptr] : "<none>";
|
||||
|
||||
NSK_DISPLAY3(" summary: %s: %s <- %s\n",
|
||||
g_refKindStr[reference_kind], szInfo, szRefInfo);
|
||||
}
|
||||
|
||||
/* ============================================================================= */
|
||||
|
||||
jint JNICALL wrongHeapReferenceCallback(
|
||||
jvmtiHeapReferenceKind reference_kind,
|
||||
const jvmtiHeapReferenceInfo* reference_info,
|
||||
jlong class_tag,
|
||||
jlong referrer_class_tag,
|
||||
jlong size,
|
||||
jlong* tag_ptr,
|
||||
jlong* referrer_tag_ptr,
|
||||
jint length,
|
||||
void* user_data)
|
||||
{
|
||||
CHECK_USER_DATA(user_data);
|
||||
NSK_COMPLAIN0("heap reference callback was called, where it should not be\n");
|
||||
nsk_jvmti_setFailStatus();
|
||||
printHeapRefCallbackInfo(reference_kind, reference_info, class_tag, referrer_class_tag, size, tag_ptr, referrer_tag_ptr, length);
|
||||
|
||||
return JVMTI_VISIT_OBJECTS;
|
||||
}
|
||||
|
||||
jint JNICALL wrongPrimitiveFieldCallback(
|
||||
jvmtiHeapReferenceKind reference_kind,
|
||||
const jvmtiHeapReferenceInfo* reference_info,
|
||||
jlong class_tag,
|
||||
jlong* tag_ptr,
|
||||
jvalue value,
|
||||
jvmtiPrimitiveType value_type,
|
||||
void* user_data)
|
||||
{
|
||||
CHECK_USER_DATA(user_data);
|
||||
NSK_COMPLAIN0("primitive field callback was called, where it should not be\n");
|
||||
nsk_jvmti_setFailStatus();
|
||||
|
||||
return JVMTI_VISIT_OBJECTS;
|
||||
}
|
||||
|
||||
jint JNICALL wrongArrayPrimitiveValueCallback(
|
||||
jlong class_tag,
|
||||
jlong size,
|
||||
jlong* tag_ptr,
|
||||
jint element_count,
|
||||
jvmtiPrimitiveType element_type,
|
||||
const void* elements,
|
||||
void* user_data)
|
||||
{
|
||||
CHECK_USER_DATA(user_data);
|
||||
NSK_COMPLAIN0("array primitive value callback was called, where it should not be\n");
|
||||
nsk_jvmti_setFailStatus();
|
||||
|
||||
return JVMTI_VISIT_OBJECTS;
|
||||
}
|
||||
|
||||
jint JNICALL wrongStringPrimitiveValueCallback(
|
||||
jlong class_tag,
|
||||
jlong size,
|
||||
jlong* tag_ptr,
|
||||
const jchar* value,
|
||||
jint value_length,
|
||||
void* user_data)
|
||||
{
|
||||
CHECK_USER_DATA(user_data);
|
||||
NSK_COMPLAIN0("string primitive value callback was called, where it should not be\n");
|
||||
nsk_jvmti_setFailStatus();
|
||||
|
||||
return JVMTI_VISIT_OBJECTS;
|
||||
}
|
||||
|
||||
/* ============================================================================= */
|
||||
|
||||
void jvmti_FollowRefObject_init()
|
||||
{
|
||||
g_wrongHeapCallbacks.heap_iteration_callback = NULL;
|
||||
g_wrongHeapCallbacks.heap_reference_callback = wrongHeapReferenceCallback;
|
||||
g_wrongHeapCallbacks.primitive_field_callback = wrongPrimitiveFieldCallback;
|
||||
g_wrongHeapCallbacks.array_primitive_value_callback = wrongArrayPrimitiveValueCallback;
|
||||
g_wrongHeapCallbacks.string_primitive_value_callback = wrongStringPrimitiveValueCallback;
|
||||
|
||||
Java_nsk_jvmti_unit_FollowReferences_FollowRefObjects_resetTags(NULL, NULL);
|
||||
Java_nsk_jvmti_unit_FollowReferences_FollowRefObjects_resetRefsToVerify(NULL, NULL);
|
||||
}
|
||||
|
||||
/* ============================================================================= */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@ -0,0 +1,108 @@
|
||||
/*
|
||||
* Copyright (c) 2006, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
#ifndef __FollowRefObject_h
|
||||
#define __FollowRefObject_h
|
||||
|
||||
#include <jvmti.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* ============================================================================= */
|
||||
|
||||
void jvmti_FollowRefObject_init();
|
||||
|
||||
/* ============================================================================= */
|
||||
|
||||
#define DBG(x) x
|
||||
#define DEREF(ptr) (((ptr) == NULL ? 0 : *(ptr)))
|
||||
|
||||
extern jvmtiHeapCallbacks g_wrongHeapCallbacks; /* Callbacks that blame */
|
||||
|
||||
extern const char * const g_refKindStr[28]; /* JVMTI_HEAP_REFERENCE_xxx */
|
||||
|
||||
/* ============================================================================= */
|
||||
|
||||
#define MAX_TAG 1000
|
||||
#define MAX_REFS (MAX_TAG * 3)
|
||||
|
||||
#define FLAG_TAG_SET 0x01
|
||||
|
||||
extern char * g_szTagInfo[MAX_TAG];
|
||||
extern char g_tagFlags[MAX_TAG];
|
||||
extern int g_tagVisitCount[MAX_TAG];
|
||||
|
||||
void markTagSet(jlong tag_val);
|
||||
void markTagVisited(jlong tag_val);
|
||||
|
||||
jboolean checkThatAllTagsVisited();
|
||||
|
||||
/* ============================================================================= */
|
||||
|
||||
typedef struct {
|
||||
|
||||
jlong _tagFrom,
|
||||
_tagTo;
|
||||
|
||||
jint _refKind;
|
||||
|
||||
int _expectedCount,
|
||||
_actualCount;
|
||||
|
||||
} RefToVerify;
|
||||
|
||||
extern int g_refsToVerifyCnt;
|
||||
|
||||
extern RefToVerify g_refsToVerify[MAX_REFS];
|
||||
|
||||
jboolean markRefToVerify(jlong tagFrom, jlong tagTo, int refKind);
|
||||
|
||||
/* ============================================================================= */
|
||||
|
||||
extern int g_fakeUserData;
|
||||
extern int g_userDataError;
|
||||
|
||||
#define CHECK_USER_DATA(p) checkUserData(__FILE__, __LINE__, (p))
|
||||
|
||||
void checkUserData(const char * szFile, const int line, void * user_data);
|
||||
|
||||
/* ============================================================================= */
|
||||
|
||||
void printHeapRefCallbackInfo(
|
||||
jvmtiHeapReferenceKind reference_kind,
|
||||
const jvmtiHeapReferenceInfo* reference_info,
|
||||
jlong class_tag,
|
||||
jlong referrer_class_tag,
|
||||
jlong size,
|
||||
jlong* tag_ptr,
|
||||
jlong* referrer_tag_ptr,
|
||||
jint length);
|
||||
|
||||
/* ============================================================================= */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
684
test/hotspot/jtreg/vmTestbase/nsk/share/jvmti/jvmti_tools.c
Normal file
684
test/hotspot/jtreg/vmTestbase/nsk/share/jvmti/jvmti_tools.c
Normal file
@ -0,0 +1,684 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
|
||||
/*************************************************************/
|
||||
|
||||
#include "jvmti.h"
|
||||
|
||||
/*************************************************************/
|
||||
|
||||
#include "nsk_tools.h"
|
||||
#include "jni_tools.h"
|
||||
#include "jvmti_tools.h"
|
||||
#include "JVMTITools.h"
|
||||
|
||||
/*************************************************************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*************************************************************/
|
||||
|
||||
#define NSK_JVMTI_WAITTIME 2
|
||||
|
||||
#define NSK_JVMTI_MAX_OPTIONS 10
|
||||
#define NSK_JVMTI_OPTION_START '-'
|
||||
#define NSK_JVMTI_OPTION_VAL_SEP '='
|
||||
|
||||
#define NSK_JVMTI_OPT_PATH_TO_NEW_BYTE_CODE "pathToNewByteCode"
|
||||
#define PATH_FORMAT "%s%02d/%s"
|
||||
#define DIR_NAME "newclass"
|
||||
|
||||
static volatile int redefineAttempted = NSK_FALSE;
|
||||
static volatile int redefineSucceed = NSK_FALSE;
|
||||
static volatile int agentFailed = NSK_FALSE;
|
||||
|
||||
static struct {
|
||||
struct {
|
||||
int count;
|
||||
char* names[NSK_JVMTI_MAX_OPTIONS];
|
||||
char* values[NSK_JVMTI_MAX_OPTIONS];
|
||||
char* string;
|
||||
} options;
|
||||
int waittime;
|
||||
} context;
|
||||
|
||||
/*************************************************************/
|
||||
|
||||
static int check_option(int dashed, const char name[], const char value[]) {
|
||||
if (strcmp("verbose", name) == 0) {
|
||||
if (strlen(value) > 0) {
|
||||
nsk_complain("nsk_jvmti_parseOptions(): unexpected value in option: %s=%s\n", name, value);
|
||||
return NSK_FALSE;
|
||||
}
|
||||
nsk_setVerboseMode(NSK_TRUE);
|
||||
} else if (strcmp("trace", name) == 0) {
|
||||
if (strlen(value) <= 0) {
|
||||
nsk_complain("nsk_jvmti_parseOptions(): no value for option: %s\n", name);
|
||||
return NSK_FALSE;
|
||||
}
|
||||
if (strcmp("none", value) == 0) {
|
||||
nsk_setTraceMode(NSK_TRACE_NONE);
|
||||
} else if (strcmp("before", value) == 0) {
|
||||
nsk_setTraceMode(NSK_TRACE_BEFORE);
|
||||
} else if (strcmp("after", value) == 0) {
|
||||
nsk_setTraceMode(NSK_TRACE_AFTER);
|
||||
} else if (strcmp("all", value) == 0) {
|
||||
nsk_setTraceMode(NSK_TRACE_ALL);
|
||||
} else {
|
||||
nsk_complain("nsk_jvmti_parseOptions(): uexpected value in option: %s=%s\n", name, value);
|
||||
return NSK_FALSE;
|
||||
}
|
||||
nsk_setVerboseMode(NSK_TRUE);
|
||||
} else if (strcmp("waittime", name) == 0) {
|
||||
if (strlen(value) <= 0) {
|
||||
nsk_complain("nsk_jvmti_parseOptions(): no value for option: %s\n", name);
|
||||
return NSK_FALSE;
|
||||
}
|
||||
{
|
||||
char* end = NULL;
|
||||
long n = strtol(value, &end, 10);
|
||||
if (end == NULL || end == value || *end != '\0') {
|
||||
nsk_complain("nsk_jvmti_parseOptions(): not integer value in option: %s=%s\n", name, value);
|
||||
return NSK_FALSE;
|
||||
}
|
||||
if (n < 0) {
|
||||
nsk_complain("nsk_jvmti_parseOptions(): negative value in option: %s=%s\n", name, value);
|
||||
return NSK_FALSE;
|
||||
}
|
||||
context.waittime = (int)n;
|
||||
}
|
||||
} else if (dashed) {
|
||||
nsk_complain("nsk_jvmti_parseOptions(): unknown option: %c%s\n",
|
||||
NSK_JVMTI_OPTION_START, name);
|
||||
return NSK_FALSE;
|
||||
}
|
||||
return NSK_TRUE;
|
||||
}
|
||||
|
||||
static int add_option(const char opt[], int opt_len, const char val[], int val_len) {
|
||||
char* name;
|
||||
char* value;
|
||||
|
||||
int success = NSK_TRUE;
|
||||
int dashed_opt = NSK_FALSE;
|
||||
|
||||
if (opt[0] == NSK_JVMTI_OPTION_START) {
|
||||
dashed_opt = NSK_TRUE;
|
||||
opt++;
|
||||
opt_len--;
|
||||
}
|
||||
if (opt_len <= 0) {
|
||||
nsk_complain("nsk_jvmti_parseOptions(): found empty option\n");
|
||||
return NSK_FALSE;
|
||||
}
|
||||
|
||||
name = (char*)malloc(opt_len + 1);
|
||||
value = (char*)malloc(val_len + 1);
|
||||
|
||||
if (name == NULL || value == NULL) {
|
||||
nsk_complain("nsk_jvmti_parseOptions(): out of memory\n");
|
||||
success = NSK_FALSE;
|
||||
} else {
|
||||
strncpy(name, opt, opt_len);
|
||||
name[opt_len] = '\0';
|
||||
strncpy(value, val, val_len);
|
||||
value[val_len] = '\0';
|
||||
|
||||
if (!check_option(dashed_opt, name, value)) {
|
||||
success = NSK_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if (success) {
|
||||
if (context.options.count >= NSK_JVMTI_MAX_OPTIONS) {
|
||||
nsk_complain("nsk_jvmti_parseOptions(): too many options for parsing\n");
|
||||
success = NSK_FALSE;
|
||||
} else {
|
||||
context.options.names[context.options.count] = name;
|
||||
context.options.values[context.options.count] = value;
|
||||
context.options.count++;
|
||||
}
|
||||
}
|
||||
|
||||
if (!success) {
|
||||
if (name != NULL)
|
||||
free(name);
|
||||
if (value != NULL)
|
||||
free(value);
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
static void nsk_jvmti_free() {
|
||||
if (context.options.count > 0) {
|
||||
int i;
|
||||
for (i = 0; i < context.options.count; i++) {
|
||||
free(context.options.names[i]);
|
||||
free(context.options.values[i]);
|
||||
}
|
||||
context.options.count = 0;
|
||||
}
|
||||
if (context.options.string != NULL) {
|
||||
free(context.options.string);
|
||||
context.options.string = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
int isOptSep(char c) {
|
||||
return isspace(c) || c == '~';
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* The current option will not perform more than one
|
||||
* single option which given, this is due to places explained
|
||||
* in this question.
|
||||
*
|
||||
**/
|
||||
|
||||
/*
|
||||
* This whole play can be reduced with simple StringTokenizer (strtok).
|
||||
*
|
||||
*/
|
||||
|
||||
int nsk_jvmti_parseOptions(const char options[]) {
|
||||
size_t len;
|
||||
const char* opt;
|
||||
int success = NSK_TRUE;
|
||||
|
||||
context.options.string = NULL;
|
||||
context.options.count = 0;
|
||||
context.waittime = 2;
|
||||
|
||||
if (options == NULL)
|
||||
return NSK_TRUE;
|
||||
|
||||
len = strlen(options);
|
||||
context.options.string = (char*)malloc(len + 2);
|
||||
|
||||
if (context.options.string == NULL) {
|
||||
nsk_complain("nsk_jvmti_parseOptions(): out of memory\n");
|
||||
return NSK_FALSE;
|
||||
}
|
||||
strncpy(context.options.string, options, len);
|
||||
context.options.string[len] = '\0';
|
||||
context.options.string[len+1] = '\0';
|
||||
|
||||
for (opt = context.options.string; ; ) {
|
||||
const char* opt_end;
|
||||
const char* val_sep;
|
||||
int opt_len=0;
|
||||
int val_len=0;
|
||||
int exit=1;
|
||||
|
||||
while (*opt != '\0' && isOptSep(*opt)) opt++;
|
||||
if (*opt == '\0') break;
|
||||
|
||||
val_sep = NULL;
|
||||
/*
|
||||
This should break when the first option it encounters other wise
|
||||
*/
|
||||
for (opt_end = opt, opt_len=0; !(*opt_end == '\0' || isOptSep(*opt_end)); opt_end++,opt_len++) {
|
||||
if (*opt_end == NSK_JVMTI_OPTION_VAL_SEP) {
|
||||
val_sep = opt_end;
|
||||
exit=0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (exit == 1) break;
|
||||
|
||||
/* now scan for the search for the option value end.
|
||||
|
||||
*/
|
||||
exit =1;
|
||||
opt_end++;
|
||||
val_sep++;
|
||||
/**
|
||||
* I was expecting this jvmti_parseOptions(),
|
||||
* should be for multiple options as well.
|
||||
* If this break is not there then It will expects
|
||||
* to have. so a space should be sufficient as well.
|
||||
*/
|
||||
for(val_len=0; !(*opt_end == '\0' || isOptSep(*opt_end)); opt_end++,val_len++) {
|
||||
//if (*opt_end == NSK_JVMTI_OPTION_START) {
|
||||
// break;
|
||||
//}
|
||||
}
|
||||
|
||||
if (!add_option(opt, opt_len, val_sep, val_len)) {
|
||||
success = NSK_FALSE;
|
||||
break;
|
||||
}
|
||||
opt_end++;
|
||||
opt = opt_end;
|
||||
}
|
||||
|
||||
if (!success) {
|
||||
nsk_jvmti_free();
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************/
|
||||
|
||||
/**
|
||||
* Returns value of given option name; or NULL if no such option found.
|
||||
* If search name is NULL then complains an error and returns NULL.
|
||||
*/
|
||||
const char* nsk_jvmti_findOptionValue(const char name[]) {
|
||||
int i;
|
||||
|
||||
if (name == NULL) {
|
||||
nsk_complain("nsk_jvmti_findOptionValue(): option name is NULL\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (i = 0; i < context.options.count; i++) {
|
||||
if (strcmp(name, context.options.names[i]) == 0)
|
||||
return context.options.values[i];
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns string value of given option; or defaultValue if no such option found.
|
||||
* If options is specified but has empty value then complains an error and returns NULL.
|
||||
*/
|
||||
const char* nsk_jvmti_findOptionStringValue(const char name[], const char* defaultValue) {
|
||||
const char* value;
|
||||
|
||||
if (name == NULL) {
|
||||
nsk_complain("nsk_jvmti_findOptionStringValue(): option name is NULL\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
value = nsk_jvmti_findOptionValue(name);
|
||||
if (value == NULL) {
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
if (strlen(value) <= 0) {
|
||||
nsk_complain("nsk_jvmti_findOptionStringValue(): empty value of option: %s=%s\n",
|
||||
name, value);
|
||||
return NULL;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns integer value of given option; or defaultValue if no such option found.
|
||||
* If options is specified but has no integer value then complains an error and returns -1.
|
||||
*/
|
||||
int nsk_jvmti_findOptionIntValue(const char name[], int defaultValue) {
|
||||
const char* value;
|
||||
|
||||
if (name == NULL) {
|
||||
nsk_complain("nsk_jvmti_findOptionIntValue(): option name is NULL\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
value = nsk_jvmti_findOptionValue(name);
|
||||
if (value == NULL) {
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
if (strlen(value) <= 0) {
|
||||
nsk_complain("nsk_jvmti_findOptionIntValue(): empty value of option: %s=%s\n",
|
||||
name, value);
|
||||
return -1;
|
||||
}
|
||||
|
||||
{
|
||||
char* endptr = NULL;
|
||||
int n = strtol(value, &endptr, 10);
|
||||
|
||||
if (endptr == NULL || *endptr != '\0') {
|
||||
nsk_complain("nsk_jvmti_findOptionIntValue(): not integer value of option: %s=%s\n",
|
||||
name, value);
|
||||
return -1;
|
||||
}
|
||||
return n;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns number of parsed options.
|
||||
*/
|
||||
int nsk_jvmti_getOptionsCount() {
|
||||
return context.options.count;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns name of i-th parsed option.
|
||||
* If no such option then complains an error and returns NULL.
|
||||
*/
|
||||
const char* nsk_jvmti_getOptionName(int i) {
|
||||
if (i < 0 || i >= context.options.count) {
|
||||
nsk_complain("nsk_jvmti_getOptionName(): option index out of bounds: %d\n", i);
|
||||
return NULL;
|
||||
}
|
||||
return context.options.names[i];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns value of i-th parsed option.
|
||||
* If no such option then complains an error and returns NULL.
|
||||
*/
|
||||
const char* nsk_jvmti_getOptionValue(int i) {
|
||||
if (i < 0 || i >= context.options.count) {
|
||||
nsk_complain("nsk_jvmti_getOptionValue(): option index out of bounds: %d\n", i);
|
||||
return NULL;
|
||||
}
|
||||
return context.options.values[i];
|
||||
}
|
||||
|
||||
/*************************************************************/
|
||||
|
||||
/**
|
||||
* Returns value of -waittime option or default value if not specified.
|
||||
*/
|
||||
int nsk_jvmti_getWaitTime() {
|
||||
return context.waittime;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets specified waittime value.
|
||||
*/
|
||||
void nsk_jvmti_setWaitTime(int waittime) {
|
||||
context.waittime = waittime;
|
||||
}
|
||||
|
||||
/*************************************************************/
|
||||
|
||||
int nsk_jvmti_lverify(int positive, jvmtiError error, jvmtiError expected,
|
||||
const char file[], int line, const char format[], ...)
|
||||
{
|
||||
int failure=0;
|
||||
int negative = !positive;
|
||||
int errorCode = (int)error;
|
||||
const char* errorName = TranslateError(error);
|
||||
va_list ap;
|
||||
va_start(ap,format);
|
||||
nsk_lvtrace(NSK_TRACE_AFTER,file,line,format,ap);
|
||||
if (negative || expected != JVMTI_ERROR_NONE)
|
||||
nsk_ltrace(NSK_TRACE_AFTER,file,line,
|
||||
" jvmti error: code=%d, name=%s\n",errorCode,errorName);
|
||||
if ((error == expected) == negative) {
|
||||
nsk_lvcomplain(file,line,format,ap);
|
||||
nsk_printf("# jvmti error: code=%d, name=%s\n",errorCode,errorName);
|
||||
if (expected != JVMTI_ERROR_NONE)
|
||||
nsk_printf("# error expected: code=%d, name=%s\n",
|
||||
expected, TranslateError(expected));
|
||||
failure=1;
|
||||
};
|
||||
va_end(ap);
|
||||
return !failure;
|
||||
}
|
||||
|
||||
/*************************************************************/
|
||||
|
||||
JNIEXPORT jstring JNICALL
|
||||
Java_nsk_share_jvmti_ArgumentHandler_getAgentOptionsString(JNIEnv *jni, jobject obj) {
|
||||
jstring str_obj = NULL;
|
||||
|
||||
if (!NSK_JNI_VERIFY(jni, (str_obj =
|
||||
NSK_CPP_STUB2(NewStringUTF, jni, context.options.string)) != NULL)) {
|
||||
return NULL;
|
||||
}
|
||||
return str_obj;
|
||||
}
|
||||
|
||||
/*************************************************************/
|
||||
|
||||
/**
|
||||
* This method will try to redefine the class (classToRedefine) by loading
|
||||
* physical file. <b>pathToNewByteCode</b> option which is passed
|
||||
* on OnLoad Phase also used.
|
||||
*
|
||||
* So This method will do a file read pathToByteCode+fileName+.class (total path).
|
||||
* Constrcuts a class objects and does a redefine of the class.
|
||||
* On successfull redefine this method will return eaither JNI_TRUE or JNI_FALSE
|
||||
*
|
||||
* Hint::
|
||||
* 1)
|
||||
* If there are many redefine on same testcase, then please try to use
|
||||
* integer value (newclass00, newclass01, newclass02 , ....) way.
|
||||
*
|
||||
* 2) When you compile these please do keep, a metatag on testcase as
|
||||
* # build : native classes classes.redef
|
||||
*
|
||||
* 3) When you do build these classes are psysically located in build as.
|
||||
*
|
||||
* TESTBASE/bin/newclass0* directory.
|
||||
* eg: for nks/jvmti/scenarios/hotswap/HS204/hs204t001 you should see
|
||||
* TESTBASE/bin/newclass0* /nsk/hotswap/HS204/hs204t001/MyClass.class
|
||||
*
|
||||
*/
|
||||
|
||||
int nsk_jvmti_redefineClass(jvmtiEnv * jvmti,
|
||||
jclass classToRedefine,
|
||||
const char * fileName) {
|
||||
redefineAttempted = NSK_TRUE;
|
||||
if ( nsk_jvmti_findOptionValue(NSK_JVMTI_OPT_PATH_TO_NEW_BYTE_CODE)
|
||||
== NULL ) {
|
||||
nsk_printf("# error expected: %s \n",
|
||||
NSK_JVMTI_OPT_PATH_TO_NEW_BYTE_CODE );
|
||||
nsk_printf("Hint :: missing java -agentlib:agentlib=%s=DirName, ($TESTBASE/bin) \n",
|
||||
NSK_JVMTI_OPT_PATH_TO_NEW_BYTE_CODE );
|
||||
return NSK_FALSE;
|
||||
}
|
||||
if ( fileName == NULL) {
|
||||
nsk_printf("# error file name expected did not found \n");
|
||||
return NSK_FALSE;
|
||||
}
|
||||
{
|
||||
char file [1024];
|
||||
//= "DEFAULT";
|
||||
sprintf(file,"%s/%s.class",
|
||||
nsk_jvmti_findOptionValue(NSK_JVMTI_OPT_PATH_TO_NEW_BYTE_CODE),
|
||||
fileName);
|
||||
nsk_printf("# info :: File = %s \n",file);
|
||||
|
||||
{
|
||||
FILE *bytecode;
|
||||
unsigned char * classBytes;
|
||||
jvmtiError error;
|
||||
jint size;
|
||||
|
||||
bytecode = fopen(file, "rb");
|
||||
error= JVMTI_ERROR_NONE;
|
||||
if ( bytecode == NULL ) {
|
||||
nsk_printf("# error **Agent::error opening file %s \n",file);
|
||||
return NSK_FALSE;
|
||||
}
|
||||
|
||||
nsk_printf("# info **Agent:: opening file %s \n",file);
|
||||
fseek(bytecode, 0, SEEK_END);
|
||||
size = ftell(bytecode);
|
||||
nsk_printf("# info file size= %ld\n",ftell(bytecode));
|
||||
rewind(bytecode);
|
||||
error = (*jvmti)->Allocate(jvmti, size,&classBytes);
|
||||
if ( error != JVMTI_ERROR_NONE) {
|
||||
nsk_printf(" Failed to create memory %s \n",TranslateError(error));
|
||||
return NSK_FALSE;
|
||||
}
|
||||
|
||||
if ( ((jint) fread( classBytes, 1,size,bytecode )) != size ) {
|
||||
nsk_printf(" # error failed to read all the bytes , could be less or more \n");
|
||||
return NSK_FALSE;
|
||||
} else {
|
||||
nsk_printf(" File red completely \n");
|
||||
}
|
||||
fclose(bytecode);
|
||||
{
|
||||
jvmtiClassDefinition classDef;
|
||||
classDef.klass = classToRedefine;
|
||||
classDef.class_byte_count= size;
|
||||
classDef.class_bytes = classBytes;
|
||||
error = (*jvmti)->RedefineClasses(jvmti,1,&classDef);
|
||||
if ( error != JVMTI_ERROR_NONE ) {
|
||||
nsk_printf("# error occured while redefining %s ",
|
||||
TranslateError(error) );
|
||||
return NSK_FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
redefineSucceed= NSK_TRUE;
|
||||
return NSK_TRUE;
|
||||
}
|
||||
|
||||
JNIEXPORT jboolean JNICALL
|
||||
Java_nsk_share_jvmti_RedefineAgent_redefineAttempted(JNIEnv *jni, jobject obj) {
|
||||
|
||||
if (redefineAttempted == NSK_TRUE) {
|
||||
return JNI_TRUE;
|
||||
}else {
|
||||
return JNI_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
JNIEXPORT jboolean JNICALL
|
||||
Java_nsk_share_jvmti_RedefineAgent_isRedefined(JNIEnv * jni, jobject obj ) {
|
||||
|
||||
if (redefineSucceed == NSK_TRUE) {
|
||||
return JNI_TRUE;
|
||||
}else {
|
||||
return JNI_FALSE;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* This jni method is a Java wrapper for agent status.
|
||||
*/
|
||||
JNIEXPORT jboolean JNICALL
|
||||
Java_nsk_share_jvmti_RedefineAgent_agentStatus(JNIEnv * jni, jobject obj ) {
|
||||
if ( agentFailed == NSK_TRUE) {
|
||||
return JNI_FALSE;
|
||||
} else {
|
||||
return JNI_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
void nsk_jvmti_getFileName(int redefineCnt, const char * dir, char * buf, size_t bufsize) {
|
||||
snprintf(buf, bufsize, PATH_FORMAT, DIR_NAME, redefineCnt, dir);
|
||||
buf[bufsize-1] = '\0';
|
||||
}
|
||||
|
||||
int nsk_jvmti_enableNotification(jvmtiEnv *jvmti,jvmtiEvent event, jthread thread) {
|
||||
jvmtiError rc=JVMTI_ERROR_NONE;
|
||||
rc = (*jvmti)->SetEventNotificationMode(jvmti,JVMTI_ENABLE, event, thread);
|
||||
if (rc != JVMTI_ERROR_NONE) {
|
||||
nsk_printf("# error Failed to set Notification for Event \n ");
|
||||
return NSK_FALSE;
|
||||
}
|
||||
return NSK_TRUE;
|
||||
}
|
||||
|
||||
int nsk_jvmti_disableNotification(jvmtiEnv *jvmti,jvmtiEvent event, jthread thread) {
|
||||
jvmtiError rc=JVMTI_ERROR_NONE;
|
||||
rc = (*jvmti)->SetEventNotificationMode(jvmti,JVMTI_DISABLE, event, thread);
|
||||
if (rc != JVMTI_ERROR_NONE) {
|
||||
nsk_printf(" Failed to disaable Notification for Event ");
|
||||
return NSK_FALSE;
|
||||
}
|
||||
return NSK_TRUE;
|
||||
}
|
||||
|
||||
void nsk_jvmti_agentFailed() {
|
||||
agentFailed = NSK_TRUE;
|
||||
}
|
||||
|
||||
int isThreadExpected(jvmtiEnv *jvmti, jthread thread) {
|
||||
static const char *vm_jfr_buffer_thread_name = "VM JFR Buffer Thread";
|
||||
static const char *jfr_request_timer_thread_name = "JFR request timer";
|
||||
|
||||
jvmtiThreadInfo threadinfo;
|
||||
NSK_JVMTI_VERIFY((*jvmti)->GetThreadInfo(jvmti, thread, &threadinfo));
|
||||
|
||||
if (strcmp(threadinfo.name, vm_jfr_buffer_thread_name) == 0)
|
||||
return 0;
|
||||
|
||||
if (strcmp(threadinfo.name, jfr_request_timer_thread_name) == 0)
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
jint createRawMonitor(jvmtiEnv *env, const char *name, jrawMonitorID *monitor) {
|
||||
jvmtiError error = NSK_CPP_STUB3(CreateRawMonitor, env, name, monitor);
|
||||
if (!NSK_JVMTI_VERIFY(error)) {
|
||||
return JNI_ERR;
|
||||
}
|
||||
return JNI_OK;
|
||||
}
|
||||
|
||||
void exitOnError(jvmtiError error) {
|
||||
if (!NSK_JVMTI_VERIFY(error)) {
|
||||
exit(error);
|
||||
}
|
||||
}
|
||||
|
||||
void rawMonitorEnter(jvmtiEnv *env, jrawMonitorID monitor) {
|
||||
jvmtiError error = NSK_CPP_STUB2(RawMonitorEnter, env, monitor);
|
||||
exitOnError(error);
|
||||
}
|
||||
|
||||
void rawMonitorExit(jvmtiEnv *env, jrawMonitorID monitor) {
|
||||
jvmtiError error = NSK_CPP_STUB2(RawMonitorExit, env, monitor);
|
||||
exitOnError(error);
|
||||
}
|
||||
|
||||
void rawMonitorNotify(jvmtiEnv *env, jrawMonitorID monitor) {
|
||||
jvmtiError error = NSK_CPP_STUB2(RawMonitorNotify, env, monitor);
|
||||
exitOnError(error);
|
||||
}
|
||||
|
||||
void rawMonitorWait(jvmtiEnv *env, jrawMonitorID monitor, jlong millis) {
|
||||
jvmtiError error = NSK_CPP_STUB3(RawMonitorWait, env, monitor, millis);
|
||||
exitOnError(error);
|
||||
}
|
||||
|
||||
void getPhase(jvmtiEnv *env, jvmtiPhase *phase) {
|
||||
jvmtiError error = NSK_CPP_STUB2(GetPhase, env, phase);
|
||||
exitOnError(error);
|
||||
}
|
||||
|
||||
/*************************************************************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
400
test/hotspot/jtreg/vmTestbase/nsk/share/jvmti/jvmti_tools.h
Normal file
400
test/hotspot/jtreg/vmTestbase/nsk/share/jvmti/jvmti_tools.h
Normal file
@ -0,0 +1,400 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
#ifndef NSK_JVMTI_TOOLS_DEFINED
|
||||
#define NSK_JVMTI_TOOLS_DEFINED
|
||||
|
||||
/*************************************************************/
|
||||
|
||||
#include "jvmti.h"
|
||||
|
||||
/*************************************************************/
|
||||
|
||||
#include "nsk_tools.h"
|
||||
#include "jni_tools.h"
|
||||
#include "JVMTITools.h"
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/******************** Diagnostics errors *********************/
|
||||
|
||||
/**
|
||||
* Call JVMTI function in action, check error code to be
|
||||
* JVMTI_ERROR_NONE and complain error otherwise.
|
||||
* Also trace action execution if tracing mode is on.
|
||||
*/
|
||||
#define NSK_JVMTI_VERIFY(action) \
|
||||
(nsk_ltrace(NSK_TRACE_BEFORE,__FILE__,__LINE__,"%s\n",#action), \
|
||||
nsk_jvmti_lverify(NSK_TRUE,action,JVMTI_ERROR_NONE, \
|
||||
__FILE__,__LINE__,"%s\n",#action))
|
||||
|
||||
/**
|
||||
* Call JVMTI function in action, check error code to be
|
||||
* not JVMTI_ERROR_NONE and complain error otherwise.
|
||||
* Also trace action execution if tracing mode is on.
|
||||
*/
|
||||
#define NSK_JVMTI_VERIFY_NEGATIVE(action) \
|
||||
(nsk_ltrace(NSK_TRACE_BEFORE,__FILE__,__LINE__,"%s\n",#action), \
|
||||
nsk_jvmti_lverify(NSK_FALSE,action,JVMTI_ERROR_NONE, \
|
||||
__FILE__,__LINE__,"%s\n",#action))
|
||||
|
||||
/**
|
||||
* Call JVMTI function in action, check error code to be
|
||||
* equal to 'code' and complain error otherwise.
|
||||
* Also trace action execution if tracing mode is on.
|
||||
*/
|
||||
#define NSK_JVMTI_VERIFY_CODE(code, action) \
|
||||
(nsk_ltrace(NSK_TRACE_BEFORE,__FILE__,__LINE__,"%s\n",#action), \
|
||||
nsk_jvmti_lverify(NSK_TRUE,action,code,__FILE__,__LINE__,"%s\n",#action))
|
||||
|
||||
|
||||
/********************* Initialization ************************/
|
||||
|
||||
/**
|
||||
* Initialize framework and setup command line options for the JVMTI test.
|
||||
* If something fails, complains an error and returns 0 (NSK_FALSE).
|
||||
* On success returns 1 (NSK_TRUE).
|
||||
*/
|
||||
int nsk_jvmti_parseOptions(const char options[]);
|
||||
|
||||
/**
|
||||
* Creates JVMTI environment for the JVMTI test.
|
||||
* If something fails, complains an error and returns NULL.
|
||||
*/
|
||||
jvmtiEnv* nsk_jvmti_createJVMTIEnv(JavaVM* jvm, void* reserved);
|
||||
|
||||
/**
|
||||
* Register function to be run in agent thread.
|
||||
* If something fails, complains an error and returns 0 (NSK_FALSE).
|
||||
* On success returns 1 (NSK_TRUE).
|
||||
*/
|
||||
int nsk_jvmti_setAgentProc(jvmtiStartFunction proc, void* arg);
|
||||
|
||||
/**
|
||||
* Initialize multiple agent
|
||||
*/
|
||||
int nsk_jvmti_init_MA(jvmtiEventCallbacks* callbacks);
|
||||
|
||||
|
||||
/********************** Agent thread *************************/
|
||||
|
||||
/**
|
||||
* Returns thread object associated with agent thread..
|
||||
* If something fails, complains an error and returns NULL.
|
||||
*/
|
||||
jthread nsk_jvmti_getAgentThread();
|
||||
|
||||
/**
|
||||
* Returns JNI environment constructed for agent thread.
|
||||
* If something fails, complains an error and returns NULL.
|
||||
*/
|
||||
JNIEnv* nsk_jvmti_getAgentJNIEnv();
|
||||
|
||||
/**
|
||||
* Returns JVMTI environment constructed for agent.
|
||||
* If something fails, complains an error and returns NULL.
|
||||
*/
|
||||
jvmtiEnv* nsk_jvmti_getAgentJVMTIEnv();
|
||||
|
||||
/**
|
||||
* Waits for next synchronization point with debuggee class,
|
||||
* Then synchronizes current status and pauses debuggee thread.
|
||||
* If something fails, complains an error and returns 0 (NSK_FALSE).
|
||||
* On success returns 1 (NSK_TRUE).
|
||||
*/
|
||||
int nsk_jvmti_waitForSync(jlong timeout);
|
||||
|
||||
/**
|
||||
* Allow debuggee thread to continue execution after pausing on synchronization.
|
||||
* If something fails, complains an error and returns 0 (NSK_FALSE).
|
||||
* On success returns 1 (NSK_TRUE).
|
||||
*/
|
||||
int nsk_jvmti_resumeSync();
|
||||
|
||||
/**
|
||||
* Sleep current thread for given timeout in milliseconds.
|
||||
*/
|
||||
void nsk_jvmti_sleep(jlong timeout);
|
||||
|
||||
/**
|
||||
* Reset agent data to prepare for another run.
|
||||
*/
|
||||
void nsk_jvmti_resetAgentData();
|
||||
|
||||
/*********************** Agent status ************************/
|
||||
|
||||
#define NSK_STATUS_PASSED 0
|
||||
#define NSK_STATUS_FAILED 2
|
||||
#define NSK_STATUS_BASE 95
|
||||
|
||||
/**
|
||||
* Sets NSK_STATUS_FAILED as current agent status.
|
||||
*/
|
||||
void nsk_jvmti_setFailStatus();
|
||||
|
||||
/**
|
||||
* Returns 1 (NSK_TRUE) is current agent status is not NSK_STATUS_PASSED.
|
||||
* Returns 0 (NSK_FALSE) otherwise.
|
||||
*/
|
||||
int nsk_jvmti_isFailStatus();
|
||||
|
||||
/**
|
||||
* Returns current agent status.
|
||||
*/
|
||||
jint nsk_jvmti_getStatus();
|
||||
|
||||
|
||||
/********************* Classes and threads ******************/
|
||||
|
||||
/**
|
||||
* Finds first class with given signatire among loaded classes.
|
||||
* If no class found or something fails, complains an error and returns NULL.
|
||||
* On success creates and returns global reference to the found class.
|
||||
*/
|
||||
jclass nsk_jvmti_classBySignature(const char signature[]);
|
||||
|
||||
/**
|
||||
* Finds first thread with given name among alive threads.
|
||||
* If no thread found or something fails, complains an error and returns NULL.
|
||||
* On success creates and returns global reference to the found thread.
|
||||
*/
|
||||
jthread nsk_jvmti_threadByName(const char name[]);
|
||||
|
||||
|
||||
/******************* Breakpoints and locations ***************/
|
||||
|
||||
/**
|
||||
* Requests all capabilities needed for finding line location.
|
||||
* If something fails, complains an error and returns 0 (NSK_FALSE).
|
||||
* On success returns 1 (NSK_TRUE).
|
||||
*/
|
||||
int nsk_jvmti_addLocationCapabilities();
|
||||
|
||||
/**
|
||||
* Requests all capabilities needed for setting breakpoints.
|
||||
* If something fails, complains an error and returns 0 (NSK_FALSE).
|
||||
* On success returns 1 (NSK_TRUE).
|
||||
*/
|
||||
int nsk_jvmti_addBreakpointCapabilities();
|
||||
|
||||
#define NSK_JVMTI_INVALID_JLOCATION -2
|
||||
|
||||
/**
|
||||
* Returns jlocation for given method line.
|
||||
* If something fails, complains an error and returns NSK_JVMTI_INVALID_JLOCATION.
|
||||
*/
|
||||
jlocation nsk_jvmti_getLineLocation(jclass cls, jmethodID method, int line);
|
||||
|
||||
/**
|
||||
* Sets breakpoint to the given method line and return breakpoint location.
|
||||
* If something fails, complains an error and returns NSK_JVMTI_INVALID_JLOCATION.
|
||||
*/
|
||||
jlocation nsk_jvmti_setLineBreakpoint(jclass cls, jmethodID method, int line);
|
||||
|
||||
/**
|
||||
* Removes breakpoint from the given method line and return breakpoint location.
|
||||
* If something fails, complains an error and returns NSK_JVMTI_INVALID_JLOCATION.
|
||||
*/
|
||||
jlocation nsk_jvmti_clearLineBreakpoint(jclass cls, jmethodID method, int line);
|
||||
|
||||
|
||||
/********************* Events management *********************/
|
||||
|
||||
/**
|
||||
* Enables or disables all events of given list for given thread or NULL.
|
||||
* If something fails, complains an error and returns 0 (NSK_FALSE).
|
||||
*/
|
||||
int nsk_jvmti_enableEvents(jvmtiEventMode enable, int size,
|
||||
jvmtiEvent list[], jthread thread);
|
||||
|
||||
/**
|
||||
* Returns:
|
||||
* NSK_TRUE if given event is of optional functionality.
|
||||
* NSK_FALSE if given event is of required functionality.
|
||||
*/
|
||||
int nsk_jvmti_isOptionalEvent(jvmtiEvent event);
|
||||
|
||||
/**
|
||||
* Shows possessed capabilities
|
||||
*/
|
||||
void nsk_jvmti_showPossessedCapabilities(jvmtiEnv *jvmti);
|
||||
|
||||
/**
|
||||
* This method enables a single event
|
||||
* Return NSK_TRUE when on success and NSK_FALSE on failure.
|
||||
*/
|
||||
int nsk_jvmti_enableNotification(jvmtiEnv *jvmti, jvmtiEvent event, jthread thread);
|
||||
|
||||
/**
|
||||
* This method disables a single event
|
||||
* Return NSK_TRUE when on success and NSK_FALSE on failure.
|
||||
*/
|
||||
|
||||
int nsk_jvmti_disableNotification(jvmtiEnv *jvmti, jvmtiEvent event, jthread thread);
|
||||
|
||||
|
||||
/******************** Access test options ********************/
|
||||
|
||||
/**
|
||||
* Returns value of given option name; or NULL if no such option found.
|
||||
* If search name is NULL then complains an error and returns NULL.
|
||||
*/
|
||||
const char* nsk_jvmti_findOptionValue(const char name[]);
|
||||
|
||||
/**
|
||||
* Returns string value of given option; or defaultValue if no such option found.
|
||||
* If options is specified but has empty value then complains an error and returns NULL.
|
||||
*/
|
||||
const char* nsk_jvmti_findOptionStringValue(const char name[], const char* defaultValue);
|
||||
|
||||
/**
|
||||
* Returns integer value of given option; or defaultValue if no such option found.
|
||||
* If options is specified but has no integer value then complains an error and returns -1.
|
||||
*/
|
||||
int nsk_jvmti_findOptionIntValue(const char name[], int defaultValue);
|
||||
|
||||
/**
|
||||
* Returns number of parsed options.
|
||||
*/
|
||||
int nsk_jvmti_getOptionsCount();
|
||||
|
||||
/**
|
||||
* Returns name of i-th parsed option.
|
||||
* If no such option then complains an error and returns NULL.
|
||||
*/
|
||||
const char* nsk_jvmti_getOptionName(int i);
|
||||
|
||||
/**
|
||||
* Returns value of i-th parsed option.
|
||||
* If no such option then complains an error and returns NULL.
|
||||
*/
|
||||
const char* nsk_jvmti_getOptionValue(int i);
|
||||
|
||||
|
||||
/******************** Access system options ******************/
|
||||
|
||||
/**
|
||||
* Returns value of -waittime option or default value if not specified.
|
||||
*/
|
||||
int nsk_jvmti_getWaitTime();
|
||||
|
||||
/**
|
||||
* Sets specified waittime value.
|
||||
*/
|
||||
void nsk_jvmti_setWaitTime(int waittime);
|
||||
|
||||
|
||||
/*************************************************************/
|
||||
|
||||
/**
|
||||
* If positive, assert jvmtiError is equal to expected; or
|
||||
* if !positive, assert jvmtiError is not equal to expected.
|
||||
* Assert means: complain if the assertion is false.
|
||||
* Return the assertion value, either NSK_TRUE or NSK_FALSE.
|
||||
* Anyway, trace if "nsk_tools" mode is verbose.
|
||||
*/
|
||||
int nsk_jvmti_lverify(int positive, jvmtiError code, jvmtiError expected,
|
||||
const char file[], int line, const char format[], ...);
|
||||
|
||||
/************************************************************/
|
||||
|
||||
|
||||
/**
|
||||
* This method could be useful for hotswap testcases developed under.`
|
||||
* nsk/jvmti/scenarios/hotswap.
|
||||
*
|
||||
*/
|
||||
/**
|
||||
* This method will try to redefine the class (classToRedefine) by loading
|
||||
* physical file. <b>pathToNewByteCode</b> option which is passed
|
||||
* on OnLoad Phase also used.
|
||||
*
|
||||
* So This method will do a file read pathToByteCode+fileName+.class (total path).
|
||||
* Constrcuts a class objects and does a redefine of the class.
|
||||
* On successfull redefine this method will return eaither JNI_TRUE or JNI_FALSE
|
||||
*
|
||||
* Hint::
|
||||
* 1)
|
||||
* If there are many redefine on same testcase, then please try to use
|
||||
* integer value (newclass00, newclass01, newclass02 , ....) way.
|
||||
*
|
||||
* 2) When you compile these please do keep, a metatag on testcase as
|
||||
* # build : native classes classes.redef
|
||||
*
|
||||
* 3) When you do build these classes are psysically located in build as.
|
||||
*
|
||||
* TESTBASE/bin/newclass0* directory.
|
||||
* eg: for nks/jvmti/scenarios/hotswap/HS204/hs204t001 you should see
|
||||
* TESTBASE/bin/newclass0* /nsk/hotswap/HS204/hs204t001/MyClass.class
|
||||
*
|
||||
*/
|
||||
|
||||
int nsk_jvmti_redefineClass(jvmtiEnv * jvmti,
|
||||
jclass classToRedefine,
|
||||
const char * fileName);
|
||||
/**
|
||||
* changed this signature with Ekaterina's suggestion to move.
|
||||
*
|
||||
*/
|
||||
void nsk_jvmti_getFileName(int redefineCnt, const char * dir, char * buf, size_t bufsize);
|
||||
|
||||
/**
|
||||
* This method sets agent status to failed, This would enables native agent to set its status.
|
||||
* There is <b>nsk_jvmti_setFailStatus()</b> method which is in sync with debugge/debugger combination.
|
||||
* For non-debugger agents, this method can be used. There is java wrapper for this status,
|
||||
* defined in java nsk.share.jvmti.RedefineAgent class as boolean : agentStatus().
|
||||
*
|
||||
*/
|
||||
void nsk_jvmti_agentFailed();
|
||||
|
||||
int isThreadExpected(jvmtiEnv *jvmti, jthread thread);
|
||||
|
||||
jint createRawMonitor(jvmtiEnv *env, const char *name, jrawMonitorID *monitor);
|
||||
|
||||
void exitOnError(jvmtiError error);
|
||||
|
||||
/**
|
||||
Wrappers for corresponded JVMTI functions check error code and force exit on error
|
||||
*/
|
||||
void rawMonitorEnter(jvmtiEnv *env, jrawMonitorID monitor);
|
||||
void rawMonitorExit(jvmtiEnv *env, jrawMonitorID monitor);
|
||||
void rawMonitorNotify(jvmtiEnv *env, jrawMonitorID monitor);
|
||||
void rawMonitorWait(jvmtiEnv *env, jrawMonitorID monitor, jlong millis);
|
||||
void getPhase(jvmtiEnv *env, jvmtiPhase *phase);
|
||||
|
||||
/*******************************************************************/
|
||||
|
||||
#if (defined(WIN32) || defined(_WIN32))
|
||||
#define snprintf _snprintf
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
@ -0,0 +1,78 @@
|
||||
/*
|
||||
* Copyright (c) 2010, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @modules java.base/jdk.internal.misc
|
||||
*
|
||||
* @summary converted from VM Testbase vm/mlvm/anonloader/func/castToGrandparent.
|
||||
* VM Testbase keywords: [feature_mlvm]
|
||||
* VM Testbase readme:
|
||||
* DESCRIPTION
|
||||
* Cast an object loaded with Unsafe.defineAnonymousClass to superclass of its parent class. This cast should succeed.
|
||||
*
|
||||
* @library /vmTestbase
|
||||
* /test/lib
|
||||
* @run driver jdk.test.lib.FileInstaller . .
|
||||
*
|
||||
* @comment build test class and indify classes
|
||||
* @build vm.mlvm.anonloader.func.castToGrandparent.Test
|
||||
* @run driver vm.mlvm.share.IndifiedClassesBuilder
|
||||
*
|
||||
* @run main/othervm vm.mlvm.anonloader.func.castToGrandparent.Test
|
||||
*/
|
||||
|
||||
package vm.mlvm.anonloader.func.castToGrandparent;
|
||||
|
||||
import vm.mlvm.anonloader.share.AnonkTestee01;
|
||||
import vm.mlvm.anonloader.share.AnonkTestee02;
|
||||
import vm.mlvm.share.Env;
|
||||
import vm.mlvm.share.MlvmTest;
|
||||
import vm.share.FileUtils;
|
||||
import vm.share.UnsafeAccess;
|
||||
|
||||
public class Test extends MlvmTest {
|
||||
private static final Class<?> PARENT = AnonkTestee02.class;
|
||||
|
||||
@Override
|
||||
public boolean run() throws Exception {
|
||||
byte[] classBytes = FileUtils.readClass(PARENT.getName());
|
||||
Class<?> cls = UnsafeAccess.unsafe.defineAnonymousClass(
|
||||
PARENT, classBytes, null);
|
||||
Object anonObject = cls.newInstance();
|
||||
// Try to cast anonymous class to its grandparent
|
||||
AnonkTestee01 anonCastToParent = (AnonkTestee01) anonObject;
|
||||
if ( anonCastToParent.equals(anonObject) )
|
||||
Env.traceNormal("Anonymous object can be cast to original one");
|
||||
|
||||
// Try to cast using another method
|
||||
new AnonkTestee01().getClass().cast(anonObject);
|
||||
|
||||
Env.traceNormal("Anonymous class can be cast to original one");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static void main(String[] args) { MlvmTest.launch(args); }
|
||||
}
|
@ -0,0 +1,81 @@
|
||||
/*
|
||||
* Copyright (c) 2010, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @modules java.base/jdk.internal.misc
|
||||
*
|
||||
* @summary converted from VM Testbase vm/mlvm/anonloader/func/castToParent.
|
||||
* VM Testbase keywords: [feature_mlvm, clarify-spec, exclude]
|
||||
* VM Testbase comments: 8199227
|
||||
* VM Testbase readme:
|
||||
* DESCRIPTION
|
||||
* Try to cast an object of a class, which is loaded by Unsafe.defineAnonymousClass to its
|
||||
* parent (called AnonkTestee01) using the following cast methods:
|
||||
* - (AnonkTestee01) o
|
||||
* - o.getClass().cast(new AnonkTestee01());
|
||||
*
|
||||
* @library /vmTestbase
|
||||
* /test/lib
|
||||
* @run driver jdk.test.lib.FileInstaller . .
|
||||
* @ignore 8199227
|
||||
*
|
||||
* @comment build test class and indify classes
|
||||
* @build vm.mlvm.anonloader.func.castToParent.Test
|
||||
* @run driver vm.mlvm.share.IndifiedClassesBuilder
|
||||
*
|
||||
* @run main/othervm vm.mlvm.anonloader.func.castToParent.Test
|
||||
*/
|
||||
|
||||
package vm.mlvm.anonloader.func.castToParent;
|
||||
|
||||
import vm.mlvm.anonloader.share.AnonkTestee01;
|
||||
import vm.mlvm.share.Env;
|
||||
import vm.mlvm.share.MlvmTest;
|
||||
import vm.share.FileUtils;
|
||||
import vm.share.UnsafeAccess;
|
||||
|
||||
public class Test extends MlvmTest {
|
||||
private static final Class<?> PARENT = AnonkTestee01.class;
|
||||
|
||||
public boolean run() throws Exception {
|
||||
byte[] classBytes = FileUtils.readClass(PARENT.getName());
|
||||
Class<?> cls = UnsafeAccess.unsafe.defineAnonymousClass(PARENT,
|
||||
classBytes, null);
|
||||
Object o = cls.newInstance();
|
||||
// Try to cast anonymous class to its parent
|
||||
AnonkTestee01 anonCastToParent = (AnonkTestee01) o;
|
||||
if ( anonCastToParent.equals(o) )
|
||||
Env.traceNormal("Anonymous object can be cast to original one");
|
||||
|
||||
// Cast the class
|
||||
new AnonkTestee01().getClass().cast(o);
|
||||
|
||||
Env.traceNormal("Anonymous can be cast to original class");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static void main(String[] args) { MlvmTest.launch(args); }
|
||||
}
|
82
test/hotspot/jtreg/vmTestbase/vm/mlvm/anonloader/func/classNameInStackTrace/Test.java
Normal file
82
test/hotspot/jtreg/vmTestbase/vm/mlvm/anonloader/func/classNameInStackTrace/Test.java
Normal file
@ -0,0 +1,82 @@
|
||||
/*
|
||||
* Copyright (c) 2010, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @modules java.base/jdk.internal.misc
|
||||
*
|
||||
* @summary converted from VM Testbase vm/mlvm/anonloader/func/classNameInStackTrace.
|
||||
* VM Testbase keywords: [feature_mlvm]
|
||||
* VM Testbase readme:
|
||||
* DESCRIPTION
|
||||
* An exception is thrown by class loaded by Unsafe.defineAnonymousClass. Verify that
|
||||
* the exception's stack trace contains name of the current test class (i.e.,
|
||||
* verify that the stack trace is not broken)
|
||||
*
|
||||
* @library /vmTestbase
|
||||
* /test/lib
|
||||
* @run driver jdk.test.lib.FileInstaller . .
|
||||
*
|
||||
* @comment build test class and indify classes
|
||||
* @build vm.mlvm.anonloader.func.classNameInStackTrace.Test
|
||||
* @run driver vm.mlvm.share.IndifiedClassesBuilder
|
||||
*
|
||||
* @run main/othervm vm.mlvm.anonloader.func.classNameInStackTrace.Test
|
||||
*/
|
||||
|
||||
package vm.mlvm.anonloader.func.classNameInStackTrace;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.PrintStream;
|
||||
|
||||
import vm.mlvm.anonloader.share.AnonkTestee01;
|
||||
import vm.mlvm.share.MlvmTest;
|
||||
import vm.share.FileUtils;
|
||||
import vm.share.UnsafeAccess;
|
||||
|
||||
public class Test extends MlvmTest {
|
||||
private static final Class<?> PARENT = AnonkTestee01.class;
|
||||
|
||||
public boolean run() throws Exception {
|
||||
byte[] classBytes = FileUtils.readClass(PARENT.getName());
|
||||
Class<?> cls = UnsafeAccess.unsafe.defineAnonymousClass(PARENT,
|
||||
classBytes, null);
|
||||
try {
|
||||
// hashCode() in AnonkTestee01 always throws an exception
|
||||
cls.newInstance().hashCode();
|
||||
return false;
|
||||
|
||||
} catch ( RuntimeException e ) {
|
||||
ByteArrayOutputStream byteOS = new ByteArrayOutputStream();
|
||||
PrintStream printStream = new PrintStream(byteOS);
|
||||
e.printStackTrace(printStream);
|
||||
printStream.close();
|
||||
String stackTrace = byteOS.toString("ASCII");
|
||||
getLog().display("Caught exception stack trace: " + stackTrace);
|
||||
return stackTrace.contains(Test.class.getName());
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) { MlvmTest.launch(args); }
|
||||
}
|
50
test/hotspot/jtreg/vmTestbase/vm/mlvm/anonloader/func/finalSuperclass/TestDescription.java
Normal file
50
test/hotspot/jtreg/vmTestbase/vm/mlvm/anonloader/func/finalSuperclass/TestDescription.java
Normal file
@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @modules java.base/jdk.internal.misc java.base/jdk.internal.org.objectweb.asm
|
||||
*
|
||||
* @summary converted from VM Testbase vm/mlvm/anonloader/func/finalSuperclass.
|
||||
* VM Testbase keywords: [feature_mlvm]
|
||||
* VM Testbase readme:
|
||||
* DESCRIPTION
|
||||
* Try to load anonymous class derived from java.lang.System. The verification
|
||||
* system (split verifier and system class loader) should reject such attempt and
|
||||
* throw VerifyError.
|
||||
*
|
||||
* @library /vmTestbase
|
||||
* /test/lib
|
||||
* @run driver jdk.test.lib.FileInstaller . .
|
||||
*
|
||||
* @comment build test class and indify classes
|
||||
* @build vm.mlvm.anonloader.share.ReplaceClassParentTest
|
||||
* @run driver vm.mlvm.share.IndifiedClassesBuilder
|
||||
*
|
||||
* @run main/othervm
|
||||
* vm.mlvm.anonloader.share.ReplaceClassParentTest
|
||||
* -newParent java/lang/System
|
||||
* -requireExceptions java.lang.VerifyError
|
||||
*/
|
||||
|
@ -0,0 +1,71 @@
|
||||
/*
|
||||
* Copyright (c) 2010, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @modules java.base/jdk.internal.misc
|
||||
*
|
||||
* @summary converted from VM Testbase vm/mlvm/anonloader/func/findByName.
|
||||
* VM Testbase keywords: [feature_mlvm]
|
||||
* VM Testbase readme:
|
||||
* DESCRIPTION
|
||||
* Try to find a class loaded using Unsafe.defineAnonymousClass through the VM system dictionary
|
||||
* (using Class.forName()). It is an error when the class can be found in this way.
|
||||
*
|
||||
* @library /vmTestbase
|
||||
* /test/lib
|
||||
* @run driver jdk.test.lib.FileInstaller . .
|
||||
*
|
||||
* @comment build test class and indify classes
|
||||
* @build vm.mlvm.anonloader.func.findByName.Test
|
||||
* @run driver vm.mlvm.share.IndifiedClassesBuilder
|
||||
*
|
||||
* @run main/othervm vm.mlvm.anonloader.func.findByName.Test
|
||||
*/
|
||||
|
||||
package vm.mlvm.anonloader.func.findByName;
|
||||
|
||||
import vm.mlvm.anonloader.share.AnonkTestee01;
|
||||
import vm.mlvm.share.MlvmTest;
|
||||
import vm.share.FileUtils;
|
||||
import vm.share.UnsafeAccess;
|
||||
|
||||
public class Test extends MlvmTest {
|
||||
private static final Class<?> PARENT = AnonkTestee01.class;
|
||||
|
||||
public boolean run() throws Exception {
|
||||
try {
|
||||
byte[] classBytes = FileUtils.readClass(PARENT.getName());
|
||||
Class<?> c = UnsafeAccess.unsafe.defineAnonymousClass(PARENT,
|
||||
classBytes, null);
|
||||
getLog().display("Anonymous class name: " + c.getName());
|
||||
Class.forName(c.getName()).newInstance();
|
||||
return false;
|
||||
} catch ( ClassNotFoundException e ) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) { MlvmTest.launch(args); }
|
||||
}
|
@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Copyright (c) 2010, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @modules java.base/jdk.internal.misc java.base/jdk.internal.org.objectweb.asm
|
||||
*
|
||||
* @summary converted from VM Testbase vm/mlvm/anonloader/func/invalidSuperclass.
|
||||
* VM Testbase keywords: [feature_mlvm]
|
||||
*
|
||||
* @library /vmTestbase
|
||||
* /test/lib
|
||||
* @run driver jdk.test.lib.FileInstaller . .
|
||||
*
|
||||
* @comment build test class and indify classes
|
||||
* @build vm.mlvm.anonloader.func.invalidSuperclass.Test
|
||||
* @run driver vm.mlvm.share.IndifiedClassesBuilder
|
||||
*
|
||||
* @run main/othervm -Xverify:all vm.mlvm.anonloader.func.invalidSuperclass.Test
|
||||
*/
|
||||
|
||||
package vm.mlvm.anonloader.func.invalidSuperclass;
|
||||
|
||||
import vm.mlvm.anonloader.share.ReplaceClassParentTest;
|
||||
import vm.mlvm.share.MlvmTestExecutor;
|
||||
|
||||
/**
|
||||
* Using Unsafe.defineAnonymousClass to load a class that has a patched superclass name, which is invalid.
|
||||
* Verify that such class cannot be loaded.
|
||||
*
|
||||
*/
|
||||
public class Test extends ReplaceClassParentTest {
|
||||
|
||||
@Override
|
||||
protected void initializeTest() throws Throwable {
|
||||
super.initializeTest();
|
||||
setReplaceParent(String.format("%9999s", "Can you find me?"));
|
||||
setRequiredExceptions(java.lang.NoClassDefFoundError.class);
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
MlvmTestExecutor.launch(args);
|
||||
}
|
||||
}
|
@ -0,0 +1,79 @@
|
||||
/*
|
||||
* Copyright (c) 2010, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @modules java.base/jdk.internal.misc
|
||||
*
|
||||
* @summary converted from VM Testbase vm/mlvm/anonloader/func/isGarbageCollected.
|
||||
* VM Testbase keywords: [feature_mlvm]
|
||||
* VM Testbase readme:
|
||||
* DESCRIPTION
|
||||
* Load an anonymous class, drop all references to it and verify that it is collected
|
||||
* by GC afterwards (call System.gc() just in case). PhantomReference is used to
|
||||
* check that the anonymous class is gone.
|
||||
*
|
||||
* @library /vmTestbase
|
||||
* /test/lib
|
||||
* @run driver jdk.test.lib.FileInstaller . .
|
||||
*
|
||||
* @comment build test class and indify classes
|
||||
* @build vm.mlvm.anonloader.func.isGarbageCollected.Test
|
||||
* @run driver vm.mlvm.share.IndifiedClassesBuilder
|
||||
*
|
||||
* @run main/othervm vm.mlvm.anonloader.func.isGarbageCollected.Test
|
||||
*/
|
||||
|
||||
package vm.mlvm.anonloader.func.isGarbageCollected;
|
||||
|
||||
import java.lang.ref.PhantomReference;
|
||||
import java.lang.ref.Reference;
|
||||
import java.lang.ref.ReferenceQueue;
|
||||
|
||||
import vm.mlvm.anonloader.share.AnonkTestee01;
|
||||
import vm.mlvm.share.MlvmTest;
|
||||
import vm.share.FileUtils;
|
||||
import vm.share.UnsafeAccess;
|
||||
|
||||
public class Test extends MlvmTest {
|
||||
private static final Class<?> PARENT = AnonkTestee01.class;
|
||||
|
||||
public boolean run() throws Exception {
|
||||
ReferenceQueue<Class<?>> refQueue = new ReferenceQueue<Class<?>>();
|
||||
PhantomReference<Class<?>> anonClassRef = createClass(refQueue);
|
||||
System.gc();
|
||||
Reference<? extends Class<?>> deletedObject = refQueue.remove();
|
||||
return anonClassRef.equals(deletedObject);
|
||||
}
|
||||
|
||||
// a private method is great to keep anonClass reference local to make it GCed on the next cycle
|
||||
private PhantomReference<Class<?>> createClass(ReferenceQueue<Class<?>> refQueue) throws Exception {
|
||||
byte[] classBytes = FileUtils.readClass(PARENT.getName());
|
||||
Class<?> anonClass = UnsafeAccess.unsafe.defineAnonymousClass(PARENT,
|
||||
classBytes, null);
|
||||
return new PhantomReference<Class<?>>(anonClass, refQueue);
|
||||
}
|
||||
|
||||
public static void main(String[] args) { MlvmTest.launch(args); }
|
||||
}
|
@ -0,0 +1,83 @@
|
||||
/*
|
||||
* Copyright (c) 2010, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @modules java.base/jdk.internal.misc java.base/jdk.internal.org.objectweb.asm
|
||||
*
|
||||
* @summary converted from VM Testbase vm/mlvm/anonloader/func/uniqueClassAndObject.
|
||||
* VM Testbase keywords: [feature_mlvm]
|
||||
* VM Testbase readme:
|
||||
* DESCRIPTION
|
||||
* Create two anonymous classes and instantiate an object from each of them.
|
||||
* Verify that the references to these objects are different and references
|
||||
* to their classes are not equal too.
|
||||
*
|
||||
* @library /vmTestbase
|
||||
* /test/lib
|
||||
* @run driver jdk.test.lib.FileInstaller . .
|
||||
*
|
||||
* @comment build test class and indify classes
|
||||
* @build vm.mlvm.anonloader.func.uniqueClassAndObject.Test
|
||||
* @run driver vm.mlvm.share.IndifiedClassesBuilder
|
||||
*
|
||||
* @run main/othervm vm.mlvm.anonloader.func.uniqueClassAndObject.Test
|
||||
*/
|
||||
|
||||
package vm.mlvm.anonloader.func.uniqueClassAndObject;
|
||||
|
||||
import jdk.internal.org.objectweb.asm.ClassReader;
|
||||
import vm.mlvm.anonloader.share.AnonkTestee01;
|
||||
import vm.mlvm.share.MlvmTest;
|
||||
import vm.share.FileUtils;
|
||||
import vm.share.UnsafeAccess;
|
||||
|
||||
public class Test extends MlvmTest {
|
||||
private static final Class<?> PARENT = AnonkTestee01.class;
|
||||
|
||||
@Override
|
||||
public boolean run() throws Exception {
|
||||
byte[] classBytes = FileUtils.readClass(PARENT.getName());
|
||||
ClassReader reader = new ClassReader(classBytes);
|
||||
Object o1 = UnsafeAccess.unsafe.defineAnonymousClass(PARENT,
|
||||
classBytes, null).newInstance();
|
||||
int cpLength = reader.getItemCount();
|
||||
Object cpPatch[] = new Object[cpLength];
|
||||
Object o2 = UnsafeAccess.unsafe.defineAnonymousClass(PARENT,
|
||||
classBytes, cpPatch).newInstance();
|
||||
if ( o1 == o2 ) {
|
||||
getLog().complain("Error: The objects are equal");
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( o1.getClass() == o2.getClass() ) {
|
||||
getLog().complain("Error: The classes are equal");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static void main(String[] args) { MlvmTest.launch(args); }
|
||||
}
|
@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright (c) 2010, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package vm.mlvm.anonloader.share;
|
||||
|
||||
import vm.mlvm.share.Env;
|
||||
|
||||
public class AnonkTestee01 {
|
||||
public final static String muzzy = "BIG \uFFFF\u0000\uFFFE\uFEFF MUZZY";
|
||||
public final static String
|
||||
theDrumIsTheDrumIsTheDrumIsTheDrumIsTheDrumIsTheDrumIsTheDrumIsTheDrumIsTheDrumIsTheDrumIsTheDrumIsTheDrumIsTheDrumIsTheDrumIsTheDrumIsTheDrumIsTheDrumIsTheDrumIsTheDrumIsTheDrumIsTheDrumIsTheDrumIsTheDrumIsTheDrumIsTheDrum
|
||||
= String.format("%65500c%X", 'c', Env.getRNG().nextLong());
|
||||
|
||||
public final String beatingTheDrumIsTheDrumIsTheDrumIsTheDrumIsTheDrumIsTheDrumIsTheDrumIsTheDrumIsTheDrumIsTheDrumIsTheDrumIsTheDrumIsTheDrumIsTheDrumIsTheDrumIsTheDrumIsTheDrumIsTheDrumIsTheDrumIsTheDrumIsTheDrumIsTheDrumIsTheDrumIsTheDrumIsTheDrum() {
|
||||
return theDrumIsTheDrumIsTheDrumIsTheDrumIsTheDrumIsTheDrumIsTheDrumIsTheDrumIsTheDrumIsTheDrumIsTheDrumIsTheDrumIsTheDrumIsTheDrumIsTheDrumIsTheDrumIsTheDrumIsTheDrumIsTheDrumIsTheDrumIsTheDrumIsTheDrumIsTheDrumIsTheDrumIsTheDrum;
|
||||
}
|
||||
|
||||
public final String toString() {
|
||||
return "Something that looks like " + super.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
throw new RuntimeException("Making fun of errors");
|
||||
}
|
||||
}
|
@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright (c) 2010, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package vm.mlvm.anonloader.share;
|
||||
|
||||
public class AnonkTestee02 extends AnonkTestee01 {
|
||||
public AnonkTestee02() {}
|
||||
}
|
@ -0,0 +1,85 @@
|
||||
/*
|
||||
* Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package vm.mlvm.anonloader.share;
|
||||
|
||||
import jdk.internal.org.objectweb.asm.ClassReader;
|
||||
import vm.mlvm.share.MlvmTest;
|
||||
import vm.mlvm.share.MlvmTestExecutor;
|
||||
import vm.mlvm.share.Env;
|
||||
import vm.share.FileUtils;
|
||||
import vm.share.UnsafeAccess;
|
||||
import vm.share.options.Option;
|
||||
|
||||
/**
|
||||
* This is a base class for kind of tests, which modify the parent class name of test dummy class vm.mlvm.share.AnonkTestee01
|
||||
* with an arbitrary string, load the modified class using Unsafe.defineAnonymousClass and instantiate it.
|
||||
* <p>
|
||||
* The tests can extend this class or use it from command-line to provide the actual data:
|
||||
* <ul>
|
||||
* <li>new parent class name,
|
||||
* <li>optionally the list of expected exceptions to be thrown during class loading and instantiation
|
||||
* (see {@link vm.mlvm.share.MlvmTest#setRequiredExceptions(Class<? extends Throwable>... classes)} for details)
|
||||
* </ul>
|
||||
*/
|
||||
|
||||
public class ReplaceClassParentTest extends MlvmTest {
|
||||
|
||||
@Option(name = "newParent", default_value = "", description = "String to replace the name of the parent class of the testee")
|
||||
private String newParentOpt;
|
||||
|
||||
public void setReplaceParent(String newParent) {
|
||||
newParentOpt = newParent;
|
||||
}
|
||||
|
||||
private static final Class<?> TESTEE_CLASS = AnonkTestee01.class;
|
||||
|
||||
public ReplaceClassParentTest() {
|
||||
}
|
||||
|
||||
public boolean run() throws Throwable {
|
||||
byte[] classBytes = FileUtils.readClass(TESTEE_CLASS.getName());
|
||||
ClassReader reader = new ClassReader(classBytes);
|
||||
int superclassNameIdx = reader.readUnsignedShort(reader.header + 4);
|
||||
int cpLength = reader.getItemCount();
|
||||
if (superclassNameIdx == 0) {
|
||||
throw new RuntimeException("Test bug: unable to find super class"
|
||||
+ " name index");
|
||||
}
|
||||
Env.traceDebug("Superclass name CP index: " + superclassNameIdx
|
||||
+ "; replacing CP entry with '" + newParentOpt + "'");
|
||||
// now, construction of cp patch
|
||||
Object cpPatch[] = new Object[cpLength];
|
||||
cpPatch[superclassNameIdx] = newParentOpt;
|
||||
// define and instantiate
|
||||
UnsafeAccess.unsafe.defineAnonymousClass(TESTEE_CLASS, classBytes,
|
||||
cpPatch).newInstance();
|
||||
// Whether test should pass or fail should be specified via requireExceptions mechanism in MlvmTest
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
MlvmTestExecutor.launch(args);
|
||||
}
|
||||
}
|
@ -0,0 +1,228 @@
|
||||
/*
|
||||
* Copyright (c) 2010, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package vm.mlvm.anonloader.share;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Paths;
|
||||
import nsk.share.test.Stresser;
|
||||
import vm.share.options.Option;
|
||||
import vm.share.options.OptionSupport;
|
||||
import vm.share.options.IgnoreUnknownArgumentsHandler;
|
||||
import vm.mlvm.share.Env;
|
||||
import vm.mlvm.share.MlvmTest;
|
||||
import vm.mlvm.share.CustomClassLoaders;
|
||||
import vm.share.FileUtils;
|
||||
import vm.share.UnsafeAccess;
|
||||
|
||||
/**
|
||||
* Does stress-testing of class loading subsystem.
|
||||
* This class should be subclassed by the tests
|
||||
* to provide test class data.
|
||||
*
|
||||
* <p>StressClassLoadingTest performs a number of iterations
|
||||
* (the default value is 100 000).
|
||||
* Each iteration gets class bytes from the subclass
|
||||
* and loads it into JVM using either:
|
||||
* <ul>
|
||||
* <li>a custom {@link java.lang.ClassLoader} implementation or
|
||||
* <li>{@link sun.misc.Unsafe#defineAnonymousClass} call.
|
||||
* </ul>
|
||||
*
|
||||
* <p>Loading is done in a separate thread. If this thread is stuck,
|
||||
* it is killed after some timeout (default is 10 seconds, please see
|
||||
* -parseTimeout option). The class file is saved as hangXX.class, where XX
|
||||
* starts at 00 and is increased on every hangup.
|
||||
* A prefix can be added to the file name using {@link #setFileNamePrefix}
|
||||
*
|
||||
* <p>The test fails, if there were hangups.
|
||||
*
|
||||
* <p>By default, before loading class, the bytes are
|
||||
* saved to {@code _AnonkTestee01.class} file in the current directory.
|
||||
* If JVM crashes, the bytecodes can be analysed.
|
||||
* Class saving is controlled by -saveClassFile option.
|
||||
* A prefix can be added to the file name using {@link #setFileNamePrefix}
|
||||
* function.
|
||||
*
|
||||
* <p>There is a tool to load the saved .class file.
|
||||
* The tool tries to load class using a number of class loaders. For more
|
||||
* information, please see tool documentation: {@link vm.mlvm.tools.LoadClass}.
|
||||
*
|
||||
* @see vm.mlvm.tools.LoadClass
|
||||
*/
|
||||
public abstract class StressClassLoadingTest extends MlvmTest {
|
||||
private static final String RESCUE_FILE_NAME = "_AnonkTestee01.class";
|
||||
private static final String HUNG_CLASS_FILE_NAME = "hang%02d.class";
|
||||
|
||||
@Option(name = "iterations", default_value = "100000",
|
||||
description = "How many times generate a class and parse it")
|
||||
private static int iterations;
|
||||
|
||||
@Option(name = "saveClassFile", default_value = "true",
|
||||
description = "Save generated class file before loading."
|
||||
+ " Useful when VM crashes on loading")
|
||||
private static boolean saveClassFile;
|
||||
|
||||
@Option(name = "parseTimeout", default_value = "10000",
|
||||
description = "Timeout in millisectionds to detect hung parser"
|
||||
+ " thread. The parser thread is killed after the timeout")
|
||||
private static int parseTimeout;
|
||||
|
||||
@Option(name = "unsafeLoad", default_value = "false",
|
||||
description = "An option for adhoc experiments: load class via "
|
||||
+ "Unsafe.defineAnonymousClass(). Since in this way the "
|
||||
+ "loading process skips several security checks, if the "
|
||||
+ "class is not valid, crashes and assertions are normal.")
|
||||
private static boolean unsafeLoad;
|
||||
|
||||
private String fileNamePrefix = "";
|
||||
|
||||
private final static AtomicBoolean classFileMessagePrinted
|
||||
= new AtomicBoolean(false);
|
||||
|
||||
/**
|
||||
* Sets prefix for names of the files, created by test:
|
||||
* _AnonkTestee01.class and hangXX.class.
|
||||
*
|
||||
* @param p a prefix to add before file name.
|
||||
* @throws java.lang.NullPointerException if p is null
|
||||
*/
|
||||
public void setFileNamePrefix(String p) {
|
||||
Objects.requireNonNull(p);
|
||||
fileNamePrefix = p;
|
||||
}
|
||||
|
||||
static volatile boolean optionsSetup = false;
|
||||
public static void setupOptions(Object instance) {
|
||||
if (!optionsSetup) {
|
||||
synchronized (StressClassLoadingTest.class) {
|
||||
if (!optionsSetup) {
|
||||
OptionSupport.setup(instance, Env.getArgParser().getRawArguments(), new IgnoreUnknownArgumentsHandler());
|
||||
optionsSetup = true;
|
||||
|
||||
Env.traceNormal("StressClassLoadingTest options: iterations: " + iterations);
|
||||
Env.traceNormal("StressClassLoadingTest options: unsafeLoad: " + unsafeLoad);
|
||||
Env.traceNormal("StressClassLoadingTest options: parseTimeout: " + parseTimeout);
|
||||
Env.traceNormal("StressClassLoadingTest options: saveClassFile: " + saveClassFile);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean run() throws Exception {
|
||||
setupOptions(this);
|
||||
|
||||
int hangNum = 0;
|
||||
|
||||
Stresser stresser = createStresser();
|
||||
stresser.start(iterations);
|
||||
|
||||
while (stresser.continueExecution()) {
|
||||
stresser.iteration();
|
||||
|
||||
byte[] classBytes = generateClassBytes();
|
||||
Class<?> hostClass = getHostClass();
|
||||
String className = hostClass.getName();
|
||||
File rescueFile = new File(String.format("%s_%d_%s",
|
||||
fileNamePrefix, stresser.getIteration(), RESCUE_FILE_NAME));
|
||||
if (saveClassFile) {
|
||||
// Write out the class file being loaded. It's useful
|
||||
// to have if the JVM crashes.
|
||||
FileUtils.writeBytesToFile(rescueFile, classBytes);
|
||||
if (classFileMessagePrinted.compareAndSet(false, true)) {
|
||||
Env.traceImportant("If the JVM crashes then "
|
||||
+ "the class file causing the crash is saved as *_*_"
|
||||
+ RESCUE_FILE_NAME);
|
||||
}
|
||||
}
|
||||
|
||||
Thread parserThread = new Thread() {
|
||||
public void run() {
|
||||
try {
|
||||
Class<?> c;
|
||||
if (unsafeLoad) {
|
||||
c = UnsafeAccess.unsafe.defineAnonymousClass(hostClass, classBytes, null);
|
||||
} else {
|
||||
c = CustomClassLoaders.makeClassBytesLoader(classBytes, className)
|
||||
.loadClass(className);
|
||||
}
|
||||
c.newInstance();
|
||||
} catch (Throwable e) {
|
||||
Env.traceVerbose(e, "parser caught exception");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
parserThread.setDaemon(true);
|
||||
parserThread.start();
|
||||
parserThread.join(parseTimeout);
|
||||
|
||||
if (parserThread.isAlive()) {
|
||||
Env.complain("Killing parser thread");
|
||||
StackTraceElement[] stack = parserThread.getStackTrace();
|
||||
Env.traceImportant(parserThread + " stack trace:");
|
||||
for (int i = 0; i < stack.length; ++i) {
|
||||
Env.traceImportant(parserThread + "\tat " + stack[i]);
|
||||
}
|
||||
|
||||
if (saveClassFile) {
|
||||
Files.move(rescueFile.toPath(), Paths.get(fileNamePrefix
|
||||
+ String.format(HUNG_CLASS_FILE_NAME, hangNum)));
|
||||
}
|
||||
++hangNum;
|
||||
} else if (saveClassFile) {
|
||||
rescueFile.delete();
|
||||
}
|
||||
}
|
||||
|
||||
stresser.finish();
|
||||
|
||||
if (hangNum > 0) {
|
||||
Env.complain("There were " + hangNum + " hangups during parsing."
|
||||
+ " The class files, which produced hangup were saved as "
|
||||
+ fileNamePrefix + String.format(HUNG_CLASS_FILE_NAME, 0)
|
||||
+ "... in the test directory. You may want to analyse them."
|
||||
+ " Failing this test because of hangups.");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generated class bytes. The method is called for each iteration.
|
||||
*
|
||||
* @return Byte array with the generated class
|
||||
*/
|
||||
protected abstract byte[] generateClassBytes();
|
||||
|
||||
/**
|
||||
* Returns a host class for the generated class.
|
||||
*
|
||||
* @return A host class that for the generated class
|
||||
*/
|
||||
protected abstract Class<?> getHostClass();
|
||||
}
|
@ -0,0 +1,24 @@
|
||||
#
|
||||
# Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
#
|
||||
# This code is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License version 2 only, as
|
||||
# published by the Free Software Foundation.
|
||||
#
|
||||
# This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
# version 2 for more details (a copy is included in the LICENSE file that
|
||||
# accompanied this code).
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License version
|
||||
# 2 along with this work; if not, write to the Free Software Foundation,
|
||||
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
#
|
||||
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
# or visit www.oracle.com if you need additional information or have any
|
||||
# questions.
|
||||
#
|
||||
|
||||
exclusiveAccess.dirs=.
|
@ -0,0 +1,121 @@
|
||||
/*
|
||||
* Copyright (c) 2010, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @modules java.base/jdk.internal.misc
|
||||
*
|
||||
* @summary converted from VM Testbase vm/mlvm/anonloader/stress/byteMutation.
|
||||
* VM Testbase keywords: [feature_mlvm, nonconcurrent]
|
||||
*
|
||||
* @library /vmTestbase
|
||||
* /test/lib
|
||||
* @run driver jdk.test.lib.FileInstaller . .
|
||||
*
|
||||
* @comment build test class and indify classes
|
||||
* @build vm.mlvm.anonloader.stress.byteMutation.Test
|
||||
* @run driver vm.mlvm.share.IndifiedClassesBuilder
|
||||
*
|
||||
* @run main/othervm vm.mlvm.anonloader.stress.byteMutation.Test -stressIterationsFactor 100000
|
||||
*/
|
||||
|
||||
package vm.mlvm.anonloader.stress.byteMutation;
|
||||
|
||||
import vm.mlvm.anonloader.share.AnonkTestee01;
|
||||
import vm.mlvm.anonloader.share.StressClassLoadingTest;
|
||||
import vm.share.FileUtils;
|
||||
import vm.share.options.Option;
|
||||
|
||||
/**
|
||||
* The test does the following in a cycle:
|
||||
*
|
||||
* <ol>
|
||||
* <li>Takes bytes from a valid class file
|
||||
* <li>Sets 1 to 5 bytes in random positions to random values
|
||||
* <li>Tries to load such class using:
|
||||
* <ul>
|
||||
* <li>a custom class loader,
|
||||
* <li>{@link sun.misc.Unsafe#defineAnonymousClass}
|
||||
* when {@code -unsafeLoad true} option is passed to the test.
|
||||
* </ul>
|
||||
* </ol>
|
||||
*
|
||||
* <p>In most cases the resulting class file is invalid and rejected by
|
||||
* the VM verifier. But this test tries to find pathological cases, such
|
||||
* as infinite loops during verification or VM crashes.
|
||||
*
|
||||
* <p>NB: There is a tool to load invalid classes saved by this test.
|
||||
* Please see tool documentation at {@link vm.mlvm.tools.LoadClass}
|
||||
*
|
||||
*/
|
||||
public class Test extends StressClassLoadingTest {
|
||||
private final static Class<?> HOST_CLASS = AnonkTestee01.class;
|
||||
private final byte[] testeeBytes;
|
||||
@Option(name = "mutationCount", default_value = "3",
|
||||
description = "How many bytes to mutate in a class")
|
||||
private int mutationCount = 3;
|
||||
|
||||
/**
|
||||
* Constructs the test.
|
||||
* @throws Exception if there are any errors when
|
||||
* reading {@link vm.mlvm.anonloader.share.AnonkTestee01} class bytecodes.
|
||||
*/
|
||||
public Test() throws Exception {
|
||||
this.testeeBytes = FileUtils.readClass(AnonkTestee01.class.getName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns {@link vm.mlvm.anonloader.share.AnonkTestee01} class to the
|
||||
* parent.
|
||||
* @return {@link vm.mlvm.anonloader.share.AnonkTestee01} class.
|
||||
*/
|
||||
@Override
|
||||
protected Class<?> getHostClass() {
|
||||
return HOST_CLASS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Takes {@link vm.mlvm.anonloader.share.AnonkTestee01} class bytecodes
|
||||
* and modifies mutationCount bytes setting them to random values.
|
||||
* @return {@link vm.mlvm.anonloader.share.AnonkTestee01} class bytecodes with modified bytes.
|
||||
*/
|
||||
@Override
|
||||
protected byte[] generateClassBytes() {
|
||||
// TODO: there is non-zero probability that generated bytecode will be
|
||||
// valid, so it should be a subject of fuzzing mechanism
|
||||
byte[] alteredBytes = testeeBytes.clone();
|
||||
for (int j = 0; j < mutationCount; ++j) {
|
||||
alteredBytes[getRNG().nextInt(alteredBytes.length)] = (byte) getRNG().nextInt(256);
|
||||
}
|
||||
return alteredBytes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs the test.
|
||||
* @param args Test arguments.
|
||||
*/
|
||||
public static void main(String[] args) {
|
||||
StressClassLoadingTest.launch(args);
|
||||
}
|
||||
}
|
@ -0,0 +1,24 @@
|
||||
#
|
||||
# Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
#
|
||||
# This code is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License version 2 only, as
|
||||
# published by the Free Software Foundation.
|
||||
#
|
||||
# This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
# version 2 for more details (a copy is included in the LICENSE file that
|
||||
# accompanied this code).
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License version
|
||||
# 2 along with this work; if not, write to the Free Software Foundation,
|
||||
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
#
|
||||
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
# or visit www.oracle.com if you need additional information or have any
|
||||
# questions.
|
||||
#
|
||||
|
||||
exclusiveAccess.dirs=.
|
@ -0,0 +1,90 @@
|
||||
/*
|
||||
* Copyright (c) 2010, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @modules java.base/jdk.internal.misc
|
||||
*
|
||||
* @summary converted from VM Testbase vm/mlvm/anonloader/stress/oome/heap.
|
||||
* VM Testbase keywords: [feature_mlvm, nonconcurrent]
|
||||
*
|
||||
* @library /vmTestbase
|
||||
* /test/lib
|
||||
* @run driver jdk.test.lib.FileInstaller . .
|
||||
*
|
||||
* @comment build test class and indify classes
|
||||
* @build vm.mlvm.anonloader.stress.oome.heap.Test
|
||||
* @run driver vm.mlvm.share.IndifiedClassesBuilder
|
||||
*
|
||||
* @run main/othervm -XX:-UseGCOverheadLimit vm.mlvm.anonloader.stress.oome.heap.Test
|
||||
*/
|
||||
|
||||
package vm.mlvm.anonloader.stress.oome.heap;
|
||||
|
||||
import java.util.List;
|
||||
import java.io.IOException;
|
||||
|
||||
import vm.mlvm.anonloader.share.AnonkTestee01;
|
||||
import vm.mlvm.share.MlvmOOMTest;
|
||||
import vm.mlvm.share.MlvmTestExecutor;
|
||||
import vm.mlvm.share.Env;
|
||||
import vm.share.FileUtils;
|
||||
import vm.share.UnsafeAccess;
|
||||
|
||||
/**
|
||||
* This test loads a class using Unsafe.defineAnonymousClass, creates instances
|
||||
* of that class and stores them, expecting Heap OOME.
|
||||
*
|
||||
*/
|
||||
|
||||
public class Test extends MlvmOOMTest {
|
||||
@Override
|
||||
protected void checkOOME(OutOfMemoryError oome) {
|
||||
String message = oome.getMessage();
|
||||
if (!"Java heap space".equals(message)) {
|
||||
throw new RuntimeException("TEST FAIL : wrong OOME", oome);
|
||||
}
|
||||
}
|
||||
@Override
|
||||
protected void eatMemory(List<Object> list) {
|
||||
byte[] classBytes = null;
|
||||
try {
|
||||
classBytes = FileUtils.readClass(AnonkTestee01.class.getName());
|
||||
} catch (IOException e) {
|
||||
Env.throwAsUncheckedException(e);
|
||||
}
|
||||
try {
|
||||
while (true) {
|
||||
list.add(UnsafeAccess.unsafe.defineAnonymousClass(AnonkTestee01.class,
|
||||
classBytes, null).newInstance());
|
||||
}
|
||||
} catch (InstantiationException | IllegalAccessException e) {
|
||||
Env.throwAsUncheckedException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
MlvmTestExecutor.launch(args);
|
||||
}
|
||||
}
|
24
test/hotspot/jtreg/vmTestbase/vm/mlvm/anonloader/stress/oome/metaspace/TEST.properties
Normal file
24
test/hotspot/jtreg/vmTestbase/vm/mlvm/anonloader/stress/oome/metaspace/TEST.properties
Normal file
@ -0,0 +1,24 @@
|
||||
#
|
||||
# Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
#
|
||||
# This code is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License version 2 only, as
|
||||
# published by the Free Software Foundation.
|
||||
#
|
||||
# This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
# version 2 for more details (a copy is included in the LICENSE file that
|
||||
# accompanied this code).
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License version
|
||||
# 2 along with this work; if not, write to the Free Software Foundation,
|
||||
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
#
|
||||
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
# or visit www.oracle.com if you need additional information or have any
|
||||
# questions.
|
||||
#
|
||||
|
||||
exclusiveAccess.dirs=.
|
@ -0,0 +1,86 @@
|
||||
/*
|
||||
* Copyright (c) 2010, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @modules java.base/jdk.internal.misc
|
||||
*
|
||||
* @summary converted from VM Testbase vm/mlvm/anonloader/stress/oome/metaspace.
|
||||
* VM Testbase keywords: [feature_mlvm, nonconcurrent]
|
||||
*
|
||||
* @library /vmTestbase
|
||||
* /test/lib
|
||||
* @run driver jdk.test.lib.FileInstaller . .
|
||||
*
|
||||
* @comment build test class and indify classes
|
||||
* @build vm.mlvm.anonloader.stress.oome.metaspace.Test
|
||||
* @run driver vm.mlvm.share.IndifiedClassesBuilder
|
||||
*
|
||||
* @run main/othervm -XX:-UseGCOverheadLimit -XX:MetaspaceSize=10m -XX:MaxMetaspaceSize=20m vm.mlvm.anonloader.stress.oome.metaspace.Test
|
||||
*/
|
||||
|
||||
package vm.mlvm.anonloader.stress.oome.metaspace;
|
||||
|
||||
import java.util.List;
|
||||
import java.io.IOException;
|
||||
|
||||
import vm.mlvm.anonloader.share.AnonkTestee01;
|
||||
import vm.mlvm.share.MlvmOOMTest;
|
||||
import vm.mlvm.share.MlvmTestExecutor;
|
||||
import vm.mlvm.share.Env;
|
||||
import vm.share.FileUtils;
|
||||
import vm.share.UnsafeAccess;
|
||||
|
||||
/**
|
||||
* This test loads classes using Unsafe.defineAnonymousClass and stores them,
|
||||
* expecting Metaspace OOME.
|
||||
*
|
||||
*/
|
||||
public class Test extends MlvmOOMTest {
|
||||
@Override
|
||||
protected void checkOOME(OutOfMemoryError oome) {
|
||||
String message = oome.getMessage();
|
||||
if (!"Metaspace".equals(message) && !"Compressed class space".equals(message)) {
|
||||
throw new RuntimeException("TEST FAIL : wrong OOME", oome);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void eatMemory(List<Object> list) {
|
||||
byte[] classBytes = null;
|
||||
try {
|
||||
classBytes = FileUtils.readClass(AnonkTestee01.class.getName());
|
||||
} catch (IOException e) {
|
||||
Env.throwAsUncheckedException(e);
|
||||
}
|
||||
while (true) {
|
||||
list.add(UnsafeAccess.unsafe.defineAnonymousClass(AnonkTestee01.class,
|
||||
classBytes, null));
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
MlvmTestExecutor.launch(args);
|
||||
}
|
||||
}
|
@ -0,0 +1,24 @@
|
||||
#
|
||||
# Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
#
|
||||
# This code is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License version 2 only, as
|
||||
# published by the Free Software Foundation.
|
||||
#
|
||||
# This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
# version 2 for more details (a copy is included in the LICENSE file that
|
||||
# accompanied this code).
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License version
|
||||
# 2 along with this work; if not, write to the Free Software Foundation,
|
||||
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
#
|
||||
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
# or visit www.oracle.com if you need additional information or have any
|
||||
# questions.
|
||||
#
|
||||
|
||||
exclusiveAccess.dirs=.
|
@ -0,0 +1,112 @@
|
||||
/*
|
||||
* Copyright (c) 2010, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @modules java.base/jdk.internal.misc
|
||||
*
|
||||
* @summary converted from VM Testbase vm/mlvm/anonloader/stress/parallelLoad.
|
||||
* VM Testbase keywords: [feature_mlvm, nonconcurrent]
|
||||
*
|
||||
* @library /vmTestbase
|
||||
* /test/lib
|
||||
* @run driver jdk.test.lib.FileInstaller . .
|
||||
*
|
||||
* @comment build test class and indify classes
|
||||
* @build vm.mlvm.anonloader.stress.parallelLoad.Test
|
||||
* @run driver vm.mlvm.share.IndifiedClassesBuilder
|
||||
*
|
||||
* @run main/othervm
|
||||
* -XX:+BytecodeVerificationLocal
|
||||
* vm.mlvm.anonloader.stress.parallelLoad.Test
|
||||
* -threadsPerCpu 4
|
||||
* -threadsExtra 20
|
||||
* -parseTimeout 0
|
||||
* -unsafeLoad true
|
||||
*/
|
||||
|
||||
package vm.mlvm.anonloader.stress.parallelLoad;
|
||||
|
||||
import vm.mlvm.anonloader.share.StressClassLoadingTest;
|
||||
import vm.mlvm.anonloader.share.AnonkTestee01;
|
||||
import vm.mlvm.share.MlvmTestExecutor;
|
||||
import vm.mlvm.share.MultiThreadedTest;
|
||||
import vm.share.FileUtils;
|
||||
|
||||
/**
|
||||
* Verifies that loading classes in parallel from several threads using
|
||||
* {@link sun.misc.Unsafe#defineAnonymousClass}
|
||||
* does not produce exceptions and crashes.
|
||||
*
|
||||
*/
|
||||
public class Test extends MultiThreadedTest {
|
||||
private static final Class<?> HOST_CLASS = AnonkTestee01.class;
|
||||
private static final String NAME_PREFIX = "thread%03d";
|
||||
|
||||
private final byte[] classBytes;
|
||||
|
||||
private static class SubTest extends StressClassLoadingTest {
|
||||
private final byte[] classBytes;
|
||||
|
||||
public SubTest(byte[] classBytes) {
|
||||
this.classBytes = classBytes;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Class<?> getHostClass() {
|
||||
return HOST_CLASS;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected byte[] generateClassBytes() {
|
||||
return classBytes;
|
||||
}
|
||||
}
|
||||
|
||||
public Test() throws Exception {
|
||||
classBytes = FileUtils.readClass(HOST_CLASS.getName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a sub-test class and runs it. The sub-test class loads
|
||||
* {@link vm.mlvm.anonloader.share.AnonkTestee01} class bytecodes
|
||||
* using {@link sun.misc.Unsafe#defineAnonymousClass}
|
||||
* @param numThread Number of the thread
|
||||
* @throws Exception if there any exceptions thrown in the sub-test
|
||||
*/
|
||||
@Override
|
||||
protected boolean runThread(int numThread) throws Exception {
|
||||
SubTest subTest = new SubTest(classBytes);
|
||||
subTest.setFileNamePrefix(String.format(NAME_PREFIX, numThread));
|
||||
return subTest.run();
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs the test.
|
||||
* @param args Test arguments.
|
||||
*/
|
||||
public static void main(String[] args) {
|
||||
MlvmTestExecutor.launch(args);
|
||||
}
|
||||
}
|
24
test/hotspot/jtreg/vmTestbase/vm/mlvm/anonloader/stress/randomBytecodes/TEST.properties
Normal file
24
test/hotspot/jtreg/vmTestbase/vm/mlvm/anonloader/stress/randomBytecodes/TEST.properties
Normal file
@ -0,0 +1,24 @@
|
||||
#
|
||||
# Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
#
|
||||
# This code is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License version 2 only, as
|
||||
# published by the Free Software Foundation.
|
||||
#
|
||||
# This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
# version 2 for more details (a copy is included in the LICENSE file that
|
||||
# accompanied this code).
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License version
|
||||
# 2 along with this work; if not, write to the Free Software Foundation,
|
||||
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
#
|
||||
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
# or visit www.oracle.com if you need additional information or have any
|
||||
# questions.
|
||||
#
|
||||
|
||||
exclusiveAccess.dirs=.
|
@ -0,0 +1,118 @@
|
||||
/*
|
||||
* Copyright (c) 2010, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @modules java.base/jdk.internal.misc
|
||||
*
|
||||
* @summary converted from VM Testbase vm/mlvm/anonloader/stress/randomBytecodes.
|
||||
* VM Testbase keywords: [feature_mlvm, nonconcurrent]
|
||||
*
|
||||
* @library /vmTestbase
|
||||
* /test/lib
|
||||
* @run driver jdk.test.lib.FileInstaller . .
|
||||
*
|
||||
* @comment build test class and indify classes
|
||||
* @build vm.mlvm.anonloader.stress.randomBytecodes.Test
|
||||
* @run driver vm.mlvm.share.IndifiedClassesBuilder
|
||||
*
|
||||
* @run main/othervm vm.mlvm.anonloader.stress.randomBytecodes.Test -stressIterationsFactor 100000
|
||||
*/
|
||||
|
||||
package vm.mlvm.anonloader.stress.randomBytecodes;
|
||||
|
||||
import java.util.Arrays;
|
||||
import vm.mlvm.anonloader.share.StressClassLoadingTest;
|
||||
|
||||
/**
|
||||
* The test does the following in a cycle:
|
||||
* <ol>
|
||||
* <li>Creates a class bytecodes that has a valid 12-byte header
|
||||
* and has totally random bytes after the header
|
||||
* <li>Tries to load such class using:
|
||||
* <ul>
|
||||
* <li>a custom class loader, or
|
||||
* <li>{@link sun.misc.Unsafe#defineAnonymousClass}
|
||||
* when {@code -unsafeLoad true} is set.
|
||||
* </ul>
|
||||
* </ol>
|
||||
*
|
||||
* <p>In most cases the resulting class file is invalid and rejected by
|
||||
* the VM verifier. But this test is looking for pathological cases
|
||||
* such as infinite loops in the verifier or VM crashes.
|
||||
*
|
||||
* <p>NB: There is a tool to load invalid classes saved by this test.
|
||||
* Please see tool documentation at {@link vm.mlvm.tools.LoadClass}.
|
||||
*
|
||||
*/
|
||||
public class Test extends StressClassLoadingTest {
|
||||
private static final Class<?> HOST_CLASS = Test.class;
|
||||
private static final int MAX_SIZE = 0xFFF7;
|
||||
private static final byte[] CLASS_HEADER = new byte[] {
|
||||
(byte)0xCA, (byte)0xFE, (byte)0xBA, (byte)0xBE,
|
||||
0x00, 0x00, 0x00, 0x32
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns {@link vm.mlvm.anonloader.share.AnonkTestee01} class to the
|
||||
* parent.
|
||||
* @return {@link vm.mlvm.anonloader.share.AnonkTestee01} class.
|
||||
*/
|
||||
@Override
|
||||
protected Class<?> getHostClass() {
|
||||
return HOST_CLASS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a class with valid header (magic and version fields) and
|
||||
* random bytes after the header.
|
||||
* <p>Class size is random ([8..65527]).
|
||||
* Byte values are limited to [0..11] range in order to increase
|
||||
* possiblity that the random class passes the initial (dead-on-arrival)
|
||||
* stages of the verifier and is rejected
|
||||
* in more interesting ones, like method bytecode verification.
|
||||
* Class version is 52.
|
||||
*
|
||||
* @return Class with valid Java header (8 bytes) and totally random bytes
|
||||
* after the header
|
||||
*/
|
||||
@Override
|
||||
protected byte[] generateClassBytes() {
|
||||
final byte[] classBytes = Arrays.copyOf(CLASS_HEADER,
|
||||
CLASS_HEADER.length + getRNG().nextInt(MAX_SIZE));
|
||||
for (int j = CLASS_HEADER.length; j < classBytes.length; j++) {
|
||||
classBytes[j] = (byte) getRNG().nextInt(12);
|
||||
}
|
||||
|
||||
return classBytes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs the test.
|
||||
* @param args Test arguments.
|
||||
*/
|
||||
public static void main(String[] args) {
|
||||
StressClassLoadingTest.launch(args);
|
||||
}
|
||||
}
|
@ -0,0 +1,135 @@
|
||||
/*
|
||||
* Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package vm.mlvm.cp.share;
|
||||
|
||||
import jdk.internal.org.objectweb.asm.ClassWriter;
|
||||
import jdk.internal.org.objectweb.asm.ClassWriterExt;
|
||||
import jdk.internal.org.objectweb.asm.MethodVisitor;
|
||||
import jdk.internal.org.objectweb.asm.Opcodes;
|
||||
import jdk.internal.org.objectweb.asm.Handle;
|
||||
|
||||
import vm.mlvm.share.ClassfileGenerator;
|
||||
import vm.mlvm.share.Env;
|
||||
|
||||
public class GenCPFullOfMH extends GenFullCP {
|
||||
|
||||
public static void main(String[] args) {
|
||||
ClassfileGenerator.main(args);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void generateCommonData(ClassWriterExt cw) {
|
||||
cw.setCacheMHandles(false);
|
||||
|
||||
cw.visitField(Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC,
|
||||
STATIC_FIELD_NAME,
|
||||
STATIC_FIELD_SIGNATURE, null, false);
|
||||
|
||||
cw.visitField(Opcodes.ACC_PUBLIC,
|
||||
INSTANCE_FIELD_NAME,
|
||||
INSTANCE_FIELD_SIGNATURE, null, false);
|
||||
|
||||
createInitMethod(cw);
|
||||
createTargetMethod(cw);
|
||||
|
||||
MethodVisitor mv = cw.visitMethod(
|
||||
Opcodes.ACC_PUBLIC,
|
||||
INSTANCE_TARGET_METHOD_NAME,
|
||||
INSTANCE_TARGET_METHOD_SIGNATURE,
|
||||
null,
|
||||
new String[0]);
|
||||
finishMethodCode(mv);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void generateCPEntryData(ClassWriter cw, MethodVisitor mw) {
|
||||
HandleType[] types = HandleType.values();
|
||||
HandleType type = types[Env.getRNG().nextInt(types.length)];
|
||||
|
||||
switch (type) {
|
||||
case PUTFIELD:
|
||||
case PUTSTATIC:
|
||||
mw.visitInsn(Opcodes.ICONST_0);
|
||||
break;
|
||||
case INVOKESPECIAL:
|
||||
case INVOKEVIRTUAL:
|
||||
case INVOKEINTERFACE:
|
||||
mw.visitInsn(Opcodes.ACONST_NULL);
|
||||
break;
|
||||
}
|
||||
|
||||
Handle handle;
|
||||
switch (type) {
|
||||
case GETFIELD:
|
||||
case PUTFIELD:
|
||||
handle = new Handle(type.asmTag,
|
||||
fullClassName,
|
||||
INSTANCE_FIELD_NAME,
|
||||
INSTANCE_FIELD_SIGNATURE);
|
||||
break;
|
||||
case GETSTATIC:
|
||||
case PUTSTATIC:
|
||||
handle = new Handle(type.asmTag,
|
||||
fullClassName,
|
||||
STATIC_FIELD_NAME,
|
||||
STATIC_FIELD_SIGNATURE);
|
||||
break;
|
||||
case NEWINVOKESPECIAL:
|
||||
handle = new Handle(type.asmTag,
|
||||
fullClassName,
|
||||
INIT_METHOD_NAME,
|
||||
INIT_METHOD_SIGNATURE);
|
||||
break;
|
||||
case INVOKESTATIC:
|
||||
handle = new Handle(type.asmTag,
|
||||
fullClassName,
|
||||
TARGET_METHOD_NAME,
|
||||
TARGET_METHOD_SIGNATURE);
|
||||
break;
|
||||
case INVOKEINTERFACE:
|
||||
handle = new Handle(type.asmTag,
|
||||
getDummyInterfaceClassName(),
|
||||
INSTANCE_TARGET_METHOD_NAME,
|
||||
INSTANCE_TARGET_METHOD_SIGNATURE);
|
||||
break;
|
||||
case INVOKESPECIAL:
|
||||
case INVOKEVIRTUAL:
|
||||
handle = new Handle(type.asmTag,
|
||||
fullClassName,
|
||||
INSTANCE_TARGET_METHOD_NAME,
|
||||
INSTANCE_TARGET_METHOD_SIGNATURE);
|
||||
break;
|
||||
default:
|
||||
throw new Error("Unexpected handle type " + type);
|
||||
}
|
||||
mw.visitLdcInsn(handle);
|
||||
|
||||
switch (type) {
|
||||
case GETFIELD:
|
||||
case GETSTATIC:
|
||||
mw.visitInsn(Opcodes.POP);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package vm.mlvm.cp.share;
|
||||
|
||||
import jdk.internal.org.objectweb.asm.ClassWriter;
|
||||
import jdk.internal.org.objectweb.asm.ClassWriterExt;
|
||||
import jdk.internal.org.objectweb.asm.MethodVisitor;
|
||||
import jdk.internal.org.objectweb.asm.Opcodes;
|
||||
import jdk.internal.org.objectweb.asm.Type;
|
||||
|
||||
import vm.mlvm.share.ClassfileGenerator;
|
||||
|
||||
public class GenCPFullOfMT extends GenFullCP {
|
||||
|
||||
public static void main(String[] args) {
|
||||
ClassfileGenerator.main(args);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void generateCommonData(ClassWriterExt cw) {
|
||||
cw.setCacheMTypes(false);
|
||||
super.generateCommonData(cw);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void generateCPEntryData(ClassWriter cw, MethodVisitor mw) {
|
||||
mw.visitLdcInsn(Type.getMethodType("(FIZ)V"));
|
||||
mw.visitInsn(Opcodes.POP);
|
||||
}
|
||||
|
||||
}
|
316
test/hotspot/jtreg/vmTestbase/vm/mlvm/cp/share/GenFullCP.java
Normal file
316
test/hotspot/jtreg/vmTestbase/vm/mlvm/cp/share/GenFullCP.java
Normal file
@ -0,0 +1,316 @@
|
||||
/*
|
||||
* Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package vm.mlvm.cp.share;
|
||||
|
||||
import jdk.internal.org.objectweb.asm.ByteVector;
|
||||
import jdk.internal.org.objectweb.asm.ClassWriter;
|
||||
import jdk.internal.org.objectweb.asm.ClassWriterExt;
|
||||
import jdk.internal.org.objectweb.asm.MethodVisitor;
|
||||
import jdk.internal.org.objectweb.asm.Opcodes;
|
||||
import jdk.internal.org.objectweb.asm.Type;
|
||||
|
||||
import vm.mlvm.share.ClassfileGenerator;
|
||||
import vm.mlvm.share.Env;
|
||||
|
||||
public abstract class GenFullCP extends ClassfileGenerator {
|
||||
|
||||
/**
|
||||
* Generate field description for object type from class name:
|
||||
* return "L" + className + ";";
|
||||
* @param className Class name
|
||||
* @return field descriptor representing the class type
|
||||
*/
|
||||
protected static String fd(String className) {
|
||||
return "L" + className + ";";
|
||||
}
|
||||
|
||||
// Universal constants
|
||||
protected static final String JL_OBJECT = "java/lang/Object";
|
||||
protected static final String JL_CLASS = "java/lang/Class";
|
||||
protected static final String JL_CLASSLOADER = "java/lang/ClassLoader";
|
||||
protected static final String JL_STRING = "java/lang/String";
|
||||
protected static final String JL_RUNTIMEEXCEPTION = "java/lang/RuntimeException";
|
||||
protected static final String JL_BOOTSTRAPMETHODERROR = "java/lang/BootstrapMethodError";
|
||||
protected static final String JL_THROWABLE = "java/lang/Throwable";
|
||||
protected static final String JLI_METHODTYPE = "java/lang/invoke/MethodType";
|
||||
protected static final String JLI_METHODHANDLE = "java/lang/invoke/MethodHandle";
|
||||
protected static final String JLI_METHODHANDLES = "java/lang/invoke/MethodHandles";
|
||||
protected static final String JLI_METHODHANDLES_LOOKUP = "java/lang/invoke/MethodHandles$Lookup";
|
||||
protected static final String JLI_CALLSITE = "java/lang/invoke/CallSite";
|
||||
protected static final String JLI_CONSTANTCALLSITE = "java/lang/invoke/ConstantCallSite";
|
||||
|
||||
protected static final String VOID_NO_ARG_METHOD_SIGNATURE = "()V";
|
||||
|
||||
protected static final String NEW_INVOKE_SPECIAL_CLASS_NAME = "java/lang/invoke/NewInvokeSpecialCallSite";
|
||||
protected static final String NEW_INVOKE_SPECIAL_BOOTSTRAP_METHOD_SIGNATURE = "(" + fd(JLI_METHODHANDLES_LOOKUP) + fd(JL_STRING) + fd(JLI_METHODTYPE) + ")V";
|
||||
|
||||
protected static final String INIT_METHOD_NAME = "<init>";
|
||||
protected static final String STATIC_INIT_METHOD_NAME = "<clinit>";
|
||||
|
||||
// Generated class constants
|
||||
protected static final int CLASSFILE_VERSION = 51;
|
||||
|
||||
protected static final int CP_CONST_COUNT = 65400;
|
||||
protected static final int MAX_METHOD_SIZE = 65400;
|
||||
protected static final int BYTES_PER_LDC = 5;
|
||||
protected static final int LDC_PER_METHOD = MAX_METHOD_SIZE / BYTES_PER_LDC;
|
||||
protected static final int METHOD_COUNT = CP_CONST_COUNT / LDC_PER_METHOD;
|
||||
|
||||
protected static final String PARENT_CLASS_NAME = JL_OBJECT;
|
||||
|
||||
protected static final String INIT_METHOD_SIGNATURE = VOID_NO_ARG_METHOD_SIGNATURE;
|
||||
|
||||
protected static final String MAIN_METHOD_NAME = "main";
|
||||
protected static final String MAIN_METHOD_SIGNATURE = "(" + "[" + fd(JL_STRING) + ")V";
|
||||
|
||||
protected static final String TEST_METHOD_NAME = "test";
|
||||
protected static final String TEST_METHOD_SIGNATURE = VOID_NO_ARG_METHOD_SIGNATURE;
|
||||
|
||||
protected static final String STATIC_FIELD_NAME = "testStatic";
|
||||
protected static final String STATIC_FIELD_SIGNATURE = "Z";
|
||||
|
||||
protected static final String INSTANCE_FIELD_NAME = "testInstance";
|
||||
protected static final String INSTANCE_FIELD_SIGNATURE = "Z";
|
||||
|
||||
protected static final String STATIC_BOOTSTRAP_FIELD_NAME = "testCSStatic";
|
||||
protected static final String STATIC_BOOTSTRAP_FIELD_SIGNATURE = fd(JLI_CALLSITE);
|
||||
|
||||
protected static final String INSTANCE_BOOTSTRAP_FIELD_NAME = "testCSInstance";
|
||||
protected static final String INSTANCE_BOOTSTRAP_FIELD_SIGNATURE = fd(JLI_CALLSITE);
|
||||
|
||||
protected static final String BOOTSTRAP_METHOD_NAME = "bootstrap";
|
||||
protected static final String BOOTSTRAP_METHOD_SIGNATURE = "(" + fd(JLI_METHODHANDLES_LOOKUP) + fd(JL_STRING) + fd(JLI_METHODTYPE) + ")" + fd(JLI_CALLSITE);
|
||||
|
||||
protected static final String INSTANCE_BOOTSTRAP_METHOD_NAME = "bootstrapInstance";
|
||||
protected static final String INSTANCE_BOOTSTRAP_METHOD_SIGNATURE = BOOTSTRAP_METHOD_SIGNATURE;
|
||||
|
||||
protected static final String TARGET_METHOD_NAME = "target";
|
||||
protected static final String TARGET_METHOD_SIGNATURE = VOID_NO_ARG_METHOD_SIGNATURE;
|
||||
|
||||
protected static final String INSTANCE_TARGET_METHOD_NAME = "targetInstance";
|
||||
protected static final String INSTANCE_TARGET_METHOD_SIGNATURE = VOID_NO_ARG_METHOD_SIGNATURE;
|
||||
|
||||
protected interface DummyInterface {
|
||||
public void targetInstance();
|
||||
}
|
||||
|
||||
// Helper methods
|
||||
|
||||
protected static String getDummyInterfaceClassName() {
|
||||
return DummyInterface.class.getName().replace('.', '/');
|
||||
}
|
||||
|
||||
protected static void createLogMsgCode(MethodVisitor mv, String msg) {
|
||||
mv.visitLdcInsn(msg);
|
||||
mv.visitMethodInsn(Opcodes.INVOKESTATIC, "vm/mlvm/share/Env", "traceVerbose", "(Ljava/lang/String;)V");
|
||||
}
|
||||
|
||||
protected static void createThrowRuntimeExceptionCode(MethodVisitor mv, String msg) {
|
||||
createThrowRuntimeExceptionCodeHelper(mv, msg, false);
|
||||
}
|
||||
|
||||
// Expects a throwable (the cause) to be on top of the stack when called.
|
||||
protected static void createThrowRuntimeExceptionCodeWithCause(MethodVisitor mv, String msg) {
|
||||
createThrowRuntimeExceptionCodeHelper(mv, msg, true);
|
||||
}
|
||||
|
||||
// If set_cause is true it expects a Throwable (the cause) to be on top of the stack when called.
|
||||
protected static void createThrowRuntimeExceptionCodeHelper(MethodVisitor mv, String msg, boolean set_cause) {
|
||||
mv.visitTypeInsn(Opcodes.NEW, JL_RUNTIMEEXCEPTION);
|
||||
mv.visitInsn(Opcodes.DUP);
|
||||
mv.visitLdcInsn(msg);
|
||||
mv.visitMethodInsn(Opcodes.INVOKESPECIAL, JL_RUNTIMEEXCEPTION,
|
||||
INIT_METHOD_NAME, "(" + fd(JL_STRING) + ")V");
|
||||
if (set_cause) {
|
||||
mv.visitInsn(Opcodes.SWAP);
|
||||
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, JL_RUNTIMEEXCEPTION,
|
||||
"initCause", "(" + fd(JL_THROWABLE) + ")"+ fd(JL_THROWABLE));
|
||||
}
|
||||
mv.visitInsn(Opcodes.ATHROW);
|
||||
}
|
||||
|
||||
protected static void createThrowRuntimeExceptionMethod(ClassWriter cw, boolean isStatic, String methodName, String methodSignature) {
|
||||
MethodVisitor mv = cw.visitMethod(
|
||||
Opcodes.ACC_PUBLIC | (isStatic ? Opcodes.ACC_STATIC : 0),
|
||||
methodName, methodSignature,
|
||||
null,
|
||||
new String[0]);
|
||||
|
||||
createThrowRuntimeExceptionCode(mv, "Method " + methodName + methodSignature + " should not be called!");
|
||||
|
||||
mv.visitMaxs(-1, -1);
|
||||
mv.visitEnd();
|
||||
}
|
||||
|
||||
protected static void finishMethodCode(MethodVisitor mv) {
|
||||
finishMethodCode(mv, Opcodes.RETURN);
|
||||
}
|
||||
|
||||
protected static void finishMethodCode(MethodVisitor mv, int returnOpcode) {
|
||||
mv.visitInsn(returnOpcode);
|
||||
mv.visitMaxs(-1, -1);
|
||||
mv.visitEnd();
|
||||
}
|
||||
|
||||
protected void createClassInitMethod(ClassWriter cw) {
|
||||
}
|
||||
|
||||
protected void createInitMethod(ClassWriter cw) {
|
||||
MethodVisitor mv = cw.visitMethod(
|
||||
Opcodes.ACC_PUBLIC,
|
||||
INIT_METHOD_NAME, INIT_METHOD_SIGNATURE,
|
||||
null,
|
||||
new String[0]);
|
||||
|
||||
mv.visitIntInsn(Opcodes.ALOAD, 0);
|
||||
mv.visitMethodInsn(Opcodes.INVOKESPECIAL,
|
||||
PARENT_CLASS_NAME,
|
||||
INIT_METHOD_NAME, INIT_METHOD_SIGNATURE);
|
||||
|
||||
createLogMsgCode(mv, fullClassName + " constructor called");
|
||||
|
||||
finishMethodCode(mv);
|
||||
}
|
||||
|
||||
protected void createTargetMethod(ClassWriter cw) {
|
||||
MethodVisitor mv = cw.visitMethod(
|
||||
Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC,
|
||||
TARGET_METHOD_NAME, TARGET_METHOD_SIGNATURE,
|
||||
null,
|
||||
new String[0]);
|
||||
|
||||
createLogMsgCode(mv, fullClassName + "." + TARGET_METHOD_NAME + TARGET_METHOD_SIGNATURE + " called");
|
||||
|
||||
finishMethodCode(mv);
|
||||
}
|
||||
|
||||
protected void createBootstrapMethod(ClassWriter cw) {
|
||||
createBootstrapMethod(cw, true, BOOTSTRAP_METHOD_NAME, BOOTSTRAP_METHOD_SIGNATURE);
|
||||
}
|
||||
|
||||
protected void createBootstrapMethod(ClassWriter cw, boolean isStatic, String methodName, String methodSignature) {
|
||||
MethodVisitor mv = cw.visitMethod(
|
||||
(isStatic ? Opcodes.ACC_STATIC : 0) | Opcodes.ACC_PUBLIC,
|
||||
methodName, methodSignature,
|
||||
null, new String[0]);
|
||||
|
||||
createLogMsgCode(mv, fullClassName + "." + BOOTSTRAP_METHOD_NAME + BOOTSTRAP_METHOD_SIGNATURE + " called");
|
||||
|
||||
int argShift = isStatic ? 0 : 1;
|
||||
|
||||
mv.visitTypeInsn(Opcodes.NEW, JLI_CONSTANTCALLSITE);
|
||||
mv.visitInsn(Opcodes.DUP);
|
||||
mv.visitVarInsn(Opcodes.ALOAD, 0 + argShift);
|
||||
mv.visitLdcInsn(Type.getObjectType(fullClassName));
|
||||
mv.visitVarInsn(Opcodes.ALOAD, 1 + argShift);
|
||||
mv.visitVarInsn(Opcodes.ALOAD, 2 + argShift);
|
||||
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL,
|
||||
JLI_METHODHANDLES_LOOKUP, "findStatic",
|
||||
"(" + fd(JL_CLASS) + fd(JL_STRING) + fd(JLI_METHODTYPE) + ")" + fd(JLI_METHODHANDLE));
|
||||
mv.visitMethodInsn(Opcodes.INVOKESPECIAL, JLI_CONSTANTCALLSITE,
|
||||
INIT_METHOD_NAME, "(" + fd(JLI_METHODHANDLE) + ")V");
|
||||
|
||||
finishMethodCode(mv, Opcodes.ARETURN);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Klass[] generateBytecodes() {
|
||||
|
||||
// COMPUTE_FRAMES were disabled due to JDK-8079697
|
||||
ClassWriterExt cw = new ClassWriterExt(/*ClassWriter.COMPUTE_FRAMES |*/ ClassWriter.COMPUTE_MAXS);
|
||||
|
||||
String[] interfaces = new String[1];
|
||||
interfaces[0] = getDummyInterfaceClassName();
|
||||
cw.visit(CLASSFILE_VERSION, Opcodes.ACC_PUBLIC, fullClassName, null, PARENT_CLASS_NAME, interfaces);
|
||||
|
||||
generateCommonData(cw);
|
||||
|
||||
MethodVisitor mainMV = cw.visitMethod(
|
||||
Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC,
|
||||
MAIN_METHOD_NAME, MAIN_METHOD_SIGNATURE,
|
||||
null, new String[0]);
|
||||
|
||||
mainMV.visitTypeInsn(Opcodes.NEW, fullClassName);
|
||||
mainMV.visitInsn(Opcodes.DUP);
|
||||
mainMV.visitMethodInsn(Opcodes.INVOKESPECIAL, fullClassName, INIT_METHOD_NAME, INIT_METHOD_SIGNATURE);
|
||||
|
||||
int constCount = 0;
|
||||
int methodNum = 0;
|
||||
|
||||
// TODO: check real CP size and also limit number of iterations in this cycle
|
||||
while (constCount < CP_CONST_COUNT) {
|
||||
final String methodName = TEST_METHOD_NAME + String.format("%02d", methodNum);
|
||||
|
||||
MethodVisitor mw = cw.visitMethod(
|
||||
Opcodes.ACC_PUBLIC,
|
||||
methodName, TEST_METHOD_SIGNATURE,
|
||||
null, new String[0]);
|
||||
|
||||
generateTestMethodProlog(mw);
|
||||
|
||||
// TODO: check real CP size and also limit number of iterations in this cycle
|
||||
while (constCount < CP_CONST_COUNT && cw.getBytecodeLength(mw) < MAX_METHOD_SIZE) {
|
||||
generateCPEntryData(cw, mw);
|
||||
++constCount;
|
||||
}
|
||||
|
||||
generateTestMethodEpilog(mw);
|
||||
|
||||
mw.visitMaxs(-1, -1);
|
||||
mw.visitEnd();
|
||||
|
||||
Env.traceNormal("Method " + fullClassName + "." + methodName + "(): "
|
||||
+ constCount + " constants in CP, "
|
||||
+ cw.getBytecodeLength(mw) + " bytes of code");
|
||||
|
||||
mainMV.visitInsn(Opcodes.DUP);
|
||||
mainMV.visitMethodInsn(Opcodes.INVOKEVIRTUAL, fullClassName, methodName, TEST_METHOD_SIGNATURE);
|
||||
|
||||
++methodNum;
|
||||
}
|
||||
|
||||
mainMV.visitInsn(Opcodes.POP);
|
||||
finishMethodCode(mainMV);
|
||||
|
||||
cw.visitEnd();
|
||||
return new Klass[] { new Klass(this.pkgName, this.shortClassName, MAIN_METHOD_NAME, MAIN_METHOD_SIGNATURE, cw.toByteArray()) };
|
||||
}
|
||||
|
||||
protected void generateCommonData(ClassWriterExt cw) {
|
||||
createClassInitMethod(cw);
|
||||
createInitMethod(cw);
|
||||
createTargetMethod(cw);
|
||||
createBootstrapMethod(cw);
|
||||
}
|
||||
|
||||
protected void generateTestMethodProlog(MethodVisitor mw) {
|
||||
}
|
||||
|
||||
protected abstract void generateCPEntryData(ClassWriter cw, MethodVisitor mw);
|
||||
|
||||
protected void generateTestMethodEpilog(MethodVisitor mw) {
|
||||
mw.visitInsn(Opcodes.RETURN);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,111 @@
|
||||
/*
|
||||
* Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package vm.mlvm.cp.share;
|
||||
|
||||
import jdk.internal.org.objectweb.asm.ClassWriter;
|
||||
import jdk.internal.org.objectweb.asm.ClassWriterExt;
|
||||
import jdk.internal.org.objectweb.asm.Handle;
|
||||
import jdk.internal.org.objectweb.asm.MethodVisitor;
|
||||
import jdk.internal.org.objectweb.asm.Opcodes;
|
||||
import jdk.internal.org.objectweb.asm.Type;
|
||||
|
||||
import vm.mlvm.share.ClassfileGenerator;
|
||||
import vm.mlvm.share.Env;
|
||||
|
||||
public class GenManyIndyCorrectBootstrap extends GenFullCP {
|
||||
|
||||
/**
|
||||
* Generates a class file and writes it to a file
|
||||
* @see vm.mlvm.share.ClassfileGenerator
|
||||
* @param args Parameters for ClassfileGenerator.main() method
|
||||
*/
|
||||
public static void main(String[] args) {
|
||||
ClassfileGenerator.main(args);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates static init method, which constructs a call site object, which refers to the target method
|
||||
* and invokes Dummy.setMH() on this call site
|
||||
* @param cw Class writer object
|
||||
*/
|
||||
@Override
|
||||
protected void createClassInitMethod(ClassWriter cw) {
|
||||
MethodVisitor mw = cw.visitMethod(
|
||||
Opcodes.ACC_PUBLIC + Opcodes.ACC_STATIC,
|
||||
STATIC_INIT_METHOD_NAME, INIT_METHOD_SIGNATURE,
|
||||
null,
|
||||
new String[0]);
|
||||
|
||||
mw.visitMethodInsn(Opcodes.INVOKESTATIC, JLI_METHODHANDLES, "lookup", "()" + fd(JLI_METHODHANDLES_LOOKUP));
|
||||
mw.visitLdcInsn(Type.getObjectType(fullClassName));
|
||||
mw.visitLdcInsn(TARGET_METHOD_NAME);
|
||||
mw.visitLdcInsn(TARGET_METHOD_SIGNATURE);
|
||||
mw.visitLdcInsn(Type.getObjectType(fullClassName));
|
||||
mw.visitMethodInsn(Opcodes.INVOKEVIRTUAL, JL_CLASS,
|
||||
"getClassLoader", "()" + fd(JL_CLASSLOADER));
|
||||
mw.visitMethodInsn(Opcodes.INVOKESTATIC, JLI_METHODTYPE,
|
||||
"fromMethodDescriptorString", "(" + fd(JL_STRING) + fd(JL_CLASSLOADER) + ")" + fd(JLI_METHODTYPE));
|
||||
mw.visitMethodInsn(Opcodes.INVOKEVIRTUAL, JLI_METHODHANDLES_LOOKUP,
|
||||
"findStatic", "(" + fd(JL_CLASS) + fd(JL_STRING) + fd(JLI_METHODTYPE) + ")" + fd(JLI_METHODHANDLE));
|
||||
mw.visitMethodInsn(Opcodes.INVOKESTATIC, NEW_INVOKE_SPECIAL_CLASS_NAME,
|
||||
"setMH", "(" + fd(JLI_METHODHANDLE) + ")V");
|
||||
|
||||
finishMethodCode(mw);
|
||||
}
|
||||
|
||||
/**
|
||||
* Disables invoke dynamic CP entry caching and generate default common data
|
||||
* @param cw Class writer object
|
||||
*/
|
||||
@Override
|
||||
protected void generateCommonData(ClassWriterExt cw) {
|
||||
cw.setCacheInvokeDynamic(false);
|
||||
super.generateCommonData(cw);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates an invokedynamic instruction (plus CP entry)
|
||||
* which has a valid reference kind in the CP method handle entry for the bootstrap method
|
||||
* @param cw Class writer object
|
||||
* @param mw Method writer object
|
||||
*/
|
||||
@Override
|
||||
protected void generateCPEntryData(ClassWriter cw, MethodVisitor mw) {
|
||||
Handle bsm;
|
||||
if (Env.getRNG().nextBoolean()) {
|
||||
bsm = new Handle(Opcodes.H_NEWINVOKESPECIAL,
|
||||
NEW_INVOKE_SPECIAL_CLASS_NAME,
|
||||
INIT_METHOD_NAME,
|
||||
NEW_INVOKE_SPECIAL_BOOTSTRAP_METHOD_SIGNATURE);
|
||||
} else {
|
||||
bsm = new Handle(Opcodes.H_INVOKESTATIC,
|
||||
this.fullClassName,
|
||||
BOOTSTRAP_METHOD_NAME,
|
||||
BOOTSTRAP_METHOD_SIGNATURE);
|
||||
}
|
||||
mw.visitInvokeDynamicInsn(TARGET_METHOD_NAME,
|
||||
TARGET_METHOD_SIGNATURE,
|
||||
bsm);
|
||||
}
|
||||
}
|
@ -0,0 +1,274 @@
|
||||
/*
|
||||
* Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package vm.mlvm.cp.share;
|
||||
|
||||
import jdk.internal.org.objectweb.asm.ClassWriter;
|
||||
import jdk.internal.org.objectweb.asm.ClassWriterExt;
|
||||
import jdk.internal.org.objectweb.asm.Handle;
|
||||
import jdk.internal.org.objectweb.asm.MethodVisitor;
|
||||
import jdk.internal.org.objectweb.asm.Opcodes;
|
||||
import jdk.internal.org.objectweb.asm.Type;
|
||||
import jdk.internal.org.objectweb.asm.Label;
|
||||
|
||||
import vm.mlvm.share.ClassfileGenerator;
|
||||
import vm.mlvm.share.Env;
|
||||
|
||||
public class GenManyIndyIncorrectBootstrap extends GenFullCP {
|
||||
|
||||
/**
|
||||
* Generates a class file and writes it to a file
|
||||
* @see vm.mlvm.share.ClassfileGenerator
|
||||
* @param args Parameters for ClassfileGenerator.main() method
|
||||
*/
|
||||
public static void main(String[] args) {
|
||||
ClassfileGenerator.main(args);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create class constructor, which
|
||||
* create a call site for target method
|
||||
* and puts it into static and instance fields
|
||||
* @param cw Class writer object
|
||||
*/
|
||||
@Override
|
||||
protected void createInitMethod(ClassWriter cw) {
|
||||
MethodVisitor mw = cw.visitMethod(
|
||||
Opcodes.ACC_PUBLIC,
|
||||
INIT_METHOD_NAME, INIT_METHOD_SIGNATURE,
|
||||
null,
|
||||
new String[0]);
|
||||
|
||||
mw.visitVarInsn(Opcodes.ALOAD, 0);
|
||||
mw.visitMethodInsn(Opcodes.INVOKESPECIAL, PARENT_CLASS_NAME,
|
||||
INIT_METHOD_NAME, INIT_METHOD_SIGNATURE);
|
||||
|
||||
// Create a call site for the target method and store it into bootstrap fields
|
||||
mw.visitVarInsn(Opcodes.ALOAD, 0);
|
||||
mw.visitTypeInsn(Opcodes.NEW, JLI_CONSTANTCALLSITE);
|
||||
mw.visitInsn(Opcodes.DUP);
|
||||
mw.visitMethodInsn(Opcodes.INVOKESTATIC, JLI_METHODHANDLES,
|
||||
"lookup", "()" + fd(JLI_METHODHANDLES_LOOKUP));
|
||||
mw.visitLdcInsn(Type.getObjectType(fullClassName));
|
||||
mw.visitLdcInsn(TARGET_METHOD_NAME);
|
||||
mw.visitLdcInsn(TARGET_METHOD_SIGNATURE);
|
||||
mw.visitLdcInsn(Type.getObjectType(fullClassName));
|
||||
mw.visitMethodInsn(Opcodes.INVOKEVIRTUAL, JL_CLASS,
|
||||
"getClassLoader", "()" + fd(JL_CLASSLOADER));
|
||||
mw.visitMethodInsn(Opcodes.INVOKESTATIC, JLI_METHODTYPE,
|
||||
"fromMethodDescriptorString", "(" + fd(JL_STRING) + fd(JL_CLASSLOADER) + ")" + fd(JLI_METHODTYPE));
|
||||
mw.visitMethodInsn(Opcodes.INVOKEVIRTUAL, JLI_METHODHANDLES_LOOKUP,
|
||||
"findStatic", "(" + fd(JL_CLASS) + fd(JL_STRING) + fd(JLI_METHODTYPE) + ")" + fd(JLI_METHODHANDLE));
|
||||
mw.visitMethodInsn(Opcodes.INVOKESPECIAL, JLI_CONSTANTCALLSITE,
|
||||
INIT_METHOD_NAME, "(" + fd(JLI_METHODHANDLE) + ")V");
|
||||
mw.visitInsn(Opcodes.DUP);
|
||||
mw.visitFieldInsn(Opcodes.PUTSTATIC, fullClassName, STATIC_BOOTSTRAP_FIELD_NAME, STATIC_BOOTSTRAP_FIELD_SIGNATURE);
|
||||
mw.visitFieldInsn(Opcodes.PUTFIELD, fullClassName, INSTANCE_BOOTSTRAP_FIELD_NAME, INSTANCE_BOOTSTRAP_FIELD_SIGNATURE);
|
||||
|
||||
finishMethodCode(mw);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a target method which always throw. It should not be called,
|
||||
* since all invokedynamic instructions have invalid bootstrap method types
|
||||
* @param cw Class writer object
|
||||
*/
|
||||
@Override
|
||||
protected void createTargetMethod(ClassWriter cw) {
|
||||
createThrowRuntimeExceptionMethod(cw, true, TARGET_METHOD_NAME, TARGET_METHOD_SIGNATURE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a bootstrap method which always throw. It should not be called,
|
||||
* since all invokedynamic instructions have invalid bootstrap method types
|
||||
* @param cw Class writer object
|
||||
*/
|
||||
@Override
|
||||
protected void createBootstrapMethod(ClassWriter cw) {
|
||||
createThrowRuntimeExceptionMethod(cw, true, BOOTSTRAP_METHOD_NAME, BOOTSTRAP_METHOD_SIGNATURE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates common data for class plus two fields that hold CallSite
|
||||
* and used as bootstrap targets
|
||||
* @param cw Class writer object
|
||||
*/
|
||||
@Override
|
||||
protected void generateCommonData(ClassWriterExt cw) {
|
||||
cw.setCacheInvokeDynamic(false);
|
||||
|
||||
cw.visitField(Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC,
|
||||
STATIC_BOOTSTRAP_FIELD_NAME,
|
||||
STATIC_BOOTSTRAP_FIELD_SIGNATURE, null, null);
|
||||
|
||||
cw.visitField(Opcodes.ACC_PUBLIC,
|
||||
INSTANCE_BOOTSTRAP_FIELD_NAME,
|
||||
INSTANCE_BOOTSTRAP_FIELD_SIGNATURE, null, null);
|
||||
|
||||
super.generateCommonData(cw);
|
||||
|
||||
createThrowRuntimeExceptionMethod(cw, false, INSTANCE_BOOTSTRAP_METHOD_NAME, INSTANCE_BOOTSTRAP_METHOD_SIGNATURE);
|
||||
}
|
||||
|
||||
Label throwMethodLabel;
|
||||
|
||||
// The exception to expect that is wrapped in a BootstrapMethodError
|
||||
static final String WRAPPED_EXCEPTION = "java/lang/invoke/WrongMethodTypeException";
|
||||
|
||||
// The error to expect that is not wrapped in a BootstrapMethodError and
|
||||
// is thrown directly
|
||||
static final String DIRECT_ERROR = "java/lang/IncompatibleClassChangeError";
|
||||
|
||||
/**
|
||||
* Generates an invokedynamic instruction (plus CP entry)
|
||||
* which has invalid reference kind in the CP method handle entry for the bootstrap method
|
||||
* @param cw Class writer object
|
||||
* @param mw Method writer object
|
||||
*/
|
||||
@Override
|
||||
protected void generateCPEntryData(ClassWriter cw, MethodVisitor mw) {
|
||||
HandleType[] types = HandleType.values();
|
||||
HandleType type = types[Env.getRNG().nextInt(types.length)];
|
||||
|
||||
switch (type) {
|
||||
case GETFIELD:
|
||||
case PUTFIELD:
|
||||
case GETSTATIC:
|
||||
case PUTSTATIC:
|
||||
case INVOKESPECIAL:
|
||||
case INVOKEVIRTUAL:
|
||||
case INVOKEINTERFACE:
|
||||
// Handle these cases
|
||||
break;
|
||||
default:
|
||||
// And don't generate code for all other cases
|
||||
return;
|
||||
}
|
||||
|
||||
Label indyThrowableBegin = new Label();
|
||||
Label indyThrowableEnd = new Label();
|
||||
Label catchThrowableLabel = new Label();
|
||||
|
||||
Label indyBootstrapBegin = new Label();
|
||||
Label indyBootstrapEnd = new Label();
|
||||
Label catchBootstrapLabel = new Label();
|
||||
|
||||
mw.visitTryCatchBlock(indyBootstrapBegin, indyBootstrapEnd, catchBootstrapLabel, JL_BOOTSTRAPMETHODERROR);
|
||||
mw.visitLabel(indyBootstrapBegin);
|
||||
|
||||
mw.visitTryCatchBlock(indyThrowableBegin, indyThrowableEnd, catchThrowableLabel, JL_THROWABLE);
|
||||
mw.visitLabel(indyThrowableBegin);
|
||||
|
||||
Handle bsm;
|
||||
switch (type) {
|
||||
case GETFIELD:
|
||||
case PUTFIELD:
|
||||
bsm = new Handle(type.asmTag,
|
||||
fullClassName,
|
||||
INSTANCE_BOOTSTRAP_FIELD_NAME,
|
||||
INSTANCE_BOOTSTRAP_FIELD_SIGNATURE);
|
||||
break;
|
||||
case GETSTATIC:
|
||||
case PUTSTATIC:
|
||||
bsm = new Handle(type.asmTag,
|
||||
fullClassName,
|
||||
STATIC_BOOTSTRAP_FIELD_NAME,
|
||||
STATIC_BOOTSTRAP_FIELD_SIGNATURE);
|
||||
break;
|
||||
case INVOKESPECIAL:
|
||||
case INVOKEVIRTUAL:
|
||||
case INVOKEINTERFACE:
|
||||
bsm = new Handle(type.asmTag,
|
||||
fullClassName,
|
||||
INSTANCE_BOOTSTRAP_METHOD_NAME,
|
||||
INSTANCE_BOOTSTRAP_METHOD_SIGNATURE);
|
||||
break;
|
||||
default:
|
||||
throw new Error("Unexpected handle type " + type);
|
||||
}
|
||||
|
||||
mw.visitInvokeDynamicInsn(TARGET_METHOD_NAME,
|
||||
TARGET_METHOD_SIGNATURE,
|
||||
bsm);
|
||||
|
||||
mw.visitLabel(indyBootstrapEnd);
|
||||
mw.visitLabel(indyThrowableEnd);
|
||||
|
||||
// No exception at all, throw error
|
||||
Label throwLabel = new Label();
|
||||
mw.visitJumpInsn(Opcodes.GOTO, throwLabel);
|
||||
|
||||
// JDK-8079697 workaround: we have to generate stackmaps manually
|
||||
mw.visitFrame(Opcodes.F_SAME1, 0, new Object[0], 1, new Object[] { JL_BOOTSTRAPMETHODERROR });
|
||||
|
||||
// Got a bootstrapmethoderror as expected, check that it is wrapping what we expect
|
||||
mw.visitLabel(catchBootstrapLabel);
|
||||
|
||||
// Save error in case we need to rethrow it
|
||||
mw.visitInsn(Opcodes.DUP);
|
||||
mw.visitVarInsn(Opcodes.ASTORE, 1);
|
||||
mw.visitMethodInsn(Opcodes.INVOKEVIRTUAL, JL_THROWABLE, "getCause", "()" + fd(JL_THROWABLE));
|
||||
|
||||
// If it is the expected exception, goto next block
|
||||
mw.visitTypeInsn(Opcodes.INSTANCEOF, WRAPPED_EXCEPTION);
|
||||
Label nextBlockLabel = new Label();
|
||||
mw.visitJumpInsn(Opcodes.IFNE, nextBlockLabel);
|
||||
|
||||
// Not the exception we were expectiong, throw error
|
||||
mw.visitVarInsn(Opcodes.ALOAD, 1); // Use full chain as cause
|
||||
createThrowRuntimeExceptionCodeWithCause(mw,
|
||||
"invokedynamic got an unexpected wrapped exception (expected " + WRAPPED_EXCEPTION
|
||||
+ ", bootstrap type=" + type
|
||||
+ ", opcode=" + type.asmTag + ")!");
|
||||
|
||||
// JDK-8079697 workaround: we have to generate stackmaps manually
|
||||
mw.visitFrame(Opcodes.F_SAME1, 0, new Object[0], 1, new Object[] { JL_THROWABLE });
|
||||
mw.visitLabel(catchThrowableLabel);
|
||||
|
||||
// Save error in case we need to rethrow it
|
||||
mw.visitInsn(Opcodes.DUP);
|
||||
mw.visitVarInsn(Opcodes.ASTORE, 1);
|
||||
|
||||
// If it is the expected exception, goto next block
|
||||
mw.visitTypeInsn(Opcodes.INSTANCEOF, DIRECT_ERROR);
|
||||
mw.visitJumpInsn(Opcodes.IFNE, nextBlockLabel);
|
||||
|
||||
// Not the exception we were expectiong, throw error
|
||||
mw.visitVarInsn(Opcodes.ALOAD, 1); // Use full chain as cause
|
||||
createThrowRuntimeExceptionCodeWithCause(mw,
|
||||
"invokedynamic got an unexpected exception (expected " + DIRECT_ERROR
|
||||
+ ", bootstrap type" + type
|
||||
+ ", opcode=" + type.asmTag + ")!");
|
||||
|
||||
// JDK-8079697 workaround: we have to generate stackmaps manually
|
||||
mw.visitFrame(Opcodes.F_CHOP, 0, new Object[0], 0, new Object[0]);
|
||||
|
||||
// Unable to place this code once in the method epilog due to bug in ASM
|
||||
mw.visitLabel(throwLabel);
|
||||
createThrowRuntimeExceptionCode(mw,
|
||||
"invokedynamic should always throw (bootstrap type" + type +", opcode=" + type.asmTag + ")!");
|
||||
|
||||
mw.visitFrame(Opcodes.F_SAME, 0, new Object[0], 0, new Object[0]);
|
||||
mw.visitLabel(nextBlockLabel);
|
||||
}
|
||||
}
|
@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package vm.mlvm.cp.share;
|
||||
|
||||
import jdk.internal.org.objectweb.asm.ClassWriter;
|
||||
import jdk.internal.org.objectweb.asm.MethodVisitor;
|
||||
import jdk.internal.org.objectweb.asm.Opcodes;
|
||||
import jdk.internal.org.objectweb.asm.Handle;
|
||||
|
||||
import vm.mlvm.share.ClassfileGenerator;
|
||||
|
||||
public class GenManyIndyOneCPX extends GenFullCP {
|
||||
|
||||
public static void main(String[] args) {
|
||||
ClassfileGenerator.main(args);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void generateCPEntryData(ClassWriter cw, MethodVisitor mw) {
|
||||
Handle bsm = new Handle(Opcodes.H_INVOKESTATIC,
|
||||
fullClassName,
|
||||
BOOTSTRAP_METHOD_NAME,
|
||||
BOOTSTRAP_METHOD_SIGNATURE);
|
||||
|
||||
mw.visitInvokeDynamicInsn(TARGET_METHOD_NAME,
|
||||
TARGET_METHOD_SIGNATURE,
|
||||
bsm);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package vm.mlvm.cp.share;
|
||||
|
||||
import jdk.internal.org.objectweb.asm.Opcodes;
|
||||
|
||||
public enum HandleType {
|
||||
GETFIELD(Opcodes.H_GETFIELD),
|
||||
PUTFIELD(Opcodes.H_PUTFIELD),
|
||||
GETSTATIC(Opcodes.H_GETSTATIC),
|
||||
PUTSTATIC(Opcodes.H_PUTSTATIC),
|
||||
NEWINVOKESPECIAL(Opcodes.H_NEWINVOKESPECIAL),
|
||||
INVOKESTATIC(Opcodes.H_INVOKESTATIC),
|
||||
INVOKEINTERFACE(Opcodes.H_INVOKEINTERFACE),
|
||||
INVOKESPECIAL(Opcodes.H_INVOKESPECIAL),
|
||||
INVOKEVIRTUAL(Opcodes.H_INVOKEVIRTUAL);
|
||||
|
||||
public final int asmTag;
|
||||
private HandleType(int asmTag) {
|
||||
this.asmTag = asmTag;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
57
test/hotspot/jtreg/vmTestbase/vm/mlvm/cp/stress/classfmt/correctBootstrap/TestDescription.java
Normal file
57
test/hotspot/jtreg/vmTestbase/vm/mlvm/cp/stress/classfmt/correctBootstrap/TestDescription.java
Normal file
@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @modules java.base/jdk.internal.org.objectweb.asm
|
||||
*
|
||||
* @summary converted from VM Testbase vm/mlvm/cp/stress/classfmt/correctBootstrap.
|
||||
* VM Testbase keywords: [feature_mlvm]
|
||||
* VM Testbase readme:
|
||||
* DESCRIPTION
|
||||
* Create a constant pool, which contains maximum number of invokedynamic constants and corresponding
|
||||
* invokedynamic commands that refer to correct bootstrap method types. Verify that bootstrap/target
|
||||
* methods are invoked. The maximum number of invokedynamic calls is determined dynamically.
|
||||
*
|
||||
* @library /vmTestbase
|
||||
* /test/lib
|
||||
* /vmTestbase/vm/mlvm/patches
|
||||
*
|
||||
* @comment patch for java.base
|
||||
* @build java.base/*
|
||||
*
|
||||
* @comment build generator
|
||||
* @build vm.mlvm.cp.share.GenManyIndyCorrectBootstrap
|
||||
*
|
||||
* @run driver jdk.test.lib.FileInstaller . .
|
||||
*
|
||||
* @comment build test class and indify classes
|
||||
* @build vm.mlvm.share.ClassfileGeneratorTest
|
||||
* @run driver vm.mlvm.share.IndifiedClassesBuilder
|
||||
*
|
||||
* @run main/othervm
|
||||
* vm.mlvm.share.ClassfileGeneratorTest
|
||||
* -generator vm.mlvm.cp.share.GenManyIndyCorrectBootstrap
|
||||
*/
|
||||
|
58
test/hotspot/jtreg/vmTestbase/vm/mlvm/cp/stress/classfmt/incorrectBootstrap/TestDescription.java
Normal file
58
test/hotspot/jtreg/vmTestbase/vm/mlvm/cp/stress/classfmt/incorrectBootstrap/TestDescription.java
Normal file
@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @modules java.base/jdk.internal.org.objectweb.asm
|
||||
*
|
||||
* @summary converted from VM Testbase vm/mlvm/cp/stress/classfmt/incorrectBootstrap.
|
||||
* VM Testbase keywords: [feature_mlvm]
|
||||
* VM Testbase readme:
|
||||
* DESCRIPTION
|
||||
* Create a constant pool, which contains maximum number of invokedynamic constants and corresponding
|
||||
* invokedynamic commands that refer to incorrect bootstrap method types. Verify that appropriate
|
||||
* exception is thrown for each invokedynamic command and bootstrap/target methods are never invoked.
|
||||
* The maximum number of invokedynamic calls is determined dynamically.
|
||||
*
|
||||
* @library /vmTestbase
|
||||
* /test/lib
|
||||
* /vmTestbase/vm/mlvm/patches
|
||||
*
|
||||
* @comment patch for java.base
|
||||
* @build java.base/*
|
||||
*
|
||||
* @comment build generator
|
||||
* @build vm.mlvm.cp.share.GenManyIndyIncorrectBootstrap
|
||||
*
|
||||
* @run driver jdk.test.lib.FileInstaller . .
|
||||
*
|
||||
* @comment build test class and indify classes
|
||||
* @build vm.mlvm.share.ClassfileGeneratorTest
|
||||
* @run driver vm.mlvm.share.IndifiedClassesBuilder
|
||||
*
|
||||
* @run main/othervm
|
||||
* vm.mlvm.share.ClassfileGeneratorTest
|
||||
* -generator vm.mlvm.cp.share.GenManyIndyIncorrectBootstrap
|
||||
*/
|
||||
|
24
test/hotspot/jtreg/vmTestbase/vm/mlvm/cp/stress/classfmt/manyIndyOneCPX/TEST.properties
Normal file
24
test/hotspot/jtreg/vmTestbase/vm/mlvm/cp/stress/classfmt/manyIndyOneCPX/TEST.properties
Normal file
@ -0,0 +1,24 @@
|
||||
#
|
||||
# Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
#
|
||||
# This code is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License version 2 only, as
|
||||
# published by the Free Software Foundation.
|
||||
#
|
||||
# This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
# version 2 for more details (a copy is included in the LICENSE file that
|
||||
# accompanied this code).
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License version
|
||||
# 2 along with this work; if not, write to the Free Software Foundation,
|
||||
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
#
|
||||
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
# or visit www.oracle.com if you need additional information or have any
|
||||
# questions.
|
||||
#
|
||||
|
||||
exclusiveAccess.dirs=.
|
58
test/hotspot/jtreg/vmTestbase/vm/mlvm/cp/stress/classfmt/manyIndyOneCPX/TestDescription.java
Normal file
58
test/hotspot/jtreg/vmTestbase/vm/mlvm/cp/stress/classfmt/manyIndyOneCPX/TestDescription.java
Normal file
@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @modules java.base/jdk.internal.org.objectweb.asm
|
||||
*
|
||||
* @summary converted from VM Testbase vm/mlvm/cp/stress/classfmt/manyIndyOneCPX.
|
||||
* VM Testbase keywords: [feature_mlvm, hangup, nonconcurrent, exclude]
|
||||
* VM Testbase comments: 8199227
|
||||
* VM Testbase readme:
|
||||
* DESCRIPTION
|
||||
* The test creates and executes a class containing lot of invokedynamic instructions
|
||||
* pointing to just one constant pool CONSTANT_InvokeDynamic entry.
|
||||
*
|
||||
* @library /vmTestbase
|
||||
* /test/lib
|
||||
* /vmTestbase/vm/mlvm/patches
|
||||
*
|
||||
* @comment patch for java.base
|
||||
* @build java.base/*
|
||||
*
|
||||
* @comment build generator
|
||||
* @build vm.mlvm.cp.share.GenManyIndyOneCPX
|
||||
*
|
||||
* @run driver jdk.test.lib.FileInstaller . .
|
||||
* @ignore 8199227
|
||||
*
|
||||
* @comment build test class and indify classes
|
||||
* @build vm.mlvm.share.ClassfileGeneratorTest
|
||||
* @run driver vm.mlvm.share.IndifiedClassesBuilder
|
||||
*
|
||||
* @run main/othervm
|
||||
* vm.mlvm.share.ClassfileGeneratorTest
|
||||
* -generator vm.mlvm.cp.share.GenManyIndyOneCPX
|
||||
*/
|
||||
|
@ -0,0 +1,24 @@
|
||||
#
|
||||
# Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
#
|
||||
# This code is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License version 2 only, as
|
||||
# published by the Free Software Foundation.
|
||||
#
|
||||
# This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
# version 2 for more details (a copy is included in the LICENSE file that
|
||||
# accompanied this code).
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License version
|
||||
# 2 along with this work; if not, write to the Free Software Foundation,
|
||||
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
#
|
||||
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
# or visit www.oracle.com if you need additional information or have any
|
||||
# questions.
|
||||
#
|
||||
|
||||
exclusiveAccess.dirs=.
|
@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @modules java.base/jdk.internal.org.objectweb.asm
|
||||
*
|
||||
* @summary converted from VM Testbase vm/mlvm/cp/stress/classfmt/mh.
|
||||
* VM Testbase keywords: [feature_mlvm, nonconcurrent]
|
||||
* VM Testbase readme:
|
||||
* DESCRIPTION
|
||||
* Create a constant pool, which contains maximum number of method handle constants and corresponding
|
||||
* ldc commands. Verify that the class is loaded without errors.
|
||||
* The maximum is determined dynamically.
|
||||
*
|
||||
* @library /vmTestbase
|
||||
* /test/lib
|
||||
* /vmTestbase/vm/mlvm/patches
|
||||
*
|
||||
* @comment patch for java.base
|
||||
* @build java.base/*
|
||||
*
|
||||
* @comment build generator
|
||||
* @build vm.mlvm.cp.share.GenCPFullOfMH
|
||||
*
|
||||
* @run driver jdk.test.lib.FileInstaller . .
|
||||
*
|
||||
* @comment build test class and indify classes
|
||||
* @build vm.mlvm.share.ClassfileGeneratorTest
|
||||
* @run driver vm.mlvm.share.IndifiedClassesBuilder
|
||||
*
|
||||
* @run main/othervm vm.mlvm.share.ClassfileGeneratorTest -generator vm.mlvm.cp.share.GenCPFullOfMH
|
||||
*/
|
||||
|
@ -0,0 +1,24 @@
|
||||
#
|
||||
# Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
#
|
||||
# This code is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License version 2 only, as
|
||||
# published by the Free Software Foundation.
|
||||
#
|
||||
# This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
# version 2 for more details (a copy is included in the LICENSE file that
|
||||
# accompanied this code).
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License version
|
||||
# 2 along with this work; if not, write to the Free Software Foundation,
|
||||
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
#
|
||||
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
# or visit www.oracle.com if you need additional information or have any
|
||||
# questions.
|
||||
#
|
||||
|
||||
exclusiveAccess.dirs=.
|
@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @modules java.base/jdk.internal.org.objectweb.asm
|
||||
*
|
||||
* @summary converted from VM Testbase vm/mlvm/cp/stress/classfmt/mt.
|
||||
* VM Testbase keywords: [feature_mlvm, nonconcurrent]
|
||||
* VM Testbase readme:
|
||||
* DESCRIPTION
|
||||
* Create a constant pool, which contains maximum number of method type constants and corresponding
|
||||
* ldc commands. Verify that the class is loaded without errors.
|
||||
* The maximum is determined dynamically.
|
||||
*
|
||||
* @library /vmTestbase
|
||||
* /test/lib
|
||||
* /vmTestbase/vm/mlvm/patches
|
||||
*
|
||||
* @comment patch for java.base
|
||||
* @build java.base/*
|
||||
*
|
||||
* @comment build generator
|
||||
* @build vm.mlvm.cp.share.GenCPFullOfMT
|
||||
*
|
||||
* @run driver jdk.test.lib.FileInstaller . .
|
||||
*
|
||||
* @comment build test class and indify classes
|
||||
* @build vm.mlvm.share.ClassfileGeneratorTest
|
||||
* @run driver vm.mlvm.share.IndifiedClassesBuilder
|
||||
*
|
||||
* @run main/othervm vm.mlvm.share.ClassfileGeneratorTest -generator vm.mlvm.cp.share.GenCPFullOfMT
|
||||
*/
|
||||
|
1935
test/hotspot/jtreg/vmTestbase/vm/mlvm/indy/func/java/rawRetypes/INDIFY_Test6998541.java
Normal file
1935
test/hotspot/jtreg/vmTestbase/vm/mlvm/indy/func/java/rawRetypes/INDIFY_Test6998541.java
Normal file
File diff suppressed because it is too large
Load Diff
229
test/hotspot/jtreg/vmTestbase/vm/mlvm/indy/func/java/rawRetypes/INDIFY_Test6998541.jmpp
Normal file
229
test/hotspot/jtreg/vmTestbase/vm/mlvm/indy/func/java/rawRetypes/INDIFY_Test6998541.jmpp
Normal file
@ -0,0 +1,229 @@
|
||||
/*
|
||||
* Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package vm.mlvm.indy.func.java.rawRetypes;
|
||||
|
||||
import java.lang.invoke.CallSite;
|
||||
import java.lang.invoke.ConstantCallSite;
|
||||
import java.lang.invoke.MethodHandle;
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import java.lang.invoke.MethodType;
|
||||
|
||||
public class INDIFY_Test6998541 {
|
||||
private static final int N = 100000;
|
||||
|
||||
#
|
||||
# String[] types = new String[] { "void", "boolean", "byte", "char", "short", "int", "long", "float", "double" };
|
||||
#
|
||||
# String[][] primTypes = new String[][] {
|
||||
# new String[] { "boolean", "Boolean", "false" },
|
||||
# new String[] { "byte", "Byte", "0" },
|
||||
# new String[] { "char", "Character", "0" },
|
||||
# new String[] { "short", "Short", "0" },
|
||||
# new String[] { "int", "Integer", "0" },
|
||||
# new String[] { "long", "Long", "0L" },
|
||||
# new String[] { "float", "Float", "0f" },
|
||||
# new String[] { "double", "Double", "0d" }
|
||||
# };
|
||||
#
|
||||
|
||||
public static void main(String[] args) throws Throwable {
|
||||
#
|
||||
# for ( String[] t : primTypes ) {
|
||||
#
|
||||
@("do" + t[0]) ();
|
||||
#
|
||||
# }
|
||||
#
|
||||
}
|
||||
|
||||
#
|
||||
# for ( String[] t : primTypes ) {
|
||||
#
|
||||
private static void @("do" + t[0]) () throws Throwable {
|
||||
System.out.println(@("\"do" + t[0] + "\""));
|
||||
|
||||
# if ( t[0].equals("boolean") ) {
|
||||
#
|
||||
for (int i = 0; i < N; i++ ) {
|
||||
@(t[0])2prim(false);
|
||||
@(t[0])2prim(true);
|
||||
#
|
||||
# } else {
|
||||
#
|
||||
@(t[0]) x = @(t[1]).MIN_VALUE;
|
||||
@(t[0]) D = @(t[1]).MAX_VALUE / (N / 2);
|
||||
for (int i = 0; i < N; i++, x += D) {
|
||||
#
|
||||
@(t[0])2prim(x);
|
||||
|
||||
# if ( t[0].equals("int") ) {
|
||||
void2prim(x);
|
||||
prim2void(x);
|
||||
prim2prim(x);
|
||||
# }
|
||||
# }
|
||||
|
||||
#
|
||||
}
|
||||
}
|
||||
# }
|
||||
#
|
||||
|
||||
private static void void2prim(int i) throws Throwable {
|
||||
#
|
||||
# for ( String[] t : primTypes ) {
|
||||
#
|
||||
assertEquals( @(t[2]), (@(t[0])) INDY_@(t[0])_foo_void().invokeExact()); // void -> @(t[0])
|
||||
#
|
||||
# }
|
||||
#
|
||||
}
|
||||
|
||||
#
|
||||
# for ( String[] f : primTypes ) {
|
||||
#
|
||||
private static void @(f[0])2prim(@(f[0]) x) throws Throwable {
|
||||
# if ( f[0].equals("boolean") ) {
|
||||
int i = x ? 1 : 0;
|
||||
# } else {
|
||||
@(f[0]) i = x;
|
||||
# }
|
||||
#
|
||||
# for ( String[] t : primTypes ) {
|
||||
# if ( t[0].equals("boolean") ) {
|
||||
# if ( f[0].equals("boolean") ) {
|
||||
boolean z = x;
|
||||
# } else {
|
||||
boolean z = (x != 0);
|
||||
# }
|
||||
assertEquals(z, (@(t[0])) INDY_@(t[0])_foo_@(f[0])().invokeExact(x)); // @(f[0]) -> @(t[0])
|
||||
# } else {
|
||||
assertEquals((@(t[0])) i, (@(t[0])) INDY_@(t[0])_foo_@(f[0])().invokeExact(x)); // @(f[0]) -> @(t[0])
|
||||
# }
|
||||
# }
|
||||
#
|
||||
}
|
||||
#
|
||||
# }
|
||||
#
|
||||
|
||||
private static void prim2void(int x) throws Throwable {
|
||||
#
|
||||
# for ( String[] f : primTypes ) {
|
||||
# if ( f[0].equals("boolean") ) {
|
||||
boolean z = (x != 0);
|
||||
INDY_void_foo_@(f[0])().invokeExact(z); // @(f[0]) -> void
|
||||
# } else {
|
||||
INDY_void_foo_@(f[0])().invokeExact((@(f[0])) x); // @(f[0]) -> void
|
||||
# }
|
||||
# }
|
||||
#
|
||||
}
|
||||
|
||||
private static void void2void() throws Throwable {
|
||||
INDY_void_foo_void().invokeExact(); // void -> void
|
||||
}
|
||||
|
||||
private static void prim2prim(int x) throws Throwable {
|
||||
#
|
||||
# for ( String[] f : primTypes ) {
|
||||
# if ( f[0].equals("boolean") ) {
|
||||
boolean z = (x != 0);
|
||||
assertEquals( z, (@(f[0])) INDY_@(f[0])_spread_@(f[0])().invokeExact(z)); // spread: @(f[0]) -> @(f[0])
|
||||
# } else {
|
||||
assertEquals((@(f[0])) x, (@(f[0])) INDY_@(f[0])_spread_@(f[0])().invokeExact((@(f[0])) x)); // spread: @(f[0]) -> @(f[0])
|
||||
# }
|
||||
# }
|
||||
}
|
||||
|
||||
private static void assertEquals(Object o, Object o2) {
|
||||
if (!o.equals(o2))
|
||||
throw new AssertionError("expected: " + o + ", found: " + o2);
|
||||
}
|
||||
|
||||
#
|
||||
# String[] names = new String[] { "foo", "spread" };
|
||||
#
|
||||
# for ( String ret : types ) {
|
||||
# for ( String arg : types ) {
|
||||
#
|
||||
# String argParam, argTypeParam, methodTypeArg;
|
||||
# if ( ! arg.equals("void") ) {
|
||||
# argParam = "x";
|
||||
# argTypeParam = arg + " x";
|
||||
# methodTypeArg = ", " + arg + ".class";
|
||||
# } else {
|
||||
# argTypeParam = argParam = methodTypeArg = "";
|
||||
# }
|
||||
#
|
||||
# for ( String name : names ) {
|
||||
# String methodName = "INDY_" + ret + "_" + name + "_" + arg;
|
||||
# String wrapperName = "indyWrapper_" + ret + "_" + name;
|
||||
|
||||
private static MethodHandle @methodName;
|
||||
private static MethodHandle @methodName () throws Throwable {
|
||||
if ( @methodName != null ) return @methodName;
|
||||
return ((CallSite) MH_bootstrap().invokeWithArguments(
|
||||
MethodHandles.lookup(),
|
||||
@("\"" + name + "\""),
|
||||
MethodType.methodType(@ret .class @methodTypeArg))).dynamicInvoker();
|
||||
}
|
||||
|
||||
#
|
||||
# }
|
||||
# }
|
||||
# }
|
||||
#
|
||||
|
||||
|
||||
private static MethodType MT_bootstrap () { return MethodType.methodType(CallSite.class, MethodHandles.Lookup.class, String.class, MethodType.class); }
|
||||
|
||||
private static MethodHandle MH_bootstrap () throws Throwable {
|
||||
return MethodHandles.lookup().findStatic(INDIFY_Test6998541.class, "bootstrap", MT_bootstrap());
|
||||
}
|
||||
|
||||
private static CallSite bootstrap(MethodHandles.Lookup declaring, String name, MethodType methodType) throws Throwable {
|
||||
MethodHandles.Lookup lookup = MethodHandles.lookup();
|
||||
MethodHandle mh;
|
||||
if (methodType.parameterCount() == 0) {
|
||||
mh = lookup.findStatic(INDIFY_Test6998541.class, "identity", MethodType.methodType(void.class));
|
||||
} else {
|
||||
Class<?> type = methodType.parameterType(0);
|
||||
mh = lookup.findStatic(INDIFY_Test6998541.class, "identity", MethodType.methodType(type, type));
|
||||
|
||||
if ("spread".equals(name)) {
|
||||
int paramCount = mh.type().parameterCount();
|
||||
mh = mh.asSpreader(Object[].class, paramCount).asCollector(Object[].class, paramCount);
|
||||
}
|
||||
}
|
||||
mh = mh.asType(methodType);
|
||||
return new ConstantCallSite(mh);
|
||||
}
|
||||
|
||||
# for ( String t : types ) {
|
||||
# if ( t.equals("void") ) continue;
|
||||
private static @t identity(@t v) { return v; }
|
||||
# }
|
||||
private static void identity() {}
|
||||
}
|
@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 6998541
|
||||
*
|
||||
* @summary converted from VM Testbase vm/mlvm/indy/func/java/rawRetypes.
|
||||
* VM Testbase keywords: [feature_mlvm, duplicate-of-jtreg-test, exclude]
|
||||
* VM Testbase comments: 8199227
|
||||
* VM Testbase readme:
|
||||
* DESCRIPTION
|
||||
* This is test for raw retypes (conversions between primitive types)
|
||||
* TODO: This test is clearly JCK one, so it has to be modified to be a stress test.
|
||||
*
|
||||
* @library /vmTestbase
|
||||
* /test/lib
|
||||
* @run driver jdk.test.lib.FileInstaller . .
|
||||
* @ignore 8199227
|
||||
*
|
||||
* @comment build test class and indify classes
|
||||
* @build vm.mlvm.indy.func.java.rawRetypes.INDIFY_Test6998541
|
||||
* @run driver vm.mlvm.share.IndifiedClassesBuilder
|
||||
*
|
||||
* @run main/othervm vm.mlvm.indy.func.java.rawRetypes.INDIFY_Test6998541
|
||||
*/
|
||||
|
141
test/hotspot/jtreg/vmTestbase/vm/mlvm/indy/func/java/thisAsArgument/INDIFY_Test.java
Normal file
141
test/hotspot/jtreg/vmTestbase/vm/mlvm/indy/func/java/thisAsArgument/INDIFY_Test.java
Normal file
@ -0,0 +1,141 @@
|
||||
/*
|
||||
* Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* @test
|
||||
*
|
||||
* @summary converted from VM Testbase vm/mlvm/indy/func/java/thisAsArgument.
|
||||
* VM Testbase keywords: [feature_mlvm]
|
||||
* VM Testbase readme:
|
||||
* DESCRIPTION
|
||||
* The test is written for a CR 6927831:
|
||||
* InvokeDynamic throws NoClassDefFoundError in the following test:
|
||||
* package test;
|
||||
* import java.dyn.InvokeDynamic;
|
||||
* import java.dyn.InvokeDynamicBootstrapError;
|
||||
* public class Self {
|
||||
* public static void main(String[] args) {
|
||||
* try {
|
||||
* InvokeDynamic.<void>greet(new Self());
|
||||
* } catch ( InvokeDynamicBootstrapError e ) {
|
||||
* System.out.println("TEST PASSED");
|
||||
* } catch ( Throwable t ) {
|
||||
* System.err.println("Oops!");
|
||||
* t.printStackTrace();
|
||||
* }
|
||||
* }
|
||||
* }
|
||||
* ...when it is launched with -classpath:
|
||||
* $ java -classpath bin test.Self
|
||||
* Oops!
|
||||
* java.lang.NoClassDefFoundError: test/Self
|
||||
* at test.Self.main(Self.java:10)
|
||||
* If we replace -classpath with -Xbootclasspath:
|
||||
* $ java -Xbootclasspath/a:bin test.Self
|
||||
* TEST PASSED
|
||||
*
|
||||
* @library /vmTestbase
|
||||
* /test/lib
|
||||
* @run driver jdk.test.lib.FileInstaller . .
|
||||
*
|
||||
* @comment build test class and indify classes
|
||||
* @build vm.mlvm.indy.func.java.thisAsArgument.INDIFY_Test
|
||||
* @run driver vm.mlvm.share.IndifiedClassesBuilder
|
||||
*
|
||||
* @run main/othervm vm.mlvm.indy.func.java.thisAsArgument.INDIFY_Test
|
||||
*/
|
||||
|
||||
package vm.mlvm.indy.func.java.thisAsArgument;
|
||||
|
||||
import java.lang.invoke.CallSite;
|
||||
import java.lang.invoke.MethodHandle;
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import java.lang.invoke.MethodType;
|
||||
import java.util.Arrays;
|
||||
|
||||
import vm.mlvm.share.MlvmTest;
|
||||
|
||||
public class INDIFY_Test extends MlvmTest {
|
||||
|
||||
public static void main(String[] args) { MlvmTest.launch(args); }
|
||||
|
||||
// Indify-specific bootstrap trampoline
|
||||
private static MethodType MT_bootstrap() {
|
||||
return MethodType.methodType(Object.class, Object.class, Object.class, Object.class);
|
||||
}
|
||||
private static MethodHandle MH_bootstrap() throws NoSuchMethodException, IllegalAccessException {
|
||||
return MethodHandles.lookup().findStatic(
|
||||
INDIFY_Test.class,
|
||||
"bootstrap",
|
||||
MT_bootstrap());
|
||||
}
|
||||
|
||||
public static Object bootstrap(Object lookup, Object name, Object type) throws Throwable {
|
||||
getLog().trace(0, "bootstrap(" +
|
||||
Arrays.asList(lookup.getClass(), lookup,
|
||||
name.getClass(), name,
|
||||
type.getClass(), type) + ") called");
|
||||
|
||||
return new Object();
|
||||
}
|
||||
|
||||
public static void target(INDIFY_Test arg) {
|
||||
getLog().trace(0, "target called: arg=" + arg);
|
||||
new Throwable("Stack trace").printStackTrace(getLog().getOutStream());
|
||||
}
|
||||
|
||||
// Indify-specific invokedynamic call substitution
|
||||
private static MethodHandle INDY_call;
|
||||
private static MethodHandle INDY_call() throws Throwable {
|
||||
if (INDY_call != null)
|
||||
return INDY_call;
|
||||
|
||||
CallSite cs = (CallSite) MH_bootstrap().invokeWithArguments(
|
||||
MethodHandles.lookup(),
|
||||
"target",
|
||||
MethodType.methodType(void.class, INDIFY_Test.class));
|
||||
|
||||
return cs.dynamicInvoker();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean run() throws Throwable {
|
||||
try {
|
||||
// Substitution for:
|
||||
// InvokeDynamic.target(new INDIFY_Test());
|
||||
INDIFY_Test test = new INDIFY_Test();
|
||||
INDY_call().invokeExact(test);
|
||||
getLog().complain("Target method should not be called");
|
||||
return false;
|
||||
} catch ( BootstrapMethodError e ) {
|
||||
getLog().trace(0, "Caught exception as expected:");
|
||||
e.printStackTrace(getLog().getOutStream());
|
||||
return true;
|
||||
} catch ( Throwable t ) {
|
||||
getLog().complain("Wrong exception caught!");
|
||||
t.printStackTrace(getLog().getOutStream());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package vm.mlvm.indy.func.java.thisAsArgument;
|
||||
|
||||
import vm.mlvm.share.MlvmTest;
|
||||
|
||||
public class Test extends MlvmTest {
|
||||
|
||||
public static void main(String[] args) { MlvmTest.launch(args); }
|
||||
|
||||
@Override
|
||||
public boolean run() throws Throwable {
|
||||
try {
|
||||
InvokeDynamic.greet(new Test());
|
||||
return false;
|
||||
} catch ( InvokeDynamicBootstrapError e ) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
131
test/hotspot/jtreg/vmTestbase/vm/mlvm/indy/func/java/verifyStackTrace/INDIFY_Test.java
Normal file
131
test/hotspot/jtreg/vmTestbase/vm/mlvm/indy/func/java/verifyStackTrace/INDIFY_Test.java
Normal file
@ -0,0 +1,131 @@
|
||||
/*
|
||||
* Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* @test
|
||||
*
|
||||
* @summary converted from VM Testbase vm/mlvm/indy/func/java/verifyStackTrace.
|
||||
* VM Testbase keywords: [feature_mlvm]
|
||||
* VM Testbase readme:
|
||||
* DESCRIPTION
|
||||
* The test verifies that a stack trace is readable and contains a correct stack in a bootstrap and a target methods
|
||||
*
|
||||
* @library /vmTestbase
|
||||
* /test/lib
|
||||
* @run driver jdk.test.lib.FileInstaller . .
|
||||
*
|
||||
* @comment build test class and indify classes
|
||||
* @build vm.mlvm.indy.func.java.verifyStackTrace.INDIFY_Test
|
||||
* @run driver vm.mlvm.share.IndifiedClassesBuilder
|
||||
*
|
||||
* @run main/othervm vm.mlvm.indy.func.java.verifyStackTrace.INDIFY_Test
|
||||
*/
|
||||
|
||||
package vm.mlvm.indy.func.java.verifyStackTrace;
|
||||
|
||||
import java.lang.invoke.CallSite;
|
||||
import java.lang.invoke.ConstantCallSite;
|
||||
import java.lang.invoke.MethodHandle;
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import java.lang.invoke.MethodHandles.Lookup;
|
||||
import java.lang.invoke.MethodType;
|
||||
|
||||
import vm.mlvm.share.MlvmTest;
|
||||
|
||||
public class INDIFY_Test extends MlvmTest {
|
||||
|
||||
private static final String METHOD_NAME = "runFunky";
|
||||
private static final int MAX_FRAME = 10;
|
||||
|
||||
public INDIFY_Test() {}
|
||||
|
||||
private static MethodType MT_bootstrap() {
|
||||
return MethodType.methodType(CallSite.class, Lookup.class, String.class, MethodType.class);
|
||||
}
|
||||
|
||||
private static MethodHandle MH_bootstrap() throws NoSuchMethodException, IllegalAccessException {
|
||||
return MethodHandles.lookup().findStatic(
|
||||
INDIFY_Test.class,
|
||||
"bootstrap",
|
||||
MT_bootstrap());
|
||||
}
|
||||
|
||||
public static CallSite bootstrap(Lookup c, String name, MethodType mt) throws Throwable {
|
||||
getLog().trace(0, "Lookup " + c + "; method name = " + name + "; method type = " + mt);
|
||||
|
||||
boolean found = false;
|
||||
StackTraceElement trace[] = new Throwable().getStackTrace();
|
||||
for ( int i = 1; i < MAX_FRAME; i++ ) {
|
||||
StackTraceElement stackFrame = trace[i];
|
||||
getLog().trace(0, "Caller " + i + " stack frame: " + stackFrame);
|
||||
if ( stackFrame.getMethodName().equals(METHOD_NAME) ) {
|
||||
getLog().trace(0, "Required stack frame found");
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! found )
|
||||
throw new RuntimeException("Can't find caller method name (" + METHOD_NAME + ") in a bootstrap method stack");
|
||||
|
||||
return new ConstantCallSite(MethodHandles.lookup().findStatic(INDIFY_Test.class, "target", mt));
|
||||
}
|
||||
|
||||
public static Throwable target(Object o, String s, int i) {
|
||||
getLog().trace(0, "Target called! Object = " + o + "; string = " + s + "; int = " + i);
|
||||
return new Throwable();
|
||||
}
|
||||
|
||||
private static MethodHandle INDY_call;
|
||||
private static MethodHandle INDY_call() throws Throwable {
|
||||
if (INDY_call != null)
|
||||
return INDY_call;
|
||||
|
||||
CallSite cs = (CallSite) MH_bootstrap().invokeWithArguments(
|
||||
MethodHandles.lookup(),
|
||||
"greet",
|
||||
MethodType.methodType(Throwable.class, Object.class, String.class, int.class));
|
||||
|
||||
return cs.dynamicInvoker();
|
||||
}
|
||||
|
||||
public boolean runFunky() throws Throwable {
|
||||
// Throwable t = (Throwable) InvokeDynamic.greet(new Object(), "world", 123);
|
||||
Object o = new Object();
|
||||
String s = "world";
|
||||
int i = 123;
|
||||
Throwable t = (Throwable) INDY_call().invokeExact(o, s, i);
|
||||
|
||||
StackTraceElement stackFrame = t.getStackTrace()[1];
|
||||
getLog().trace(0, "Stack trace element from target call: " + stackFrame);
|
||||
if ( ! stackFrame.getMethodName().equals(METHOD_NAME) )
|
||||
throw new Exception("Wrong method name in a bootstrap method: " + stackFrame);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean run() throws Throwable { return runFunky(); }
|
||||
|
||||
public static void main(String[] args) { MlvmTest.launch(args); }
|
||||
}
|
@ -0,0 +1,79 @@
|
||||
/*
|
||||
* Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package vm.mlvm.indy.func.java.verifyStackTrace;
|
||||
|
||||
import java.dyn.CallSite;
|
||||
import java.dyn.InvokeDynamic;
|
||||
import java.dyn.Linkage;
|
||||
import java.dyn.MethodHandles;
|
||||
import java.dyn.MethodType;
|
||||
|
||||
import vm.mlvm.share.MlvmTest;
|
||||
|
||||
public class Test extends MlvmTest {
|
||||
|
||||
private static final String METHOD_NAME = "runFunky";
|
||||
private static final int MAX_FRAME = 10;
|
||||
|
||||
public Test() {}
|
||||
|
||||
public static CallSite bootstrap(Class<?> c, String name, MethodType mt) {
|
||||
getLog().trace(0, "Class " + c + "; method name = " + name + "; method type = " + mt);
|
||||
|
||||
boolean found = false;
|
||||
StackTraceElement trace[] = new Throwable().getStackTrace();
|
||||
for ( int i = 1; i < MAX_FRAME; i++ ) {
|
||||
StackTraceElement stackFrame = trace[3];
|
||||
getLog().trace(0, "Caller " + i + " stack frame: " + stackFrame);
|
||||
if ( stackFrame.getMethodName().equals(METHOD_NAME) ) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! found )
|
||||
throw new RuntimeException("Can't find caller method name (" + METHOD_NAME + ") in a bootstrap method stack");
|
||||
|
||||
return new CallSite(MethodHandles.publicLookup().findStatic(Test.class, "target", mt));
|
||||
}
|
||||
|
||||
public static Throwable target(Object o, String s, int i) {
|
||||
getLog().trace(0, "Target called! Object = " + o + "; string = " + s + "; int = " + i);
|
||||
return new Throwable();
|
||||
}
|
||||
|
||||
public boolean runFunky() throws Throwable {
|
||||
Throwable t = (Throwable) InvokeDynamic.greet(new Object(), "world", 123);
|
||||
|
||||
StackTraceElement stackFrame = t.getStackTrace()[1];
|
||||
if ( ! stackFrame.getMethodName().equals(METHOD_NAME) )
|
||||
throw new RuntimeException("Wrong method name in a bootstrap method: " + stackFrame);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean run() throws Throwable { return runFunky(); }
|
||||
|
||||
public static void main(String[] args) { MlvmTest.launch(args); }
|
||||
}
|
@ -0,0 +1,24 @@
|
||||
#
|
||||
# Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
#
|
||||
# This code is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License version 2 only, as
|
||||
# published by the Free Software Foundation.
|
||||
#
|
||||
# This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
# version 2 for more details (a copy is included in the LICENSE file that
|
||||
# accompanied this code).
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License version
|
||||
# 2 along with this work; if not, write to the Free Software Foundation,
|
||||
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
#
|
||||
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
# or visit www.oracle.com if you need additional information or have any
|
||||
# questions.
|
||||
#
|
||||
|
||||
exclusiveAccess.dirs=.
|
@ -0,0 +1,86 @@
|
||||
/*
|
||||
* Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* @test
|
||||
*
|
||||
* @summary converted from VM Testbase vm/mlvm/indy/func/jdi/breakpoint.
|
||||
* VM Testbase keywords: [feature_mlvm, nonconcurrent, quarantine]
|
||||
* VM Testbase comments: 8199578
|
||||
* VM Testbase readme:
|
||||
* DESCRIPTION
|
||||
* Using JDI set a debugger breakpoint on invokedynamic instruction.
|
||||
* Go few steps, obtaining various information from JVM.
|
||||
*
|
||||
* @library /vmTestbase
|
||||
* /test/lib
|
||||
* @run driver jdk.test.lib.FileInstaller . .
|
||||
*
|
||||
* @comment build debuggee class
|
||||
* @build vm.mlvm.share.jdi.IndyDebuggee
|
||||
*
|
||||
* @comment build test class and indify classes
|
||||
* @build vm.mlvm.indy.func.jdi.breakpoint.Test
|
||||
* @run driver vm.mlvm.share.IndifiedClassesBuilder
|
||||
*
|
||||
* @run main/othervm PropertyResolvingWrapper
|
||||
* vm.mlvm.indy.func.jdi.breakpoint.Test
|
||||
* -verbose
|
||||
* -arch=${os.family}-${os.simpleArch}
|
||||
* -waittime=5
|
||||
* -debugee.vmkind=java
|
||||
* -transport.address=dynamic
|
||||
* -debugger.debuggeeClass vm.mlvm.share.jdi.IndyDebuggee
|
||||
*/
|
||||
|
||||
package vm.mlvm.indy.func.jdi.breakpoint;
|
||||
|
||||
import vm.mlvm.share.jdi.ArgumentHandler;
|
||||
import vm.mlvm.share.jdi.BreakpointInfo;
|
||||
import vm.mlvm.share.jdi.JDIBreakpointTest;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class Test extends JDIBreakpointTest {
|
||||
// indyWrapper:S8000,bootstrap,target,stop
|
||||
@Override
|
||||
protected List<BreakpointInfo> getBreakpoints(String debuggeeClassName) {
|
||||
List<BreakpointInfo> result = new ArrayList<>();
|
||||
{
|
||||
BreakpointInfo info = new BreakpointInfo("indyWrapper");
|
||||
info.stepsToTrace = 8000;
|
||||
result.add(info);
|
||||
}
|
||||
result.add(new BreakpointInfo("bootstrap"));
|
||||
result.add(new BreakpointInfo("target"));
|
||||
result.add(new BreakpointInfo("stop"));
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
public static void main(String[] args) {
|
||||
launch(new ArgumentHandler(args));
|
||||
}
|
||||
}
|
24
test/hotspot/jtreg/vmTestbase/vm/mlvm/indy/func/jdi/breakpointOtherStratum/TEST.properties
Normal file
24
test/hotspot/jtreg/vmTestbase/vm/mlvm/indy/func/jdi/breakpointOtherStratum/TEST.properties
Normal file
@ -0,0 +1,24 @@
|
||||
#
|
||||
# Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
#
|
||||
# This code is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License version 2 only, as
|
||||
# published by the Free Software Foundation.
|
||||
#
|
||||
# This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
# version 2 for more details (a copy is included in the LICENSE file that
|
||||
# accompanied this code).
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License version
|
||||
# 2 along with this work; if not, write to the Free Software Foundation,
|
||||
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
#
|
||||
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
# or visit www.oracle.com if you need additional information or have any
|
||||
# questions.
|
||||
#
|
||||
|
||||
exclusiveAccess.dirs=.
|
110
test/hotspot/jtreg/vmTestbase/vm/mlvm/indy/func/jdi/breakpointOtherStratum/Test.java
Normal file
110
test/hotspot/jtreg/vmTestbase/vm/mlvm/indy/func/jdi/breakpointOtherStratum/Test.java
Normal file
@ -0,0 +1,110 @@
|
||||
/*
|
||||
* Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* @test
|
||||
*
|
||||
* @summary converted from VM Testbase vm/mlvm/indy/func/jdi/breakpointOtherStratum.
|
||||
* VM Testbase keywords: [feature_mlvm, nonconcurrent, quarantine]
|
||||
* VM Testbase comments: 8199578
|
||||
* VM Testbase readme:
|
||||
* DESCRIPTION
|
||||
* Performs debugging of invokedynamic call in vm.mlvm.share.jdi.INDIFY_Debuggee (with added
|
||||
* source debug information) and verifies that JDI reports correct SDE locations.
|
||||
*
|
||||
* @library /vmTestbase
|
||||
* /test/lib
|
||||
* @run driver jdk.test.lib.FileInstaller . .
|
||||
*
|
||||
* @comment build debuggee class
|
||||
* @build vm.mlvm.share.jdi.IndyDebuggee
|
||||
*
|
||||
* @comment build test class and indify classes
|
||||
* @build vm.mlvm.indy.func.jdi.breakpointOtherStratum.Test
|
||||
* @run driver vm.mlvm.share.IndifiedClassesBuilder
|
||||
*
|
||||
* @comment recompile INDIFY_SDE_DebuggeeBase with Stratum annotation processor
|
||||
* @clean vm.mlvm.share.jpda.INDIFY_SDE_DebuggeeBase
|
||||
* @run driver
|
||||
* vm.mlvm.share.StratumClassesBuilder
|
||||
* vmTestbase/vm/mlvm/share/jpda/INDIFY_SDE_DebuggeeBase.java
|
||||
*
|
||||
* @run main/othervm PropertyResolvingWrapper
|
||||
* vm.mlvm.indy.func.jdi.breakpointOtherStratum.Test
|
||||
* -verbose
|
||||
* -arch=${os.family}-${os.simpleArch}
|
||||
* -waittime=5
|
||||
* -debugee.vmkind=java
|
||||
* -debugee.vmkeys="-cp ./bin/classes${path.separator}${test.class.path}"
|
||||
* -transport.address=dynamic
|
||||
* -debugger.debuggeeClass vm.mlvm.share.jdi.IndyDebuggee
|
||||
*/
|
||||
|
||||
package vm.mlvm.indy.func.jdi.breakpointOtherStratum;
|
||||
|
||||
import vm.mlvm.share.jdi.ArgumentHandler;
|
||||
import vm.mlvm.share.jdi.BreakpointInfo;
|
||||
import vm.mlvm.share.jdi.JDIBreakpointTest;
|
||||
import vm.mlvm.share.jpda.StratumInfo;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class Test extends JDIBreakpointTest {
|
||||
|
||||
@Override
|
||||
protected List<BreakpointInfo> getBreakpoints(String debuggeeClassName) {
|
||||
List<BreakpointInfo> result = new ArrayList<>();
|
||||
// indyWrapper:S8000/Logo=INDIFY_SDE_DebuggeeBase.logo:2
|
||||
{
|
||||
BreakpointInfo info = new BreakpointInfo("indyWrapper");
|
||||
info.stepsToTrace = 8000;
|
||||
info.stratumInfo = new StratumInfo("Logo", "INDIFY_SDE_DebuggeeBase.logo", 2);
|
||||
result.add(info);
|
||||
}
|
||||
// bootstrap/Logo=INDIFY_SDE_DebuggeeBase.logo:3
|
||||
{
|
||||
BreakpointInfo info = new BreakpointInfo("bootstrap");
|
||||
info.stratumInfo = new StratumInfo("Logo", "INDIFY_SDE_DebuggeeBase.logo", 3);
|
||||
result.add(info);
|
||||
}
|
||||
// target/Logo=INDIFY_SDE_DebuggeeBase.logo:4
|
||||
{
|
||||
BreakpointInfo info = new BreakpointInfo("target");
|
||||
info.stratumInfo = new StratumInfo("Logo", "INDIFY_SDE_DebuggeeBase.logo", 4);
|
||||
result.add(info);
|
||||
}
|
||||
// stop/Logo=INDIFY_SDE_DebuggeeBase.logo:5
|
||||
{
|
||||
BreakpointInfo info = new BreakpointInfo("stop");
|
||||
info.stratumInfo = new StratumInfo("Logo", "INDIFY_SDE_DebuggeeBase.logo", 5);
|
||||
result.add(info);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
launch(new ArgumentHandler(args));
|
||||
}
|
||||
}
|
91
test/hotspot/jtreg/vmTestbase/vm/mlvm/indy/func/jvmti/mergeCP_indy2manyDiff_a/INDIFY_Dummy0.java
Normal file
91
test/hotspot/jtreg/vmTestbase/vm/mlvm/indy/func/jvmti/mergeCP_indy2manyDiff_a/INDIFY_Dummy0.java
Normal file
@ -0,0 +1,91 @@
|
||||
/*
|
||||
* Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package vm.mlvm.indy.func.jvmti.mergeCP_indy2manyDiff_a;
|
||||
|
||||
import java.lang.invoke.CallSite;
|
||||
import java.lang.invoke.ConstantCallSite;
|
||||
import java.lang.invoke.MethodHandle;
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import java.lang.invoke.MethodType;
|
||||
|
||||
import vm.mlvm.share.MlvmTest;
|
||||
|
||||
public class INDIFY_Dummy0 {
|
||||
|
||||
private static MethodType MT_bootstrap() {
|
||||
return MethodType.methodType(CallSite.class, MethodHandles.Lookup.class, String.class, MethodType.class);
|
||||
}
|
||||
|
||||
private static MethodHandle MH_bootstrap() throws NoSuchMethodException, IllegalAccessException {
|
||||
return MethodHandles.lookup().findStatic(
|
||||
INDIFY_Dummy0.class,
|
||||
"bootstrap",
|
||||
MT_bootstrap());
|
||||
}
|
||||
|
||||
public static CallSite bootstrap(MethodHandles.Lookup l, String name, MethodType mt) throws Throwable {
|
||||
MlvmTest.getLog().display("Original bootstrap(): Lookup " + l + "; method name = " + name + "; method type = " + mt);
|
||||
CallSite cs = new ConstantCallSite(l.findStatic(INDIFY_Dummy0.class, "target", mt));
|
||||
return cs;
|
||||
}
|
||||
|
||||
|
||||
public static Boolean target(Object o, String s, int i) {
|
||||
MlvmTest.getLog().display("Original target called! Object = " + o + "; string = " + s + "; int = " + i);
|
||||
MlvmTest.getLog().display("The rest of methods are from " + (isRedefinedClass() ? "redefined" : "original") + " class");
|
||||
return false;
|
||||
}
|
||||
|
||||
public static void redefineNow() {}
|
||||
|
||||
private static MethodHandle INDY_call;
|
||||
private static MethodHandle INDY_call() throws Throwable {
|
||||
if (INDY_call != null)
|
||||
return INDY_call;
|
||||
|
||||
CallSite cs = (CallSite) MH_bootstrap().invokeWithArguments(
|
||||
MethodHandles.lookup(),
|
||||
"greet",
|
||||
MethodType.methodType(Boolean.class, Object.class, String.class, int.class));
|
||||
|
||||
return cs.dynamicInvoker();
|
||||
}
|
||||
|
||||
public static boolean invokeTarget() throws Throwable {
|
||||
return invokeTarget0();
|
||||
}
|
||||
|
||||
private static boolean invokeTarget0() throws Throwable {
|
||||
Object o = new Object();
|
||||
String s = "Original";
|
||||
int i = 456;
|
||||
boolean b = (Boolean) INDY_call().invokeExact(o, s, i);
|
||||
redefineNow();
|
||||
throw new RuntimeException("Original invokeTarget() method is executed after redefinition. Test failed.");
|
||||
}
|
||||
|
||||
public static boolean isRedefinedClass() {
|
||||
return false;
|
||||
}
|
||||
}
|
24
test/hotspot/jtreg/vmTestbase/vm/mlvm/indy/func/jvmti/mergeCP_indy2manyDiff_a/TEST.properties
Normal file
24
test/hotspot/jtreg/vmTestbase/vm/mlvm/indy/func/jvmti/mergeCP_indy2manyDiff_a/TEST.properties
Normal file
@ -0,0 +1,24 @@
|
||||
#
|
||||
# Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
#
|
||||
# This code is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License version 2 only, as
|
||||
# published by the Free Software Foundation.
|
||||
#
|
||||
# This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
# version 2 for more details (a copy is included in the LICENSE file that
|
||||
# accompanied this code).
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License version
|
||||
# 2 along with this work; if not, write to the Free Software Foundation,
|
||||
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
#
|
||||
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
# or visit www.oracle.com if you need additional information or have any
|
||||
# questions.
|
||||
#
|
||||
|
||||
exclusiveAccess.dirs=.
|
63
test/hotspot/jtreg/vmTestbase/vm/mlvm/indy/func/jvmti/mergeCP_indy2manyDiff_a/TestDescription.java
Normal file
63
test/hotspot/jtreg/vmTestbase/vm/mlvm/indy/func/jvmti/mergeCP_indy2manyDiff_a/TestDescription.java
Normal file
@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* @test
|
||||
*
|
||||
* @summary converted from VM Testbase vm/mlvm/indy/func/jvmti/mergeCP_indy2manyDiff_a.
|
||||
* VM Testbase keywords: [feature_mlvm, nonconcurrent, jvmti, redefine, noJFR]
|
||||
* VM Testbase readme:
|
||||
* DESCRIPTION
|
||||
* Test calls a boostrap and a target methods via InvokeDynamic call, monitoring that
|
||||
* a method in the debuggee class (Dummy0.redefineNow()) is called (monitoring is done
|
||||
* via MethodEntry event). After calling the target method, Dummy0 class is redefined
|
||||
* using RedefineClasses function to another Dummy0 class and PopFrame function
|
||||
* is called to reenter the method.
|
||||
* To verify logic of merging constant pools with regard to JSR 292, the original class has just
|
||||
* one invokedynamic call and the new Dummy0 has several invokedynamic calls with different arguments.
|
||||
* The test verifies that when class is redefined and frame is popped,
|
||||
* the new target method is executed and the site is relinked.
|
||||
*
|
||||
* @library /vmTestbase
|
||||
* /test/lib
|
||||
*
|
||||
* @comment build dummy class
|
||||
* @build vm.mlvm.indy.func.jvmti.mergeCP_indy2manyDiff_a.INDIFY_Dummy0
|
||||
*
|
||||
* @comment compile newclass to bin/newclass
|
||||
* @run driver nsk.share.ExtraClassesBuilder newclass
|
||||
* @run driver vm.mlvm.share.IndifiedClassesBuilder bin/newclass
|
||||
*
|
||||
* @run driver jdk.test.lib.FileInstaller . .
|
||||
*
|
||||
* @comment build test class and indify classes
|
||||
* @build vm.mlvm.indy.func.jvmti.share.IndyRedefineTest
|
||||
* @run driver vm.mlvm.share.IndifiedClassesBuilder
|
||||
*
|
||||
* @run main/othervm/native
|
||||
* -agentlib:IndyRedefineClass=verbose=~pathToNewByteCode=./bin/newclass
|
||||
* vm.mlvm.indy.func.jvmti.share.IndyRedefineTest
|
||||
* -dummyClassName=vm.mlvm.indy.func.jvmti.mergeCP_indy2manyDiff_a.INDIFY_Dummy0
|
||||
*/
|
||||
|
96
test/hotspot/jtreg/vmTestbase/vm/mlvm/indy/func/jvmti/mergeCP_indy2manyDiff_a/newclass/INDIFY_Dummy0.java
Normal file
96
test/hotspot/jtreg/vmTestbase/vm/mlvm/indy/func/jvmti/mergeCP_indy2manyDiff_a/newclass/INDIFY_Dummy0.java
Normal file
@ -0,0 +1,96 @@
|
||||
/*
|
||||
* Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package vm.mlvm.indy.func.jvmti.mergeCP_indy2manyDiff_a;
|
||||
|
||||
import java.lang.invoke.CallSite;
|
||||
import java.lang.invoke.ConstantCallSite;
|
||||
import java.lang.invoke.MethodHandle;
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import java.lang.invoke.MethodType;
|
||||
|
||||
import vm.mlvm.share.MlvmTest;
|
||||
|
||||
public class INDIFY_Dummy0 {
|
||||
|
||||
private static MethodType MT_bootstrap() {
|
||||
return MethodType.methodType(CallSite.class, MethodHandles.Lookup.class, String.class, MethodType.class);
|
||||
}
|
||||
|
||||
private static MethodHandle MH_bootstrap() throws NoSuchMethodException, IllegalAccessException {
|
||||
return MethodHandles.lookup().findStatic(
|
||||
INDIFY_Dummy0.class,
|
||||
"bootstrap",
|
||||
MT_bootstrap());
|
||||
}
|
||||
|
||||
public static CallSite bootstrap(MethodHandles.Lookup l, String name, MethodType mt) throws Throwable {
|
||||
MlvmTest.getLog().display("Redefined bootstrap(): Lookup " + l + "; method name = " + name + "; method type = " + mt);
|
||||
CallSite cs = new ConstantCallSite(l.findStatic(INDIFY_Dummy0.class, "target", mt));
|
||||
return cs;
|
||||
}
|
||||
|
||||
public static Boolean target(Object o, String s, int i) {
|
||||
MlvmTest.getLog().display("Redefined target called! Object = " + o + "; string = " + s + "; int = " + i);
|
||||
MlvmTest.getLog().display("The rest of methods are from " + (isRedefinedClass() ? "redefined" : "original") + " class");
|
||||
return true;
|
||||
}
|
||||
|
||||
public static void redefineNow() {}
|
||||
|
||||
private static MethodHandle INDY_call;
|
||||
private static MethodHandle INDY_call() throws Throwable {
|
||||
if (INDY_call != null)
|
||||
return INDY_call;
|
||||
|
||||
CallSite cs = (CallSite) MH_bootstrap().invokeWithArguments(
|
||||
MethodHandles.lookup(),
|
||||
"greet",
|
||||
MethodType.methodType(Boolean.class, Object.class, String.class, int.class));
|
||||
|
||||
return cs.dynamicInvoker();
|
||||
}
|
||||
|
||||
public static boolean invokeTarget() throws Throwable {
|
||||
return invokeTarget0();
|
||||
}
|
||||
|
||||
private static boolean invokeTarget0() throws Throwable {
|
||||
Object o = new Object();
|
||||
String s = "Redefined";
|
||||
int i = 456;
|
||||
boolean b = (Boolean) INDY_call().invokeExact(o, s, i);
|
||||
b ^= (Boolean) INDY_call().invokeExact(o, s, i);
|
||||
o = new Object();
|
||||
s = s + s;
|
||||
i = i + i;
|
||||
b ^= (Boolean) INDY_call().invokeExact(o, s, i);
|
||||
b ^= (Boolean) INDY_call().invokeExact(o, s, i);
|
||||
b ^= (Boolean) INDY_call().invokeExact(o, s, i);
|
||||
return b;
|
||||
}
|
||||
|
||||
public static boolean isRedefinedClass() {
|
||||
return true;
|
||||
}
|
||||
}
|
85
test/hotspot/jtreg/vmTestbase/vm/mlvm/indy/func/jvmti/mergeCP_indy2manyDiff_b/INDIFY_Dummy0.java
Normal file
85
test/hotspot/jtreg/vmTestbase/vm/mlvm/indy/func/jvmti/mergeCP_indy2manyDiff_b/INDIFY_Dummy0.java
Normal file
@ -0,0 +1,85 @@
|
||||
/*
|
||||
* Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package vm.mlvm.indy.func.jvmti.mergeCP_indy2manyDiff_b;
|
||||
|
||||
import java.lang.invoke.CallSite;
|
||||
import java.lang.invoke.MethodHandle;
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import java.lang.invoke.MethodType;
|
||||
|
||||
import vm.mlvm.share.MlvmTest;
|
||||
|
||||
public class INDIFY_Dummy0 {
|
||||
|
||||
private static MethodType MT_bootstrap() {
|
||||
return MethodType.methodType(CallSite.class, MethodHandles.Lookup.class, String.class, MethodType.class);
|
||||
}
|
||||
|
||||
private static MethodHandle MH_bootstrap() throws NoSuchMethodException, IllegalAccessException {
|
||||
return MethodHandles.lookup().findStatic(
|
||||
INDIFY_Dummy0.class,
|
||||
"bootstrap",
|
||||
MT_bootstrap());
|
||||
}
|
||||
|
||||
public static CallSite bootstrap(MethodHandles.Lookup l, String name, MethodType mt) throws Throwable {
|
||||
MlvmTest.getLog().display("Original bootstrap(): Lookup " + l + "; method name = " + name + "; method type = " + mt);
|
||||
redefineNow();
|
||||
throw new RuntimeException("Bootstrap method has not been redefined. Test failed.");
|
||||
}
|
||||
|
||||
public static Boolean target(Object o, String s, int i) {
|
||||
throw new RuntimeException("Original target method was called. Test failed.");
|
||||
}
|
||||
|
||||
public static void redefineNow() {}
|
||||
|
||||
private static MethodHandle INDY_call;
|
||||
private static MethodHandle INDY_call() throws Throwable {
|
||||
if (INDY_call != null)
|
||||
return INDY_call;
|
||||
|
||||
CallSite cs = (CallSite) MH_bootstrap().invokeWithArguments(
|
||||
MethodHandles.lookup(),
|
||||
"greet",
|
||||
MethodType.methodType(Boolean.class, Object.class, String.class, int.class));
|
||||
|
||||
return cs.dynamicInvoker();
|
||||
}
|
||||
|
||||
public static boolean invokeTarget() throws Throwable {
|
||||
return invokeTarget0();
|
||||
}
|
||||
|
||||
private static boolean invokeTarget0() throws Throwable {
|
||||
Object o = new Object();
|
||||
String s = "Original";
|
||||
int i = 456;
|
||||
return (Boolean) INDY_call().invokeExact(o, s, i);
|
||||
}
|
||||
|
||||
public static boolean isRedefinedClass() {
|
||||
return false;
|
||||
}
|
||||
}
|
24
test/hotspot/jtreg/vmTestbase/vm/mlvm/indy/func/jvmti/mergeCP_indy2manyDiff_b/TEST.properties
Normal file
24
test/hotspot/jtreg/vmTestbase/vm/mlvm/indy/func/jvmti/mergeCP_indy2manyDiff_b/TEST.properties
Normal file
@ -0,0 +1,24 @@
|
||||
#
|
||||
# Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
#
|
||||
# This code is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License version 2 only, as
|
||||
# published by the Free Software Foundation.
|
||||
#
|
||||
# This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
# version 2 for more details (a copy is included in the LICENSE file that
|
||||
# accompanied this code).
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License version
|
||||
# 2 along with this work; if not, write to the Free Software Foundation,
|
||||
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
#
|
||||
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
# or visit www.oracle.com if you need additional information or have any
|
||||
# questions.
|
||||
#
|
||||
|
||||
exclusiveAccess.dirs=.
|
64
test/hotspot/jtreg/vmTestbase/vm/mlvm/indy/func/jvmti/mergeCP_indy2manyDiff_b/TestDescription.java
Normal file
64
test/hotspot/jtreg/vmTestbase/vm/mlvm/indy/func/jvmti/mergeCP_indy2manyDiff_b/TestDescription.java
Normal file
@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* @test
|
||||
*
|
||||
* @summary converted from VM Testbase vm/mlvm/indy/func/jvmti/mergeCP_indy2manyDiff_b.
|
||||
* VM Testbase keywords: [feature_mlvm, nonconcurrent, jvmti, redefine, quarantine, noJFR]
|
||||
* VM Testbase comments: 8013267
|
||||
* VM Testbase readme:
|
||||
* DESCRIPTION
|
||||
* Test calls a boostrap and a target methods via InvokeDynamic call, monitoring that
|
||||
* a method in the debuggee class (Dummy0.redefineNow()) is called (monitoring is done
|
||||
* via MethodEntry event). At this moment, Dummy0 class is redefined using RedefineClasses
|
||||
* function to another Dummy0 class and PopFrame function is called to reenter the method.
|
||||
* To verify logic of merging constant pools with regard to JSR 292, the original class has just
|
||||
* one invokedynamic call and the new Dummy0 has several invokedynamic calls with different arguments.
|
||||
* The test verifies that when class is redefined in a target method (at that moment,
|
||||
* the call site is linked) and frame is popped, the new target method is executed and
|
||||
* the site is relinked.
|
||||
*
|
||||
* @library /vmTestbase
|
||||
* /test/lib
|
||||
*
|
||||
* @comment build dummy class
|
||||
* @build vm.mlvm.indy.func.jvmti.mergeCP_indy2manyDiff_b.INDIFY_Dummy0
|
||||
*
|
||||
* @comment compile newclass to bin/newclass
|
||||
* @run driver nsk.share.ExtraClassesBuilder newclass
|
||||
* @run driver vm.mlvm.share.IndifiedClassesBuilder bin/newclass
|
||||
*
|
||||
* @run driver jdk.test.lib.FileInstaller . .
|
||||
*
|
||||
* @comment build test class and indify classes
|
||||
* @build vm.mlvm.indy.func.jvmti.share.IndyRedefineTest
|
||||
* @run driver vm.mlvm.share.IndifiedClassesBuilder
|
||||
*
|
||||
* @run main/othervm/native
|
||||
* -agentlib:IndyRedefineClass=verbose=~pathToNewByteCode=./bin/newclass
|
||||
* vm.mlvm.indy.func.jvmti.share.IndyRedefineTest
|
||||
* -dummyClassName=vm.mlvm.indy.func.jvmti.mergeCP_indy2manyDiff_b.INDIFY_Dummy0
|
||||
*/
|
||||
|
97
test/hotspot/jtreg/vmTestbase/vm/mlvm/indy/func/jvmti/mergeCP_indy2manyDiff_b/newclass/INDIFY_Dummy0.java
Normal file
97
test/hotspot/jtreg/vmTestbase/vm/mlvm/indy/func/jvmti/mergeCP_indy2manyDiff_b/newclass/INDIFY_Dummy0.java
Normal file
@ -0,0 +1,97 @@
|
||||
/*
|
||||
* Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package vm.mlvm.indy.func.jvmti.mergeCP_indy2manyDiff_b;
|
||||
|
||||
import java.lang.invoke.CallSite;
|
||||
import java.lang.invoke.ConstantCallSite;
|
||||
import java.lang.invoke.MethodHandle;
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import java.lang.invoke.MethodType;
|
||||
|
||||
import vm.mlvm.share.MlvmTest;
|
||||
|
||||
public class INDIFY_Dummy0 {
|
||||
|
||||
private static MethodType MT_bootstrap() {
|
||||
return MethodType.methodType(CallSite.class, MethodHandles.Lookup.class, String.class, MethodType.class);
|
||||
}
|
||||
|
||||
private static MethodHandle MH_bootstrap() throws NoSuchMethodException, IllegalAccessException {
|
||||
return MethodHandles.lookup().findStatic(
|
||||
INDIFY_Dummy0.class,
|
||||
"bootstrap",
|
||||
MT_bootstrap());
|
||||
}
|
||||
|
||||
public static CallSite bootstrap(MethodHandles.Lookup l, String name, MethodType mt) throws Throwable {
|
||||
MlvmTest.getLog().display("Redefined bootstrap(): Lookup " + l + "; method name = " + name + "; method type = " + mt);
|
||||
//in the original file: redefineNow();
|
||||
CallSite cs = new ConstantCallSite(l.findStatic(INDIFY_Dummy0.class, "target", mt));
|
||||
return cs;
|
||||
}
|
||||
|
||||
public static Boolean target(Object o, String s, int i) {
|
||||
MlvmTest.getLog().display("Redefined target called! Object = " + o + "; string = " + s + "; int = " + i);
|
||||
MlvmTest.getLog().display("The rest of methods are from " + (isRedefinedClass() ? "redefined" : "original") + " class");
|
||||
return true;
|
||||
}
|
||||
|
||||
public static void redefineNow() {}
|
||||
|
||||
private static MethodHandle INDY_call;
|
||||
private static MethodHandle INDY_call() throws Throwable {
|
||||
if (INDY_call != null)
|
||||
return INDY_call;
|
||||
|
||||
CallSite cs = (CallSite) MH_bootstrap().invokeWithArguments(
|
||||
MethodHandles.lookup(),
|
||||
"greet",
|
||||
MethodType.methodType(Boolean.class, Object.class, String.class, int.class));
|
||||
|
||||
return cs.dynamicInvoker();
|
||||
}
|
||||
|
||||
public static boolean invokeTarget() throws Throwable {
|
||||
return invokeTarget0();
|
||||
}
|
||||
|
||||
private static boolean invokeTarget0() throws Throwable {
|
||||
Object o = new Object();
|
||||
String s = "Redefined";
|
||||
int i = 456;
|
||||
boolean b = (Boolean) INDY_call().invokeExact(o, s, i);
|
||||
b ^= (Boolean) INDY_call().invokeExact(o, s, i);
|
||||
o = new Object();
|
||||
s = s + s;
|
||||
i = i + i;
|
||||
b ^= (Boolean) INDY_call().invokeExact(o, s, i);
|
||||
b ^= (Boolean) INDY_call().invokeExact(o, s, i);
|
||||
b ^= (Boolean) INDY_call().invokeExact(o, s, i);
|
||||
return b;
|
||||
}
|
||||
|
||||
public static boolean isRedefinedClass() {
|
||||
return true;
|
||||
}
|
||||
}
|
90
test/hotspot/jtreg/vmTestbase/vm/mlvm/indy/func/jvmti/mergeCP_indy2manySame_a/INDIFY_Dummy0.java
Normal file
90
test/hotspot/jtreg/vmTestbase/vm/mlvm/indy/func/jvmti/mergeCP_indy2manySame_a/INDIFY_Dummy0.java
Normal file
@ -0,0 +1,90 @@
|
||||
/*
|
||||
* Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package vm.mlvm.indy.func.jvmti.mergeCP_indy2manySame_a;
|
||||
|
||||
import java.lang.invoke.CallSite;
|
||||
import java.lang.invoke.ConstantCallSite;
|
||||
import java.lang.invoke.MethodHandle;
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import java.lang.invoke.MethodType;
|
||||
|
||||
import vm.mlvm.share.MlvmTest;
|
||||
|
||||
public class INDIFY_Dummy0 {
|
||||
|
||||
private static MethodType MT_bootstrap() {
|
||||
return MethodType.methodType(CallSite.class, MethodHandles.Lookup.class, String.class, MethodType.class);
|
||||
}
|
||||
|
||||
private static MethodHandle MH_bootstrap() throws NoSuchMethodException, IllegalAccessException {
|
||||
return MethodHandles.lookup().findStatic(
|
||||
INDIFY_Dummy0.class,
|
||||
"bootstrap",
|
||||
MT_bootstrap());
|
||||
}
|
||||
|
||||
public static CallSite bootstrap(MethodHandles.Lookup l, String name, MethodType mt) throws Throwable {
|
||||
MlvmTest.getLog().display("Original bootstrap(): Lookup " + l + "; method name = " + name + "; method type = " + mt);
|
||||
CallSite cs = new ConstantCallSite(l.findStatic(INDIFY_Dummy0.class, "target", mt));
|
||||
return cs;
|
||||
}
|
||||
|
||||
public static Boolean target(Object o, String s, int i) {
|
||||
MlvmTest.getLog().display("Original target called! Object = " + o + "; string = " + s + "; int = " + i);
|
||||
MlvmTest.getLog().display("The rest of methods are from " + (isRedefinedClass() ? "redefined" : "original") + " class");
|
||||
return false;
|
||||
}
|
||||
|
||||
public static void redefineNow() {}
|
||||
|
||||
private static MethodHandle INDY_call;
|
||||
private static MethodHandle INDY_call() throws Throwable {
|
||||
if (INDY_call != null)
|
||||
return INDY_call;
|
||||
|
||||
CallSite cs = (CallSite) MH_bootstrap().invokeWithArguments(
|
||||
MethodHandles.lookup(),
|
||||
"greet",
|
||||
MethodType.methodType(Boolean.class, Object.class, String.class, int.class));
|
||||
|
||||
return cs.dynamicInvoker();
|
||||
}
|
||||
|
||||
public static boolean invokeTarget() throws Throwable {
|
||||
return invokeTarget0();
|
||||
}
|
||||
|
||||
private static boolean invokeTarget0() throws Throwable {
|
||||
Object o = new Object();
|
||||
String s = "Original";
|
||||
int i = 456;
|
||||
boolean b = (Boolean) INDY_call().invokeExact(o, s, i);
|
||||
redefineNow();
|
||||
throw new RuntimeException("Original invokeTarget() method is executed after redefinition. Test failed.");
|
||||
}
|
||||
|
||||
public static boolean isRedefinedClass() {
|
||||
return false;
|
||||
}
|
||||
}
|
24
test/hotspot/jtreg/vmTestbase/vm/mlvm/indy/func/jvmti/mergeCP_indy2manySame_a/TEST.properties
Normal file
24
test/hotspot/jtreg/vmTestbase/vm/mlvm/indy/func/jvmti/mergeCP_indy2manySame_a/TEST.properties
Normal file
@ -0,0 +1,24 @@
|
||||
#
|
||||
# Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
#
|
||||
# This code is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License version 2 only, as
|
||||
# published by the Free Software Foundation.
|
||||
#
|
||||
# This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
# version 2 for more details (a copy is included in the LICENSE file that
|
||||
# accompanied this code).
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License version
|
||||
# 2 along with this work; if not, write to the Free Software Foundation,
|
||||
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
#
|
||||
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
# or visit www.oracle.com if you need additional information or have any
|
||||
# questions.
|
||||
#
|
||||
|
||||
exclusiveAccess.dirs=.
|
63
test/hotspot/jtreg/vmTestbase/vm/mlvm/indy/func/jvmti/mergeCP_indy2manySame_a/TestDescription.java
Normal file
63
test/hotspot/jtreg/vmTestbase/vm/mlvm/indy/func/jvmti/mergeCP_indy2manySame_a/TestDescription.java
Normal file
@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* @test
|
||||
*
|
||||
* @summary converted from VM Testbase vm/mlvm/indy/func/jvmti/mergeCP_indy2manySame_a.
|
||||
* VM Testbase keywords: [feature_mlvm, nonconcurrent, jvmti, redefine, noJFR]
|
||||
* VM Testbase readme:
|
||||
* DESCRIPTION
|
||||
* Test calls a boostrap and a target methods via InvokeDynamic call, monitoring that
|
||||
* a method in the debuggee class (Dummy0.redefineNow()) is called (monitoring is done
|
||||
* via MethodEntry event). After calling the target method, Dummy0 class is redefined
|
||||
* using RedefineClasses function to another Dummy0 class and PopFrame function
|
||||
* is called to reenter the method.
|
||||
* To verify logic of merging constant pools with regard to JSR 292, the original class has just
|
||||
* one invokedynamic call and the new Dummy0 has several identical invokedynamic calls.
|
||||
* The test verifies that when class is redefined and frame is popped,
|
||||
* the new target method is executed and the site is relinked.
|
||||
*
|
||||
* @library /vmTestbase
|
||||
* /test/lib
|
||||
*
|
||||
* @comment build dummy class
|
||||
* @build vm.mlvm.indy.func.jvmti.mergeCP_indy2manySame_a.INDIFY_Dummy0
|
||||
*
|
||||
* @comment compile newclass to bin/newclass
|
||||
* @run driver nsk.share.ExtraClassesBuilder newclass
|
||||
* @run driver vm.mlvm.share.IndifiedClassesBuilder bin/newclass
|
||||
*
|
||||
* @run driver jdk.test.lib.FileInstaller . .
|
||||
*
|
||||
* @comment build test class and indify classes
|
||||
* @build vm.mlvm.indy.func.jvmti.share.IndyRedefineTest
|
||||
* @run driver vm.mlvm.share.IndifiedClassesBuilder
|
||||
*
|
||||
* @run main/othervm/native
|
||||
* -agentlib:IndyRedefineClass=verbose=~pathToNewByteCode=./bin/newclass
|
||||
* vm.mlvm.indy.func.jvmti.share.IndyRedefineTest
|
||||
* -dummyClassName=vm.mlvm.indy.func.jvmti.mergeCP_indy2manySame_a.INDIFY_Dummy0
|
||||
*/
|
||||
|
90
test/hotspot/jtreg/vmTestbase/vm/mlvm/indy/func/jvmti/mergeCP_indy2manySame_a/newclass/INDIFY_Dummy0.java
Normal file
90
test/hotspot/jtreg/vmTestbase/vm/mlvm/indy/func/jvmti/mergeCP_indy2manySame_a/newclass/INDIFY_Dummy0.java
Normal file
@ -0,0 +1,90 @@
|
||||
/*
|
||||
* Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package vm.mlvm.indy.func.jvmti.mergeCP_indy2manySame_a;
|
||||
|
||||
import java.lang.invoke.CallSite;
|
||||
import java.lang.invoke.ConstantCallSite;
|
||||
import java.lang.invoke.MethodHandle;
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import java.lang.invoke.MethodType;
|
||||
|
||||
import vm.mlvm.share.MlvmTest;
|
||||
|
||||
public class INDIFY_Dummy0 {
|
||||
|
||||
private static MethodType MT_bootstrap() {
|
||||
return MethodType.methodType(CallSite.class, MethodHandles.Lookup.class, String.class, MethodType.class);
|
||||
}
|
||||
|
||||
private static MethodHandle MH_bootstrap() throws NoSuchMethodException, IllegalAccessException {
|
||||
return MethodHandles.lookup().findStatic(
|
||||
INDIFY_Dummy0.class,
|
||||
"bootstrap",
|
||||
MT_bootstrap());
|
||||
}
|
||||
|
||||
public static CallSite bootstrap(MethodHandles.Lookup l, String name, MethodType mt) throws Throwable {
|
||||
MlvmTest.getLog().display("Redefined bootstrap(): Lookup " + l + "; method name = " + name + "; method type = " + mt);
|
||||
CallSite cs = new ConstantCallSite(l.findStatic(INDIFY_Dummy0.class, "target", mt));
|
||||
return cs;
|
||||
}
|
||||
|
||||
public static Boolean target(Object o, String s, int i) {
|
||||
MlvmTest.getLog().display("Redefined target called! Object = " + o + "; string = " + s + "; int = " + i);
|
||||
MlvmTest.getLog().display("The rest of methods are from " + (isRedefinedClass() ? "redefined" : "original") + " class");
|
||||
return true;
|
||||
}
|
||||
|
||||
public static void redefineNow() {}
|
||||
|
||||
private static MethodHandle INDY_call;
|
||||
private static MethodHandle INDY_call() throws Throwable {
|
||||
if (INDY_call != null)
|
||||
return INDY_call;
|
||||
|
||||
CallSite cs = (CallSite) MH_bootstrap().invokeWithArguments(
|
||||
MethodHandles.lookup(),
|
||||
"greet",
|
||||
MethodType.methodType(Boolean.class, Object.class, String.class, int.class));
|
||||
|
||||
return cs.dynamicInvoker();
|
||||
}
|
||||
|
||||
public static boolean invokeTarget() throws Throwable {
|
||||
return invokeTarget0();
|
||||
}
|
||||
|
||||
private static boolean invokeTarget0() throws Throwable {
|
||||
Object o = new Object();
|
||||
String s = "Redefined";
|
||||
int i = 456;
|
||||
return (Boolean) INDY_call().invokeExact(o, s, i)
|
||||
&& (Boolean) INDY_call().invokeExact(o, s, i)
|
||||
&& (Boolean) INDY_call().invokeExact(o, s, i);
|
||||
}
|
||||
|
||||
public static boolean isRedefinedClass() {
|
||||
return true;
|
||||
}
|
||||
}
|
85
test/hotspot/jtreg/vmTestbase/vm/mlvm/indy/func/jvmti/mergeCP_indy2manySame_b/INDIFY_Dummy0.java
Normal file
85
test/hotspot/jtreg/vmTestbase/vm/mlvm/indy/func/jvmti/mergeCP_indy2manySame_b/INDIFY_Dummy0.java
Normal file
@ -0,0 +1,85 @@
|
||||
/*
|
||||
* Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package vm.mlvm.indy.func.jvmti.mergeCP_indy2manySame_b;
|
||||
|
||||
import java.lang.invoke.CallSite;
|
||||
import java.lang.invoke.MethodHandle;
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import java.lang.invoke.MethodType;
|
||||
|
||||
import vm.mlvm.share.MlvmTest;
|
||||
|
||||
public class INDIFY_Dummy0 {
|
||||
|
||||
private static MethodType MT_bootstrap() {
|
||||
return MethodType.methodType(CallSite.class, MethodHandles.Lookup.class, String.class, MethodType.class);
|
||||
}
|
||||
|
||||
private static MethodHandle MH_bootstrap() throws NoSuchMethodException, IllegalAccessException {
|
||||
return MethodHandles.lookup().findStatic(
|
||||
INDIFY_Dummy0.class,
|
||||
"bootstrap",
|
||||
MT_bootstrap());
|
||||
}
|
||||
|
||||
public static CallSite bootstrap(MethodHandles.Lookup l, String name, MethodType mt) throws Throwable {
|
||||
MlvmTest.getLog().display("Original bootstrap(): Lookup " + l + "; method name = " + name + "; method type = " + mt);
|
||||
redefineNow();
|
||||
throw new RuntimeException("Bootstrap method has not been redefined. Test failed.");
|
||||
}
|
||||
|
||||
public static Boolean target(Object o, String s, int i) {
|
||||
throw new RuntimeException("Original target method was called. Test failed.");
|
||||
}
|
||||
|
||||
public static void redefineNow() {}
|
||||
|
||||
private static MethodHandle INDY_call;
|
||||
private static MethodHandle INDY_call() throws Throwable {
|
||||
if (INDY_call != null)
|
||||
return INDY_call;
|
||||
|
||||
CallSite cs = (CallSite) MH_bootstrap().invokeWithArguments(
|
||||
MethodHandles.lookup(),
|
||||
"greet",
|
||||
MethodType.methodType(Boolean.class, Object.class, String.class, int.class));
|
||||
|
||||
return cs.dynamicInvoker();
|
||||
}
|
||||
|
||||
public static boolean invokeTarget() throws Throwable {
|
||||
return invokeTarget0();
|
||||
}
|
||||
|
||||
private static boolean invokeTarget0() throws Throwable {
|
||||
Object o = new Object();
|
||||
String s = "Original";
|
||||
int i = 456;
|
||||
return (Boolean) INDY_call().invokeExact(o, s, i);
|
||||
}
|
||||
|
||||
public static boolean isRedefinedClass() {
|
||||
return false;
|
||||
}
|
||||
}
|
24
test/hotspot/jtreg/vmTestbase/vm/mlvm/indy/func/jvmti/mergeCP_indy2manySame_b/TEST.properties
Normal file
24
test/hotspot/jtreg/vmTestbase/vm/mlvm/indy/func/jvmti/mergeCP_indy2manySame_b/TEST.properties
Normal file
@ -0,0 +1,24 @@
|
||||
#
|
||||
# Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
#
|
||||
# This code is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License version 2 only, as
|
||||
# published by the Free Software Foundation.
|
||||
#
|
||||
# This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
# version 2 for more details (a copy is included in the LICENSE file that
|
||||
# accompanied this code).
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License version
|
||||
# 2 along with this work; if not, write to the Free Software Foundation,
|
||||
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
#
|
||||
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
# or visit www.oracle.com if you need additional information or have any
|
||||
# questions.
|
||||
#
|
||||
|
||||
exclusiveAccess.dirs=.
|
64
test/hotspot/jtreg/vmTestbase/vm/mlvm/indy/func/jvmti/mergeCP_indy2manySame_b/TestDescription.java
Normal file
64
test/hotspot/jtreg/vmTestbase/vm/mlvm/indy/func/jvmti/mergeCP_indy2manySame_b/TestDescription.java
Normal file
@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* @test
|
||||
*
|
||||
* @summary converted from VM Testbase vm/mlvm/indy/func/jvmti/mergeCP_indy2manySame_b.
|
||||
* VM Testbase keywords: [feature_mlvm, nonconcurrent, jvmti, redefine, quarantine, noJFR]
|
||||
* VM Testbase comments: 8013267
|
||||
* VM Testbase readme:
|
||||
* DESCRIPTION
|
||||
* Test calls a boostrap and a target methods via InvokeDynamic call, monitoring that
|
||||
* a method in the debuggee class (Dummy0.redefineNow()) is called (monitoring is done
|
||||
* via MethodEntry event). At this moment, Dummy0 class is redefined using RedefineClasses
|
||||
* function to another Dummy0 class and PopFrame function is called to reenter the method.
|
||||
* To verify logic of merging constant pools with regard to JSR 292, the original class has just
|
||||
* one invokedynamic call and the new Dummy0 has several identical invokedynamic calls.
|
||||
* The test verifies that when class is redefined in a target method (at that moment,
|
||||
* the call site is linked) and frame is popped, the new target method is executed and
|
||||
* the site is relinked.
|
||||
*
|
||||
* @library /vmTestbase
|
||||
* /test/lib
|
||||
*
|
||||
* @comment build dummy class
|
||||
* @build vm.mlvm.indy.func.jvmti.mergeCP_indy2manySame_b.INDIFY_Dummy0
|
||||
*
|
||||
* @comment compile newclass to bin/newclass
|
||||
* @run driver nsk.share.ExtraClassesBuilder newclass
|
||||
* @run driver vm.mlvm.share.IndifiedClassesBuilder bin/newclass
|
||||
*
|
||||
* @run driver jdk.test.lib.FileInstaller . .
|
||||
*
|
||||
* @comment build test class and indify classes
|
||||
* @build vm.mlvm.indy.func.jvmti.share.IndyRedefineTest
|
||||
* @run driver vm.mlvm.share.IndifiedClassesBuilder
|
||||
*
|
||||
* @run main/othervm/native
|
||||
* -agentlib:IndyRedefineClass=verbose=~pathToNewByteCode=./bin/newclass
|
||||
* vm.mlvm.indy.func.jvmti.share.IndyRedefineTest
|
||||
* -dummyClassName=vm.mlvm.indy.func.jvmti.mergeCP_indy2manySame_b.INDIFY_Dummy0
|
||||
*/
|
||||
|
91
test/hotspot/jtreg/vmTestbase/vm/mlvm/indy/func/jvmti/mergeCP_indy2manySame_b/newclass/INDIFY_Dummy0.java
Normal file
91
test/hotspot/jtreg/vmTestbase/vm/mlvm/indy/func/jvmti/mergeCP_indy2manySame_b/newclass/INDIFY_Dummy0.java
Normal file
@ -0,0 +1,91 @@
|
||||
/*
|
||||
* Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package vm.mlvm.indy.func.jvmti.mergeCP_indy2manySame_b;
|
||||
|
||||
import java.lang.invoke.CallSite;
|
||||
import java.lang.invoke.ConstantCallSite;
|
||||
import java.lang.invoke.MethodHandle;
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import java.lang.invoke.MethodType;
|
||||
|
||||
import vm.mlvm.share.MlvmTest;
|
||||
|
||||
public class INDIFY_Dummy0 {
|
||||
|
||||
private static MethodType MT_bootstrap() {
|
||||
return MethodType.methodType(CallSite.class, MethodHandles.Lookup.class, String.class, MethodType.class);
|
||||
}
|
||||
|
||||
private static MethodHandle MH_bootstrap() throws NoSuchMethodException, IllegalAccessException {
|
||||
return MethodHandles.lookup().findStatic(
|
||||
INDIFY_Dummy0.class,
|
||||
"bootstrap",
|
||||
MT_bootstrap());
|
||||
}
|
||||
|
||||
public static CallSite bootstrap(MethodHandles.Lookup l, String name, MethodType mt) throws Throwable {
|
||||
MlvmTest.getLog().display("Redefined bootstrap(): Lookup " + l + "; method name = " + name + "; method type = " + mt);
|
||||
//in the original file: redefineNow();
|
||||
CallSite cs = new ConstantCallSite(l.findStatic(INDIFY_Dummy0.class, "target", mt));
|
||||
return cs;
|
||||
}
|
||||
|
||||
public static Boolean target(Object o, String s, int i) {
|
||||
MlvmTest.getLog().display("Redefined target called! Object = " + o + "; string = " + s + "; int = " + i);
|
||||
MlvmTest.getLog().display("The rest of methods are from " + (isRedefinedClass() ? "redefined" : "original") + " class");
|
||||
return true;
|
||||
}
|
||||
|
||||
public static void redefineNow() {}
|
||||
|
||||
private static MethodHandle INDY_call;
|
||||
private static MethodHandle INDY_call() throws Throwable {
|
||||
if (INDY_call != null)
|
||||
return INDY_call;
|
||||
|
||||
CallSite cs = (CallSite) MH_bootstrap().invokeWithArguments(
|
||||
MethodHandles.lookup(),
|
||||
"greet",
|
||||
MethodType.methodType(Boolean.class, Object.class, String.class, int.class));
|
||||
|
||||
return cs.dynamicInvoker();
|
||||
}
|
||||
|
||||
public static boolean invokeTarget() throws Throwable {
|
||||
return invokeTarget0();
|
||||
}
|
||||
|
||||
private static boolean invokeTarget0() throws Throwable {
|
||||
Object o = new Object();
|
||||
String s = "Redefined";
|
||||
int i = 456;
|
||||
return (Boolean) INDY_call().invokeExact(o, s, i)
|
||||
&& (Boolean) INDY_call().invokeExact(o, s, i)
|
||||
&& (Boolean) INDY_call().invokeExact(o, s, i);
|
||||
}
|
||||
|
||||
public static boolean isRedefinedClass() {
|
||||
return true;
|
||||
}
|
||||
}
|
85
test/hotspot/jtreg/vmTestbase/vm/mlvm/indy/func/jvmti/mergeCP_indy2none_a/INDIFY_Dummy0.java
Normal file
85
test/hotspot/jtreg/vmTestbase/vm/mlvm/indy/func/jvmti/mergeCP_indy2none_a/INDIFY_Dummy0.java
Normal file
@ -0,0 +1,85 @@
|
||||
/*
|
||||
* Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package vm.mlvm.indy.func.jvmti.mergeCP_indy2none_a;
|
||||
|
||||
import java.lang.invoke.CallSite;
|
||||
import java.lang.invoke.MethodHandle;
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import java.lang.invoke.MethodType;
|
||||
|
||||
import vm.mlvm.share.MlvmTest;
|
||||
|
||||
public class INDIFY_Dummy0 {
|
||||
|
||||
private static MethodType MT_bootstrap() {
|
||||
return MethodType.methodType(CallSite.class, MethodHandles.Lookup.class, String.class, MethodType.class);
|
||||
}
|
||||
|
||||
private static MethodHandle MH_bootstrap() throws NoSuchMethodException, IllegalAccessException {
|
||||
return MethodHandles.lookup().findStatic(
|
||||
INDIFY_Dummy0.class,
|
||||
"bootstrap",
|
||||
MT_bootstrap());
|
||||
}
|
||||
|
||||
public static CallSite bootstrap(MethodHandles.Lookup l, String name, MethodType mt) throws Throwable {
|
||||
MlvmTest.getLog().display("Original bootstrap(): Lookup " + l + "; method name = " + name + "; method type = " + mt);
|
||||
redefineNow();
|
||||
throw new RuntimeException("Bootstrap method has not been redefined. Test failed.");
|
||||
}
|
||||
|
||||
public static Boolean target(Object o, String s, int i) {
|
||||
throw new RuntimeException("Original target method was called. Test failed.");
|
||||
}
|
||||
|
||||
public static void redefineNow() {}
|
||||
|
||||
private static MethodHandle INDY_call;
|
||||
private static MethodHandle INDY_call() throws Throwable {
|
||||
if (INDY_call != null)
|
||||
return INDY_call;
|
||||
|
||||
CallSite cs = (CallSite) MH_bootstrap().invokeWithArguments(
|
||||
MethodHandles.lookup(),
|
||||
"greet",
|
||||
MethodType.methodType(Boolean.class, Object.class, String.class, int.class));
|
||||
|
||||
return cs.dynamicInvoker();
|
||||
}
|
||||
|
||||
public static boolean invokeTarget() throws Throwable {
|
||||
return invokeTarget0();
|
||||
}
|
||||
|
||||
private static boolean invokeTarget0() throws Throwable {
|
||||
Object o = new Object();
|
||||
String s = "Original";
|
||||
int i = 456;
|
||||
return (Boolean) INDY_call().invokeExact(o, s, i);
|
||||
}
|
||||
|
||||
public static boolean isRedefinedClass() {
|
||||
return false;
|
||||
}
|
||||
}
|
24
test/hotspot/jtreg/vmTestbase/vm/mlvm/indy/func/jvmti/mergeCP_indy2none_a/TEST.properties
Normal file
24
test/hotspot/jtreg/vmTestbase/vm/mlvm/indy/func/jvmti/mergeCP_indy2none_a/TEST.properties
Normal file
@ -0,0 +1,24 @@
|
||||
#
|
||||
# Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
#
|
||||
# This code is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License version 2 only, as
|
||||
# published by the Free Software Foundation.
|
||||
#
|
||||
# This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
# version 2 for more details (a copy is included in the LICENSE file that
|
||||
# accompanied this code).
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License version
|
||||
# 2 along with this work; if not, write to the Free Software Foundation,
|
||||
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
#
|
||||
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
# or visit www.oracle.com if you need additional information or have any
|
||||
# questions.
|
||||
#
|
||||
|
||||
exclusiveAccess.dirs=.
|
64
test/hotspot/jtreg/vmTestbase/vm/mlvm/indy/func/jvmti/mergeCP_indy2none_a/TestDescription.java
Normal file
64
test/hotspot/jtreg/vmTestbase/vm/mlvm/indy/func/jvmti/mergeCP_indy2none_a/TestDescription.java
Normal file
@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* @test
|
||||
*
|
||||
* @summary converted from VM Testbase vm/mlvm/indy/func/jvmti/mergeCP_indy2none_a.
|
||||
* VM Testbase keywords: [feature_mlvm, nonconcurrent, jvmti, redefine, quarantine, noJFR]
|
||||
* VM Testbase comments: 8013267
|
||||
* VM Testbase readme:
|
||||
* DESCRIPTION
|
||||
* Test calls a boostrap and a target methods via InvokeDynamic call, monitoring that
|
||||
* a method in the debuggee class (Dummy0.redefineNow()) is called (monitoring is done
|
||||
* via MethodEntry event). After calling the target method, Dummy0 class is redefined
|
||||
* using RedefineClasses function to another Dummy0 class and PopFrame function
|
||||
* is called to reenter the method.
|
||||
* To verify logic of merging constant pools with regard to JSR 292, the original class has
|
||||
* a invokedynamic call and the new Dummy0 does not have invokedynamic at all.
|
||||
* The test verifies that when class is redefined and frame is popped,
|
||||
* the new target method is executed and the site is relinked.
|
||||
*
|
||||
* @library /vmTestbase
|
||||
* /test/lib
|
||||
*
|
||||
* @comment build dummy class
|
||||
* @build vm.mlvm.indy.func.jvmti.mergeCP_indy2none_a.INDIFY_Dummy0
|
||||
*
|
||||
* @comment compile newclass to bin/newclass
|
||||
* @run driver nsk.share.ExtraClassesBuilder newclass
|
||||
* @run driver vm.mlvm.share.IndifiedClassesBuilder bin/newclass
|
||||
*
|
||||
* @run driver jdk.test.lib.FileInstaller . .
|
||||
*
|
||||
* @comment build test class and indify classes
|
||||
* @build vm.mlvm.indy.func.jvmti.share.IndyRedefineTest
|
||||
* @run driver vm.mlvm.share.IndifiedClassesBuilder
|
||||
*
|
||||
* @run main/othervm/native
|
||||
* -agentlib:IndyRedefineClass=verbose=~pathToNewByteCode=./bin/newclass
|
||||
* vm.mlvm.indy.func.jvmti.share.IndyRedefineTest
|
||||
* -dummyClassName=vm.mlvm.indy.func.jvmti.mergeCP_indy2none_a.INDIFY_Dummy0
|
||||
*/
|
||||
|
89
test/hotspot/jtreg/vmTestbase/vm/mlvm/indy/func/jvmti/mergeCP_indy2none_a/newclass/INDIFY_Dummy0.java
Normal file
89
test/hotspot/jtreg/vmTestbase/vm/mlvm/indy/func/jvmti/mergeCP_indy2none_a/newclass/INDIFY_Dummy0.java
Normal file
@ -0,0 +1,89 @@
|
||||
/*
|
||||
* Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package vm.mlvm.indy.func.jvmti.mergeCP_indy2none_a;
|
||||
|
||||
import java.lang.invoke.CallSite;
|
||||
import java.lang.invoke.ConstantCallSite;
|
||||
import java.lang.invoke.MethodHandle;
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import java.lang.invoke.MethodType;
|
||||
|
||||
import vm.mlvm.share.MlvmTest;
|
||||
|
||||
public class INDIFY_Dummy0 {
|
||||
|
||||
private static MethodType MT_bootstrap() {
|
||||
return MethodType.methodType(CallSite.class, MethodHandles.Lookup.class, String.class, MethodType.class);
|
||||
}
|
||||
|
||||
private static MethodHandle MH_bootstrap() throws NoSuchMethodException, IllegalAccessException {
|
||||
return MethodHandles.lookup().findStatic(
|
||||
INDIFY_Dummy0.class,
|
||||
"bootstrap",
|
||||
MT_bootstrap());
|
||||
}
|
||||
|
||||
public static CallSite bootstrap(MethodHandles.Lookup l, String name, MethodType mt) throws Throwable {
|
||||
MlvmTest.getLog().display("Redefined bootstrap(): Lookup " + l + "; method name = " + name + "; method type = " + mt);
|
||||
//In the original class: redefineNow();
|
||||
CallSite cs = new ConstantCallSite(l.findStatic(INDIFY_Dummy0.class, "target", mt));
|
||||
return cs;
|
||||
}
|
||||
|
||||
public static Boolean target(Object o, String s, int i) {
|
||||
MlvmTest.getLog().display("Redefined target called! Object = " + o + "; string = " + s + "; int = " + i);
|
||||
MlvmTest.getLog().display("The rest of methods are from " + (isRedefinedClass() ? "redefined" : "original") + " class");
|
||||
return true;
|
||||
}
|
||||
|
||||
public static void redefineNow() {}
|
||||
|
||||
private static MethodHandle INDY_call;
|
||||
private static MethodHandle INDY_call() throws Throwable {
|
||||
if (INDY_call != null)
|
||||
return INDY_call;
|
||||
|
||||
CallSite cs = (CallSite) MH_bootstrap().invokeWithArguments(
|
||||
MethodHandles.lookup(),
|
||||
"greet",
|
||||
MethodType.methodType(Boolean.class, Object.class, String.class, int.class));
|
||||
|
||||
return cs.dynamicInvoker();
|
||||
}
|
||||
|
||||
public static boolean invokeTarget() throws Throwable {
|
||||
return invokeTarget0();
|
||||
}
|
||||
|
||||
private static boolean invokeTarget0() throws Throwable {
|
||||
Object o = new Object();
|
||||
String s = "Redefined";
|
||||
int i = 456;
|
||||
return (Boolean) INDY_call().invokeExact(o, s, i);
|
||||
}
|
||||
|
||||
public static boolean isRedefinedClass() {
|
||||
return true;
|
||||
}
|
||||
}
|
87
test/hotspot/jtreg/vmTestbase/vm/mlvm/indy/func/jvmti/mergeCP_indy2none_b/INDIFY_Dummy0.java
Normal file
87
test/hotspot/jtreg/vmTestbase/vm/mlvm/indy/func/jvmti/mergeCP_indy2none_b/INDIFY_Dummy0.java
Normal file
@ -0,0 +1,87 @@
|
||||
/*
|
||||
* Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package vm.mlvm.indy.func.jvmti.mergeCP_indy2none_b;
|
||||
|
||||
import java.lang.invoke.CallSite;
|
||||
import java.lang.invoke.ConstantCallSite;
|
||||
import java.lang.invoke.MethodHandle;
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import java.lang.invoke.MethodType;
|
||||
|
||||
import vm.mlvm.share.MlvmTest;
|
||||
|
||||
public class INDIFY_Dummy0 {
|
||||
|
||||
private static MethodType MT_bootstrap() {
|
||||
return MethodType.methodType(CallSite.class, MethodHandles.Lookup.class, String.class, MethodType.class);
|
||||
}
|
||||
|
||||
private static MethodHandle MH_bootstrap() throws NoSuchMethodException, IllegalAccessException {
|
||||
return MethodHandles.lookup().findStatic(
|
||||
INDIFY_Dummy0.class,
|
||||
"bootstrap",
|
||||
MT_bootstrap());
|
||||
}
|
||||
|
||||
public static CallSite bootstrap(MethodHandles.Lookup l, String name, MethodType mt) throws Throwable {
|
||||
MlvmTest.getLog().display("Original bootstrap(): Lookup " + l + "; method name = " + name + "; method type = " + mt);
|
||||
CallSite cs = new ConstantCallSite(l.findStatic(INDIFY_Dummy0.class, "target", mt));
|
||||
return cs;
|
||||
}
|
||||
|
||||
public static Boolean target(Object o, String s, int i) {
|
||||
redefineNow();
|
||||
throw new RuntimeException("Original target method was called. Test failed.");
|
||||
}
|
||||
|
||||
public static void redefineNow() {}
|
||||
|
||||
private static MethodHandle INDY_call;
|
||||
private static MethodHandle INDY_call() throws Throwable {
|
||||
if (INDY_call != null)
|
||||
return INDY_call;
|
||||
|
||||
CallSite cs = (CallSite) MH_bootstrap().invokeWithArguments(
|
||||
MethodHandles.lookup(),
|
||||
"greet",
|
||||
MethodType.methodType(Boolean.class, Object.class, String.class, int.class));
|
||||
|
||||
return cs.dynamicInvoker();
|
||||
}
|
||||
|
||||
public static boolean invokeTarget() throws Throwable {
|
||||
return invokeTarget0();
|
||||
}
|
||||
|
||||
private static boolean invokeTarget0() throws Throwable {
|
||||
Object o = new Object();
|
||||
String s = "Original";
|
||||
int i = 456;
|
||||
return (Boolean) INDY_call().invokeExact(o, s, i);
|
||||
}
|
||||
|
||||
public static boolean isRedefinedClass() {
|
||||
return false;
|
||||
}
|
||||
}
|
24
test/hotspot/jtreg/vmTestbase/vm/mlvm/indy/func/jvmti/mergeCP_indy2none_b/TEST.properties
Normal file
24
test/hotspot/jtreg/vmTestbase/vm/mlvm/indy/func/jvmti/mergeCP_indy2none_b/TEST.properties
Normal file
@ -0,0 +1,24 @@
|
||||
#
|
||||
# Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
#
|
||||
# This code is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License version 2 only, as
|
||||
# published by the Free Software Foundation.
|
||||
#
|
||||
# This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
# version 2 for more details (a copy is included in the LICENSE file that
|
||||
# accompanied this code).
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License version
|
||||
# 2 along with this work; if not, write to the Free Software Foundation,
|
||||
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
#
|
||||
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
# or visit www.oracle.com if you need additional information or have any
|
||||
# questions.
|
||||
#
|
||||
|
||||
exclusiveAccess.dirs=.
|
63
test/hotspot/jtreg/vmTestbase/vm/mlvm/indy/func/jvmti/mergeCP_indy2none_b/TestDescription.java
Normal file
63
test/hotspot/jtreg/vmTestbase/vm/mlvm/indy/func/jvmti/mergeCP_indy2none_b/TestDescription.java
Normal file
@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* @test
|
||||
*
|
||||
* @summary converted from VM Testbase vm/mlvm/indy/func/jvmti/mergeCP_indy2none_b.
|
||||
* VM Testbase keywords: [feature_mlvm, nonconcurrent, jvmti, redefine, noJFR]
|
||||
* VM Testbase readme:
|
||||
* DESCRIPTION
|
||||
* Test calls a boostrap and a target methods via InvokeDynamic call, monitoring that
|
||||
* a method in the debuggee class (Dummy0.redefineNow()) is called (monitoring is done
|
||||
* via MethodEntry event). At this moment, Dummy0 class is redefined using RedefineClasses
|
||||
* function to another Dummy0 class and PopFrame function is called to reenter the method.
|
||||
* To verify logic of merging constant pools with regard to JSR 292, the original class has
|
||||
* a invokedynamic call and the new Dummy0 does not have invokedynamic at all.
|
||||
* The test verifies that when class is redefined in a target method (at that moment,
|
||||
* the call site is linked) and frame is popped, the new target method is executed and
|
||||
* the site is relinked.
|
||||
*
|
||||
* @library /vmTestbase
|
||||
* /test/lib
|
||||
*
|
||||
* @comment build dummy class
|
||||
* @build vm.mlvm.indy.func.jvmti.mergeCP_indy2none_b.INDIFY_Dummy0
|
||||
*
|
||||
* @comment compile newclass to bin/newclass
|
||||
* @run driver nsk.share.ExtraClassesBuilder newclass
|
||||
* @run driver vm.mlvm.share.IndifiedClassesBuilder bin/newclass
|
||||
*
|
||||
* @run driver jdk.test.lib.FileInstaller . .
|
||||
*
|
||||
* @comment build test class and indify classes
|
||||
* @build vm.mlvm.indy.func.jvmti.share.IndyRedefineTest
|
||||
* @run driver vm.mlvm.share.IndifiedClassesBuilder
|
||||
*
|
||||
* @run main/othervm/native
|
||||
* -agentlib:IndyRedefineClass=verbose=~pathToNewByteCode=./bin/newclass
|
||||
* vm.mlvm.indy.func.jvmti.share.IndyRedefineTest
|
||||
* -dummyClassName=vm.mlvm.indy.func.jvmti.mergeCP_indy2none_b.INDIFY_Dummy0
|
||||
*/
|
||||
|
82
test/hotspot/jtreg/vmTestbase/vm/mlvm/indy/func/jvmti/mergeCP_indy2none_b/newclass/INDIFY_Dummy0.java
Normal file
82
test/hotspot/jtreg/vmTestbase/vm/mlvm/indy/func/jvmti/mergeCP_indy2none_b/newclass/INDIFY_Dummy0.java
Normal file
@ -0,0 +1,82 @@
|
||||
/*
|
||||
* Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package vm.mlvm.indy.func.jvmti.mergeCP_indy2none_b;
|
||||
|
||||
import vm.mlvm.share.MlvmTest;
|
||||
|
||||
import java.lang.invoke.*;
|
||||
|
||||
public class INDIFY_Dummy0 {
|
||||
private static MethodType MT_bootstrap() {
|
||||
return MethodType.methodType(CallSite.class, MethodHandles.Lookup.class, String.class, MethodType.class);
|
||||
}
|
||||
|
||||
private static MethodHandle MH_bootstrap() throws NoSuchMethodException, IllegalAccessException {
|
||||
return MethodHandles.lookup().findStatic(
|
||||
INDIFY_Dummy0.class,
|
||||
"bootstrap",
|
||||
MT_bootstrap());
|
||||
}
|
||||
|
||||
public static CallSite bootstrap(MethodHandles.Lookup l, String name, MethodType mt) throws Throwable {
|
||||
MlvmTest.getLog().display("Redefined bootstrap(): Lookup " + l + "; method name = " + name + "; method type = " + mt);
|
||||
CallSite cs = new ConstantCallSite(l.findStatic(INDIFY_Dummy0.class, "target", mt));
|
||||
return cs;
|
||||
}
|
||||
public static Boolean target(Object o, String s, int i) {
|
||||
MlvmTest.getLog().display("Redefined target called! Object = " + o + "; string = " + s + "; int = " + i);
|
||||
MlvmTest.getLog().display("The rest of methods are from " + (isRedefinedClass() ? "redefined" : "original") + " class");
|
||||
return true;
|
||||
}
|
||||
|
||||
public static void redefineNow() {}
|
||||
|
||||
private static MethodHandle INDY_call;
|
||||
private static MethodHandle INDY_call() throws Throwable {
|
||||
if (INDY_call != null)
|
||||
return INDY_call;
|
||||
|
||||
CallSite cs = (CallSite) MH_bootstrap().invokeWithArguments(
|
||||
MethodHandles.lookup(),
|
||||
"greet",
|
||||
MethodType.methodType(Boolean.class, Object.class, String.class, int.class));
|
||||
|
||||
return cs.dynamicInvoker();
|
||||
}
|
||||
|
||||
public static boolean invokeTarget() throws Throwable {
|
||||
return invokeTarget0();
|
||||
}
|
||||
|
||||
private static boolean invokeTarget0() throws Throwable {
|
||||
Object o = new Object();
|
||||
String s = "Redefined";
|
||||
int i = 456;
|
||||
return (Boolean) target(o, s, i);
|
||||
}
|
||||
|
||||
public static boolean isRedefinedClass() {
|
||||
return true;
|
||||
}
|
||||
}
|
90
test/hotspot/jtreg/vmTestbase/vm/mlvm/indy/func/jvmti/mergeCP_indy2same_a/INDIFY_Dummy0.java
Normal file
90
test/hotspot/jtreg/vmTestbase/vm/mlvm/indy/func/jvmti/mergeCP_indy2same_a/INDIFY_Dummy0.java
Normal file
@ -0,0 +1,90 @@
|
||||
/*
|
||||
* Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package vm.mlvm.indy.func.jvmti.mergeCP_indy2same_a;
|
||||
|
||||
import java.lang.invoke.CallSite;
|
||||
import java.lang.invoke.ConstantCallSite;
|
||||
import java.lang.invoke.MethodHandle;
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import java.lang.invoke.MethodType;
|
||||
|
||||
import vm.mlvm.share.MlvmTest;
|
||||
|
||||
public class INDIFY_Dummy0 {
|
||||
|
||||
private static MethodType MT_bootstrap() {
|
||||
return MethodType.methodType(CallSite.class, MethodHandles.Lookup.class, String.class, MethodType.class);
|
||||
}
|
||||
|
||||
private static MethodHandle MH_bootstrap() throws NoSuchMethodException, IllegalAccessException {
|
||||
return MethodHandles.lookup().findStatic(
|
||||
INDIFY_Dummy0.class,
|
||||
"bootstrap",
|
||||
MT_bootstrap());
|
||||
}
|
||||
|
||||
public static CallSite bootstrap(MethodHandles.Lookup l, String name, MethodType mt) throws Throwable {
|
||||
MlvmTest.getLog().display("bootstrap(): Lookup " + l + "; method name = " + name + "; method type = " + mt);
|
||||
CallSite cs = new ConstantCallSite(l.findStatic(INDIFY_Dummy0.class, "target", mt));
|
||||
return cs;
|
||||
}
|
||||
|
||||
public static Boolean target(Object o, String s, int i) {
|
||||
MlvmTest.getLog().display("Target called! Object = " + o + "; string = " + s + "; int = " + i);
|
||||
MlvmTest.getLog().display("The rest of methods are from " + (isRedefinedClass() ? "redefined" : "original") + " class");
|
||||
return false;
|
||||
}
|
||||
|
||||
public static void redefineNow() {}
|
||||
|
||||
private static MethodHandle INDY_call;
|
||||
private static MethodHandle INDY_call() throws Throwable {
|
||||
if (INDY_call != null)
|
||||
return INDY_call;
|
||||
|
||||
CallSite cs = (CallSite) MH_bootstrap().invokeWithArguments(
|
||||
MethodHandles.lookup(),
|
||||
"greet",
|
||||
MethodType.methodType(Boolean.class, Object.class, String.class, int.class));
|
||||
|
||||
return cs.dynamicInvoker();
|
||||
}
|
||||
|
||||
public static boolean invokeTarget() throws Throwable {
|
||||
return invokeTarget0();
|
||||
}
|
||||
|
||||
private static boolean invokeTarget0() throws Throwable {
|
||||
Object o = new Object();
|
||||
String s = "";
|
||||
int i = 456;
|
||||
boolean b = (Boolean) INDY_call().invokeExact(o, s, i);
|
||||
redefineNow();
|
||||
return (Boolean) INDY_call().invokeExact(o, s, i);
|
||||
}
|
||||
|
||||
public static boolean isRedefinedClass() {
|
||||
return false;
|
||||
}
|
||||
}
|
24
test/hotspot/jtreg/vmTestbase/vm/mlvm/indy/func/jvmti/mergeCP_indy2same_a/TEST.properties
Normal file
24
test/hotspot/jtreg/vmTestbase/vm/mlvm/indy/func/jvmti/mergeCP_indy2same_a/TEST.properties
Normal file
@ -0,0 +1,24 @@
|
||||
#
|
||||
# Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
#
|
||||
# This code is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License version 2 only, as
|
||||
# published by the Free Software Foundation.
|
||||
#
|
||||
# This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
# version 2 for more details (a copy is included in the LICENSE file that
|
||||
# accompanied this code).
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License version
|
||||
# 2 along with this work; if not, write to the Free Software Foundation,
|
||||
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
#
|
||||
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
# or visit www.oracle.com if you need additional information or have any
|
||||
# questions.
|
||||
#
|
||||
|
||||
exclusiveAccess.dirs=.
|
63
test/hotspot/jtreg/vmTestbase/vm/mlvm/indy/func/jvmti/mergeCP_indy2same_a/TestDescription.java
Normal file
63
test/hotspot/jtreg/vmTestbase/vm/mlvm/indy/func/jvmti/mergeCP_indy2same_a/TestDescription.java
Normal file
@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* @test
|
||||
*
|
||||
* @summary converted from VM Testbase vm/mlvm/indy/func/jvmti/mergeCP_indy2same_a.
|
||||
* VM Testbase keywords: [feature_mlvm, nonconcurrent, jvmti, redefine, noJFR]
|
||||
* VM Testbase readme:
|
||||
* DESCRIPTION
|
||||
* Test calls a boostrap and a target methods via InvokeDynamic call, monitoring that
|
||||
* a method in the debuggee class (Dummy0.redefineNow()) is called (monitoring is done
|
||||
* via MethodEntry event). After calling the target method, Dummy0 class is redefined
|
||||
* using RedefineClasses function to another Dummy0 class and PopFrame function
|
||||
* is called to reenter the method.
|
||||
* To verify logic of merging constant pools with regard to JSR 292, the original class
|
||||
* and the target one have the nearly the same code and the same CP.
|
||||
* The test verifies that when class is redefined and frame is popped,
|
||||
* the new target method is executed and the site is relinked.
|
||||
*
|
||||
* @library /vmTestbase
|
||||
* /test/lib
|
||||
*
|
||||
* @comment build dummy class
|
||||
* @build vm.mlvm.indy.func.jvmti.mergeCP_indy2same_a.INDIFY_Dummy0
|
||||
*
|
||||
* @comment compile newclass to bin/newclass
|
||||
* @run driver nsk.share.ExtraClassesBuilder newclass
|
||||
* @run driver vm.mlvm.share.IndifiedClassesBuilder bin/newclass
|
||||
*
|
||||
* @run driver jdk.test.lib.FileInstaller . .
|
||||
*
|
||||
* @comment build test class and indify classes
|
||||
* @build vm.mlvm.indy.func.jvmti.share.IndyRedefineTest
|
||||
* @run driver vm.mlvm.share.IndifiedClassesBuilder
|
||||
*
|
||||
* @run main/othervm/native
|
||||
* -agentlib:IndyRedefineClass=verbose=~pathToNewByteCode=./bin/newclass
|
||||
* vm.mlvm.indy.func.jvmti.share.IndyRedefineTest
|
||||
* -dummyClassName=vm.mlvm.indy.func.jvmti.mergeCP_indy2same_a.INDIFY_Dummy0
|
||||
*/
|
||||
|
90
test/hotspot/jtreg/vmTestbase/vm/mlvm/indy/func/jvmti/mergeCP_indy2same_a/newclass/INDIFY_Dummy0.java
Normal file
90
test/hotspot/jtreg/vmTestbase/vm/mlvm/indy/func/jvmti/mergeCP_indy2same_a/newclass/INDIFY_Dummy0.java
Normal file
@ -0,0 +1,90 @@
|
||||
/*
|
||||
* Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package vm.mlvm.indy.func.jvmti.mergeCP_indy2same_a;
|
||||
|
||||
import java.lang.invoke.CallSite;
|
||||
import java.lang.invoke.ConstantCallSite;
|
||||
import java.lang.invoke.MethodHandle;
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import java.lang.invoke.MethodType;
|
||||
|
||||
import vm.mlvm.share.MlvmTest;
|
||||
|
||||
public class INDIFY_Dummy0 {
|
||||
|
||||
private static MethodType MT_bootstrap() {
|
||||
return MethodType.methodType(CallSite.class, MethodHandles.Lookup.class, String.class, MethodType.class);
|
||||
}
|
||||
|
||||
private static MethodHandle MH_bootstrap() throws NoSuchMethodException, IllegalAccessException {
|
||||
return MethodHandles.lookup().findStatic(
|
||||
INDIFY_Dummy0.class,
|
||||
"bootstrap",
|
||||
MT_bootstrap());
|
||||
}
|
||||
|
||||
public static CallSite bootstrap(MethodHandles.Lookup l, String name, MethodType mt) throws Throwable {
|
||||
MlvmTest.getLog().display("bootstrap(): Lookup " + l + "; method name = " + name + "; method type = " + mt);
|
||||
CallSite cs = new ConstantCallSite(l.findStatic(INDIFY_Dummy0.class, "target", mt));
|
||||
return cs;
|
||||
}
|
||||
|
||||
public static Boolean target(Object o, String s, int i) {
|
||||
MlvmTest.getLog().display("Target called! Object = " + o + "; string = " + s + "; int = " + i);
|
||||
MlvmTest.getLog().display("The rest of methods are from " + (isRedefinedClass() ? "redefined" : "original") + " class");
|
||||
return true;
|
||||
}
|
||||
|
||||
public static void redefineNow() {}
|
||||
|
||||
private static MethodHandle INDY_call;
|
||||
private static MethodHandle INDY_call() throws Throwable {
|
||||
if (INDY_call != null)
|
||||
return INDY_call;
|
||||
|
||||
CallSite cs = (CallSite) MH_bootstrap().invokeWithArguments(
|
||||
MethodHandles.lookup(),
|
||||
"greet",
|
||||
MethodType.methodType(Boolean.class, Object.class, String.class, int.class));
|
||||
|
||||
return cs.dynamicInvoker();
|
||||
}
|
||||
|
||||
public static boolean invokeTarget() throws Throwable {
|
||||
return invokeTarget0();
|
||||
}
|
||||
|
||||
private static boolean invokeTarget0() throws Throwable {
|
||||
Object o = new Object();
|
||||
String s = "";
|
||||
int i = 456;
|
||||
boolean b = (Boolean) INDY_call().invokeExact(o, s, i);
|
||||
// In the original class here goes: redefineNow();
|
||||
return (Boolean) INDY_call().invokeExact(o, s, i);
|
||||
}
|
||||
|
||||
public static boolean isRedefinedClass() {
|
||||
return true;
|
||||
}
|
||||
}
|
89
test/hotspot/jtreg/vmTestbase/vm/mlvm/indy/func/jvmti/mergeCP_indy2same_b/INDIFY_Dummy0.java
Normal file
89
test/hotspot/jtreg/vmTestbase/vm/mlvm/indy/func/jvmti/mergeCP_indy2same_b/INDIFY_Dummy0.java
Normal file
@ -0,0 +1,89 @@
|
||||
/*
|
||||
* Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package vm.mlvm.indy.func.jvmti.mergeCP_indy2same_b;
|
||||
|
||||
import java.lang.invoke.CallSite;
|
||||
import java.lang.invoke.ConstantCallSite;
|
||||
import java.lang.invoke.MethodHandle;
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import java.lang.invoke.MethodType;
|
||||
|
||||
import vm.mlvm.share.MlvmTest;
|
||||
|
||||
public class INDIFY_Dummy0 {
|
||||
|
||||
private static MethodType MT_bootstrap() {
|
||||
return MethodType.methodType(CallSite.class, MethodHandles.Lookup.class, String.class, MethodType.class);
|
||||
}
|
||||
|
||||
private static MethodHandle MH_bootstrap() throws NoSuchMethodException, IllegalAccessException {
|
||||
return MethodHandles.lookup().findStatic(
|
||||
INDIFY_Dummy0.class,
|
||||
"bootstrap",
|
||||
MT_bootstrap());
|
||||
}
|
||||
|
||||
public static CallSite bootstrap(MethodHandles.Lookup l, String name, MethodType mt) throws Throwable {
|
||||
MlvmTest.getLog().display("bootstrap(): Lookup " + l + "; method name = " + name + "; method type = " + mt);
|
||||
redefineNow();
|
||||
CallSite cs = new ConstantCallSite(l.findStatic(INDIFY_Dummy0.class, "target", mt));
|
||||
return cs;
|
||||
}
|
||||
|
||||
public static Boolean target(Object o, String s, int i) {
|
||||
MlvmTest.getLog().display("Target called! Object = " + o + "; string = " + s + "; int = " + i);
|
||||
MlvmTest.getLog().display("The rest of methods are from " + (isRedefinedClass() ? "redefined" : "original") + " class");
|
||||
return false;
|
||||
}
|
||||
|
||||
public static void redefineNow() {}
|
||||
|
||||
private static MethodHandle INDY_call;
|
||||
private static MethodHandle INDY_call() throws Throwable {
|
||||
if (INDY_call != null)
|
||||
return INDY_call;
|
||||
|
||||
CallSite cs = (CallSite) MH_bootstrap().invokeWithArguments(
|
||||
MethodHandles.lookup(),
|
||||
"greet",
|
||||
MethodType.methodType(Boolean.class, Object.class, String.class, int.class));
|
||||
|
||||
return cs.dynamicInvoker();
|
||||
}
|
||||
|
||||
public static boolean invokeTarget() throws Throwable {
|
||||
return invokeTarget0();
|
||||
}
|
||||
|
||||
private static boolean invokeTarget0() throws Throwable {
|
||||
Object o = new Object();
|
||||
String s = "";
|
||||
int i = 456;
|
||||
return (Boolean) INDY_call().invokeExact(o, s, i);
|
||||
}
|
||||
|
||||
public static boolean isRedefinedClass() {
|
||||
return false;
|
||||
}
|
||||
}
|
24
test/hotspot/jtreg/vmTestbase/vm/mlvm/indy/func/jvmti/mergeCP_indy2same_b/TEST.properties
Normal file
24
test/hotspot/jtreg/vmTestbase/vm/mlvm/indy/func/jvmti/mergeCP_indy2same_b/TEST.properties
Normal file
@ -0,0 +1,24 @@
|
||||
#
|
||||
# Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
#
|
||||
# This code is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License version 2 only, as
|
||||
# published by the Free Software Foundation.
|
||||
#
|
||||
# This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
# version 2 for more details (a copy is included in the LICENSE file that
|
||||
# accompanied this code).
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License version
|
||||
# 2 along with this work; if not, write to the Free Software Foundation,
|
||||
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
#
|
||||
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
# or visit www.oracle.com if you need additional information or have any
|
||||
# questions.
|
||||
#
|
||||
|
||||
exclusiveAccess.dirs=.
|
63
test/hotspot/jtreg/vmTestbase/vm/mlvm/indy/func/jvmti/mergeCP_indy2same_b/TestDescription.java
Normal file
63
test/hotspot/jtreg/vmTestbase/vm/mlvm/indy/func/jvmti/mergeCP_indy2same_b/TestDescription.java
Normal file
@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* @test
|
||||
*
|
||||
* @summary converted from VM Testbase vm/mlvm/indy/func/jvmti/mergeCP_indy2same_b.
|
||||
* VM Testbase keywords: [feature_mlvm, nonconcurrent, jvmti, redefine, noJFR]
|
||||
* VM Testbase readme:
|
||||
* DESCRIPTION
|
||||
* Test calls a boostrap and a target methods via InvokeDynamic call, monitoring that
|
||||
* a method in the debuggee class (Dummy0.redefineNow()) is called (monitoring is done
|
||||
* via MethodEntry event). At this moment, Dummy0 class is redefined using RedefineClasses
|
||||
* function to another Dummy0 class and PopFrame function is called to reenter the method.
|
||||
* To verify logic of merging constant pools with regard to JSR 292, the original class
|
||||
* and the target one have the nearly the same code and the same CP.
|
||||
* The test verifies that when class is redefined in a target method (at that moment,
|
||||
* the call site is linked) and frame is popped, the new target method is executed and
|
||||
* the site is relinked.
|
||||
*
|
||||
* @library /vmTestbase
|
||||
* /test/lib
|
||||
*
|
||||
* @comment build dummy class
|
||||
* @build vm.mlvm.indy.func.jvmti.mergeCP_indy2same_b.INDIFY_Dummy0
|
||||
*
|
||||
* @comment compile newclass to bin/newclass
|
||||
* @run driver nsk.share.ExtraClassesBuilder newclass
|
||||
* @run driver vm.mlvm.share.IndifiedClassesBuilder bin/newclass
|
||||
*
|
||||
* @run driver jdk.test.lib.FileInstaller . .
|
||||
*
|
||||
* @comment build test class and indify classes
|
||||
* @build vm.mlvm.indy.func.jvmti.share.IndyRedefineTest
|
||||
* @run driver vm.mlvm.share.IndifiedClassesBuilder
|
||||
*
|
||||
* @run main/othervm/native
|
||||
* -agentlib:IndyRedefineClass=verbose=~pathToNewByteCode=./bin/newclass
|
||||
* vm.mlvm.indy.func.jvmti.share.IndyRedefineTest
|
||||
* -dummyClassName=vm.mlvm.indy.func.jvmti.mergeCP_indy2same_b.INDIFY_Dummy0
|
||||
*/
|
||||
|
88
test/hotspot/jtreg/vmTestbase/vm/mlvm/indy/func/jvmti/mergeCP_indy2same_b/newclass/INDIFY_Dummy0.java
Normal file
88
test/hotspot/jtreg/vmTestbase/vm/mlvm/indy/func/jvmti/mergeCP_indy2same_b/newclass/INDIFY_Dummy0.java
Normal file
@ -0,0 +1,88 @@
|
||||
/*
|
||||
* Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package vm.mlvm.indy.func.jvmti.mergeCP_indy2same_b;
|
||||
|
||||
import java.lang.invoke.CallSite;
|
||||
import java.lang.invoke.ConstantCallSite;
|
||||
import java.lang.invoke.MethodHandle;
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import java.lang.invoke.MethodType;
|
||||
|
||||
import vm.mlvm.share.MlvmTest;
|
||||
|
||||
public class INDIFY_Dummy0 {
|
||||
|
||||
private static MethodType MT_bootstrap() {
|
||||
return MethodType.methodType(CallSite.class, MethodHandles.Lookup.class, String.class, MethodType.class);
|
||||
}
|
||||
|
||||
private static MethodHandle MH_bootstrap() throws NoSuchMethodException, IllegalAccessException {
|
||||
return MethodHandles.lookup().findStatic(
|
||||
INDIFY_Dummy0.class,
|
||||
"bootstrap",
|
||||
MT_bootstrap());
|
||||
}
|
||||
|
||||
public static CallSite bootstrap(MethodHandles.Lookup l, String name, MethodType mt) throws Throwable {
|
||||
MlvmTest.getLog().display("bootstrap(): Lookup " + l + "; method name = " + name + "; method type = " + mt);
|
||||
CallSite cs = new ConstantCallSite(l.findStatic(INDIFY_Dummy0.class, "target", mt));
|
||||
return cs;
|
||||
}
|
||||
|
||||
public static Boolean target(Object o, String s, int i) {
|
||||
MlvmTest.getLog().display("Target called! Object = " + o + "; string = " + s + "; int = " + i);
|
||||
MlvmTest.getLog().display("The rest of methods are from " + (isRedefinedClass() ? "redefined" : "original") + " class");
|
||||
return true;
|
||||
}
|
||||
|
||||
public static void redefineNow() {}
|
||||
|
||||
private static MethodHandle INDY_call;
|
||||
private static MethodHandle INDY_call() throws Throwable {
|
||||
if (INDY_call != null)
|
||||
return INDY_call;
|
||||
|
||||
CallSite cs = (CallSite) MH_bootstrap().invokeWithArguments(
|
||||
MethodHandles.lookup(),
|
||||
"greet",
|
||||
MethodType.methodType(Boolean.class, Object.class, String.class, int.class));
|
||||
|
||||
return cs.dynamicInvoker();
|
||||
}
|
||||
|
||||
public static boolean invokeTarget() throws Throwable {
|
||||
return invokeTarget0();
|
||||
}
|
||||
|
||||
private static boolean invokeTarget0() throws Throwable {
|
||||
Object o = new Object();
|
||||
String s = "";
|
||||
int i = 456;
|
||||
return (Boolean) INDY_call().invokeExact(o, s, i);
|
||||
}
|
||||
|
||||
public static boolean isRedefinedClass() {
|
||||
return true;
|
||||
}
|
||||
}
|
87
test/hotspot/jtreg/vmTestbase/vm/mlvm/indy/func/jvmti/mergeCP_none2indy_a/INDIFY_Dummy0.java
Normal file
87
test/hotspot/jtreg/vmTestbase/vm/mlvm/indy/func/jvmti/mergeCP_none2indy_a/INDIFY_Dummy0.java
Normal file
@ -0,0 +1,87 @@
|
||||
/*
|
||||
* Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package vm.mlvm.indy.func.jvmti.mergeCP_none2indy_a;
|
||||
|
||||
import vm.mlvm.share.MlvmTest;
|
||||
|
||||
import java.lang.invoke.*;
|
||||
|
||||
|
||||
public class INDIFY_Dummy0 {
|
||||
|
||||
public static Boolean target(Object o, String s, int i) {
|
||||
MlvmTest.getLog().display("Original target called! Object = " + o + "; string = " + s + "; int = " + i);
|
||||
MlvmTest.getLog().display("The rest of methods are from " + (isRedefinedClass() ? "redefined" : "original") + " class");
|
||||
return false;
|
||||
}
|
||||
|
||||
public static void redefineNow() {}
|
||||
|
||||
private static MethodHandle INDY_call;
|
||||
private static MethodHandle INDY_call() throws Throwable {
|
||||
if (INDY_call != null)
|
||||
return INDY_call;
|
||||
|
||||
CallSite cs = (CallSite) MH_bootstrap().invokeWithArguments(
|
||||
MethodHandles.lookup(),
|
||||
"greet",
|
||||
MethodType.methodType(Boolean.class, Object.class, String.class, int.class));
|
||||
|
||||
return cs.dynamicInvoker();
|
||||
}
|
||||
|
||||
public static boolean invokeTarget() throws Throwable {
|
||||
return invokeTarget0();
|
||||
}
|
||||
|
||||
private static boolean invokeTarget0() throws Throwable {
|
||||
Object o = new Object();
|
||||
String s = "Original";
|
||||
int i = 456;
|
||||
boolean b = target(o, s, i);
|
||||
redefineNow();
|
||||
throw new RuntimeException("Original invokeTarget() method is executed after redefinition. Test failed.");
|
||||
}
|
||||
|
||||
public static boolean isRedefinedClass() {
|
||||
return false;
|
||||
}
|
||||
|
||||
private static MethodType MT_bootstrap() {
|
||||
return MethodType.methodType(CallSite.class, MethodHandles.Lookup.class, String.class, MethodType.class);
|
||||
}
|
||||
|
||||
private static MethodHandle MH_bootstrap() throws NoSuchMethodException, IllegalAccessException {
|
||||
return MethodHandles.lookup().findStatic(
|
||||
INDIFY_Dummy0.class,
|
||||
"bootstrap",
|
||||
MT_bootstrap());
|
||||
}
|
||||
|
||||
public static CallSite bootstrap(MethodHandles.Lookup l, String name, MethodType mt) throws Throwable {
|
||||
MlvmTest.getLog().display("Redefined bootstrap(): Lookup " + l + "; method name = " + name + "; method type = " + mt);
|
||||
CallSite cs = new ConstantCallSite(l.findStatic(INDIFY_Dummy0.class, "target", mt));
|
||||
return cs;
|
||||
}
|
||||
}
|
24
test/hotspot/jtreg/vmTestbase/vm/mlvm/indy/func/jvmti/mergeCP_none2indy_a/TEST.properties
Normal file
24
test/hotspot/jtreg/vmTestbase/vm/mlvm/indy/func/jvmti/mergeCP_none2indy_a/TEST.properties
Normal file
@ -0,0 +1,24 @@
|
||||
#
|
||||
# Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
#
|
||||
# This code is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License version 2 only, as
|
||||
# published by the Free Software Foundation.
|
||||
#
|
||||
# This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
# version 2 for more details (a copy is included in the LICENSE file that
|
||||
# accompanied this code).
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License version
|
||||
# 2 along with this work; if not, write to the Free Software Foundation,
|
||||
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
#
|
||||
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
# or visit www.oracle.com if you need additional information or have any
|
||||
# questions.
|
||||
#
|
||||
|
||||
exclusiveAccess.dirs=.
|
63
test/hotspot/jtreg/vmTestbase/vm/mlvm/indy/func/jvmti/mergeCP_none2indy_a/TestDescription.java
Normal file
63
test/hotspot/jtreg/vmTestbase/vm/mlvm/indy/func/jvmti/mergeCP_none2indy_a/TestDescription.java
Normal file
@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* @test
|
||||
*
|
||||
* @summary converted from VM Testbase vm/mlvm/indy/func/jvmti/mergeCP_none2indy_a.
|
||||
* VM Testbase keywords: [feature_mlvm, nonconcurrent, jvmti, redefine, noJFR]
|
||||
* VM Testbase readme:
|
||||
* DESCRIPTION
|
||||
* Test calls a boostrap and a target methods via InvokeDynamic call, monitoring that
|
||||
* a method in the debuggee class (Dummy0.redefineNow()) is called (monitoring is done
|
||||
* via MethodEntry event). After calling the target method, Dummy0 class is redefined
|
||||
* using RedefineClasses function to another Dummy0 class and PopFrame function
|
||||
* is called to reenter the method.
|
||||
* To verify logic of merging constant pools with regard to JSR 292, the original class
|
||||
* does not have a invokedynamic call at all and the new Dummy0 does have one.
|
||||
* The test verifies that when class is redefined and frame is popped,
|
||||
* the new target method is executed and the site is relinked.
|
||||
*
|
||||
* @library /vmTestbase
|
||||
* /test/lib
|
||||
*
|
||||
* @comment build dummy class
|
||||
* @build vm.mlvm.indy.func.jvmti.mergeCP_none2indy_a.INDIFY_Dummy0
|
||||
*
|
||||
* @comment compile newclass to bin/newclass
|
||||
* @run driver nsk.share.ExtraClassesBuilder newclass
|
||||
* @run driver vm.mlvm.share.IndifiedClassesBuilder bin/newclass
|
||||
*
|
||||
* @run driver jdk.test.lib.FileInstaller . .
|
||||
*
|
||||
* @comment build test class and indify classes
|
||||
* @build vm.mlvm.indy.func.jvmti.share.IndyRedefineTest
|
||||
* @run driver vm.mlvm.share.IndifiedClassesBuilder
|
||||
*
|
||||
* @run main/othervm/native
|
||||
* -agentlib:IndyRedefineClass=verbose=~pathToNewByteCode=./bin/newclass
|
||||
* vm.mlvm.indy.func.jvmti.share.IndyRedefineTest
|
||||
* -dummyClassName=vm.mlvm.indy.func.jvmti.mergeCP_none2indy_a.INDIFY_Dummy0
|
||||
*/
|
||||
|
88
test/hotspot/jtreg/vmTestbase/vm/mlvm/indy/func/jvmti/mergeCP_none2indy_a/newclass/INDIFY_Dummy0.java
Normal file
88
test/hotspot/jtreg/vmTestbase/vm/mlvm/indy/func/jvmti/mergeCP_none2indy_a/newclass/INDIFY_Dummy0.java
Normal file
@ -0,0 +1,88 @@
|
||||
/*
|
||||
* Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package vm.mlvm.indy.func.jvmti.mergeCP_none2indy_a;
|
||||
|
||||
import java.lang.invoke.CallSite;
|
||||
import java.lang.invoke.ConstantCallSite;
|
||||
import java.lang.invoke.MethodHandle;
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import java.lang.invoke.MethodType;
|
||||
|
||||
import vm.mlvm.share.MlvmTest;
|
||||
|
||||
public class INDIFY_Dummy0 {
|
||||
|
||||
private static MethodType MT_bootstrap() {
|
||||
return MethodType.methodType(CallSite.class, MethodHandles.Lookup.class, String.class, MethodType.class);
|
||||
}
|
||||
|
||||
private static MethodHandle MH_bootstrap() throws NoSuchMethodException, IllegalAccessException {
|
||||
return MethodHandles.lookup().findStatic(
|
||||
INDIFY_Dummy0.class,
|
||||
"bootstrap",
|
||||
MT_bootstrap());
|
||||
}
|
||||
|
||||
public static CallSite bootstrap(MethodHandles.Lookup l, String name, MethodType mt) throws Throwable {
|
||||
MlvmTest.getLog().display("Redefined bootstrap(): Lookup " + l + "; method name = " + name + "; method type = " + mt);
|
||||
CallSite cs = new ConstantCallSite(l.findStatic(INDIFY_Dummy0.class, "target", mt));
|
||||
return cs;
|
||||
}
|
||||
|
||||
public static Boolean target(Object o, String s, int i) {
|
||||
MlvmTest.getLog().display("Redefined target called! Object = " + o + "; string = " + s + "; int = " + i);
|
||||
MlvmTest.getLog().display("The rest of methods are from " + (isRedefinedClass() ? "redefined" : "original") + " class");
|
||||
return true;
|
||||
}
|
||||
|
||||
public static void redefineNow() {}
|
||||
|
||||
private static MethodHandle INDY_call;
|
||||
private static MethodHandle INDY_call() throws Throwable {
|
||||
if (INDY_call != null)
|
||||
return INDY_call;
|
||||
|
||||
CallSite cs = (CallSite) MH_bootstrap().invokeWithArguments(
|
||||
MethodHandles.lookup(),
|
||||
"greet",
|
||||
MethodType.methodType(Boolean.class, Object.class, String.class, int.class));
|
||||
|
||||
return cs.dynamicInvoker();
|
||||
}
|
||||
|
||||
public static boolean invokeTarget() throws Throwable {
|
||||
return invokeTarget0();
|
||||
}
|
||||
|
||||
private static boolean invokeTarget0() throws Throwable {
|
||||
Object o = new Object();
|
||||
String s = "Redefined";
|
||||
int i = 456;
|
||||
return (Boolean) INDY_call().invokeExact(o, s, i);
|
||||
}
|
||||
|
||||
public static boolean isRedefinedClass() {
|
||||
return true;
|
||||
}
|
||||
}
|
82
test/hotspot/jtreg/vmTestbase/vm/mlvm/indy/func/jvmti/mergeCP_none2indy_b/INDIFY_Dummy0.java
Normal file
82
test/hotspot/jtreg/vmTestbase/vm/mlvm/indy/func/jvmti/mergeCP_none2indy_b/INDIFY_Dummy0.java
Normal file
@ -0,0 +1,82 @@
|
||||
/*
|
||||
* Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package vm.mlvm.indy.func.jvmti.mergeCP_none2indy_b;
|
||||
|
||||
import vm.mlvm.share.MlvmTest;
|
||||
|
||||
import java.lang.invoke.*;
|
||||
|
||||
public class INDIFY_Dummy0 {
|
||||
private static MethodType MT_bootstrap() {
|
||||
return MethodType.methodType(CallSite.class, MethodHandles.Lookup.class, String.class, MethodType.class);
|
||||
}
|
||||
|
||||
private static MethodHandle MH_bootstrap() throws NoSuchMethodException, IllegalAccessException {
|
||||
return MethodHandles.lookup().findStatic(
|
||||
INDIFY_Dummy0.class,
|
||||
"bootstrap",
|
||||
MT_bootstrap());
|
||||
}
|
||||
|
||||
public static CallSite bootstrap(MethodHandles.Lookup l, String name, MethodType mt) throws Throwable {
|
||||
MlvmTest.getLog().display("Original bootstrap(): Lookup " + l + "; method name = " + name + "; method type = " + mt);
|
||||
CallSite cs = new ConstantCallSite(l.findStatic(INDIFY_Dummy0.class, "target", mt));
|
||||
return cs;
|
||||
}
|
||||
|
||||
public static Boolean target(Object o, String s, int i) {
|
||||
redefineNow();
|
||||
throw new RuntimeException("Original target method was called instead of the redefined one. Test failed.");
|
||||
}
|
||||
|
||||
public static void redefineNow() {}
|
||||
|
||||
private static MethodHandle INDY_call;
|
||||
private static MethodHandle INDY_call() throws Throwable {
|
||||
if (INDY_call != null)
|
||||
return INDY_call;
|
||||
|
||||
CallSite cs = (CallSite) MH_bootstrap().invokeWithArguments(
|
||||
MethodHandles.lookup(),
|
||||
"greet",
|
||||
MethodType.methodType(Boolean.class, Object.class, String.class,
|
||||
int.class));
|
||||
|
||||
return cs.dynamicInvoker();
|
||||
}
|
||||
public static boolean invokeTarget() throws Throwable {
|
||||
return invokeTarget0();
|
||||
}
|
||||
|
||||
private static boolean invokeTarget0() throws Throwable {
|
||||
Object o = new Object();
|
||||
String s = "Original";
|
||||
int i = 456;
|
||||
return target(o, s, i);
|
||||
}
|
||||
|
||||
public static boolean isRedefinedClass() {
|
||||
return false;
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user