1 /* 2 * Copyright (c) 2004, 2018, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 #include <stdio.h> 25 #include <string.h> 26 #include <jvmti.h> 27 #include "agent_common.h" 28 29 #include "nsk_tools.h" 30 #include "jni_tools.h" 31 #include "JVMTITools.h" 32 #include "jvmti_tools.h" 33 34 extern "C" { 35 36 #define EXP_OBJ_NUMBER 1 37 38 static JNIEnv *jni = NULL; 39 static jvmtiEnv *jvmti = NULL; 40 static jvmtiEventCallbacks callbacks; 41 static jvmtiCapabilities caps; 42 43 static jlong timeout = 0; 44 static jobject referrer = NULL; 45 static const char* SUBCLASS_SIGNATURE = "Lnsk/jvmti/scenarios/allocation/AP05/ap05t002Subclass;"; 46 static const long TAG1 = 1l, TAG2 = 2l; 47 static int caseNumber = 0, forthRef = 0, backRef = 0; 48 49 /* jvmtiHeapRootCallback */ 50 jvmtiIterationControl JNICALL 51 heapRootCallback(jvmtiHeapRootKind root_kind, 52 jlong class_tag, 53 jlong size, 54 jlong* tag_ptr, 55 void* user_data) { 56 return JVMTI_ITERATION_CONTINUE; 57 } 58 59 /* jvmtiStackReferenceCallback */ 60 jvmtiIterationControl JNICALL 61 stackReferenceCallback(jvmtiHeapRootKind root_kind, 62 jlong class_tag, 63 jlong size, 64 jlong* tag_ptr, 65 jlong thread_tag, 66 jint depth, 67 jmethodID method, 68 jint slot, 69 void* user_data) { 70 return JVMTI_ITERATION_CONTINUE; 71 } 72 73 74 /* jvmtiObjectReferenceCallback */ 75 jvmtiIterationControl JNICALL 76 objectReferenceCallback(jvmtiObjectReferenceKind reference_kind, 77 jlong class_tag, 78 jlong size, 79 jlong* tag_ptr, 80 jlong referrer_tag, 81 jint referrer_index, 82 void* user_data) { 83 84 if (*tag_ptr != 0 && referrer_tag != 0) { 85 NSK_DISPLAY4("objectReferenceCallback: reference kind=%s, referrer_index=%d, referrer_tag=%d, referree_tag=%d\n", 86 TranslateObjectRefKind(reference_kind), (int)referrer_index, (long)referrer_tag, (long)*tag_ptr); 87 88 if (*tag_ptr == TAG1 && referrer_tag == TAG2) { 89 forthRef++; 90 } else if (*tag_ptr == TAG2 && referrer_tag == TAG1) { 91 backRef++; 92 } 93 } 94 return JVMTI_ITERATION_CONTINUE; 95 } 96 97 98 /************************/ 99 100 JNIEXPORT void JNICALL 101 Java_nsk_jvmti_scenarios_allocation_AP05_ap05t002_setTag(JNIEnv* jni, 102 jobject obj, 103 jobject target, 104 jlong tag) { 105 106 if (!NSK_JVMTI_VERIFY(jvmti->SetTag(target, tag))) { 107 nsk_jvmti_setFailStatus(); 108 } 109 } 110 111 JNIEXPORT void JNICALL 112 Java_nsk_jvmti_scenarios_allocation_AP05_ap05t002_setReferrer(JNIEnv* jni, jclass klass, jobject ref, jint caseNum) { 113 caseNumber = caseNum; 114 if (!NSK_JNI_VERIFY(jni, (referrer = jni->NewGlobalRef(ref)) != NULL)) 115 nsk_jvmti_setFailStatus(); 116 } 117 118 static void runCase() { 119 NSK_DISPLAY0("\nCalling IterateOverReachableObjects\n"); 120 forthRef = 0; 121 backRef = 0; 122 if (!NSK_JVMTI_VERIFY(jvmti->IterateOverReachableObjects(heapRootCallback, 123 stackReferenceCallback, 124 objectReferenceCallback, 125 NULL /*user_data*/))) { 126 nsk_jvmti_setFailStatus(); 127 } 128 if (forthRef != 1) { 129 NSK_COMPLAIN1("IterateOverReachableObjects found unexpected number of references\n\t" 130 "from referrer to referree; found: %d, expected: 1\n\n", forthRef); 131 nsk_jvmti_setFailStatus(); 132 } 133 if (backRef != 1) { 134 NSK_COMPLAIN1("IterateOverReachableObjects found unexpected number of references\n\t" 135 "from referree to referrer; found: %d, expected: 1\n\n", backRef); 136 nsk_jvmti_setFailStatus(); 137 } 138 139 NSK_DISPLAY0("\nCalling IterateOverObjectsReachableFromObject\n"); 140 forthRef = 0; 141 backRef = 0; 142 if (!NSK_JVMTI_VERIFY(jvmti->IterateOverObjectsReachableFromObject(referrer, 143 objectReferenceCallback, 144 NULL /*user_data*/))) { 145 nsk_jvmti_setFailStatus(); 146 } 147 if (forthRef != 1) { 148 NSK_COMPLAIN1("IterateOverObjectsReachableFromObject found unexpected number of references\n\t" 149 "from referrer to referree; found: %d, expected: 1\n\n", forthRef); 150 nsk_jvmti_setFailStatus(); 151 } 152 if (backRef != 1) { 153 NSK_COMPLAIN1("IterateOverObjectsReachableFromObject found unexpected number of references\n\t" 154 "from referree to referrer; found: %d, expected: 1\n\n", backRef); 155 nsk_jvmti_setFailStatus(); 156 } 157 } 158 159 static void JNICALL 160 agentProc(jvmtiEnv* jvmti, JNIEnv* jni, void* arg) { 161 162 jclass debugeeClass = NULL; 163 164 NSK_DISPLAY0("Wait for debugee start\n\n"); 165 if (!NSK_VERIFY(nsk_jvmti_waitForSync(timeout))) 166 return; 167 168 do { 169 NSK_DISPLAY0("CASE #1\n"); 170 runCase(); 171 172 NSK_TRACE(jni->DeleteGlobalRef(referrer)); 173 if (!NSK_VERIFY(nsk_jvmti_resumeSync())) 174 return; 175 if (!NSK_VERIFY(nsk_jvmti_waitForSync(timeout))) 176 return; 177 178 NSK_DISPLAY0("CASE #2\n"); 179 runCase(); 180 181 NSK_TRACE(jni->DeleteGlobalRef(referrer)); 182 } while (0); 183 184 NSK_DISPLAY0("Let debugee to finish\n"); 185 if (!NSK_VERIFY(nsk_jvmti_resumeSync())) 186 return; 187 } 188 189 #ifdef STATIC_BUILD 190 JNIEXPORT jint JNICALL Agent_OnLoad_ap05t002(JavaVM *jvm, char *options, void *reserved) { 191 return Agent_Initialize(jvm, options, reserved); 192 } 193 JNIEXPORT jint JNICALL Agent_OnAttach_ap05t002(JavaVM *jvm, char *options, void *reserved) { 194 return Agent_Initialize(jvm, options, reserved); 195 } 196 JNIEXPORT jint JNI_OnLoad_ap05t002(JavaVM *jvm, char *options, void *reserved) { 197 return JNI_VERSION_1_8; 198 } 199 #endif 200 jint Agent_Initialize(JavaVM *jvm, char *options, void *reserved) { 201 /* init framework and parse options */ 202 if (!NSK_VERIFY(nsk_jvmti_parseOptions(options))) 203 return JNI_ERR; 204 205 /* create JVMTI environment */ 206 if (!NSK_VERIFY((jvmti = 207 nsk_jvmti_createJVMTIEnv(jvm, reserved)) != NULL)) 208 return JNI_ERR; 209 210 memset(&caps, 0, sizeof(jvmtiCapabilities)); 211 caps.can_tag_objects = 1; 212 213 if (!NSK_JVMTI_VERIFY(jvmti->AddCapabilities(&caps))) 214 return JNI_ERR; 215 216 if (!NSK_JVMTI_VERIFY(jvmti->GetCapabilities(&caps))) 217 return JNI_ERR; 218 219 if (!caps.can_tag_objects) 220 NSK_DISPLAY0("Warning: tagging objects is not implemented\n"); 221 222 if (!NSK_VERIFY(nsk_jvmti_setAgentProc(agentProc, NULL))) 223 return JNI_ERR; 224 NSK_DISPLAY0("agentProc has been set\n\n"); 225 226 return JNI_OK; 227 } 228 229 }