102 JNIEnv* jni,
103 jobject firstObject,
104 jfieldID firstField,
105 const char firstFieldName[],
106 jfieldID nextField,
107 const char nextFieldName[],
108 int count,
109 ObjectDesc objectDescList[],
110 jlong tag,
111 int reachable)
112 {
113 jobject obj = NULL;
114 jlong objTag = (reachable ? tag : -tag);
115
116 if (count <= 0)
117 return NSK_TRUE;
118
119 count--;
120 tag++;
121
122 if (!NSK_JNI_VERIFY(jni, (obj =
123 NSK_CPP_STUB3(GetObjectField, jni, firstObject, firstField)) != NULL)) {
124 nsk_jvmti_setFailStatus();
125 return NSK_FALSE;
126 }
127
128 objectDescList[count].tag = objTag;
129 if (reachable) {
130 objectDescList[count].exp_found++;
131 }
132
133 if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB3(SetTag, jvmti, obj, objTag))) {
134 nsk_jvmti_setFailStatus();
135 }
136 printf(" tag=%-5ld object=0x%p\n", (long)objTag, (void*)obj);
137 fflush(0);
138 if (!getAndTagChainObjects(jvmti, jni, obj,
139 nextField,
140 nextFieldName,
141 nextField,
142 nextFieldName,
143 count,
144 objectDescList,
145 tag,
146 reachable)) {
147 return NSK_FALSE;
148 }
149
150 NSK_TRACE(NSK_CPP_STUB2(DeleteLocalRef, jni, obj));
151 return NSK_TRUE;
152 } /* getAndTagChainObjects */
153
154 /** Obtain all tested objects from debugee class and tag them recursively. */
155 static int getAndTagTestedObjects(
156 jvmtiEnv* jvmti,
157 JNIEnv* jni,
158 int chainLength,
159 int* objectsCount,
160 ObjectDesc** objectDescList,
161 jobject* rootObject)
162 {
163 jclass debugeeClass = NULL;
164 jclass rootObjectClass = NULL;
165 jclass chainObjectClass = NULL;
166
167 jfieldID objectField = NULL;
168 jfieldID reachableChainField = NULL;
169 jfieldID unreachableChainField = NULL;
170 jfieldID tailField = NULL;
171
172 /* root object + reachable and unreachable object chains */
173 *objectsCount = 1 + 2 * chainLength;
174
175 printf("Allocate memory for objects list: %d objects\n", *objectsCount);
176 fflush(0);
177 if (!NSK_JVMTI_VERIFY(
178 NSK_CPP_STUB3(Allocate, jvmti, (*objectsCount * sizeof(ObjectDesc)),
179 (unsigned char**)objectDescList))) {
180 nsk_jvmti_setFailStatus();
181 return NSK_FALSE;
182 }
183 printf(" ... allocated array: 0x%p\n", (void*)objectDescList);
184 fflush(0);
185
186 {
187 int k;
188 for (k = 0; k < *objectsCount; k++) {
189 (*objectDescList)[k].tag = 0;
190 (*objectDescList)[k].exp_class_tag = chainClassTag;
191 (*objectDescList)[k].exp_found = 0;
192 (*objectDescList)[k].found = 0;
193 }
194 }
195 (*objectDescList)[0].exp_class_tag = rootClassTag;
196
197 printf("Find debugee class: %s\n", DEBUGEE_CLASS_NAME);
198 fflush(0);
199 if (!NSK_JNI_VERIFY(jni, (debugeeClass =
200 NSK_CPP_STUB2(FindClass, jni, DEBUGEE_CLASS_NAME)) != NULL)) {
201 nsk_jvmti_setFailStatus();
202 return NSK_FALSE;
203 }
204 printf(" ... found class: 0x%p\n", (void*)debugeeClass);
205
206 printf("Find root object class: %s\n", ROOT_OBJECT_CLASS_NAME);
207 fflush(0);
208 if (!NSK_JNI_VERIFY(jni, (rootObjectClass =
209 NSK_CPP_STUB2(FindClass, jni, ROOT_OBJECT_CLASS_NAME)) != NULL)) {
210 nsk_jvmti_setFailStatus();
211 return NSK_FALSE;
212 }
213 printf(" ... found class: 0x%p\n", (void*)rootObjectClass);
214
215 if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB3(SetTag, jvmti, rootObjectClass, rootClassTag))) {
216 nsk_jvmti_setFailStatus();
217 }
218 printf(" tag=%-5ld rootClass=0x%p\n", (long)rootClassTag, (void*)rootObjectClass);
219
220 printf("Find chain object class: %s\n", CHAIN_OBJECT_CLASS_NAME);
221 fflush(0);
222 if (!NSK_JNI_VERIFY(jni, (chainObjectClass =
223 NSK_CPP_STUB2(FindClass, jni, CHAIN_OBJECT_CLASS_NAME)) != NULL)) {
224 nsk_jvmti_setFailStatus();
225 return NSK_FALSE;
226 }
227 printf(" ... found class: 0x%p\n", (void*)chainObjectClass);
228
229 if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB3(SetTag, jvmti, chainObjectClass, chainClassTag))) {
230 nsk_jvmti_setFailStatus();
231 }
232 printf(" tag=%-5ld chainClass=0x%p\n", (long)chainClassTag, (void*)chainObjectClass);
233
234 printf("Find static field in debugee class: %s\n", OBJECT_FIELD_NAME);
235 fflush(0);
236 if (!NSK_JNI_VERIFY(jni, (objectField =
237 NSK_CPP_STUB4(GetStaticFieldID, jni, debugeeClass,
238 OBJECT_FIELD_NAME, ROOT_OBJECT_CLASS_SIG)) != NULL)) {
239 nsk_jvmti_setFailStatus();
240 return NSK_FALSE;
241 }
242 printf(" ... got fieldID: 0x%p\n", (void*)objectField);
243
244 printf("Find instance field in root object class: %s\n", REACHABLE_CHAIN_FIELD_NAME);
245 fflush(0);
246 if (!NSK_JNI_VERIFY(jni, (reachableChainField =
247 NSK_CPP_STUB4(GetFieldID, jni, rootObjectClass,
248 REACHABLE_CHAIN_FIELD_NAME, CHAIN_OBJECT_CLASS_SIG)) != NULL)) {
249 nsk_jvmti_setFailStatus();
250 return NSK_FALSE;
251 }
252 printf(" ... got fieldID: 0x%p\n", (void*)reachableChainField);
253
254 printf("Find instance field in root object class: %s\n", UNREACHABLE_CHAIN_FIELD_NAME);
255 fflush(0);
256 if (!NSK_JNI_VERIFY(jni, (unreachableChainField =
257 NSK_CPP_STUB4(GetFieldID, jni, rootObjectClass,
258 UNREACHABLE_CHAIN_FIELD_NAME, CHAIN_OBJECT_CLASS_SIG)) != NULL)) {
259 nsk_jvmti_setFailStatus();
260 return NSK_FALSE;
261 }
262 printf(" ... got fieldID: 0x%p\n", (void*)unreachableChainField);
263
264 printf("Find instance field in chain object class: %s\n", TAIL_FIELD_NAME);
265 fflush(0);
266 if (!NSK_JNI_VERIFY(jni, (tailField =
267 NSK_CPP_STUB4(GetFieldID, jni, chainObjectClass,
268 TAIL_FIELD_NAME, CHAIN_OBJECT_CLASS_SIG)) != NULL)) {
269 nsk_jvmti_setFailStatus();
270 return NSK_FALSE;
271 }
272 printf(" ... got fieldID: 0x%p\n", (void*)tailField);
273
274 printf("Get root object from static field: %s\n", OBJECT_FIELD_NAME);
275 fflush(0);
276 if (!NSK_JNI_VERIFY(jni, (*rootObject =
277 NSK_CPP_STUB3(GetStaticObjectField, jni, debugeeClass,
278 objectField)) != NULL)) {
279 nsk_jvmti_setFailStatus();
280 return NSK_FALSE;
281 }
282 printf(" ... got object: 0x%p\n", (void*)*rootObject);
283 fflush(0);
284
285 if (!NSK_JNI_VERIFY(jni, (*rootObject =
286 NSK_CPP_STUB2(NewGlobalRef, jni, *rootObject)) != NULL)) {
287 nsk_jvmti_setFailStatus();
288 return NSK_FALSE;
289 }
290 printf(" ... global ref: 0x%p\n", (void*)*rootObject);
291
292 printf("Obtain and tag chain objects:\n");
293
294 printf(" root tested object:\n");
295 fflush(0);
296 if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB3(SetTag, jvmti, *rootObject, rootObjectTag))) {
297 nsk_jvmti_setFailStatus();
298 }
299 printf(" tag=%-5ld object=0x%p\n", (long)rootObjectTag, (void*)*rootObject);
300
301 (*objectDescList)[0].tag = rootObjectTag;
302
303 /* Root object must be referenced 1 time */
304 (*objectDescList)[0].exp_found = 1;
305
306 /* Object with tag=101 must be referenced 2 times */
307 (*objectDescList)[chainLength].exp_found = 1;
308
309 printf(" reachable objects chain: %d objects\n", chainLength);
310 fflush(0);
311 if (!getAndTagChainObjects(jvmti, jni, *rootObject,
312 reachableChainField,
313 REACHABLE_CHAIN_FIELD_NAME,
314 tailField,
315 TAIL_FIELD_NAME,
316 chainLength,
389 " expected to iterate: %d times\n"
390 " iterated: %d times\n",
391 (long) objectDescList[idx].tag,
392 objectDescList[idx].exp_found,
393 objectDescList[idx].found);
394 if (objectDescList[idx].found > 0) {
395 NSK_COMPLAIN0("Unreachable object was iterated\n");
396 nsk_jvmti_setFailStatus();
397 }
398 fflush(0);
399 }
400
401 return NSK_TRUE;
402 } /* checkTestedObjects */
403
404 /** Release references to the tested objects and free allocated memory. */
405 static int releaseTestedObjects(jvmtiEnv* jvmti, JNIEnv* jni, int chainLength,
406 ObjectDesc* objectDescList, jobject rootObject) {
407 if (rootObject != NULL) {
408 printf("Release object reference to root tested object: 0x%p\n", rootObject);
409 NSK_TRACE(NSK_CPP_STUB2(DeleteGlobalRef, jni, rootObject));
410 }
411
412 if (objectDescList != NULL) {
413 printf("Deallocate objects list: 0x%p\n", (void*)objectDescList);
414 if (!NSK_JVMTI_VERIFY(
415 NSK_CPP_STUB2(Deallocate, jvmti, (unsigned char*)objectDescList))) {
416 nsk_jvmti_setFailStatus();
417 }
418 }
419
420 fflush(0);
421 return NSK_TRUE;
422 } /* releaseTestedObjects */
423
424 /* ============================================================================= */
425
426 /** heapReferenceCallback for heap iterator. */
427 jint JNICALL heapReferenceCallback(
428 jvmtiHeapReferenceKind reference_kind,
429 const jvmtiHeapReferenceInfo* reference_info,
430 jlong class_tag,
431 jlong referrer_class_tag,
432 jlong size,
433 jlong* tag_ptr,
434 jlong* referrer_tag_ptr,
435 jint length,
628 &objectDescList, &rootObject))) {
629 return;
630 }
631 }
632
633 printf(">>> Let debugee to clean links to unreachable objects\n");
634 fflush(0);
635 {
636 if (!NSK_VERIFY(nsk_jvmti_resumeSync())) {
637 return;
638 }
639 if (!NSK_VERIFY(nsk_jvmti_waitForSync(timeout))) {
640 return;
641 }
642 }
643
644 printf("\n\n>>> Start 1-st iteration for root tested object: 0x%p\n", rootObject);
645 fflush(0);
646 {
647 jint heap_filter = JVMTI_HEAP_FILTER_UNTAGGED | JVMTI_HEAP_FILTER_CLASS_UNTAGGED;
648 if (!NSK_JVMTI_VERIFY(
649 NSK_CPP_STUB6(FollowReferences, jvmti,
650 heap_filter,
651 (jclass) NULL, /* class */
652 rootObject, /* initial_object */
653 &heapCallbacks,
654 (const void *) &fakeUserData)))
655 {
656 nsk_jvmti_setFailStatus();
657 return;
658 }
659 }
660
661 printf(">>> Check if reachable objects were iterated\n");
662 fflush(0);
663 {
664 if (!checkTestedObjects(jvmti, jni, chainLength, objectDescList)) {
665 nsk_jvmti_setFailStatus();
666 }
667 }
668
669
670 { /* Reinstall the expectations */
671 int k;
672 for (k = 0; k < objectsCount; k++) {
673 (objectDescList)[k].exp_found = 0;
674 (objectDescList)[k].found = 0;
675 }
676 }
677
678 printf("\n\n>>> Start 2-nd iteration for root tested object: 0x%p\n", rootObject);
679 fflush(0);
680 {
681 /* This time everythig is filtered out */
682 jint heap_filter = JVMTI_HEAP_FILTER_UNTAGGED | JVMTI_HEAP_FILTER_CLASS_UNTAGGED |
683 JVMTI_HEAP_FILTER_TAGGED | JVMTI_HEAP_FILTER_CLASS_TAGGED;
684 if (!NSK_JVMTI_VERIFY(
685 NSK_CPP_STUB6(FollowReferences, jvmti,
686 heap_filter,
687 (jclass) NULL, /* class */
688 rootObject, /* initial_object */
689 &heapCallbacks,
690 (const void *) &fakeUserData)))
691 {
692 nsk_jvmti_setFailStatus();
693 return;
694 }
695 }
696
697 printf(">>> Check if reachable objects were not reported this time\n");
698 fflush(0);
699 {
700 if (!checkTestedObjects(jvmti, jni, chainLength, objectDescList)) {
701 nsk_jvmti_setFailStatus();
702 }
703 }
704
705 printf(">>> Clean used data\n");
706 fflush(0);
707 {
708 if (!NSK_VERIFY(releaseTestedObjects(jvmti, jni, chainLength, objectDescList, rootObject))) {
709 return;
710 }
711 }
734 jvmtiEnv* jvmti = NULL;
735
736 if (!NSK_VERIFY(nsk_jvmti_parseOptions(options)))
737 return JNI_ERR;
738
739 timeout = nsk_jvmti_getWaitTime() * 60 * 1000;
740
741 chainLength = nsk_jvmti_findOptionIntValue("objects", DEFAULT_CHAIN_LENGTH);
742 if (!NSK_VERIFY(chainLength > 0))
743 return JNI_ERR;
744
745 if (!NSK_VERIFY((jvmti =
746 nsk_jvmti_createJVMTIEnv(jvm, reserved)) != NULL))
747 return JNI_ERR;
748
749 {
750 jvmtiCapabilities caps;
751
752 memset(&caps, 0, sizeof(caps));
753 caps.can_tag_objects = 1;
754 if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB2(AddCapabilities, jvmti, &caps))) {
755 return JNI_ERR;
756 }
757 }
758
759 /* Setting Heap Callbacks */
760 heapCallbacks.heap_iteration_callback = NULL;
761 heapCallbacks.heap_reference_callback = heapReferenceCallback;
762 heapCallbacks.primitive_field_callback = primitiveFieldCallback;
763 heapCallbacks.array_primitive_value_callback = arrayPrimitiveValueCallback;
764 heapCallbacks.string_primitive_value_callback = stringPrimitiveValueCallback;
765
766 if (!NSK_VERIFY(nsk_jvmti_setAgentProc(agentProc, NULL)))
767 return JNI_ERR;
768
769 return JNI_OK;
770 }
771
772 /* ============================================================================= */
773
774 }
|
102 JNIEnv* jni,
103 jobject firstObject,
104 jfieldID firstField,
105 const char firstFieldName[],
106 jfieldID nextField,
107 const char nextFieldName[],
108 int count,
109 ObjectDesc objectDescList[],
110 jlong tag,
111 int reachable)
112 {
113 jobject obj = NULL;
114 jlong objTag = (reachable ? tag : -tag);
115
116 if (count <= 0)
117 return NSK_TRUE;
118
119 count--;
120 tag++;
121
122 if (!NSK_JNI_VERIFY(jni, (obj = jni->GetObjectField(firstObject, firstField)) != NULL)) {
123 nsk_jvmti_setFailStatus();
124 return NSK_FALSE;
125 }
126
127 objectDescList[count].tag = objTag;
128 if (reachable) {
129 objectDescList[count].exp_found++;
130 }
131
132 if (!NSK_JVMTI_VERIFY(jvmti->SetTag(obj, objTag))) {
133 nsk_jvmti_setFailStatus();
134 }
135 printf(" tag=%-5ld object=0x%p\n", (long)objTag, (void*)obj);
136 fflush(0);
137 if (!getAndTagChainObjects(jvmti, jni, obj,
138 nextField,
139 nextFieldName,
140 nextField,
141 nextFieldName,
142 count,
143 objectDescList,
144 tag,
145 reachable)) {
146 return NSK_FALSE;
147 }
148
149 NSK_TRACE(jni->DeleteLocalRef(obj));
150 return NSK_TRUE;
151 } /* getAndTagChainObjects */
152
153 /** Obtain all tested objects from debugee class and tag them recursively. */
154 static int getAndTagTestedObjects(
155 jvmtiEnv* jvmti,
156 JNIEnv* jni,
157 int chainLength,
158 int* objectsCount,
159 ObjectDesc** objectDescList,
160 jobject* rootObject)
161 {
162 jclass debugeeClass = NULL;
163 jclass rootObjectClass = NULL;
164 jclass chainObjectClass = NULL;
165
166 jfieldID objectField = NULL;
167 jfieldID reachableChainField = NULL;
168 jfieldID unreachableChainField = NULL;
169 jfieldID tailField = NULL;
170
171 /* root object + reachable and unreachable object chains */
172 *objectsCount = 1 + 2 * chainLength;
173
174 printf("Allocate memory for objects list: %d objects\n", *objectsCount);
175 fflush(0);
176 if (!NSK_JVMTI_VERIFY(jvmti->Allocate((*objectsCount * sizeof(ObjectDesc)),
177 (unsigned char**)objectDescList))) {
178 nsk_jvmti_setFailStatus();
179 return NSK_FALSE;
180 }
181 printf(" ... allocated array: 0x%p\n", (void*)objectDescList);
182 fflush(0);
183
184 {
185 int k;
186 for (k = 0; k < *objectsCount; k++) {
187 (*objectDescList)[k].tag = 0;
188 (*objectDescList)[k].exp_class_tag = chainClassTag;
189 (*objectDescList)[k].exp_found = 0;
190 (*objectDescList)[k].found = 0;
191 }
192 }
193 (*objectDescList)[0].exp_class_tag = rootClassTag;
194
195 printf("Find debugee class: %s\n", DEBUGEE_CLASS_NAME);
196 fflush(0);
197 if (!NSK_JNI_VERIFY(jni, (debugeeClass = jni->FindClass(DEBUGEE_CLASS_NAME)) != NULL)) {
198 nsk_jvmti_setFailStatus();
199 return NSK_FALSE;
200 }
201 printf(" ... found class: 0x%p\n", (void*)debugeeClass);
202
203 printf("Find root object class: %s\n", ROOT_OBJECT_CLASS_NAME);
204 fflush(0);
205 if (!NSK_JNI_VERIFY(jni, (rootObjectClass = jni->FindClass(ROOT_OBJECT_CLASS_NAME)) != NULL)) {
206 nsk_jvmti_setFailStatus();
207 return NSK_FALSE;
208 }
209 printf(" ... found class: 0x%p\n", (void*)rootObjectClass);
210
211 if (!NSK_JVMTI_VERIFY(jvmti->SetTag(rootObjectClass, rootClassTag))) {
212 nsk_jvmti_setFailStatus();
213 }
214 printf(" tag=%-5ld rootClass=0x%p\n", (long)rootClassTag, (void*)rootObjectClass);
215
216 printf("Find chain object class: %s\n", CHAIN_OBJECT_CLASS_NAME);
217 fflush(0);
218 if (!NSK_JNI_VERIFY(jni, (chainObjectClass =
219 jni->FindClass(CHAIN_OBJECT_CLASS_NAME)) != NULL)) {
220 nsk_jvmti_setFailStatus();
221 return NSK_FALSE;
222 }
223 printf(" ... found class: 0x%p\n", (void*)chainObjectClass);
224
225 if (!NSK_JVMTI_VERIFY(jvmti->SetTag(chainObjectClass, chainClassTag))) {
226 nsk_jvmti_setFailStatus();
227 }
228 printf(" tag=%-5ld chainClass=0x%p\n", (long)chainClassTag, (void*)chainObjectClass);
229
230 printf("Find static field in debugee class: %s\n", OBJECT_FIELD_NAME);
231 fflush(0);
232 if (!NSK_JNI_VERIFY(jni, (objectField =
233 jni->GetStaticFieldID(debugeeClass, OBJECT_FIELD_NAME, ROOT_OBJECT_CLASS_SIG)) != NULL)) {
234 nsk_jvmti_setFailStatus();
235 return NSK_FALSE;
236 }
237 printf(" ... got fieldID: 0x%p\n", (void*)objectField);
238
239 printf("Find instance field in root object class: %s\n", REACHABLE_CHAIN_FIELD_NAME);
240 fflush(0);
241 if (!NSK_JNI_VERIFY(jni, (reachableChainField =
242 jni->GetFieldID(rootObjectClass, REACHABLE_CHAIN_FIELD_NAME, CHAIN_OBJECT_CLASS_SIG)) != NULL)) {
243 nsk_jvmti_setFailStatus();
244 return NSK_FALSE;
245 }
246 printf(" ... got fieldID: 0x%p\n", (void*)reachableChainField);
247
248 printf("Find instance field in root object class: %s\n", UNREACHABLE_CHAIN_FIELD_NAME);
249 fflush(0);
250 if (!NSK_JNI_VERIFY(jni, (unreachableChainField =
251 jni->GetFieldID(rootObjectClass, UNREACHABLE_CHAIN_FIELD_NAME, CHAIN_OBJECT_CLASS_SIG)) != NULL)) {
252 nsk_jvmti_setFailStatus();
253 return NSK_FALSE;
254 }
255 printf(" ... got fieldID: 0x%p\n", (void*)unreachableChainField);
256
257 printf("Find instance field in chain object class: %s\n", TAIL_FIELD_NAME);
258 fflush(0);
259 if (!NSK_JNI_VERIFY(jni, (tailField =
260 jni->GetFieldID(chainObjectClass, TAIL_FIELD_NAME, CHAIN_OBJECT_CLASS_SIG)) != NULL)) {
261 nsk_jvmti_setFailStatus();
262 return NSK_FALSE;
263 }
264 printf(" ... got fieldID: 0x%p\n", (void*)tailField);
265
266 printf("Get root object from static field: %s\n", OBJECT_FIELD_NAME);
267 fflush(0);
268 if (!NSK_JNI_VERIFY(jni, (*rootObject =
269 jni->GetStaticObjectField(debugeeClass, objectField)) != NULL)) {
270 nsk_jvmti_setFailStatus();
271 return NSK_FALSE;
272 }
273 printf(" ... got object: 0x%p\n", (void*)*rootObject);
274 fflush(0);
275
276 if (!NSK_JNI_VERIFY(jni, (*rootObject = jni->NewGlobalRef(*rootObject)) != NULL)) {
277 nsk_jvmti_setFailStatus();
278 return NSK_FALSE;
279 }
280 printf(" ... global ref: 0x%p\n", (void*)*rootObject);
281
282 printf("Obtain and tag chain objects:\n");
283
284 printf(" root tested object:\n");
285 fflush(0);
286 if (!NSK_JVMTI_VERIFY(jvmti->SetTag(*rootObject, rootObjectTag))) {
287 nsk_jvmti_setFailStatus();
288 }
289 printf(" tag=%-5ld object=0x%p\n", (long)rootObjectTag, (void*)*rootObject);
290
291 (*objectDescList)[0].tag = rootObjectTag;
292
293 /* Root object must be referenced 1 time */
294 (*objectDescList)[0].exp_found = 1;
295
296 /* Object with tag=101 must be referenced 2 times */
297 (*objectDescList)[chainLength].exp_found = 1;
298
299 printf(" reachable objects chain: %d objects\n", chainLength);
300 fflush(0);
301 if (!getAndTagChainObjects(jvmti, jni, *rootObject,
302 reachableChainField,
303 REACHABLE_CHAIN_FIELD_NAME,
304 tailField,
305 TAIL_FIELD_NAME,
306 chainLength,
379 " expected to iterate: %d times\n"
380 " iterated: %d times\n",
381 (long) objectDescList[idx].tag,
382 objectDescList[idx].exp_found,
383 objectDescList[idx].found);
384 if (objectDescList[idx].found > 0) {
385 NSK_COMPLAIN0("Unreachable object was iterated\n");
386 nsk_jvmti_setFailStatus();
387 }
388 fflush(0);
389 }
390
391 return NSK_TRUE;
392 } /* checkTestedObjects */
393
394 /** Release references to the tested objects and free allocated memory. */
395 static int releaseTestedObjects(jvmtiEnv* jvmti, JNIEnv* jni, int chainLength,
396 ObjectDesc* objectDescList, jobject rootObject) {
397 if (rootObject != NULL) {
398 printf("Release object reference to root tested object: 0x%p\n", rootObject);
399 NSK_TRACE(jni->DeleteGlobalRef(rootObject));
400 }
401
402 if (objectDescList != NULL) {
403 printf("Deallocate objects list: 0x%p\n", (void*)objectDescList);
404 if (!NSK_JVMTI_VERIFY(jvmti->Deallocate((unsigned char*)objectDescList))) {
405 nsk_jvmti_setFailStatus();
406 }
407 }
408
409 fflush(0);
410 return NSK_TRUE;
411 } /* releaseTestedObjects */
412
413 /* ============================================================================= */
414
415 /** heapReferenceCallback for heap iterator. */
416 jint JNICALL heapReferenceCallback(
417 jvmtiHeapReferenceKind reference_kind,
418 const jvmtiHeapReferenceInfo* reference_info,
419 jlong class_tag,
420 jlong referrer_class_tag,
421 jlong size,
422 jlong* tag_ptr,
423 jlong* referrer_tag_ptr,
424 jint length,
617 &objectDescList, &rootObject))) {
618 return;
619 }
620 }
621
622 printf(">>> Let debugee to clean links to unreachable objects\n");
623 fflush(0);
624 {
625 if (!NSK_VERIFY(nsk_jvmti_resumeSync())) {
626 return;
627 }
628 if (!NSK_VERIFY(nsk_jvmti_waitForSync(timeout))) {
629 return;
630 }
631 }
632
633 printf("\n\n>>> Start 1-st iteration for root tested object: 0x%p\n", rootObject);
634 fflush(0);
635 {
636 jint heap_filter = JVMTI_HEAP_FILTER_UNTAGGED | JVMTI_HEAP_FILTER_CLASS_UNTAGGED;
637 if (!NSK_JVMTI_VERIFY(jvmti->FollowReferences(heap_filter,
638 (jclass) NULL, /* class */
639 rootObject, /* initial_object */
640 &heapCallbacks,
641 (const void *) &fakeUserData))) {
642 nsk_jvmti_setFailStatus();
643 return;
644 }
645 }
646
647 printf(">>> Check if reachable objects were iterated\n");
648 fflush(0);
649 {
650 if (!checkTestedObjects(jvmti, jni, chainLength, objectDescList)) {
651 nsk_jvmti_setFailStatus();
652 }
653 }
654
655
656 { /* Reinstall the expectations */
657 int k;
658 for (k = 0; k < objectsCount; k++) {
659 (objectDescList)[k].exp_found = 0;
660 (objectDescList)[k].found = 0;
661 }
662 }
663
664 printf("\n\n>>> Start 2-nd iteration for root tested object: 0x%p\n", rootObject);
665 fflush(0);
666 {
667 /* This time everythig is filtered out */
668 jint heap_filter = JVMTI_HEAP_FILTER_UNTAGGED | JVMTI_HEAP_FILTER_CLASS_UNTAGGED |
669 JVMTI_HEAP_FILTER_TAGGED | JVMTI_HEAP_FILTER_CLASS_TAGGED;
670 if (!NSK_JVMTI_VERIFY(jvmti->FollowReferences(heap_filter,
671 (jclass) NULL, /* class */
672 rootObject, /* initial_object */
673 &heapCallbacks,
674 (const void *) &fakeUserData))) {
675 nsk_jvmti_setFailStatus();
676 return;
677 }
678 }
679
680 printf(">>> Check if reachable objects were not reported this time\n");
681 fflush(0);
682 {
683 if (!checkTestedObjects(jvmti, jni, chainLength, objectDescList)) {
684 nsk_jvmti_setFailStatus();
685 }
686 }
687
688 printf(">>> Clean used data\n");
689 fflush(0);
690 {
691 if (!NSK_VERIFY(releaseTestedObjects(jvmti, jni, chainLength, objectDescList, rootObject))) {
692 return;
693 }
694 }
717 jvmtiEnv* jvmti = NULL;
718
719 if (!NSK_VERIFY(nsk_jvmti_parseOptions(options)))
720 return JNI_ERR;
721
722 timeout = nsk_jvmti_getWaitTime() * 60 * 1000;
723
724 chainLength = nsk_jvmti_findOptionIntValue("objects", DEFAULT_CHAIN_LENGTH);
725 if (!NSK_VERIFY(chainLength > 0))
726 return JNI_ERR;
727
728 if (!NSK_VERIFY((jvmti =
729 nsk_jvmti_createJVMTIEnv(jvm, reserved)) != NULL))
730 return JNI_ERR;
731
732 {
733 jvmtiCapabilities caps;
734
735 memset(&caps, 0, sizeof(caps));
736 caps.can_tag_objects = 1;
737 if (!NSK_JVMTI_VERIFY(jvmti->AddCapabilities(&caps))) {
738 return JNI_ERR;
739 }
740 }
741
742 /* Setting Heap Callbacks */
743 heapCallbacks.heap_iteration_callback = NULL;
744 heapCallbacks.heap_reference_callback = heapReferenceCallback;
745 heapCallbacks.primitive_field_callback = primitiveFieldCallback;
746 heapCallbacks.array_primitive_value_callback = arrayPrimitiveValueCallback;
747 heapCallbacks.string_primitive_value_callback = stringPrimitiveValueCallback;
748
749 if (!NSK_VERIFY(nsk_jvmti_setAgentProc(agentProc, NULL)))
750 return JNI_ERR;
751
752 return JNI_OK;
753 }
754
755 /* ============================================================================= */
756
757 }
|