Exemple #1
0
void
cpu_sample_term(JNIEnv *env)
{
    gdata->pause_cpu_sampling   = JNI_FALSE;
    rawMonitorEnter(gdata->cpu_sample_lock); {
        /* Notify the CPU sampling thread to get out of any sampling Wait */
        rawMonitorNotifyAll(gdata->cpu_sample_lock);
    } rawMonitorExit(gdata->cpu_sample_lock);
    rawMonitorEnter(gdata->cpu_loop_lock); {
        if ( gdata->cpu_loop_running ) {
            gdata->cpu_loop_running = JNI_FALSE;
            /* Wait for cpu_loop_function() thread to tell us it completed. */
            rawMonitorWait(gdata->cpu_loop_lock, 0);
        }
    } rawMonitorExit(gdata->cpu_loop_lock);
}
Exemple #2
0
void
cpu_sample_on(JNIEnv *env, ObjectIndex object_index)
{
    if ( gdata->cpu_loop_lock == NULL ) {
        cpu_sample_init(env);
    }

    if (object_index == 0) {
        gdata->cpu_sampling             = JNI_TRUE;
        gdata->pause_cpu_sampling       = JNI_FALSE;
    } else {
        jint     count;

        tls_set_sample_status(object_index, 1);
        count = tls_sum_sample_status();
        if ( count > 0 ) {
            gdata->pause_cpu_sampling   = JNI_FALSE;
        }
    }

    /* Notify the CPU sampling thread that sampling is on */
    rawMonitorEnter(gdata->cpu_sample_lock); {
        rawMonitorNotifyAll(gdata->cpu_sample_lock);
    } rawMonitorExit(gdata->cpu_sample_lock);

}
void
site_heapdump(JNIEnv *env)
{
   
    rawMonitorEnter(gdata->data_access_lock); {

        jvmtiHeapCallbacks heapCallbacks;
        
        /* Remove class dumped status, all classes must be dumped */
        class_all_status_remove(CLASS_DUMPED);

        /* Clear in_heap_dump flag */
        tls_clear_in_heap_dump();
        
        /* Dump the last thread traces and get the lists back we need */
        tls_dump_traces(env);
       
        /* Write header for heap dump */
        io_heap_header(gdata->total_live_instances, gdata->total_live_bytes);

        /* Setup a clean reference table */
        reference_init();
        
        /* Walk over all reachable objects and dump out roots */
        gdata->gref_serial_number_counter = gdata->gref_serial_number_start;

        /* Issue thread object for fake non-existent unknown thread
         *   just in case someone refers to it. Real threads are handled
         *   during iterate over reachable objects.
         */
        io_heap_root_thread_object(0, gdata->unknown_thread_serial_num, 
                        trace_get_serial_number(gdata->system_trace_index));

        /* Iterate over heap and get the real stuff */
        (void)memset(&heapCallbacks, 0, sizeof(heapCallbacks));

        /* Select callbacks */
        heapCallbacks.heap_reference_callback       = &cbReference;
        if ( gdata->primfields == JNI_TRUE ) {
            heapCallbacks.primitive_field_callback  = &cbPrimFieldData;
        }
        if ( gdata->primarrays == JNI_TRUE ) {
            heapCallbacks.array_primitive_value_callback  = &cbPrimArrayData;
        }
        followReferences(&heapCallbacks, (void*)NULL);

        /* Process reference information. */
        object_reference_dump(env);
        object_clear_references();
        reference_cleanup();

        /* Dump the last thread traces and get the lists back we need */
        tls_dump_traces(env);

        /* Write out footer for heap dump */
        io_heap_footer();
        
    } rawMonitorExit(gdata->data_access_lock);
}
Exemple #4
0
void
site_heapdump(JNIEnv *env)
{
   
    rawMonitorEnter(gdata->data_access_lock); {
	
	struct { int i; } user_data; /* FIXUP */

	user_data.i = 0;

	/* Remove class dumped status, all classes must be dumped */
	class_all_status_remove(CLASS_DUMPED);

	/* Clear in_heap_dump flag */
	tls_clear_in_heap_dump();

	/* Dump the last thread traces and get the lists back we need */
	tls_dump_traces(env);
       
	/* Write header for heap dump */
	io_heap_header(gdata->total_live_instances, gdata->total_live_bytes);

	/* Setup a clean reference table */
	reference_init();
	
	/* Walk over all reachable objects and dump out roots */
	gdata->gref_serial_number_counter = gdata->gref_serial_number_start;

	/* Issue thread object for fake non-existent unknown thread
	 *   just in case someone refers to it. Real threads are handled
	 *   during iterate over reachable objects.
	 */
	io_heap_root_thread_object(0, gdata->unknown_thread_serial_num, 
			trace_get_serial_number(gdata->system_trace_index));

	/* Iterate over heap and get the real stuff */
	iterateOverReachableObjects(&root_object, &stack_object, 
			&reference_object, (void*)&user_data);

	/* Process reference information. */
	object_reference_dump(env);
	object_clear_references();
        reference_cleanup();

	/* Dump the last thread traces and get the lists back we need */
	tls_dump_traces(env);

	/* Write out footer for heap dump */
	io_heap_footer();
	
    } rawMonitorExit(gdata->data_access_lock);
}
Exemple #5
0
void
cpu_sample_init(JNIEnv *env)
{
    gdata->cpu_sampling  = JNI_TRUE;

    /* Create the raw monitors needed */
    gdata->cpu_loop_lock = createRawMonitor("HPROF cpu loop lock");
    gdata->cpu_sample_lock = createRawMonitor("HPROF cpu sample lock");

    rawMonitorEnter(gdata->cpu_loop_lock); {
        createAgentThread(env, "HPROF cpu sampling thread",
                            &cpu_loop_function);
        /* Wait for cpu_loop_function() to notify us it has started. */
        rawMonitorWait(gdata->cpu_loop_lock, 0);
    } rawMonitorExit(gdata->cpu_loop_lock);
}
Exemple #6
0
void
site_heapdump(JNIEnv *env)
{
   
    rawMonitorEnter(gdata->data_access_lock); {
	
	struct { int i; } user_data; /* FIXUP */

	user_data.i = 0;
    
	/* Dump the last thread traces and get the lists back we need */
	tls_dump_traces(env);
       
	/* Write header for heap dump */
	io_heap_header(gdata->total_live_instances, gdata->total_live_bytes);

	/* Write out the thread roots first (threads that ended already did) */
	tls_output_heap_threads();

	/* Setup a clean reference table */
	reference_init();
	
	/* Walk over all reachable objects and dump out roots */
	gdata->gref_serial_number_counter = gdata->gref_serial_number_start;
	iterateOverReachableObjects(&root_object, &stack_object, &reference_object, (void*)&user_data);

	/* Process reference information. */
	object_reference_dump(env);
	object_clear_references();
        reference_cleanup();

	/* Dump the last thread traces and get the lists back we need */
	tls_dump_traces(env);

	/* Write out footer for heap dump */
	io_heap_footer();
	
    } rawMonitorExit(gdata->data_access_lock);
}
Exemple #7
0
void 
site_write(JNIEnv *env, int flags, double cutoff)
{
    HPROF_ASSERT(gdata->site_table!=NULL);
    LOG3("site_write", "flags", flags);
    
    if (flags & SITE_FORCE_GC) {
        runGC();
    }

    HPROF_ASSERT(gdata->total_live_bytes!=0);

    rawMonitorEnter(gdata->data_access_lock); {
        
        IterateInfo     iterate;
        int             site_table_size;
        double          accum_percent;
        void *          comment_str;
        int             i;
        int             cutoff_count;
	int             nbytes;

        accum_percent = 0;
        site_table_size = table_element_count(gdata->site_table);
        
        (void)memset(&iterate, 0, sizeof(iterate));
	nbytes            = site_table_size * (int)sizeof(SiteIndex);
	if ( nbytes > 0 ) {
	    iterate.site_nums = HPROF_MALLOC(nbytes);
	    (void)memset(iterate.site_nums, 0, nbytes);
	}
        iterate.count   = 0;
        iterate.changed_only = flags & SITE_DUMP_INCREMENTAL;
        table_walk_items(gdata->site_table, &collect_iterator, &iterate);

        site_table_size = iterate.count;
        
        if (flags & SITE_SORT_BY_ALLOC) {
            comment_str = "allocated bytes";
            qsort(iterate.site_nums, site_table_size, sizeof(SiteIndex), 
                    &qsort_compare_allocated_bytes);
        } else {
            comment_str = "live bytes";
            qsort(iterate.site_nums, site_table_size, sizeof(SiteIndex), 
                    &qsort_compare_live_bytes); 
        }

        trace_output_unmarked(env);
        
        cutoff_count = 0;
        for (i = 0; i < site_table_size; i++) {
            SiteInfo   *info;
            SiteIndex   index;
            double      ratio;
            
            index= iterate.site_nums[i];
            HPROF_ASSERT(index!=0);
            info        = get_info(index);
            ratio       = (double)info->n_live_bytes / (double)gdata->total_live_bytes;
            if (ratio < cutoff) {
                break;
            }
            cutoff_count++;
        }
        
        io_write_sites_header(  comment_str,
                                flags,
                                cutoff,
                                gdata->total_live_bytes,
                                gdata->total_live_instances,
                                gdata->total_alloced_bytes,
                                gdata->total_alloced_instances,
                                cutoff_count);
        
        for (i = 0; i < cutoff_count; i++) {
            SiteInfo     *info;
            SiteKey      *pkey;
            SiteIndex     index;
            char         *class_signature;
            double        ratio;
            
            index = iterate.site_nums[i];
            pkey         = get_pkey(index);
            info         = get_info(index);
            
            ratio       = (double)info->n_live_bytes / (double)gdata->total_live_bytes;
            accum_percent += ratio;
            
            class_signature  = string_get(class_get_signature(pkey->cnum));
            
            io_write_sites_elem(i + 1,
                                ratio,
                                accum_percent,
                                class_signature,
                                class_get_serial_number(pkey->cnum),
                                trace_get_serial_number(pkey->trace_index),
                                info->n_live_bytes,
                                info->n_live_instances,
                                info->n_alloced_bytes,
                                info->n_alloced_instances);
        }
        
        io_write_sites_footer();

        table_walk_items(gdata->site_table, &mark_unchanged_iterator, NULL);

	if ( iterate.site_nums != NULL ) {
	    HPROF_FREE(iterate.site_nums);
        }

    } rawMonitorExit(gdata->data_access_lock);
}
Exemple #8
0
static void JNICALL
cpu_loop_function(jvmtiEnv *jvmti, JNIEnv *env, void *p)
{
    int         loop_trip_counter;
    jboolean    cpu_loop_running;

    loop_trip_counter          = 0;

    rawMonitorEnter(gdata->cpu_loop_lock); {
        gdata->cpu_loop_running = JNI_TRUE;
        cpu_loop_running = gdata->cpu_loop_running;
        /* Notify cpu_sample_init() that we have started */
        rawMonitorNotifyAll(gdata->cpu_loop_lock);
    } rawMonitorExit(gdata->cpu_loop_lock);

    rawMonitorEnter(gdata->cpu_sample_lock); /* Only waits inside loop let go */

    while ( cpu_loop_running ) {

        ++loop_trip_counter;

        LOG3("cpu_loop()", "iteration", loop_trip_counter);

        /* If a dump is in progress, we pause sampling. */
        rawMonitorEnter(gdata->dump_lock); {
            if (gdata->dump_in_process) {
                gdata->pause_cpu_sampling = JNI_TRUE;
            }
        } rawMonitorExit(gdata->dump_lock);

        /* Check to see if we need to pause sampling (listener_loop command) */
        if (gdata->pause_cpu_sampling) {

            /*
             * Pause sampling for now. Reset sample controls if
             * sampling is resumed again.
             */

            rawMonitorWait(gdata->cpu_sample_lock, 0);

            rawMonitorEnter(gdata->cpu_loop_lock); {
                cpu_loop_running = gdata->cpu_loop_running;
            } rawMonitorExit(gdata->cpu_loop_lock);

            /* Continue the while loop, which will terminate if done. */
            continue;
        }

        /* This is the normal short timed wait before getting a sample */
        rawMonitorWait(gdata->cpu_sample_lock,  (jlong)gdata->sample_interval);

        /* Make sure we really want to continue */
        rawMonitorEnter(gdata->cpu_loop_lock); {
            cpu_loop_running = gdata->cpu_loop_running;
        } rawMonitorExit(gdata->cpu_loop_lock);

        /* Break out if we are done */
        if ( !cpu_loop_running ) {
            break;
        }

        /*
         * If a dump request came in after we checked at the top of
         * the while loop, then we catch that fact here. We
         * don't want to perturb the data that is being dumped so
         * we just ignore the data from this sampling loop.
         */
        rawMonitorEnter(gdata->dump_lock); {
            if (gdata->dump_in_process) {
                gdata->pause_cpu_sampling = JNI_TRUE;
            }
        } rawMonitorExit(gdata->dump_lock);

        /* Sample all the threads and update trace costs */
        if ( !gdata->pause_cpu_sampling) {
            tls_sample_all_threads(env);
        }

        /* Check to see if we need to finish */
        rawMonitorEnter(gdata->cpu_loop_lock); {
            cpu_loop_running = gdata->cpu_loop_running;
        } rawMonitorExit(gdata->cpu_loop_lock);

    }
    rawMonitorExit(gdata->cpu_sample_lock);

    rawMonitorEnter(gdata->cpu_loop_lock); {
        /* Notify cpu_sample_term() that we are done. */
        rawMonitorNotifyAll(gdata->cpu_loop_lock);
    } rawMonitorExit(gdata->cpu_loop_lock);

    LOG2("cpu_loop()", "clean termination");
}