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/ap05t001Subclass;"; 46 static const int EXPECTED_STATIC_FIELDS_COUNT = 8; 47 /* 8 ones declared in ap05t001Superclass + 8 ones declared in ap05t001Subclass */ 48 static const int EXPECTED_INSTANCE_FIELDS_COUNT = 16; 49 static const long CLS_TAG = 1l, REFERRER_TAG = 2l, REFERREE_TAG = 10l; 50 static int staticFieldsCount = 0, instanceFieldsCount = 0; 51 52 /* jvmtiHeapRootCallback */ 53 jvmtiIterationControl JNICALL 54 heapRootCallback(jvmtiHeapRootKind root_kind, 55 jlong class_tag, 56 jlong size, 57 jlong* tag_ptr, 58 void* user_data) { 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 return JVMTI_ITERATION_CONTINUE; 74 } 75 76 77 /* jvmtiObjectReferenceCallback */ 78 jvmtiIterationControl JNICALL 79 objectReferenceCallback(jvmtiObjectReferenceKind reference_kind, 80 jlong class_tag, 81 jlong size, 82 jlong* tag_ptr, 83 jlong referrer_tag, 84 jint referrer_index, 85 void* user_data) { 86 87 if (*tag_ptr == REFERREE_TAG && (referrer_tag == CLS_TAG || referrer_tag == REFERRER_TAG)) { 88 NSK_DISPLAY4("objectReferenceCallback: reference kind=%s, referrer_index=%d, referrer_tag=%d, referree_tag=%d\n", 89 TranslateObjectRefKind(reference_kind), (int)referrer_index, (long)referrer_tag, (long)*tag_ptr); 90 if (reference_kind == JVMTI_REFERENCE_FIELD) { 91 instanceFieldsCount++; 92 } else if (reference_kind == JVMTI_REFERENCE_STATIC_FIELD) { 93 staticFieldsCount++; 94 } 95 } 96 return JVMTI_ITERATION_CONTINUE; 97 } 98 99 100 /************************/ 101 102 JNIEXPORT void JNICALL 103 Java_nsk_jvmti_scenarios_allocation_AP05_ap05t001_setTag(JNIEnv* jni, 104 jobject obj, 105 jobject target, 106 jlong tag) { 107 108 if (!NSK_JVMTI_VERIFY(jvmti->SetTag(target, tag))) { 109 nsk_jvmti_setFailStatus(); 110 } 111 } 112 113 JNIEXPORT void JNICALL 114 Java_nsk_jvmti_scenarios_allocation_AP05_ap05t001_setReferrer(JNIEnv* jni, jclass klass, jobject ref) { 115 if (!NSK_JNI_VERIFY(jni, (referrer = jni->NewGlobalRef(ref)) != NULL)) 116 nsk_jvmti_setFailStatus(); 117 } 118 119 static void JNICALL 120 agentProc(jvmtiEnv* jvmti, JNIEnv* jni, void* arg) { 121 122 jclass debugeeClass = NULL; 123 124 NSK_DISPLAY0("Wait for debugee start\n\n"); 125 if (!NSK_VERIFY(nsk_jvmti_waitForSync(timeout))) 126 return; 127 128 do { 129 staticFieldsCount = 0; 130 instanceFieldsCount = 0; 131 NSK_DISPLAY0("\nCalling IterateOverReachableObjects\n"); 132 if (!NSK_JVMTI_VERIFY(jvmti->IterateOverReachableObjects(heapRootCallback, 133 stackReferenceCallback, 134 objectReferenceCallback, 135 NULL /*user_data*/))) { 136 nsk_jvmti_setFailStatus(); 137 break; 138 } 139 if (instanceFieldsCount != EXPECTED_INSTANCE_FIELDS_COUNT) { 140 NSK_COMPLAIN3("IterateOverReachableObjects found wrong number of instance fields:\n\t" 141 " signature: %s\n\t found number: %d\n\t expected number: %d\n\n", 142 SUBCLASS_SIGNATURE, instanceFieldsCount, EXPECTED_INSTANCE_FIELDS_COUNT); 143 nsk_jvmti_setFailStatus(); 144 } 145 if (staticFieldsCount != EXPECTED_STATIC_FIELDS_COUNT) { 146 NSK_COMPLAIN3("IterateOverReachableObjects found wrong number of static fields:\n\t" 147 " signature: %s\n\t found number: %d\n\t expected number: %d\n\n", 148 SUBCLASS_SIGNATURE, staticFieldsCount, EXPECTED_STATIC_FIELDS_COUNT); 149 nsk_jvmti_setFailStatus(); 150 } 151 152 staticFieldsCount = 0; 153 instanceFieldsCount = 0; 154 NSK_DISPLAY0("\nCalling IterateOverObjectsReachableFromObject\n"); 155 { 156 if (!NSK_JVMTI_VERIFY(jvmti->IterateOverObjectsReachableFromObject( 157 referrer, objectReferenceCallback, NULL /*user_data*/))) { 158 nsk_jvmti_setFailStatus(); 159 break; 160 } 161 } 162 if (instanceFieldsCount != EXPECTED_INSTANCE_FIELDS_COUNT) { 163 NSK_COMPLAIN3("IterateOverObjectsReachableFromObject found wrong number of instance fields:\n\t" 164 " signature: %s\n\t found number: %d\n\t expected number: %d\n\n", 165 SUBCLASS_SIGNATURE, instanceFieldsCount, EXPECTED_INSTANCE_FIELDS_COUNT); 166 nsk_jvmti_setFailStatus(); 167 } 168 if (staticFieldsCount != EXPECTED_STATIC_FIELDS_COUNT) { 169 NSK_COMPLAIN3("IterateOverObjectsReachableFromObject found wrong number of static fields:\n\t" 170 " signature: %s\n\t found number: %d\n\t expected number: %d\n\n", 171 SUBCLASS_SIGNATURE, staticFieldsCount, EXPECTED_STATIC_FIELDS_COUNT); 172 nsk_jvmti_setFailStatus(); 173 } 174 175 176 NSK_TRACE(jni->DeleteGlobalRef(referrer)); 177 178 } while (0); 179 180 NSK_DISPLAY0("Let debugee to finish\n"); 181 if (!NSK_VERIFY(nsk_jvmti_resumeSync())) 182 return; 183 } 184 185 #ifdef STATIC_BUILD 186 JNIEXPORT jint JNICALL Agent_OnLoad_ap05t001(JavaVM *jvm, char *options, void *reserved) { 187 return Agent_Initialize(jvm, options, reserved); 188 } 189 JNIEXPORT jint JNICALL Agent_OnAttach_ap05t001(JavaVM *jvm, char *options, void *reserved) { 190 return Agent_Initialize(jvm, options, reserved); 191 } 192 JNIEXPORT jint JNI_OnLoad_ap05t001(JavaVM *jvm, char *options, void *reserved) { 193 return JNI_VERSION_1_8; 194 } 195 #endif 196 jint Agent_Initialize(JavaVM *jvm, char *options, void *reserved) { 197 /* init framework and parse options */ 198 if (!NSK_VERIFY(nsk_jvmti_parseOptions(options))) 199 return JNI_ERR; 200 201 /* create JVMTI environment */ 202 if (!NSK_VERIFY((jvmti = 203 nsk_jvmti_createJVMTIEnv(jvm, reserved)) != NULL)) 204 return JNI_ERR; 205 206 memset(&caps, 0, sizeof(jvmtiCapabilities)); 207 caps.can_tag_objects = 1; 208 209 if (!NSK_JVMTI_VERIFY(jvmti->AddCapabilities(&caps))) 210 return JNI_ERR; 211 212 if (!NSK_JVMTI_VERIFY(jvmti->GetCapabilities(&caps))) 213 return JNI_ERR; 214 215 if (!caps.can_tag_objects) 216 NSK_DISPLAY0("Warning: tagging objects is not implemented\n"); 217 218 if (!NSK_VERIFY(nsk_jvmti_setAgentProc(agentProc, NULL))) 219 return JNI_ERR; 220 NSK_DISPLAY0("agentProc has been set\n\n"); 221 222 return JNI_OK; 223 } 224 225 }