示例#1
0
文件: hprof_site.c 项目: cedarli/java
/* JVMTI callback function. */
static jvmtiIterationControl JNICALL
stack_object(jvmtiHeapRootKind root_kind, 
		jlong class_tag, jlong size, jlong* tag_ptr, 
		jlong thread_tag, jint depth, jmethodID method, jint slot,
		void *user_data)
{

   /* Only calls to Allocate, Deallocate, RawMonitorEnter & RawMonitorExit
    *   are allowed here (see the JVMTI Spec).
    */

    ObjectIndex  object_index;
    SerialNumber thread_serial_num;

    HPROF_ASSERT(tag_ptr!=NULL);
    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 {
	SiteIndex site_index;
	
        site_index = site_find_or_create(find_cnum(class_tag), 
				gdata->system_trace_index);
	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;
	}
	object_index = object_new(site_index, (jint)size, OBJECT_SYSTEM,
			    thread_serial_num);
	/* Create and set the tag. */
	*tag_ptr = tag_create(object_index);
    }

    HPROF_ASSERT(thread_serial_num!=0);
    HPROF_ASSERT(object_index!=0);
    switch ( root_kind ) {
        case JVMTI_HEAP_ROOT_STACK_LOCAL:
	    io_heap_root_java_frame(object_index, thread_serial_num, depth);
	    break;
        case JVMTI_HEAP_ROOT_JNI_LOCAL:
	    io_heap_root_jni_local(object_index, thread_serial_num, depth);
	    break;
	default:
	    break;
    }
    return JVMTI_ITERATION_CONTINUE;
}
/* FollowReferences heap_reference_callback */
static jint JNICALL 
cbReference(jvmtiHeapReferenceKind reference_kind, 
                  const jvmtiHeapReferenceInfo* reference_info, 
                  jlong class_tag, jlong referrer_class_tag,
                  jlong size, jlong* tag_ptr, 
                  jlong* referrer_tag_ptr, jint length, void* user_data)
{
    ObjectIndex   object_index;

   /* Only calls to Allocate, Deallocate, RawMonitorEnter & RawMonitorExit
    *   are allowed here (see the JVMTI Spec).
    */

    HPROF_ASSERT(tag_ptr!=NULL);
    HPROF_ASSERT(class_tag!=(jlong)0);
    if ( class_tag == (jlong)0 ) {
        /* We can't do anything with a class_tag==0, just skip it */
        return JVMTI_VISIT_OBJECTS;
    }
   
    switch ( reference_kind ) {
        
        case JVMTI_HEAP_REFERENCE_FIELD:
        case JVMTI_HEAP_REFERENCE_ARRAY_ELEMENT:
        case JVMTI_HEAP_REFERENCE_CLASS_LOADER:
        case JVMTI_HEAP_REFERENCE_SIGNERS:
        case JVMTI_HEAP_REFERENCE_PROTECTION_DOMAIN:
        case JVMTI_HEAP_REFERENCE_INTERFACE:
        case JVMTI_HEAP_REFERENCE_STATIC_FIELD:
        case JVMTI_HEAP_REFERENCE_CONSTANT_POOL:
            return objectReference(reference_kind, reference_info,
                   class_tag, size, tag_ptr, referrer_tag_ptr, length);
            
        case JVMTI_HEAP_REFERENCE_JNI_GLOBAL: {
                SerialNumber trace_serial_num;
                SerialNumber gref_serial_num;
                TraceIndex   trace_index;
                SiteIndex    object_site_index;
                
                setup_tag_on_root(tag_ptr, class_tag, size,
                                  gdata->unknown_thread_serial_num,
                                  &object_index, &object_site_index);
                if ( object_site_index != 0 ) {
                    SiteKey     *pkey;
                    
                    pkey = get_pkey(object_site_index);
                    trace_index = pkey->trace_index;
                } else {
                    trace_index = gdata->system_trace_index;
                }
                trace_serial_num = trace_get_serial_number(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_REFERENCE_SYSTEM_CLASS: {
                char        *sig;
                SerialNumber class_serial_num;
                SiteIndex    object_site_index;
    
                setup_tag_on_root(tag_ptr, class_tag, size,
                                  gdata->unknown_thread_serial_num,
                                  &object_index, &object_site_index);
                sig = "Unknown";
                class_serial_num = 0;
                if ( object_site_index != 0 ) {
                    SiteKey *pkey;
                    
                    pkey = get_pkey(object_site_index);
                    sig = string_get(class_get_signature(pkey->cnum));
                    class_serial_num = class_get_serial_number(pkey->cnum);
                }
                io_heap_root_system_class(object_index, sig, class_serial_num);
            }
            break;
            
        case JVMTI_HEAP_REFERENCE_MONITOR:
            setup_tag_on_root(tag_ptr, class_tag, size, 
                              gdata->unknown_thread_serial_num,
                              &object_index, NULL);
            io_heap_root_monitor(object_index);
            break;
            
        case JVMTI_HEAP_REFERENCE_STACK_LOCAL:  {
                SerialNumber thread_serial_num;
                jlong        thread_tag;

                thread_tag = reference_info->stack_local.thread_tag;
                localReference(tag_ptr, class_tag, thread_tag, size,
                             &object_index, &thread_serial_num);
                io_heap_root_java_frame(object_index, thread_serial_num, 
                             reference_info->stack_local.depth);
            }
            break;

        case JVMTI_HEAP_REFERENCE_JNI_LOCAL: {
                SerialNumber thread_serial_num;
                jlong        thread_tag;

                thread_tag = reference_info->jni_local.thread_tag;
                localReference(tag_ptr, class_tag, thread_tag, size,
                             &object_index, &thread_serial_num);
                io_heap_root_jni_local(object_index, thread_serial_num, 
                             reference_info->jni_local.depth);
            }
            break;
            
        case JVMTI_HEAP_REFERENCE_THREAD: {
                SerialNumber thread_serial_num;
                SerialNumber trace_serial_num;
                TraceIndex   trace_index;
                SiteIndex    object_site_index;
                TlsIndex     tls_index;
        
                /* It is assumed that tag_ptr is referring to a 
                 *      java.lang.Thread object here.
                 */
                if ( (*tag_ptr) != (jlong)0 ) {
                    setup_tag_on_root(tag_ptr, class_tag, size, 0,
                                      &object_index, &object_site_index);
                    trace_index       = site_get_trace_index(object_site_index);
                    /* Hopefully the ThreadStart event put this thread's
                     *   correct serial number on it's object.
                     */
                    thread_serial_num = object_get_thread_serial_number(object_index);
                } else {
                    /* Rare situation that a Thread object is not tagged.
                     *   Create special unique thread serial number in this
                     *   case, probably means we never saw a thread start
                     *   or thread end, or even an allocation of the thread
                     *   object.
                     */
                    thread_serial_num = gdata->thread_serial_number_counter++;
                    setup_tag_on_root(tag_ptr, class_tag, size,
                                      thread_serial_num,
                                      &object_index, &object_site_index);
                    trace_index = gdata->system_trace_index;
                }
                /* Get tls_index and set in_heap_dump, if we find it. */
                tls_index = tls_find(thread_serial_num);
                if ( tls_index != 0 ) {
                    tls_set_in_heap_dump(tls_index, 1);
                }
                trace_serial_num = trace_get_serial_number(trace_index);
                /* Issue thread object (must be before thread root) */
                io_heap_root_thread_object(object_index,
                                 thread_serial_num, trace_serial_num);
                /* Issue thread root */
                io_heap_root_thread(object_index, thread_serial_num);
            }
            break;
            
        case JVMTI_HEAP_REFERENCE_OTHER:
            setup_tag_on_root(tag_ptr, class_tag, size,
                              gdata->unknown_thread_serial_num,
                              &object_index, NULL);
            io_heap_root_unknown(object_index);
            break;
       
       default:
            /* Ignore anything else */
            break;

    }
    
    return JVMTI_VISIT_OBJECTS;
}