1 #include <stdio.h>
2 #include <jvmti.h>
3 #include <tijmp.h>
4 #include <find_child_objects.h>
5 #include <tag_list.h>
6 #include <walk_heap.h>
7 #include <tijmp_class_handler.h>
8
9 extern jvmtiEnv* jvmti;
10 extern jlong current_object_tag;
11
12 typedef struct {
13 tag_list* tl;
14 tag_list* tijmp_classes;
15 } tlp;
16
fco(jvmtiHeapReferenceKind reference_kind,const jvmtiHeapReferenceInfo * reference_info,jlong class_tag,jlong referrer_class_tag,jlong size,jlong * tag,jlong * referrer_tag_ptr,jint length,void * user_data)17 static jint JNICALL fco (jvmtiHeapReferenceKind reference_kind,
18 const jvmtiHeapReferenceInfo* reference_info,
19 jlong class_tag, jlong referrer_class_tag,
20 jlong size, jlong* tag, jlong* referrer_tag_ptr,
21 jint length, void* user_data) {
22 tlp* p = (tlp*)user_data;
23
24 /* ignore all odd references... */
25 if (reference_kind != JVMTI_HEAP_REFERENCE_FIELD &&
26 reference_kind != JVMTI_HEAP_REFERENCE_ARRAY_ELEMENT)
27 return 0;
28
29 /* ignore references to and from tijmp classes. */
30 if (is_tijmp_class (referrer_class_tag, p->tijmp_classes))
31 return 0;
32 if (is_tijmp_class (class_tag, p->tijmp_classes))
33 return JVMTI_VISIT_OBJECTS;
34
35 if (*tag == 0)
36 *tag = current_object_tag--;
37
38 add_tag (p->tl, *tag);
39 return JVMTI_VISIT_OBJECTS;
40 }
41
find_all_child_objects(JNIEnv * env,jobject o)42 void JNICALL find_all_child_objects (JNIEnv *env, jobject o) {
43 jvmtiError err;
44 jvmtiHeapCallbacks callbacks;
45 jint count;
46 jobject* objects;
47 jint i;
48 jobjectArray oa;
49 jclass cls;
50 jmethodID m;
51 jint class_count;
52 jclass* cp = NULL;
53 jclass** classes = &cp;
54 tag_list so;
55 tag_list tijmp_classes;
56 tlp p;
57
58 tag_classes (env, &class_count, classes);
59 (*jvmti)->Deallocate (jvmti, (unsigned char*)classes[0]);
60
61 setup_tag_list (env, &tijmp_classes, NULL);
62 find_tijmp_classes (env, &tijmp_classes);
63
64 setup_tag_list (env, &so, NULL);
65 callbacks.heap_iteration_callback = 0;
66 callbacks.heap_reference_callback = fco;
67 callbacks.primitive_field_callback = 0;
68 callbacks.array_primitive_value_callback = 0;
69 callbacks.string_primitive_value_callback = 0;
70 (*jvmti)->SetTag (jvmti, o, -1);
71
72 p.tl = &so;
73 p.tijmp_classes = &tijmp_classes;
74 err = (*jvmti)->FollowReferences (jvmti, 0, NULL, o, &callbacks, &p);
75 if (err != JVMTI_ERROR_NONE)
76 handle_global_error (err);
77
78 cls = (*env)->FindClass (env, "java/lang/Object");
79 (*jvmti)->GetObjectsWithTags (jvmti, so.next_pos, so.tags, &count, &objects, NULL);
80 oa = (*env)->NewObjectArray (env, count, cls, NULL);
81 for (i = 0; i < count; i++)
82 (*env)->SetObjectArrayElement (env, oa, i, objects[i]);
83 cleanup_tag_list (&so);
84 cleanup_tag_list (&tijmp_classes);
85
86 cls = (*env)->FindClass (env, "tijmp/TIJMPController");
87 m = (*env)->GetStaticMethodID (env, cls, "childObjects",
88 "([Ljava/lang/Object;)V");
89 if (m != NULL)
90 (*env)->CallStaticVoidMethod (env, cls, m, oa);
91 }
92