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 volatile int obj_free = 0; 44 static volatile long obj_count = 0; 45 46 static jlong timeout = 0; 47 static int user_data = 0; 48 static const char* DEBUGEE_SIGNATURE = "Lnsk/jvmti/scenarios/allocation/AP03/ap03t001;"; 49 static const jlong DEBUGEE_CLASS_TAG = (jlong)1024; 50 51 void JNICALL 52 ObjectFree(jvmtiEnv *jvmti_env, jlong tag) { 53 NSK_COMPLAIN1("Received unexpected ObjectFree event for an object with tag %ld\n\n", (long)tag); 54 nsk_jvmti_setFailStatus(); 55 obj_free++; 56 } 57 58 jvmtiIterationControl JNICALL 59 heapObjectCallback(jlong class_tag, 60 jlong size, 61 jlong* tag_ptr, 62 void* user_data) { 63 64 if (class_tag == DEBUGEE_CLASS_TAG) { 65 obj_count++; 66 } 67 68 return JVMTI_ITERATION_CONTINUE; 69 } 70 71 jvmtiIterationControl JNICALL 72 objectReferenceCallback(jvmtiObjectReferenceKind reference_kind, 73 jlong class_tag, 74 jlong size, 75 jlong* tag_ptr, 76 jlong referrer_tag, 77 jint referrer_index, 78 void* user_data) { 79 80 if (class_tag == DEBUGEE_CLASS_TAG && *tag_ptr != 0) { 81 obj_count++; 82 } 83 84 return JVMTI_ITERATION_CONTINUE; 85 } 86 87 88 /************************/ 89 90 JNIEXPORT void JNICALL 91 Java_nsk_jvmti_scenarios_allocation_AP03_ap03t001_setTag(JNIEnv* jni, jobject obj, jlong tag) { 92 93 if (!NSK_JVMTI_VERIFY(jvmti->SetTag(obj, tag))) { 94 nsk_jvmti_setFailStatus(); 95 } 96 } 97 98 static void JNICALL 99 agentProc(jvmtiEnv* jvmti, JNIEnv* jni, void* arg) { 100 101 jclass debugeeClass = NULL; 102 103 NSK_DISPLAY0("Wait for debugee start\n\n"); 104 if (!NSK_VERIFY(nsk_jvmti_waitForSync(timeout))) 105 return; 106 107 do { 108 jobject catcher; 109 jfieldID fid; 110 111 NSK_DISPLAY1("Find debugee class: %s\n", DEBUGEE_SIGNATURE); 112 debugeeClass = nsk_jvmti_classBySignature(DEBUGEE_SIGNATURE); 113 if (debugeeClass == NULL) { 114 nsk_jvmti_setFailStatus(); 115 break; 116 } 117 118 NSK_DISPLAY0("Set tag for debugee class\n\n"); 119 if (!NSK_JVMTI_VERIFY(jvmti->SetTag(debugeeClass, DEBUGEE_CLASS_TAG))) { 120 nsk_jvmti_setFailStatus(); 121 break; 122 } 123 124 NSK_DISPLAY0("Calling IterateOverInstancesOfClass with filter JVMTI_HEAP_OBJECT_TAGGED\n"); 125 obj_count = 0; 126 if (!NSK_JVMTI_VERIFY(jvmti->IterateOverInstancesOfClass(debugeeClass, 127 JVMTI_HEAP_OBJECT_TAGGED, 128 heapObjectCallback, 129 &user_data))) { 130 nsk_jvmti_setFailStatus(); 131 break; 132 } 133 134 if (obj_count != EXP_OBJ_NUMBER) { 135 nsk_jvmti_setFailStatus(); 136 NSK_COMPLAIN2( 137 "IterateOverInstancesOfClass found unexpected number of objects: %d\n" 138 "\texpected number: %d\n\n", 139 obj_count, EXP_OBJ_NUMBER); 140 } else { 141 NSK_DISPLAY1("Number of objects IterateOverInstancesOfClass has found: %d\n\n", obj_count); 142 } 143 144 NSK_DISPLAY0("Calling IterateOverHeap with filter JVMTI_HEAP_OBJECT_TAGGED\n"); 145 obj_count = 0; 146 if (!NSK_JVMTI_VERIFY( 147 jvmti->IterateOverHeap(JVMTI_HEAP_OBJECT_TAGGED, heapObjectCallback, &user_data))) { 148 nsk_jvmti_setFailStatus(); 149 break; 150 } 151 152 if (obj_count != EXP_OBJ_NUMBER) { 153 nsk_jvmti_setFailStatus(); 154 NSK_COMPLAIN2( 155 "IterateOverHeap found unexpected number of objects: %d\n" 156 "\texpected number: %d\n\n", 157 obj_count, EXP_OBJ_NUMBER); 158 } else { 159 NSK_DISPLAY1("Number of objects IterateOverHeap has found: %d\n\n", obj_count); 160 } 161 162 if (!NSK_JNI_VERIFY(jni, (fid = 163 jni->GetStaticFieldID(debugeeClass, "catcher", DEBUGEE_SIGNATURE)) != NULL)) { 164 nsk_jvmti_setFailStatus(); 165 break; 166 } 167 168 if (!NSK_JNI_VERIFY(jni, (catcher = 169 jni->GetStaticObjectField(debugeeClass, fid)) != NULL)) { 170 NSK_COMPLAIN0("GetStaticObjectField returned NULL for 'catcher' field value\n\n"); 171 nsk_jvmti_setFailStatus(); 172 break; 173 } 174 175 NSK_DISPLAY0("Calling IterateOverObjectsReachableFromObject\n"); 176 obj_count = 0; 177 if (!NSK_JVMTI_VERIFY(jvmti->IterateOverObjectsReachableFromObject(catcher, 178 objectReferenceCallback, 179 &user_data))) { 180 nsk_jvmti_setFailStatus(); 181 break; 182 } 183 184 if (obj_count != EXP_OBJ_NUMBER) { 185 nsk_jvmti_setFailStatus(); 186 NSK_COMPLAIN2( 187 "IterateOverObjectsReachableFromObject found unexpected number of objects: %d\n" 188 "\texpected number: %d\n\n", 189 obj_count, EXP_OBJ_NUMBER); 190 } else { 191 NSK_DISPLAY1("Number of objects IterateOverObjectsReachableFromObject has found: %d\n\n", obj_count); 192 } 193 } while (0); 194 195 NSK_DISPLAY0("Let debugee to finish\n"); 196 if (!NSK_VERIFY(nsk_jvmti_resumeSync())) 197 return; 198 } 199 200 #ifdef STATIC_BUILD 201 JNIEXPORT jint JNICALL Agent_OnLoad_ap03t001(JavaVM *jvm, char *options, void *reserved) { 202 return Agent_Initialize(jvm, options, reserved); 203 } 204 JNIEXPORT jint JNICALL Agent_OnAttach_ap03t001(JavaVM *jvm, char *options, void *reserved) { 205 return Agent_Initialize(jvm, options, reserved); 206 } 207 JNIEXPORT jint JNI_OnLoad_ap03t001(JavaVM *jvm, char *options, void *reserved) { 208 return JNI_VERSION_1_8; 209 } 210 #endif 211 jint Agent_Initialize(JavaVM *jvm, char *options, void *reserved) { 212 /* init framework and parse options */ 213 if (!NSK_VERIFY(nsk_jvmti_parseOptions(options))) 214 return JNI_ERR; 215 216 /* create JVMTI environment */ 217 if (!NSK_VERIFY((jvmti = 218 nsk_jvmti_createJVMTIEnv(jvm, reserved)) != NULL)) 219 return JNI_ERR; 220 221 memset(&caps, 0, sizeof(jvmtiCapabilities)); 222 caps.can_generate_object_free_events = 1; 223 caps.can_tag_objects = 1; 224 if (!NSK_JVMTI_VERIFY(jvmti->AddCapabilities(&caps))) 225 return JNI_ERR; 226 227 if (!NSK_JVMTI_VERIFY(jvmti->GetCapabilities(&caps))) 228 return JNI_ERR; 229 230 if (!caps.can_generate_object_free_events) 231 NSK_DISPLAY0("Warning: generation of object free events is not implemented\n"); 232 if (!caps.can_tag_objects) 233 NSK_DISPLAY0("Warning: tagging objects is not implemented\n"); 234 235 /* set event callback */ 236 NSK_DISPLAY0("setting event callbacks ...\n"); 237 (void) memset(&callbacks, 0, sizeof(callbacks)); 238 239 callbacks.ObjectFree = &ObjectFree; 240 241 if (!NSK_JVMTI_VERIFY(jvmti->SetEventCallbacks(&callbacks, sizeof(callbacks)))) 242 return JNI_ERR; 243 244 NSK_DISPLAY0("setting event callbacks done\nenabling JVMTI events ...\n"); 245 if (!NSK_JVMTI_VERIFY(jvmti->SetEventNotificationMode(JVMTI_ENABLE, 246 JVMTI_EVENT_OBJECT_FREE, 247 NULL))) 248 return JNI_ERR; 249 NSK_DISPLAY0("enabling the events done\n\n"); 250 251 if (!NSK_VERIFY(nsk_jvmti_setAgentProc(agentProc, NULL))) 252 return JNI_ERR; 253 NSK_DISPLAY0("agentProc has been set\n\n"); 254 255 return JNI_OK; 256 } 257 258 }