/* Primitive array data callback for FollowReferences */ static jint JNICALL cbPrimArrayData(jlong class_tag, jlong size, jlong* tag_ptr, jint element_count, jvmtiPrimitiveType element_type, const void* elements, void* user_data) { ObjectIndex object_index; RefIndex ref_index; RefIndex prev_ref_index; HPROF_ASSERT(tag_ptr!=NULL); HPROF_ASSERT(class_tag!=(jlong)0); HPROF_ASSERT((*tag_ptr)!=(jlong)0); if ( class_tag == (jlong)0 || (*tag_ptr) == (jlong)0 ) { /* We can't do anything with a class_tag==0, just skip it */ return JVMTI_VISIT_OBJECTS; } /* Assume object has been tagged, get object index */ object_index = tag_extract((*tag_ptr)); /* Save string data */ prev_ref_index = object_get_references(object_index); ref_index = reference_prim_array(prev_ref_index, element_type, elements, element_count); object_set_references(object_index, ref_index); return JVMTI_VISIT_OBJECTS; }
/* Setup tag on root object */ static void setup_tag_on_root(jlong *tag_ptr, jlong class_tag, jlong size, SerialNumber thread_serial_num, ObjectIndex *pindex, SiteIndex *psite) { ObjectIndex object_index; SiteIndex object_site_index; if ( (*tag_ptr) != (jlong)0 ) { object_index = tag_extract(*tag_ptr); if ( psite != NULL ) { object_site_index = object_get_site(object_index); } } else { object_site_index = site_find_or_create( find_cnum(class_tag), gdata->system_trace_index); object_index = object_new(object_site_index, (jint)size, OBJECT_SYSTEM, thread_serial_num); /* Create and set the tag. */ *tag_ptr = tag_create(object_index); } if ( pindex != NULL ) { *pindex = object_index; } if ( psite != NULL ) { *psite = object_site_index; } }
/* Get the object index for a class loader */ ObjectIndex loader_object_index(JNIEnv *env, LoaderIndex index) { LoaderInfo *info; ObjectIndex object_index; jobject wref; /* Assume no object index at first (default class loader) */ info = get_info(index); object_index = info->object_index; wref = info->globalref; if ( wref != NULL && object_index == 0 ) { jobject lref; object_index = 0; lref = newLocalReference(env, wref); if ( lref != NULL && !isSameObject(env, lref, NULL) ) { jlong tag; /* Get the tag on the object and extract the object_index */ tag = getTag(lref); if ( tag != (jlong)0 ) { object_index = tag_extract(tag); } } if ( lref != NULL ) { deleteLocalReference(env, lref); } info->object_index = object_index; } return object_index; }
/* JVMTI callback function. */ static jvmtiIterationControl JNICALL reference_object(jvmtiObjectReferenceKind reference_kind, jlong class_tag, jlong size, jlong* tag_ptr, jlong referrer_tag, jint referrer_index, void *user_data) { /* Only calls to Allocate, Deallocate, RawMonitorEnter & RawMonitorExit * are allowed here (see the JVMTI Spec). */ RefIndex ref_index; RefIndex prev_ref_index; ObjectIndex referrer_object_index; ObjectIndex object_index; jlong object_tag; HPROF_ASSERT(tag_ptr!=NULL); HPROF_ASSERT(referrer_tag!=(jlong)0); if ( referrer_tag != (jlong)0 ) { referrer_object_index = tag_extract(referrer_tag); } else { return JVMTI_ITERATION_CONTINUE; } object_tag = *tag_ptr; if ( object_tag != (jlong)0 ) { object_index = tag_extract(object_tag); } else { SiteIndex site_index; site_index = site_find_or_create(find_cnum(class_tag), gdata->system_trace_index); object_index = object_new(site_index, (jint)size, OBJECT_SYSTEM, gdata->system_thread_serial_num); object_tag = tag_create(object_index); *tag_ptr = object_tag; } /* Save reference information */ prev_ref_index = object_get_references(referrer_object_index); ref_index = reference_new(prev_ref_index, reference_kind, class_tag, size, object_tag, referrer_index); object_set_references(referrer_object_index, ref_index); return JVMTI_ITERATION_CONTINUE; }
/* Setup tag on root object, if tagged return object index and site index */ static void setup_tag_on_root(jlong *tag_ptr, jlong class_tag, jlong size, SerialNumber thread_serial_num, ObjectIndex *pindex, SiteIndex *psite) { HPROF_ASSERT(class_tag!=(jlong)0); if ( (*tag_ptr) != (jlong)0 ) { if ( pindex != NULL ) { *pindex = tag_extract(*tag_ptr); } if ( psite != NULL ) { *psite = object_get_site(tag_extract(*tag_ptr)); } } else { /* Create and set the tag. */ *tag_ptr = make_new_tag(class_tag, size, gdata->system_trace_index, thread_serial_num, pindex, psite); } }
static ObjectIndex tag_to_object_index(jlong tag) { ObjectIndex object_index; object_index = 0; if ( tag != (jlong)0 ) { object_index = tag_extract(tag); } return object_index; }
/* Get the object index and thread serial number for this local object */ static void localReference(jlong *tag_ptr, jlong class_tag, jlong thread_tag, jlong size, ObjectIndex *pobject_index, SerialNumber *pthread_serial_num) { ObjectIndex object_index; SerialNumber thread_serial_num; HPROF_ASSERT(pobject_index!=NULL); HPROF_ASSERT(pthread_serial_num!=NULL); HPROF_ASSERT(tag_ptr!=NULL); HPROF_ASSERT(class_tag!=(jlong)0); if ( (*tag_ptr) != (jlong)0 ) { object_index = tag_extract(*tag_ptr); thread_serial_num = object_get_thread_serial_number(object_index); thread_serial_num = checkThreadSerialNumber(thread_serial_num); } else { if ( thread_tag != (jlong)0 ) { ObjectIndex thread_object_index; thread_object_index = tag_extract(thread_tag); thread_serial_num = object_get_thread_serial_number(thread_object_index); thread_serial_num = checkThreadSerialNumber(thread_serial_num); } else { thread_serial_num = gdata->unknown_thread_serial_num; } /* Create and set the tag. */ *tag_ptr = make_new_tag(class_tag, size, gdata->system_trace_index, thread_serial_num, &object_index, NULL); } HPROF_ASSERT(thread_serial_num!=0); HPROF_ASSERT(object_index!=0); *pobject_index = object_index; *pthread_serial_num = thread_serial_num; }
static ClassIndex find_cnum(jlong class_tag) { ClassIndex cnum; ObjectIndex class_object_index; SiteIndex class_site_index; SiteKey *pkey; HPROF_ASSERT(class_tag!=(jlong)0); class_object_index = tag_extract(class_tag); class_site_index = object_get_site(class_object_index); pkey = get_pkey(class_site_index); cnum = pkey->cnum; return cnum; }
static ClassIndex find_cnum(jlong class_tag) { ClassIndex cnum; if ( class_tag != (jlong)0 ) { ObjectIndex class_object_index; SiteIndex site_index; SiteKey *pkey; class_object_index = tag_extract(class_tag); site_index = object_get_site(class_object_index); pkey = get_pkey(site_index); cnum = pkey->cnum; } else { LoaderIndex loader_index; loader_index = loader_find_or_create(NULL,NULL); cnum = class_find_or_create("Ljava/lang/Object;", loader_index); } return cnum; }
/* Primitive field data callback for FollowReferences */ static jint JNICALL cbPrimFieldData(jvmtiHeapReferenceKind reference_kind, const jvmtiHeapReferenceInfo* reference_info, jlong class_tag, jlong* tag_ptr, jvalue value, jvmtiPrimitiveType value_type, void* user_data) { ObjectIndex object_index; jint field_index; RefIndex ref_index; RefIndex prev_ref_index; HPROF_ASSERT(tag_ptr!=NULL); HPROF_ASSERT(class_tag!=(jlong)0); HPROF_ASSERT((*tag_ptr)!=(jlong)0); if ( class_tag == (jlong)0 || (*tag_ptr) == (jlong)0 ) { /* We can't do anything with a class_tag==0, just skip it */ return JVMTI_VISIT_OBJECTS; } /* If the field is 0, just skip it, we assume 0 */ if ( value.j == (jlong)0 ) { return JVMTI_VISIT_OBJECTS; } /* Get field index */ field_index = reference_info->field.index; /* We assume the object was tagged */ object_index = tag_extract((*tag_ptr)); /* Save primitive field data */ prev_ref_index = object_get_references(object_index); ref_index = reference_prim_field(prev_ref_index, reference_kind, value_type, value, field_index); object_set_references(object_index, ref_index); return JVMTI_VISIT_OBJECTS; }
/* JVMTI callback function. */ static jvmtiIterationControl JNICALL root_object(jvmtiHeapRootKind root_kind, jlong class_tag, jlong size, jlong* tag_ptr, void *user_data) { /* Only calls to Allocate, Deallocate, RawMonitorEnter & RawMonitorExit * are allowed here (see the JVMTI Spec). */ ObjectIndex object_index; SiteIndex object_site_index; HPROF_ASSERT(tag_ptr!=NULL); if ( (*tag_ptr) != (jlong)0 ) { object_index = tag_extract(*tag_ptr); object_site_index = object_get_site(object_index); } else { object_site_index = site_find_or_create(find_cnum(class_tag), gdata->system_trace_index); object_index = object_new(object_site_index, (jint)size, OBJECT_SYSTEM, gdata->system_thread_serial_num); /* Create and set the tag. */ *tag_ptr = tag_create(object_index); } switch ( root_kind ) { case JVMTI_HEAP_ROOT_JNI_GLOBAL: { SerialNumber trace_serial_num; SerialNumber gref_serial_num; if ( object_site_index != 0 ) { SiteKey *pkey; TraceIndex trace_index; pkey = get_pkey(object_site_index); trace_index = pkey->trace_index; trace_serial_num = trace_get_serial_number(trace_index); } else { trace_serial_num = trace_get_serial_number(gdata->system_trace_index); } gref_serial_num = gdata->gref_serial_number_counter++; io_heap_root_jni_global(object_index, gref_serial_num, trace_serial_num); break; } case JVMTI_HEAP_ROOT_SYSTEM_CLASS: { char *sig; sig = "Unknown"; if ( object_site_index != 0 ) { SiteKey *pkey; pkey = get_pkey(object_site_index); sig = string_get(class_get_signature(pkey->cnum)); } io_heap_root_system_class(object_index, sig); break; } case JVMTI_HEAP_ROOT_MONITOR: { io_heap_root_monitor(object_index); break; } case JVMTI_HEAP_ROOT_THREAD: { SerialNumber thread_serial_num; if ( object_index != 0 ) { thread_serial_num = object_get_thread_serial_number(object_index); } else { thread_serial_num = gdata->system_thread_serial_num; } io_heap_root_thread(object_index, thread_serial_num); break; } case JVMTI_HEAP_ROOT_OTHER: { io_heap_root_unknown(object_index); break; } default: break; } return JVMTI_ITERATION_CONTINUE; }
/* Store away plain object reference information */ static jint objectReference(jvmtiHeapReferenceKind reference_kind, const jvmtiHeapReferenceInfo* reference_info, jlong class_tag, jlong size, jlong* tag_ptr, jlong* referrer_tag_ptr, jint length) { ObjectIndex object_index; jint reference_index; RefIndex ref_index; RefIndex prev_ref_index; ObjectIndex referrer_object_index; jlong object_tag; HPROF_ASSERT(tag_ptr!=NULL); HPROF_ASSERT(class_tag!=(jlong)0); HPROF_ASSERT(referrer_tag_ptr!=NULL); HPROF_ASSERT((*referrer_tag_ptr)!=(jlong)0); if ( class_tag == (jlong)0 || (*referrer_tag_ptr) == (jlong)0 ) { /* We can't do anything with a class_tag==0, just skip it */ return JVMTI_VISIT_OBJECTS; } switch ( reference_kind ) { default: /* Currently we don't need these */ return JVMTI_VISIT_OBJECTS; case JVMTI_HEAP_REFERENCE_FIELD: case JVMTI_HEAP_REFERENCE_STATIC_FIELD: reference_index = reference_info->field.index; break; case JVMTI_HEAP_REFERENCE_ARRAY_ELEMENT: reference_index = reference_info->array.index; break; case JVMTI_HEAP_REFERENCE_CONSTANT_POOL: reference_index = reference_info->constant_pool.index; break; case JVMTI_HEAP_REFERENCE_SIGNERS: case JVMTI_HEAP_REFERENCE_PROTECTION_DOMAIN: case JVMTI_HEAP_REFERENCE_CLASS_LOADER: case JVMTI_HEAP_REFERENCE_INTERFACE: reference_index = 0; break; } /* We assume the referrer is tagged */ referrer_object_index = tag_extract((*referrer_tag_ptr)); /* Now check the referree */ object_tag = *tag_ptr; if ( object_tag != (jlong)0 ) { object_index = tag_extract(object_tag); } else { /* Create and set the tag. */ object_tag = make_new_tag(class_tag, size, gdata->system_trace_index, gdata->unknown_thread_serial_num, &object_index, NULL); *tag_ptr = object_tag; } HPROF_ASSERT(object_index!=0); /* Save reference information */ prev_ref_index = object_get_references(referrer_object_index); ref_index = reference_obj(prev_ref_index, reference_kind, object_index, reference_index, length); object_set_references(referrer_object_index, ref_index); return JVMTI_VISIT_OBJECTS; }