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 root = NULL; 45 static const char* DEBUGEE_SIGNATURE = "Lnsk/jvmti/scenarios/allocation/AP07/ap07t001;"; 46 static const jlong IGNORE_TAG = (jlong)10l; 47 48 /* jvmtiHeapRootCallback */ 49 jvmtiIterationControl JNICALL 50 heapRootCallback( jvmtiHeapRootKind root_kind, 51 jlong class_tag, 52 jlong size, 53 jlong* tag_ptr, 54 void* user_data) { 55 56 if (*tag_ptr > 0) { 57 NSK_DISPLAY2("heapRootCallback: root kind=%s, tag=%d\n", TranslateRootKind(root_kind), (long)*tag_ptr); 58 } 59 return JVMTI_ITERATION_CONTINUE; 60 } 61 62 /* jvmtiStackReferenceCallback */ 63 jvmtiIterationControl JNICALL 64 stackReferenceCallback( jvmtiHeapRootKind root_kind, 65 jlong class_tag, 66 jlong size, 67 jlong* tag_ptr, 68 jlong thread_tag, 69 jint depth, 70 jmethodID method, 71 jint slot, 72 void* user_data) { 73 74 if (*tag_ptr > 0) { 75 NSK_DISPLAY2("stackReferenceCallback: root kind=%s, tag=%d\n", TranslateRootKind(root_kind), (long)*tag_ptr); 76 } 77 return JVMTI_ITERATION_CONTINUE; 78 } 79 80 81 /* jvmtiObjectReferenceCallback */ 82 jvmtiIterationControl JNICALL 83 objectReferenceCallback( jvmtiObjectReferenceKind reference_kind, 84 jlong class_tag, 85 jlong size, 86 jlong* tag_ptr, 87 jlong referrer_tag, 88 jint referrer_index, 89 void* user_data) { 90 91 if (*tag_ptr > 0) { 92 NSK_DISPLAY2("objectReferenceCallback: reference kind=%s, tag=%d\n", TranslateObjectRefKind(reference_kind), (long)*tag_ptr); 93 } 94 if (*tag_ptr > IGNORE_TAG) { 95 nsk_jvmti_setFailStatus(); 96 NSK_COMPLAIN1("objectReferenceCallback: the checked object was not ignored, tag=%d\n\n", (long)*tag_ptr); 97 } 98 /* ignore referrees of right branch */ 99 if (*tag_ptr == IGNORE_TAG) { 100 return JVMTI_ITERATION_IGNORE; 101 } 102 return JVMTI_ITERATION_CONTINUE; 103 } 104 105 106 /************************/ 107 108 JNIEXPORT void JNICALL 109 Java_nsk_jvmti_scenarios_allocation_AP07_ap07t001_setTag( JNIEnv* jni, 110 jobject obj, 111 jobject target, 112 jlong tag ) { 113 114 if (!NSK_JVMTI_VERIFY(jvmti->SetTag(target, tag))) { 115 nsk_jvmti_setFailStatus(); 116 } 117 } 118 119 JNIEXPORT void JNICALL 120 Java_nsk_jvmti_scenarios_allocation_AP07_ap07t001_setRoot( JNIEnv* jni, jobject obj) { 121 if (!NSK_JNI_VERIFY(jni, (root = jni->NewGlobalRef(obj)) != NULL)) 122 nsk_jvmti_setFailStatus(); 123 } 124 125 static void JNICALL 126 agentProc(jvmtiEnv* jvmti, JNIEnv* jni, void* arg) { 127 128 jclass debugeeClass = NULL; 129 130 NSK_DISPLAY0("Wait for debugee start\n\n"); 131 if (!NSK_VERIFY(nsk_jvmti_waitForSync(timeout))) 132 return; 133 134 do { 135 136 NSK_DISPLAY0("Calling IterateOverReachableObjects\n"); 137 if (!NSK_JVMTI_VERIFY(jvmti->IterateOverReachableObjects(heapRootCallback, 138 stackReferenceCallback, 139 objectReferenceCallback, 140 NULL /*user_data*/))) { 141 nsk_jvmti_setFailStatus(); 142 break; 143 } 144 145 NSK_DISPLAY0("Calling IterateOverObjectsReachableFromObject\n"); 146 { 147 if (!NSK_JVMTI_VERIFY(jvmti->IterateOverObjectsReachableFromObject( 148 root, objectReferenceCallback, NULL /*user_data*/))) { 149 nsk_jvmti_setFailStatus(); 150 break; 151 } 152 } 153 154 NSK_TRACE(jni->DeleteGlobalRef(root)); 155 156 } while (0); 157 158 NSK_DISPLAY0("Let debugee to finish\n"); 159 if (!NSK_VERIFY(nsk_jvmti_resumeSync())) 160 return; 161 } 162 163 #ifdef STATIC_BUILD 164 JNIEXPORT jint JNICALL Agent_OnLoad_ap07t001(JavaVM *jvm, char *options, void *reserved) { 165 return Agent_Initialize(jvm, options, reserved); 166 } 167 JNIEXPORT jint JNICALL Agent_OnAttach_ap07t001(JavaVM *jvm, char *options, void *reserved) { 168 return Agent_Initialize(jvm, options, reserved); 169 } 170 JNIEXPORT jint JNI_OnLoad_ap07t001(JavaVM *jvm, char *options, void *reserved) { 171 return JNI_VERSION_1_8; 172 } 173 #endif 174 jint Agent_Initialize(JavaVM *jvm, char *options, void *reserved) { 175 /* init framework and parse options */ 176 if (!NSK_VERIFY(nsk_jvmti_parseOptions(options))) 177 return JNI_ERR; 178 179 /* create JVMTI environment */ 180 if (!NSK_VERIFY((jvmti = 181 nsk_jvmti_createJVMTIEnv(jvm, reserved)) != NULL)) 182 return JNI_ERR; 183 184 memset(&caps, 0, sizeof(jvmtiCapabilities)); 185 caps.can_tag_objects = 1; 186 187 if (!NSK_JVMTI_VERIFY(jvmti->AddCapabilities(&caps))) 188 return JNI_ERR; 189 190 if (!NSK_JVMTI_VERIFY(jvmti->GetCapabilities(&caps))) 191 return JNI_ERR; 192 193 if (!caps.can_tag_objects) 194 NSK_DISPLAY0("Warning: tagging objects is not implemented\n"); 195 196 if (!NSK_VERIFY(nsk_jvmti_setAgentProc(agentProc, NULL))) 197 return JNI_ERR; 198 NSK_DISPLAY0("agentProc has been set\n\n"); 199 200 return JNI_OK; 201 } 202 203 }