diff options
author | Austin Seipp <aseipp@pobox.com> | 2013-05-12 22:07:11 -0500 |
---|---|---|
committer | Austin Seipp <aseipp@pobox.com> | 2013-05-12 22:07:11 -0500 |
commit | 089cb621441bd0753731b5e4cf906a204a6d2d79 (patch) | |
tree | 19c0572591d7c0f563ba8db4cc6e438122967943 | |
parent | 9d18aeab53a621d9c620dc6242c271fbbcdc645c (diff) | |
download | haskell-089cb621441bd0753731b5e4cf906a204a6d2d79.tar.gz |
Kill dead code.
Signed-off-by: Austin Seipp <aseipp@pobox.com>
-rw-r--r-- | rts/FrontPanel.c | 796 | ||||
-rw-r--r-- | rts/FrontPanel.h | 39 | ||||
-rw-r--r-- | rts/RtsFlags.c | 47 | ||||
-rw-r--r-- | rts/RtsStartup.c | 38 | ||||
-rw-r--r-- | rts/sm/GC.c | 187 |
5 files changed, 114 insertions, 993 deletions
diff --git a/rts/FrontPanel.c b/rts/FrontPanel.c deleted file mode 100644 index b0b9bced4a..0000000000 --- a/rts/FrontPanel.c +++ /dev/null @@ -1,796 +0,0 @@ -/* ----------------------------------------------------------------------------- - * - * (c) The GHC Team 2000 - * - * RTS GTK Front Panel - * - * ---------------------------------------------------------------------------*/ - -#ifdef RTS_GTK_FRONTPANEL - -/* Alas, not Posix. */ -/* #include "PosixSource.h" */ - -#include "Rts.h" - -#include "RtsUtils.h" -#include "FrontPanel.h" -#include "Stats.h" -#include "Schedule.h" - -#include <gtk/gtk.h> -#include <unistd.h> -#include <string.h> - -#include "VisSupport.h" -#include "VisWindow.h" - -static GtkWidget *window, *map_drawing_area, *gen_drawing_area; -static GtkWidget *res_drawing_area; -static GtkWidget *continue_but, *stop_but, *quit_but; -static GtkWidget *statusbar; -static GtkWidget *live_label, *allocated_label; -static GtkWidget *footprint_label, *alloc_rate_label; -static GtkWidget *map_ruler, *gen_ruler; -static GtkWidget *res_vruler, *res_hruler; -static GtkWidget *running_label, *b_read_label, *b_write_label, *total_label; -static GtkWidget *b_mvar_label, *b_bh_label, *b_throwto_label, *sleeping_label; - -static guint status_context_id; - -gboolean continue_now = FALSE, stop_now = FALSE, quit = FALSE; -UpdateMode update_mode = Continuous; - -static GdkPixmap *map_pixmap = NULL; -static GdkPixmap *gen_pixmap = NULL; -static GdkPixmap *res_pixmap = NULL; - -#define N_GENS 10 - -static GdkColor - bdescr_color = { 0, 0xffff, 0, 0 }, /* red */ - free_color = { 0, 0, 0, 0xffff }, /* blue */ - gen_colors[N_GENS] = { - { 0, 0, 0xffff, 0 }, - { 0, 0, 0xf000, 0 }, - { 0, 0, 0xe000, 0 }, - { 0, 0, 0xd000, 0 }, - { 0, 0, 0xc000, 0 }, - { 0, 0, 0xb000, 0 }, - { 0, 0, 0xa000, 0 }, - { 0, 0, 0x9000, 0 }, - { 0, 0, 0x8000, 0 }, - { 0, 0, 0x7000, 0 } - }; - -GdkGC *my_gc = NULL; - -static void *mem_start = (void *) 0x50000000; - -static void colorBlock( void *addr, GdkColor *color, - nat block_width, nat block_height, - nat blocks_per_line ); - -static void residencyCensus( void ); -static void updateResidencyGraph( void ); -static void updateThreadsPanel( void ); - -/* Some code pinched from examples/scribble-simple in the GTK+ - * distribution. - */ - -/* Create a new backing pixmap of the appropriate size */ -static gint -configure_event( GtkWidget *widget, GdkEventConfigure *event STG_UNUSED, - GdkPixmap **pixmap ) -{ - if (*pixmap) - gdk_pixmap_unref(*pixmap); - - *pixmap = gdk_pixmap_new(widget->window, - widget->allocation.width, - widget->allocation.height, - -1); - - gdk_draw_rectangle (*pixmap, - widget->style->white_gc, - TRUE, - 0, 0, - widget->allocation.width, - widget->allocation.height); - - debugBelch("configure!\n"); - updateFrontPanel(); - return TRUE; -} - -/* Redraw the screen from the backing pixmap */ -static gint -expose_event( GtkWidget *widget, GdkEventExpose *event, GdkPixmap **pixmap ) -{ - gdk_draw_pixmap(widget->window, - widget->style->fg_gc[GTK_WIDGET_STATE (widget)], - *pixmap, - event->area.x, event->area.y, - event->area.x, event->area.y, - event->area.width, event->area.height); - - return FALSE; -} - -void -initFrontPanel( void ) -{ - GdkColormap *colormap; - GtkWidget *gen_hbox; - - gtk_init( &prog_argc, &prog_argv ); - - window = create_GHC_Front_Panel(); - map_drawing_area = lookup_widget(window, "memmap"); - gen_drawing_area = lookup_widget(window, "generations"); - res_drawing_area = lookup_widget(window, "res_drawingarea"); - stop_but = lookup_widget(window, "stop_but"); - continue_but = lookup_widget(window, "continue_but"); - quit_but = lookup_widget(window, "quit_but"); - statusbar = lookup_widget(window, "statusbar"); - live_label = lookup_widget(window, "live_label"); - footprint_label = lookup_widget(window, "footprint_label"); - allocated_label = lookup_widget(window, "allocated_label"); - alloc_rate_label = lookup_widget(window, "alloc_rate_label"); - gen_hbox = lookup_widget(window, "gen_hbox"); - gen_ruler = lookup_widget(window, "gen_ruler"); - map_ruler = lookup_widget(window, "map_ruler"); - res_vruler = lookup_widget(window, "res_vruler"); - res_hruler = lookup_widget(window, "res_hruler"); - running_label = lookup_widget(window, "running_label"); - b_read_label = lookup_widget(window, "blockread_label"); - b_write_label = lookup_widget(window, "blockwrite_label"); - b_mvar_label = lookup_widget(window, "blockmvar_label"); - b_bh_label = lookup_widget(window, "blockbh_label"); - b_throwto_label = lookup_widget(window, "blockthrowto_label"); - sleeping_label = lookup_widget(window, "sleeping_label"); - total_label = lookup_widget(window, "total_label"); - - status_context_id = - gtk_statusbar_get_context_id( GTK_STATUSBAR(statusbar), "context" ); - - /* hook up some signals for the mem map drawing area */ - gtk_signal_connect (GTK_OBJECT(map_drawing_area), "expose_event", - (GtkSignalFunc)expose_event, &map_pixmap); - gtk_signal_connect (GTK_OBJECT(map_drawing_area), "configure_event", - (GtkSignalFunc)configure_event, &map_pixmap); - - gtk_widget_set_events(map_drawing_area, GDK_EXPOSURE_MASK); - - /* hook up some signals for the gen drawing area */ - gtk_signal_connect (GTK_OBJECT(gen_drawing_area), "expose_event", - (GtkSignalFunc)expose_event, &gen_pixmap); - gtk_signal_connect (GTK_OBJECT(gen_drawing_area), "configure_event", - (GtkSignalFunc)configure_event, &gen_pixmap); - - gtk_widget_set_events(gen_drawing_area, GDK_EXPOSURE_MASK); - - /* hook up some signals for the res drawing area */ - gtk_signal_connect (GTK_OBJECT(res_drawing_area), "expose_event", - (GtkSignalFunc)expose_event, &res_pixmap); - gtk_signal_connect (GTK_OBJECT(res_drawing_area), "configure_event", - (GtkSignalFunc)configure_event, &res_pixmap); - - gtk_widget_set_events(res_drawing_area, GDK_EXPOSURE_MASK); - - /* allocate our colors */ - colormap = gdk_colormap_get_system(); - gdk_colormap_alloc_color(colormap, &bdescr_color, TRUE, TRUE); - gdk_colormap_alloc_color(colormap, &free_color, TRUE, TRUE); - - { - gboolean success[N_GENS]; - gdk_colormap_alloc_colors(colormap, gen_colors, N_GENS, TRUE, - TRUE, success); - if (!success) { barf("can't allocate colors"); } - } - - /* set the labels on the generation histogram */ - { - char buf[64]; - nat g, s; - GtkWidget *label; - - for(g = 0; g < RtsFlags.GcFlags.generations; g++) { - for(s = 0; s < generations[g].n_steps; s++) { - g_snprintf( buf, 64, "%d.%d", g, s ); - label = gtk_label_new( buf ); - gtk_box_pack_start( GTK_BOX(gen_hbox), label, - TRUE, TRUE, 5 ); - gtk_widget_show(label); - } - } - } - - gtk_widget_show(window); - - /* wait for the user to press "Continue" before getting going... */ - gtk_statusbar_push( GTK_STATUSBAR(statusbar), status_context_id, - "Program start"); - gtk_widget_set_sensitive( stop_but, FALSE ); - continue_now = FALSE; - while (continue_now == FALSE) { - gtk_main_iteration(); - } - gtk_statusbar_pop( GTK_STATUSBAR(statusbar), status_context_id ); - gtk_statusbar_push( GTK_STATUSBAR(statusbar), status_context_id, - "Running"); - - gtk_widget_set_sensitive( continue_but, FALSE ); - gtk_widget_set_sensitive( stop_but, TRUE ); - gtk_widget_set_sensitive( quit_but, FALSE ); - - while (gtk_events_pending()) { - gtk_main_iteration(); - } -} - -void -stopFrontPanel( void ) -{ - gtk_widget_set_sensitive( quit_but, TRUE ); - gtk_widget_set_sensitive( continue_but, FALSE ); - gtk_widget_set_sensitive( stop_but, FALSE ); - - updateFrontPanel(); - - gtk_statusbar_push( GTK_STATUSBAR(statusbar), status_context_id, - "Program finished"); - - quit = FALSE; - while (quit == FALSE) { - gtk_main_iteration(); - } -} - -static void -waitForContinue( void ) -{ - gtk_widget_set_sensitive( continue_but, TRUE ); - gtk_widget_set_sensitive( stop_but, FALSE ); - stop_now = FALSE; - continue_now = FALSE; - while (continue_now == FALSE) { - gtk_main_iteration(); - } - gtk_widget_set_sensitive( continue_but, FALSE ); - gtk_widget_set_sensitive( stop_but, TRUE ); -} - -void -updateFrontPanelBeforeGC( nat N ) -{ - char buf[1000]; - - updateFrontPanel(); - - if (update_mode == BeforeGC - || update_mode == BeforeAfterGC - || stop_now == TRUE) { - g_snprintf( buf, 1000, "Stopped (before GC, generation %d)", N ); - gtk_statusbar_push( GTK_STATUSBAR(statusbar), status_context_id, buf ); - waitForContinue(); - gtk_statusbar_pop( GTK_STATUSBAR(statusbar), status_context_id ); - } - - g_snprintf( buf, 1000, "Garbage collecting (generation %d)", N ); - gtk_statusbar_push( GTK_STATUSBAR(statusbar), status_context_id, buf); - - while (gtk_events_pending()) { - gtk_main_iteration(); - } -} - -static void -numLabel( GtkWidget *lbl, nat n ) -{ - char buf[64]; - g_snprintf(buf, 64, "%d", n); - gtk_label_set_text( GTK_LABEL(lbl), buf ); -} - -void -updateFrontPanelAfterGC( nat N, W_ live ) -{ - char buf[1000]; - - gtk_statusbar_pop( GTK_STATUSBAR(statusbar), status_context_id ); - - /* is a major GC? */ - if (N == RtsFlags.GcFlags.generations-1) { - residencyCensus(); - } - - updateFrontPanel(); - - if (update_mode == AfterGC - || update_mode == BeforeAfterGC - || stop_now == TRUE) { - snprintf( buf, 1000, "Stopped (after GC, generation %d)", N ); - gtk_statusbar_push( GTK_STATUSBAR(statusbar), status_context_id, buf ); - waitForContinue(); - gtk_statusbar_pop( GTK_STATUSBAR(statusbar), status_context_id ); - } - - { - double words_to_megs = (1024 * 1024) / sizeof(W_); - double time = mut_user_time(); - - snprintf( buf, 1000, "%.2f", (double)live / words_to_megs ); - gtk_label_set_text( GTK_LABEL(live_label), buf ); - - snprintf( buf, 1000, "%.2f", (double)total_allocated / words_to_megs ); - gtk_label_set_text( GTK_LABEL(allocated_label), buf ); - - snprintf( buf, 1000, "%.2f", - (double)(mblocks_allocated * MBLOCK_SIZE_W) / words_to_megs ); - gtk_label_set_text( GTK_LABEL(footprint_label), buf ); - - if ( time == 0.0 ) - snprintf( buf, 1000, "%.2f", time ); - else - snprintf( buf, 1000, "%.2f", - (double)(total_allocated / words_to_megs) / time ); - gtk_label_set_text( GTK_LABEL(alloc_rate_label), buf ); - } - - while (gtk_events_pending()) { - gtk_main_iteration(); - } -} - -void -updateFrontPanel( void ) -{ - void *m, *a; - bdescr *bd; - - updateThreadsPanel(); - - if (my_gc == NULL) { - my_gc = gdk_gc_new( window->window ); - } - - if (map_pixmap != NULL) { - nat height, width, blocks_per_line, - block_height, block_width, mblock_height; - - height = map_drawing_area->allocation.height; - width = map_drawing_area->allocation.width; - - mblock_height = height / mblocks_allocated; - blocks_per_line = 16; - block_height = mblock_height / - ((MBLOCK_SIZE/BLOCK_SIZE) / blocks_per_line); - while (block_height == 0) { - blocks_per_line *= 2; - block_height = mblock_height / - ((MBLOCK_SIZE/BLOCK_SIZE) / blocks_per_line); - } - block_width = width / blocks_per_line; - - gdk_draw_rectangle (map_pixmap, - map_drawing_area->style->bg_gc[GTK_STATE_NORMAL], - TRUE, - 0, 0, - map_drawing_area->allocation.width, - map_drawing_area->allocation.height); - - for ( m = mem_start; - (char *)m < (char *)mem_start + - (mblocks_allocated * MBLOCK_SIZE); - (char *)m += MBLOCK_SIZE ) { - - /* color the bdescr area first */ - for (a = m; a < FIRST_BLOCK(m); (char *)a += BLOCK_SIZE) { - colorBlock( a, &bdescr_color, - block_width, block_height, blocks_per_line ); - } - -#if 0 /* Segfaults because bd appears to be bogus but != NULL. stolz, 2003-06-24 */ - /* color each block */ - for (; a <= LAST_BLOCK(m); (char *)a += BLOCK_SIZE) { - bd = Bdescr((P_)a); - ASSERT(bd->start == a); - if (bd->flags & BF_FREE) { - colorBlock( a, &free_color, - block_width, block_height, blocks_per_line ); - } else { - colorBlock( a, &gen_colors[bd->gen_no], - block_width, block_height, blocks_per_line ); - } - } -#endif - } - - - { - nat height = map_drawing_area->allocation.height, - block_height, mblock_height; - - block_height = (height / mblocks_allocated) / - ((MBLOCK_SIZE/BLOCK_SIZE) / blocks_per_line); - if (block_height < 1) block_height = 1; - mblock_height = block_height * - ((MBLOCK_SIZE/BLOCK_SIZE) / blocks_per_line); - - gtk_ruler_set_range( GTK_RULER(map_ruler), 0, - (double)(height * mblocks_allocated) / - (double)((mblock_height * mblocks_allocated)), - 0, - (double)(height * mblocks_allocated) / - (double)((mblock_height * mblocks_allocated)) - ); - } - - gtk_widget_draw( map_drawing_area, NULL ); - } - - if (gen_pixmap != NULL) { - - GdkRectangle rect; - nat g, s, columns, column, max_blocks, height_blocks, - width, height; - - gdk_draw_rectangle (gen_pixmap, - gen_drawing_area->style->white_gc, - TRUE, - 0, 0, - gen_drawing_area->allocation.width, - gen_drawing_area->allocation.height); - - height = gen_drawing_area->allocation.height; - width = gen_drawing_area->allocation.width; - - columns = 0; max_blocks = 0; - for(g = 0; g < RtsFlags.GcFlags.generations; g++) { - columns += generations[g].n_steps; - for(s = 0; s < generations[g].n_steps; s++) { - if (generations[g].steps[s].n_blocks > max_blocks) { - max_blocks = generations[g].steps[s].n_blocks; - } - } - } - - /* find a reasonable height value larger than max_blocks */ - { - nat n = 0; - while (max_blocks != 0) { - max_blocks >>= 1; n++; - } - height_blocks = 1 << n; - } - - column = 0; - for(g = 0; g < RtsFlags.GcFlags.generations; g++) { - for(s = 0; s < generations[g].n_steps; s++, column++) { - gdk_gc_set_foreground(my_gc, &gen_colors[g]); - - rect.x = column * (width / columns); - - if (generations[g].steps[s].n_blocks == 0) - rect.y = height; - else - rect.y = height - - (height * generations[g].steps[s].n_blocks - / height_blocks); - - rect.width = (width / columns); - rect.height = height - rect.y; - - gdk_draw_rectangle( gen_pixmap, my_gc, TRUE/*filled*/, - rect.x, rect.y, rect.width, - rect.height ); - } - } - - gtk_ruler_set_range( GTK_RULER(gen_ruler), - height_blocks * BLOCK_SIZE / (1024 * 1024), - 0, 0, - height_blocks * BLOCK_SIZE / (1024 * 1024) - ); - - gtk_widget_draw( gen_drawing_area, NULL ); - } - - if (res_pixmap != NULL) { - updateResidencyGraph(); - } - - while (gtk_events_pending()) { - gtk_main_iteration_do(FALSE/*don't block*/); - } -} - -static void -colorBlock( void *addr, GdkColor *color, - nat block_width, nat block_height, nat blocks_per_line ) -{ - GdkRectangle rect; - nat block_no; - - gdk_gc_set_foreground(my_gc, color); - - block_no = ((char *)addr - (char *)mem_start) / BLOCK_SIZE; - - rect.x = (block_no % blocks_per_line) * block_width; - rect.y = block_no / blocks_per_line * block_height; - rect.width = block_width; - rect.height = block_height; - gdk_draw_rectangle( map_pixmap, my_gc, TRUE/*filled*/, - rect.x, rect.y, rect.width, rect.height ); -} - -static void -updateThreadsPanel( void ) -{ - nat running = 0, - b_read = 0, - b_write = 0, - b_mvar = 0, - b_throwto = 0, - b_bh = 0, - sleeping = 0, - total = 0; - - StgTSO *t; - - for (t = all_threads; t != END_TSO_QUEUE; t = t->global_link) { - switch (t->what_next) { - case ThreadKilled: break; - case ThreadComplete: break; - default: - switch (t->why_blocked) { - case BlockedOnRead: b_read++; break; - case BlockedOnWrite: b_write++; break; - case BlockedOnDelay: sleeping++; break; - case BlockedOnMVar: b_mvar++; break; - case BlockedOnException: b_throwto++; break; - case BlockedOnBlackHole: b_bh++; break; - case NotBlocked: running++; break; - } - } - } - total = running + b_read + b_write + b_mvar + b_throwto + b_bh + sleeping; - numLabel(running_label, running); - numLabel(b_read_label, b_read); - numLabel(b_write_label, b_write); - numLabel(b_mvar_label, b_mvar); - numLabel(b_bh_label, b_bh); - numLabel(b_throwto_label, b_throwto); - numLabel(sleeping_label, sleeping); - numLabel(total_label, total); -} - -typedef enum { Thunk, Fun, Constr, BlackHole, - Array, Thread, Other, N_Cats } ClosureCategory; - -#define N_SLICES 100 - -static nat *res_prof[N_SLICES]; -static double res_time[N_SLICES]; -static nat next_slice = 0; - -static void -residencyCensus( void ) -{ - nat slice = next_slice++, *prof; - bdescr *bd; - nat g, s, size, type; - StgPtr p; - StgInfoTable *info; - - if (slice >= N_SLICES) { - barf("too many slices"); - } - res_prof[slice] = stgMallocBytes(N_Cats * sizeof(nat), "residencyCensus"); - prof = res_prof[slice]; - memset(prof, 0, N_Cats * sizeof(nat)); - - res_time[slice] = mut_user_time(); - - for(g = 0; g < RtsFlags.GcFlags.generations; g++) { - for(s = 0; s < generations[g].n_steps; s++) { - - /* skip over g0s0 if multi-generational */ - if (RtsFlags.GcFlags.generations > 1 && - g == 0 && s == 0) continue; - - if (RtsFlags.GcFlags.generations == 1) { -/* bd = generations[g].steps[s].to_blocks; FIXME to_blocks does not exist */ - } else { - bd = generations[g].steps[s].blocks; - } - - for (; bd != NULL; bd = bd->link) { - - p = bd->start; - - while (p < bd->free) { - info = get_itbl((StgClosure *)p); - type = Other; - - switch (info->type) { - - case CONSTR: - case BCO: - if (((StgClosure *)p)->header.info == &stg_DEAD_WEAK_info) { - size = sizeofW(StgWeak); - type = Other; - break; - } - /* else, fall through... */ - case CONSTR_1_0: - case CONSTR_0_1: - case CONSTR_1_1: - case CONSTR_0_2: - case CONSTR_2_0: - size = sizeW_fromITBL(info); - type = Constr; - break; - - case FUN_1_0: - case FUN_0_1: - size = sizeofW(StgHeader) + 1; - goto fun; - case FUN_1_1: - case FUN_0_2: - case FUN_2_0: - case FUN: - size = sizeW_fromITBL(info); - fun: - type = Fun; - break; - - case THUNK_1_0: - case THUNK_0_1: - case THUNK_SELECTOR: - size = sizeofW(StgHeader) + 2; - goto thunk; - case THUNK_1_1: - case THUNK_0_2: - case THUNK_2_0: - case THUNK: - size = sizeW_fromITBL(info); - thunk: - type = Thunk; - break; - - case BLACKHOLE: -/* case BLACKHOLE_BQ: FIXME: case does not exist */ - size = sizeW_fromITBL(info); - type = BlackHole; - break; - - case AP: - size = pap_sizeW((StgPAP *)p); - type = Thunk; - break; - - case PAP: - size = pap_sizeW((StgPAP *)p); - type = Fun; - break; - - case ARR_WORDS: - size = arr_words_sizeW(stgCast(StgArrWords*,p)); - type = Array; - break; - - case MUT_ARR_PTRS: - case MUT_ARR_PTRS_FROZEN: - size = mut_arr_ptrs_sizeW((StgMutArrPtrs *)p); - type = Array; - break; - - case TSO: - size = tso_sizeW((StgTSO *)p); - type = Thread; - break; - - case WEAK: - case PRIM: - case MVAR: - case MUT_VAR: -/* case MUT_CONS: FIXME: case does not exist */ - case IND_PERM: - size = sizeW_fromITBL(info); - type = Other; - break; - - default: - barf("updateResidencyGraph: strange closure " - "%d", info->type ); - } - - prof[type] += size; - p += size; - } - } - } - } - -} - -static void -updateResidencyGraph( void ) -{ - nat total, prev_total, i, max_res; - double time; - double time_scale = 1; - nat last_slice = next_slice-1; - double res_scale = 1; /* in megabytes, doubles */ - nat *prof; - nat width, height; - GdkPoint points[4]; - - gdk_draw_rectangle (res_pixmap, - res_drawing_area->style->bg_gc[GTK_STATE_NORMAL], - TRUE, - 0, 0, - res_drawing_area->allocation.width, - res_drawing_area->allocation.height); - - if (next_slice == 0) return; - - time = res_time[last_slice]; - while (time > time_scale) { - time_scale *= 2; - } - - max_res = 0; - for (i = 0; i < next_slice; i++) { - prof = res_prof[i]; - total = prof[Thunk] + prof[Fun] + prof[Constr] + - prof[BlackHole] + prof[Array] + prof[Other]; - if (total > max_res) { - max_res = total; - } - } - while (max_res > res_scale) { - res_scale *= 2; - } - - height = res_drawing_area->allocation.height; - width = res_drawing_area->allocation.width; - - points[0].x = 0; - points[0].y = height; - points[1].y = height; - points[3].x = 0; - points[3].y = height; - - gdk_gc_set_foreground(my_gc, &free_color); - - prev_total = 0; - for (i = 0; i < next_slice; i++) { - prof = res_prof[i]; - total = prof[Thunk] + prof[Fun] + prof[Constr] + - prof[BlackHole] + prof[Array] + prof[Other]; - points[1].x = width * res_time[i] / time_scale; - points[2].x = points[1].x; - points[2].y = height - ((height * total) / res_scale); - gdk_draw_polygon(res_pixmap, my_gc, TRUE/*filled*/, points, 4); - points[3] = points[2]; - points[0] = points[1]; - } - - gtk_ruler_set_range( GTK_RULER(res_vruler), - res_scale / ((1024*1024)/sizeof(W_)), - 0, 0, - res_scale / ((1024*1024)/sizeof(W_)) ); - - gtk_ruler_set_range( GTK_RULER(res_hruler), - 0, time_scale, 0, time_scale ); - - - gtk_widget_draw( res_drawing_area, NULL ); -} - -#endif /* RTS_GTK_FRONTPANEL */ diff --git a/rts/FrontPanel.h b/rts/FrontPanel.h deleted file mode 100644 index 84e40d5e1b..0000000000 --- a/rts/FrontPanel.h +++ /dev/null @@ -1,39 +0,0 @@ -/* ----------------------------------------------------------------------------- - * - * (c) The GHC Team 2000-2005 - * - * RTS GTK Front Panel - * - * ---------------------------------------------------------------------------*/ - -#ifndef FRONTPANEL_H -#define FRONTPANEL_H - -#include "BeginPrivate.h" - -#ifdef RTS_GTK_FRONTPANEL - -#include "Rts.h" /* needed because this file gets included by - * auto-generated code */ - -void initFrontPanel( void ); -void stopFrontPanel( void ); -void updateFrontPanelBeforeGC( nat N ); -void updateFrontPanelAfterGC( nat N, W_ live ); -void updateFrontPanel( void ); - - -/* --------- PRIVATE ----------------------------------------- */ - -#include <gdk/gdktypes.h> - -typedef enum { BeforeGC, AfterGC, BeforeAfterGC, Continuous } UpdateMode; -extern UpdateMode update_mode; -extern gboolean continue_now, stop_now, quit; - -#endif /* RTS_GTK_FRONTPANEL */ - -#include "EndPrivate.h" - -#endif /* FRONTPANEL_H */ - diff --git a/rts/RtsFlags.c b/rts/RtsFlags.c index 3f38c8ac1f..1e541a0201 100644 --- a/rts/RtsFlags.c +++ b/rts/RtsFlags.c @@ -52,7 +52,7 @@ wchar_t **win32_prog_argv = NULL; #endif /* - * constants, used later + * constants, used later */ #define RTS 1 #define PGM 0 @@ -111,9 +111,6 @@ void initRtsFlagsDefaults(void) RtsFlags.GcFlags.compact = rtsFalse; RtsFlags.GcFlags.compactThreshold = 30.0; RtsFlags.GcFlags.sweep = rtsFalse; -#ifdef RTS_GTK_FRONTPANEL - RtsFlags.GcFlags.frontpanel = rtsFalse; -#endif RtsFlags.GcFlags.idleGCDelayTime = USToTime(300000); // 300ms #ifdef THREADED_RTS RtsFlags.GcFlags.doIdleGC = rtsTrue; @@ -260,9 +257,6 @@ usage_text[] = { " -t[<file>] One-line GC statistics (if <file> omitted, uses stderr)", " -s[<file>] Summary GC statistics (if <file> omitted, uses stderr)", " -S[<file>] Detailed GC statistics (if <file> omitted, uses stderr)", -#ifdef RTS_GTK_FRONTPANEL -" -f Display front panel (requires X11 & GTK+)", -#endif "", "", " -Z Don't squeeze out update frames on stack overflow", @@ -292,7 +286,7 @@ usage_text[] = { " -hb<bio>... closures with specified biographies (lag,drag,void,use)", "", " -R<size> Set the maximum retainer set size (default: 8)", -"", +"", " -L<chars> Maximum length of a cost-centre stack in a heap profile", " (default: 25)", "", @@ -438,9 +432,9 @@ static void splitRtsFlags(const char *s) while (isspace(*c1)) { c1++; }; c2 = c1; while (!isspace(*c2) && *c2 != '\0') { c2++; }; - + if (c1 == c2) { break; } - + t = stgMallocBytes(c2-c1+1, "RtsFlags.c:splitRtsFlags()"); strncpy(t, c1, c2-c1); t[c2-c1] = '\0'; @@ -449,7 +443,7 @@ static void splitRtsFlags(const char *s) c1 = c2; } while (*c1 != '\0'); } - + /* ----------------------------------------------------------------------------- Parse the command line arguments, collecting options for the RTS. @@ -780,15 +774,15 @@ error = rtsTrue; case 'F': OPTION_UNSAFE; RtsFlags.GcFlags.oldGenFactor = atof(rts_argv[arg]+2); - + if (RtsFlags.GcFlags.oldGenFactor < 0) bad_option( rts_argv[arg] ); break; - + case 'D': OPTION_SAFE; DEBUG_BUILD_ONLY( - { + { char *c; for (c = rts_argv[arg] + 2; *c != '\0'; c++) { @@ -908,13 +902,6 @@ error = rtsTrue; } break; -#ifdef RTS_GTK_FRONTPANEL - case 'f': - OPTION_UNSAFE; - RtsFlags.GcFlags.frontpanel = rtsTrue; - break; -#endif - case 'I': /* idle GC delay */ OPTION_UNSAFE; if (rts_argv[arg][2] == '\0') { @@ -951,7 +938,7 @@ error = rtsTrue; goto stats; stats: - { + { int r; if (rts_argv[arg][2] != '\0') { OPTION_UNSAFE; @@ -1060,7 +1047,7 @@ error = rtsTrue; RtsFlags.ProfFlags.modSelector = left; break; case 'D': - case 'd': // closure descr select + case 'd': // closure descr select RtsFlags.ProfFlags.descrSelector = left; break; case 'Y': @@ -1114,12 +1101,12 @@ error = rtsTrue; break; } break; - + default: errorBelch("invalid heap profile option: %s",rts_argv[arg]); error = rtsTrue; } - ) + ) #endif /* PROFILING */ break; @@ -1266,7 +1253,7 @@ error = rtsTrue; RtsFlags.TickyFlags.showTickyStats = rtsTrue; - { + { int r; if (rts_argv[arg][2] != '\0') { OPTION_UNSAFE; @@ -1426,7 +1413,7 @@ static void normaliseRtsOpts (void) if (RtsFlags.ProfFlags.heapProfileInterval > 0) { RtsFlags.ProfFlags.heapProfileIntervalTicks = - RtsFlags.ProfFlags.heapProfileInterval / + RtsFlags.ProfFlags.heapProfileInterval / RtsFlags.MiscFlags.tickInterval; } else { RtsFlags.ProfFlags.heapProfileIntervalTicks = 0; @@ -1538,7 +1525,7 @@ decodeSize(const char *flag, nat offset, StgWord64 min, StgWord64 max) m = atof(s); c = s[strlen(s)-1]; - if (c == 'g' || c == 'G') + if (c == 'g' || c == 'G') m *= 1024*1024*1024; else if (c == 'm' || c == 'M') m *= 1024*1024; @@ -1801,7 +1788,7 @@ void setWin32ProgArgv(int argc, wchar_t *argv[]) { int i; - + freeWin32ProgArgv(); win32_prog_argc = argc; @@ -1809,7 +1796,7 @@ setWin32ProgArgv(int argc, wchar_t *argv[]) win32_prog_argv = NULL; return; } - + win32_prog_argv = stgCallocBytes(argc + 1, sizeof (wchar_t *), "setWin32ProgArgv 1"); for (i = 0; i < argc; i++) { diff --git a/rts/RtsStartup.c b/rts/RtsStartup.c index 7b7d488e2b..d8c2058526 100644 --- a/rts/RtsStartup.c +++ b/rts/RtsStartup.c @@ -38,10 +38,6 @@ #include "FileLock.h" void exitLinker( void ); // there is no Linker.h file to include -#if defined(RTS_GTK_FRONTPANEL) -#include "FrontPanel.h" -#endif - #if defined(PROFILING) # include "ProfHeap.h" # include "RetainerProfile.h" @@ -237,17 +233,11 @@ hs_init_ghc(int *argc, char **argv[], RtsConfig rts_config) initDefaultHandlers(); } #endif - + #if defined(mingw32_HOST_OS) && !defined(THREADED_RTS) startupAsyncIO(); #endif -#ifdef RTS_GTK_FRONTPANEL - if (RtsFlags.GcFlags.frontpanel) { - initFrontPanel(); - } -#endif - #if X86_INIT_FPU x86_init_fpu(); #endif @@ -293,7 +283,7 @@ hs_add_root(void (*init_root)(void) STG_UNUSED) * False ==> threads doing foreign calls may return in the * future, but will immediately block on a mutex. * (capability->lock). - * + * * If this RTS is a DLL that we're about to unload, then you want * safe=True, otherwise the thread might return to code that has been * unloaded. If this is a standalone program that is about to exit, @@ -317,7 +307,7 @@ hs_exit_(rtsBool wait_foreign) /* start timing the shutdown */ stat_startExit(); - + OnExitHook(); flushStdHandles(); @@ -336,7 +326,7 @@ hs_exit_(rtsBool wait_foreign) /* run C finalizers for all active weak pointers */ runAllCFinalizers(weak_ptr_list); - + #if defined(RTS_USER_SIGNALS) if (RtsFlags.MiscFlags.install_signal_handlers) { freeSignalHandlers(); @@ -348,7 +338,7 @@ hs_exit_(rtsBool wait_foreign) exitTimer(wait_foreign); // set the terminal settings back to what they were -#if !defined(mingw32_HOST_OS) +#if !defined(mingw32_HOST_OS) resetTerminalSettings(); #endif @@ -357,14 +347,14 @@ hs_exit_(rtsBool wait_foreign) /* stop timing the shutdown, we're about to print stats */ stat_endExit(); - + /* shutdown the hpc support (if needed) */ exitHpc(); // clean up things from the storage manager's point of view. // also outputs the stats (+RTS -s) info. exitStorage(); - + /* free the tasks */ freeScheduler(); @@ -385,13 +375,7 @@ hs_exit_(rtsBool wait_foreign) freeThreadLabelTable(); #endif -#ifdef RTS_GTK_FRONTPANEL - if (RtsFlags.GcFlags.frontpanel) { - stopFrontPanel(); - } -#endif - -#if defined(PROFILING) +#if defined(PROFILING) reportCCSProfiling(); #endif @@ -479,15 +463,15 @@ shutdownHaskellAndSignal(int sig) } #endif -/* +/* * called from STG-land to exit the program */ void (*exitFn)(int) = 0; -void +void stg_exit(int n) -{ +{ if (exitFn) (*exitFn)(n); exit(n); diff --git a/rts/sm/GC.c b/rts/sm/GC.c index dfebd55334..ddb538472f 100644 --- a/rts/sm/GC.c +++ b/rts/sm/GC.c @@ -6,7 +6,7 @@ * * Documentation on the architecture of the Garbage Collector can be * found in the online commentary: - * + * * http://hackage.haskell.org/trac/ghc/wiki/Commentary/Rts/Storage/GC * * ---------------------------------------------------------------------------*/ @@ -41,9 +41,6 @@ #include "Prelude.h" #include "RtsSignals.h" #include "STM.h" -#if defined(RTS_GTK_FRONTPANEL) -#include "FrontPanel.h" -#endif #include "Trace.h" #include "RetainerProfile.h" #include "LdvProfile.h" @@ -75,13 +72,13 @@ * linking objects on to the list. We use a stack-type list, consing * objects on the front as they are added (this means that the * scavenge phase is depth-first, not breadth-first, but that - * shouldn't matter). + * shouldn't matter). * * A separate list is kept for objects that have been scavenged * already - this is so that we can zero all the marks afterwards. * * An object is on the list if its static link field is non-zero; this - * means that we have to mark the end of the list with '1', not NULL. + * means that we have to mark the end of the list with '1', not NULL. * * Extra notes for generational GC: * @@ -103,7 +100,7 @@ rtsBool major_gc; /* Data used for allocation area sizing. */ -static W_ g0_pcnt_kept = 30; // percentage of g0 live at last minor GC +static W_ g0_pcnt_kept = 30; // percentage of g0 live at last minor GC /* Mut-list stats */ #ifdef DEBUG @@ -216,7 +213,7 @@ GarbageCollect (nat collect_gen, // this is the main thread SET_GCT(gc_threads[cap->no]); - // tell the stats department that we've started a GC + // tell the stats department that we've started a GC stat_startGC(cap, gct); // lock the StablePtr table @@ -235,7 +232,7 @@ GarbageCollect (nat collect_gen, mutlist_OTHERS = 0; #endif - // attribute any costs to CCS_GC + // attribute any costs to CCS_GC #ifdef PROFILING for (n = 0; n < n_capabilities; n++) { save_CCS[n] = capabilities[n].r.rCCCS; @@ -254,7 +251,7 @@ GarbageCollect (nat collect_gen, // It's not always a good idea to do load balancing in parallel // GC. In particular, for a parallel program we don't want to // lose locality by moving cached data into another CPU's cache - // (this effect can be quite significant). + // (this effect can be quite significant). // // We could have a more complex way to deterimine whether to do // work stealing or not, e.g. it might be a good idea to do it @@ -283,14 +280,8 @@ GarbageCollect (nat collect_gen, debugTrace(DEBUG_gc, "GC (gen %d, using %d thread(s))", N, n_gc_threads); -#ifdef RTS_GTK_FRONTPANEL - if (RtsFlags.GcFlags.frontpanel) { - updateFrontPanelBeforeGC(N); - } -#endif - #ifdef DEBUG - // check for memory leaks if DEBUG is on + // check for memory leaks if DEBUG is on memInventory(DEBUG_gc); #endif @@ -401,10 +392,10 @@ GarbageCollect (nat collect_gen, scavenge_until_all_done(); // The other threads are now stopped. We might recurse back to // here, but from now on this is the only thread. - + // must be last... invariant is that everything is fully // scavenged at this point. - if (traverseWeakPtrList()) { // returns rtsTrue if evaced something + if (traverseWeakPtrList()) { // returns rtsTrue if evaced something inc_running(); continue; } @@ -451,7 +442,7 @@ GarbageCollect (nat collect_gen, // Finally: compact or sweep the oldest generation. if (major_gc && oldest_gen->mark) { - if (oldest_gen->compact) + if (oldest_gen->compact) compact(gct->scavenged_static_objects); else sweep(oldest_gen); @@ -460,7 +451,7 @@ GarbageCollect (nat collect_gen, copied = 0; par_max_copied = 0; par_tot_copied = 0; - { + { nat i; for (i=0; i < n_gc_threads; i++) { if (n_gc_threads > 1) { @@ -494,7 +485,7 @@ GarbageCollect (nat collect_gen, for (g = 0; g < RtsFlags.GcFlags.generations; g++) { if (g == N) { - generations[g].collections++; // for stats + generations[g].collections++; // for stats if (n_gc_threads > 1) generations[g].par_collections++; } @@ -521,7 +512,7 @@ GarbageCollect (nat collect_gen, bdescr *next, *prev; gen = &generations[g]; - // for generations we collected... + // for generations we collected... if (g <= N) { /* free old memory and shift to-space into from-space for all @@ -532,12 +523,12 @@ GarbageCollect (nat collect_gen, { // tack the new blocks on the end of the existing blocks if (gen->old_blocks != NULL) { - + prev = NULL; for (bd = gen->old_blocks; bd != NULL; bd = next) { - + next = bd->link; - + if (!(bd->flags & BF_MARKED)) { if (prev == NULL) { @@ -551,17 +542,17 @@ GarbageCollect (nat collect_gen, else { gen->n_words += bd->free - bd->start; - + // NB. this step might not be compacted next // time, so reset the BF_MARKED flags. // They are set before GC if we're going to // compact. (search for BF_MARKED above). bd->flags &= ~BF_MARKED; - + // between GCs, all blocks in the heap except // for the nursery have the BF_EVACUATED flag set. bd->flags |= BF_EVACUATED; - + prev = bd; } } @@ -606,8 +597,8 @@ GarbageCollect (nat collect_gen, dbl_link_onto(bd, &gen->large_objects); gen->n_large_words += bd->free - bd->start; } - - // add the new blocks we promoted during this GC + + // add the new blocks we promoted during this GC gen->n_large_blocks += gen->n_scavenged_large_blocks; } @@ -634,7 +625,7 @@ GarbageCollect (nat collect_gen, // update the max size of older generations after a major GC resize_generations(); - + // Free the mark stack. if (mark_stack_top_bd != NULL) { debugTrace(DEBUG_gc, "mark stack: %d blocks", @@ -671,10 +662,10 @@ GarbageCollect (nat collect_gen, resetNurseries(); // mark the garbage collected CAFs as dead -#if 0 && defined(DEBUG) // doesn't work at the moment +#if 0 && defined(DEBUG) // doesn't work at the moment if (major_gc) { gcCAFs(); } #endif - + #ifdef PROFILING // resetStaticObjectForRetainerProfiling() must be called before // zeroing below. @@ -683,7 +674,7 @@ GarbageCollect (nat collect_gen, resetStaticObjectForRetainerProfiling(gct->scavenged_static_objects); #endif - // zero the scavenged static object list + // zero the scavenged static object list if (major_gc) { nat i; if (n_gc_threads == 1) { @@ -750,11 +741,11 @@ GarbageCollect (nat collect_gen, IF_DEBUG(gc, statDescribeGens()); #ifdef DEBUG - // symbol-table based profiling + // symbol-table based profiling /* heapCensus(to_blocks); */ /* ToDo */ #endif - // restore enclosing cost centre + // restore enclosing cost centre #ifdef PROFILING for (n = 0; n < n_capabilities; n++) { capabilities[n].r.rCCCS = save_CCS[n]; @@ -762,17 +753,11 @@ GarbageCollect (nat collect_gen, #endif #ifdef DEBUG - // check for memory leaks if DEBUG is on + // check for memory leaks if DEBUG is on memInventory(DEBUG_gc); #endif -#ifdef RTS_GTK_FRONTPANEL - if (RtsFlags.GcFlags.frontpanel) { - updateFrontPanelAfterGC( N, live ); - } -#endif - - // ok, GC over: tell the stats department what happened. + // ok, GC over: tell the stats department what happened. stat_endGC(cap, gct, live_words, copied, live_blocks * BLOCK_SIZE_W - live_words /* slop */, N, n_gc_threads, par_max_copied, par_tot_copied); @@ -821,7 +806,7 @@ new_gc_thread (nat n, gc_thread *t) t->gc_count = 0; init_gc_thread(t); - + #ifdef USE_PAPI t->papi_events = -1; #endif @@ -832,7 +817,7 @@ new_gc_thread (nat n, gc_thread *t) ws->gen = &generations[g]; ASSERT(g == ws->gen->no); ws->my_gct = t; - + // We want to call // alloc_todo_block(ws,0); // but can't, because it uses gct which isn't set up at this point. @@ -960,7 +945,7 @@ any_work (void) if (mark_stack_bd != NULL && !mark_stack_empty()) { return rtsTrue; } - + // Check for global work in any step. We don't need to check for // local work, because we have already exited scavenge_loop(), // which means there is no local work for this thread. @@ -991,13 +976,13 @@ any_work (void) #endif return rtsFalse; -} +} static void scavenge_until_all_done (void) { DEBUG_ONLY( nat r ); - + loop: #if defined(THREADED_RTS) @@ -1023,7 +1008,7 @@ loop: traceEventGcIdle(gct->cap); debugTrace(DEBUG_gc, "%d GC threads still running", r); - + while (gc_running_threads != 0) { // usleep(1); if (any_work()) { @@ -1033,10 +1018,10 @@ loop: } // any_work() does not remove the work from the queue, it // just checks for the presence of work. If we find any, - // then we increment gc_running_threads and go back to + // then we increment gc_running_threads and go back to // scavenge_loop() to perform any pending work. } - + traceEventGcDone(gct->cap); } @@ -1065,7 +1050,7 @@ gcWorkerThread (Capability *cap) gct->wakeup = GC_THREAD_STANDING_BY; debugTrace(DEBUG_gc, "GC thread %d standing by...", gct->thread_index); ACQUIRE_SPIN_LOCK(&gct->gc_spin); - + #ifdef USE_PAPI // start performance counters in this thread... if (gct->papi_events == -1) { @@ -1084,7 +1069,7 @@ gcWorkerThread (Capability *cap) scavenge_capability_mut_lists(cap); scavenge_until_all_done(); - + if (!DEBUG_IS_ON) { clearNursery(cap); } @@ -1107,7 +1092,7 @@ gcWorkerThread (Capability *cap) // Wait until we're told to continue RELEASE_SPIN_LOCK(&gct->gc_spin); gct->wakeup = GC_THREAD_WAITING_TO_CONTINUE; - debugTrace(DEBUG_gc, "GC thread %d waiting to continue...", + debugTrace(DEBUG_gc, "GC thread %d waiting to continue...", gct->thread_index); ACQUIRE_SPIN_LOCK(&gct->mut_spin); debugTrace(DEBUG_gc, "GC thread %d on my way...", gct->thread_index); @@ -1213,7 +1198,7 @@ releaseGCThreads (Capability *cap USED_IF_THREADS) if (i == me || gc_threads[i]->idle) continue; if (gc_threads[i]->wakeup != GC_THREAD_WAITING_TO_CONTINUE) barf("releaseGCThreads"); - + gc_threads[i]->wakeup = GC_THREAD_INACTIVE; ACQUIRE_SPIN_LOCK(&gc_threads[i]->gc_spin); RELEASE_SPIN_LOCK(&gc_threads[i]->mut_spin); @@ -1222,7 +1207,7 @@ releaseGCThreads (Capability *cap USED_IF_THREADS) #endif /* ---------------------------------------------------------------------------- - Initialise a generation that is to be collected + Initialise a generation that is to be collected ------------------------------------------------------------------------- */ static void @@ -1293,7 +1278,7 @@ prepare_collected_gen (generation *gen) for (bd = gen->old_blocks; bd; bd = bd->link) { bd->flags &= ~BF_EVACUATED; } - + // mark the large objects as from-space for (bd = gen->large_objects; bd; bd = bd->link) { bd->flags &= ~BF_EVACUATED; @@ -1304,7 +1289,7 @@ prepare_collected_gen (generation *gen) StgWord bitmap_size; // in bytes bdescr *bitmap_bdescr; StgWord *bitmap; - + bitmap_size = gen->n_old_blocks * BLOCK_SIZE / (sizeof(W_)*BITS_PER_BYTE); if (bitmap_size > 0) { @@ -1312,19 +1297,19 @@ prepare_collected_gen (generation *gen) / BLOCK_SIZE); gen->bitmap = bitmap_bdescr; bitmap = bitmap_bdescr->start; - + debugTrace(DEBUG_gc, "bitmap_size: %d, bitmap: %p", bitmap_size, bitmap); - + // don't forget to fill it with zeros! memset(bitmap, 0, bitmap_size); - + // For each block in this step, point to its bitmap from the // block descriptor. for (bd=gen->old_blocks; bd != NULL; bd = bd->link) { bd->u.bitmap = bitmap; bitmap += BLOCK_SIZE_W / (sizeof(W_)*BITS_PER_BYTE); - + // Also at this point we set the BF_MARKED flag // for this block. The invariant is that // BF_MARKED is always unset, except during GC @@ -1355,7 +1340,7 @@ stash_mut_list (Capability *cap, nat gen_no) } /* ---------------------------------------------------------------------------- - Initialise a generation that is *not* to be collected + Initialise a generation that is *not* to be collected ------------------------------------------------------------------------- */ static void @@ -1388,10 +1373,10 @@ collect_gct_blocks (void) nat g; gen_workspace *ws; bdescr *bd, *prev; - + for (g = 0; g < RtsFlags.GcFlags.generations; g++) { ws = &gct->gens[g]; - + // there may still be a block attached to ws->todo_bd; // leave it there to use next time. @@ -1400,7 +1385,7 @@ collect_gct_blocks (void) ASSERT(gct->scan_bd == NULL); ASSERT(countBlocks(ws->scavd_list) == ws->n_scavd_blocks); - + prev = NULL; for (bd = ws->scavd_list; bd != NULL; bd = bd->link) { ws->gen->n_words += bd->free - bd->start; @@ -1409,7 +1394,7 @@ collect_gct_blocks (void) if (prev != NULL) { prev->link = ws->gen->blocks; ws->gen->blocks = ws->scavd_list; - } + } ws->gen->n_blocks += ws->n_scavd_blocks; ws->scavd_list = NULL; @@ -1492,9 +1477,9 @@ mark_root(void *user USED_IF_THREADS, StgClosure **root) saved_gct = gct; #endif SET_GCT(user); - + evacuate(root); - + SET_GCT(saved_gct); } @@ -1519,7 +1504,7 @@ zero_static_object_list(StgClosure* first_static) /* ---------------------------------------------------------------------------- Reset the sizes of the older generations when we do a major collection. - + CURRENT STRATEGY: make all generations except zero the same size. We have to stay within the maximum heap size, and leave a certain percentage of the maximum heap size available to allocate into. @@ -1534,7 +1519,7 @@ resize_generations (void) W_ live, size, min_alloc, words; const W_ max = RtsFlags.GcFlags.maxHeapSize; const W_ gens = RtsFlags.GcFlags.generations; - + // live in the oldest generations if (oldest_gen->live_estimate != 0) { words = oldest_gen->live_estimate; @@ -1543,11 +1528,11 @@ resize_generations (void) } live = (words + BLOCK_SIZE_W - 1) / BLOCK_SIZE_W + oldest_gen->n_large_blocks; - + // default max size for all generations except zero size = stg_max(live * RtsFlags.GcFlags.oldGenFactor, RtsFlags.GcFlags.minOldGenSize); - + if (RtsFlags.GcFlags.heapSizeSuggestionAuto) { if (max > 0) { RtsFlags.GcFlags.heapSizeSuggestion = stg_min(max, size); @@ -1564,7 +1549,7 @@ resize_generations (void) // certain percentage of the maximum heap size (default: 30%). if (RtsFlags.GcFlags.compact || (max > 0 && - oldest_gen->n_blocks > + oldest_gen->n_blocks > (RtsFlags.GcFlags.compactThreshold * max) / 100)) { oldest_gen->mark = 1; oldest_gen->compact = 1; @@ -1584,14 +1569,14 @@ resize_generations (void) // different if compaction is turned on, because we don't need // to double the space required to collect the old generation. if (max != 0) { - + // this test is necessary to ensure that the calculations // below don't have any negative results - we're working // with unsigned values here. if (max < min_alloc) { heapOverflow(); } - + if (oldest_gen->compact) { if ( (size + (size - 1) * (gens - 2) * 2) + min_alloc > max ) { size = (max - min_alloc) / ((gens - 1) * 2 - 1); @@ -1601,17 +1586,17 @@ resize_generations (void) size = (max - min_alloc) / ((gens - 1) * 2); } } - + if (size < live) { heapOverflow(); } } - + #if 0 debugBelch("live: %d, min_alloc: %d, size : %d, max = %d\n", live, min_alloc, size, max); #endif - + for (g = 0; g < gens; g++) { generations[g].max_blocks = size; } @@ -1630,7 +1615,7 @@ resize_nursery (void) if (RtsFlags.GcFlags.generations == 1) { // Two-space collector: W_ blocks; - + /* set up a new nursery. Allocate a nursery size based on a * function of the amount of live data (by default a factor of 2) * Use the blocks from the old nursery if possible, freeing up any @@ -1640,25 +1625,25 @@ resize_nursery (void) * size accordingly. If the nursery is the same size as the live * data (L), then we need 3L bytes. We can reduce the size of the * nursery to bring the required memory down near 2L bytes. - * + * * A normal 2-space collector would need 4L bytes to give the same * performance we get from 3L bytes, reducing to the same * performance at 2L bytes. */ blocks = generations[0].n_blocks; - + if ( RtsFlags.GcFlags.maxHeapSize != 0 && - blocks * RtsFlags.GcFlags.oldGenFactor * 2 > + blocks * RtsFlags.GcFlags.oldGenFactor * 2 > RtsFlags.GcFlags.maxHeapSize ) { - long adjusted_blocks; // signed on purpose - int pc_free; - + long adjusted_blocks; // signed on purpose + int pc_free; + adjusted_blocks = (RtsFlags.GcFlags.maxHeapSize - 2 * blocks); - - debugTrace(DEBUG_gc, "near maximum heap size of 0x%x blocks, blocks = %d, adjusted to %ld", + + debugTrace(DEBUG_gc, "near maximum heap size of 0x%x blocks, blocks = %d, adjusted to %ld", RtsFlags.GcFlags.maxHeapSize, blocks, adjusted_blocks); - + pc_free = adjusted_blocks * 100 / RtsFlags.GcFlags.maxHeapSize; if (pc_free < RtsFlags.GcFlags.pcFreeHeap) /* might even * be < 0 */ { @@ -1678,7 +1663,7 @@ resize_nursery (void) } else // Generational collector { - /* + /* * If the user has given us a suggested heap size, adjust our * allocation area to make best use of the memory available. */ @@ -1688,7 +1673,7 @@ resize_nursery (void) StgWord needed; calcNeeded(rtsFalse, &needed); // approx blocks needed at next GC - + /* Guess how much will be live in generation 0 step 0 next time. * A good approximation is obtained by finding the * percentage of g0 that was live at the last minor GC. @@ -1703,7 +1688,7 @@ resize_nursery (void) g0_pcnt_kept = ((copied / (BLOCK_SIZE_W - 10)) * 100) / countNurseryBlocks(); } - + /* Estimate a size for the allocation area based on the * information available. We might end up going slightly under * or over the suggested heap size, but we should be pretty @@ -1716,14 +1701,14 @@ resize_nursery (void) * where 'needed' is the amount of memory needed at the next * collection for collecting all gens except g0. */ - blocks = + blocks = (((long)RtsFlags.GcFlags.heapSizeSuggestion - (long)needed) * 100) / (100 + (long)g0_pcnt_kept); - + if (blocks < (long)min_nursery) { blocks = min_nursery; } - + resizeNurseries((W_)blocks); } else @@ -1744,7 +1729,7 @@ resize_nursery (void) whenever the program tries to enter a garbage collected CAF. Any garbage collected CAFs are taken off the CAF list at the same - time. + time. -------------------------------------------------------------------------- */ #if 0 && defined(DEBUG) @@ -1762,14 +1747,14 @@ gcCAFs(void) pp = &caf_list; while (p != NULL) { - + info = get_itbl(p); ASSERT(info->type == IND_STATIC); if (STATIC_LINK(info,p) == NULL) { debugTrace(DEBUG_gccafs, "CAF gc'd at 0x%04lx", (long)p); - // black hole it + // black hole it SET_INFO(p,&stg_BLACKHOLE_info); p = STATIC_LINK2(info,p); *pp = p; @@ -1782,6 +1767,6 @@ gcCAFs(void) } - debugTrace(DEBUG_gccafs, "%d CAFs live", i); + debugTrace(DEBUG_gccafs, "%d CAFs live", i); } #endif |