8199384: [TESTBUG] Open source VM testbase MLVM tests

Reviewed-by: erikj, mseledtsov, vlivanov
This commit is contained in:
Igor Ignatyev 2018-05-17 00:23:28 -07:00
parent 12a799b4e1
commit 01b0f9ea7d
268 changed files with 61414 additions and 0 deletions
make/test
test/hotspot/jtreg
ProblemList-graal.txtProblemList.txtTEST.groups
vmTestbase
nsk/share/jvmti
vm/mlvm
anonloader
func
castToGrandparent
castToParent
classNameInStackTrace
finalSuperclass
findByName
invalidSuperclass
isGarbageCollected
uniqueClassAndObject
share
stress
cp
indy/func

@ -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/

File diff suppressed because it is too large Load Diff

@ -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_ */

@ -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

@ -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

@ -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

@ -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

@ -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); }
}

@ -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); }
}

@ -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);
}
}

@ -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);
}
}

@ -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);
}
}

@ -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;
}
}

@ -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
*/

@ -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
*/

@ -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,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
*/

File diff suppressed because it is too large Load Diff

@ -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
*/

@ -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;
}
}
}

@ -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));
}
}

@ -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,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));
}
}

@ -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;
}
}

@ -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,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
*/

@ -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;
}
}

@ -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;
}
}

@ -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,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
*/

@ -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;
}
}

@ -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;
}
}

@ -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,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
*/

@ -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;
}
}

@ -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;
}
}

@ -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,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
*/

@ -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;
}
}

@ -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;
}
}

@ -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,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
*/

@ -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;
}
}

@ -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;
}
}

@ -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,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
*/

@ -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;
}
}

@ -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;
}
}

@ -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,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
*/

@ -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;
}
}

@ -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;
}
}

@ -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,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
*/

@ -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;
}
}

@ -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;
}
}

@ -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,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
*/

@ -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;
}
}

@ -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