diff options
author | Akira TAGOH <akira@tagoh.org> | 2006-06-04 16:42:00 +0000 |
---|---|---|
committer | Akira TAGOH <akira@tagoh.org> | 2006-06-04 16:42:00 +0000 |
commit | 69590a6a52d2c09cc17048dbac212c0d4399a3ec (patch) | |
tree | ce208909514415729c6c8c51da6c197ec8d166fb /src | |
parent | 58c209a709b4f4eb9ea7ec2484e16b9719289790 (diff) |
2006-06-05 Akira TAGOH <at@gclab.org>
* hieroglyph/hgmem.c (hg_mem_init_stack_start): new function.
(hg_mem_pool_add_heap): new function.
* hieroglyph/hgallocator-bfit.c (_hg_allocator_bfit_real_initialize):
use hg_mem_pool_add_heap instead of direct access.
(_hg_allocator_bfit_real_resize_pool): likewise.
* hieroglyph/hgmacros.h (HG_STACK_INIT): new macro.
(HG_MEM_INIT): new macro.
* src/visualizer.c (_heap2offset_new): new function.
(_heap2offset_free): new function.
(hg_memory_visualizer_set_max_size): store the max size for each pools.
(hg_memory_visualizer_get_max_size): similar change.
(hg_memory_visualizer_set_heap_state): new function.
(hg_memory_visualizer_set_chunk_state): implemented.
* src/hgspy.c (_hgspy_vm_thread): call HG_MEM_INIT here.
* src/hgspy_helper.c (hg_mem_pool_add_heap): new function.
Diffstat (limited to 'src')
-rwxr-xr-x | src/hgspy | 2 | ||||
-rw-r--r-- | src/hgspy.c | 21 | ||||
-rw-r--r-- | src/hgspy_helper.c | 32 | ||||
-rw-r--r-- | src/visualizer.c | 171 | ||||
-rw-r--r-- | src/visualizer.h | 12 |
5 files changed, 208 insertions, 30 deletions
@@ -2,4 +2,4 @@ topdir=`dirname $0` -LD_LIBRARY_PATH=$topdir/.libs:$LD_LIBRARY_PATH LD_PRELOAD=$topdir/.libs/libhgspy-helper.so gdb $topdir/.libs/hgspy-bin $@ +LD_LIBRARY_PATH=$topdir/.libs:$LD_LIBRARY_PATH LD_PRELOAD=$topdir/.libs/libhgspy-helper.so $topdir/.libs/hgspy-bin $@ diff --git a/src/hgspy.c b/src/hgspy.c index 48a200a..cab4ce4 100644 --- a/src/hgspy.c +++ b/src/hgspy.c @@ -26,6 +26,7 @@ #include <string.h> #include <glib/gi18n.h> #include <gtk/gtk.h> +#include <hieroglyph/hgmem.h> #include <libretto/vm.h> #include "visualizer.h" @@ -33,9 +34,11 @@ typedef struct _HieroGlyphSpy HgSpy; struct _HieroGlyphSpy { - GtkWidget *window; - GtkWidget *visualizer; - GThread *vm_thread; + GtkWidget *window; + GtkWidget *visualizer; + GThread *vm_thread; + LibrettoVM *vm; + gchar *file; }; static gpointer __hg_spy_helper_get_widget = NULL; @@ -46,12 +49,13 @@ static gpointer __hg_spy_helper_get_widget = NULL; static gpointer _hgspy_vm_thread(gpointer data) { - LibrettoVM *vm; + HG_MEM_INIT; - libretto_vm_init(); + HgSpy *spy = data; - vm = libretto_vm_new(LB_EMULATION_LEVEL_1); - libretto_vm_startjob(vm, (gchar *)data, TRUE); + libretto_vm_init(); + spy->vm = libretto_vm_new(LB_EMULATION_LEVEL_1); + libretto_vm_startjob(spy->vm, spy->file, TRUE); return NULL; } @@ -62,7 +66,8 @@ _hgspy_run_vm(HgSpy *spy, { if (spy->vm_thread != NULL) { } - g_thread_create(_hgspy_vm_thread, NULL, FALSE, NULL); + spy->file = g_strdup(file); + spy->vm_thread = g_thread_create(_hgspy_vm_thread, spy, FALSE, NULL); } static void diff --git a/src/hgspy_helper.c b/src/hgspy_helper.c index b42a4a5..70bf34e 100644 --- a/src/hgspy_helper.c +++ b/src/hgspy_helper.c @@ -27,10 +27,12 @@ #include <gmodule.h> #include <hieroglyph/hgtypes.h> #include <hieroglyph/hgmem.h> +#include "../hieroglyph/hgallocator-private.h" #include "hgspy_helper.h" #include "visualizer.h" +static gpointer __hg_mem_pool_add_heap = NULL; static gpointer __hg_mem_alloc_with_flags = NULL; static gpointer __hg_mem_free = NULL; static GModule *__handle = NULL; @@ -48,6 +50,10 @@ helper_init(void) g_warning("Failed g_module_open: %s", g_module_error()); exit(1); } + if (!g_module_symbol(__handle, "hg_mem_pool_add_heap", &__hg_mem_pool_add_heap)) { + g_warning("Failed g_module_symbol: %s", g_module_error()); + exit(1); + } if (!g_module_symbol(__handle, "hg_mem_alloc_with_flags", &__hg_mem_alloc_with_flags)) { g_warning("Failed g_module_symbol: %s", g_module_error()); exit(1); @@ -70,6 +76,16 @@ helper_finalize(void) /* * preload functions */ +void +hg_mem_pool_add_heap(HgMemPool *pool, + HgHeap *heap) +{ + ((void (*) (HgMemPool *, HgHeap *))__hg_mem_pool_add_heap) (pool, heap); + hg_memory_visualizer_set_heap_state(HG_MEMORY_VISUALIZER (visual), + hg_mem_pool_get_name(pool), + heap); +} + gpointer hg_mem_alloc_with_flags(HgMemPool *pool, gsize size, @@ -81,9 +97,13 @@ hg_mem_alloc_with_flags(HgMemPool *pool, hg_mem_get_object__inline(retval, obj); if (obj) { + gint heap_id = HG_MEMOBJ_GET_HEAP_ID (obj); + HgHeap *h = g_ptr_array_index(obj->pool->heap_list, heap_id); + hg_memory_visualizer_set_chunk_state(HG_MEMORY_VISUALIZER (visual), - HG_MEMOBJ_GET_HEAP_ID (obj), - obj, + hg_mem_pool_get_name(obj->pool), + heap_id, + (gsize)obj - (gsize)h->heaps, hg_mem_get_object_size(retval), HG_CHUNK_USED); } @@ -98,9 +118,13 @@ hg_mem_free(gpointer data) hg_mem_get_object__inline(data, obj); if (obj) { + gint heap_id = HG_MEMOBJ_GET_HEAP_ID (obj); + HgHeap *h = g_ptr_array_index(obj->pool->heap_list, heap_id); + hg_memory_visualizer_set_chunk_state(HG_MEMORY_VISUALIZER (visual), - HG_MEMOBJ_GET_HEAP_ID (obj), - obj, + hg_mem_pool_get_name(obj->pool), + heap_id, + (gsize)obj - (gsize)h->heaps, hg_mem_get_object_size(data), HG_CHUNK_FREE); } diff --git a/src/visualizer.c b/src/visualizer.c index d1c6b86..61d1185 100644 --- a/src/visualizer.c +++ b/src/visualizer.c @@ -24,7 +24,10 @@ #include "config.h" #endif #include <math.h> +#include <string.h> #include <glib/gi18n.h> +#include <hieroglyph/hgtypes.h> +#include "../hieroglyph/hgallocator-private.h" #include "visualizer.h" @@ -45,10 +48,22 @@ struct _HgMemoryVisualizer { GtkLayout parent_instance; /*< private >*/ - glong max_size; - gdouble block_size; + gdouble block_size; + GHashTable *pool2size; + GHashTable *pool2array; }; +struct Heap2Offset { + gsize *heap2offset; + gchar *bitmaps; + guint alloc; + gsize total_size; +}; + + +static struct Heap2Offset *_heap2offset_new (guint prealloc); +static void _heap2offset_free(gpointer data); + static GtkLayoutClass *parent_class = NULL; //static guint signals[LAST_SIGNAL] = { 0 }; @@ -64,11 +79,11 @@ hg_memory_visualizer_real_set_property(GObject *object, const GValue *value, GParamSpec *pspec) { - HgMemoryVisualizer *visual = HG_MEMORY_VISUALIZER (object); +// HgMemoryVisualizer *visual = HG_MEMORY_VISUALIZER (object); switch (prop_id) { case PROP_MAX_SIZE: - hg_memory_visualizer_set_max_size(visual, g_value_get_long(value)); +// hg_memory_visualizer_set_max_size(visual, g_value_get_long(value)); break; default: break; @@ -81,11 +96,11 @@ hg_memory_visualizer_real_get_property(GObject *object, GValue *value, GParamSpec *pspec) { - HgMemoryVisualizer *visual = HG_MEMORY_VISUALIZER (object); +// HgMemoryVisualizer *visual = HG_MEMORY_VISUALIZER (object); switch (prop_id) { case PROP_MAX_SIZE: - g_value_set_long(value, hg_memory_visualizer_get_max_size(visual)); +// g_value_set_long(value, hg_memory_visualizer_get_max_size(visual)); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); @@ -97,6 +112,16 @@ hg_memory_visualizer_real_get_property(GObject *object, static void hg_memory_visualizer_real_destroy(GtkObject *object) { + HgMemoryVisualizer *visual; + + g_return_if_fail (HG_IS_MEMORY_VISUALIZER (object)); + + visual = HG_MEMORY_VISUALIZER (object); + if (visual->pool2size) + g_hash_table_destroy(visual->pool2size); + if (visual->pool2array) + g_hash_table_destroy(visual->pool2array); + /* FIXME: not yet implemented */ (* GTK_OBJECT_CLASS (parent_class)->destroy) (object); @@ -259,7 +284,39 @@ hg_memory_visualizer_class_init(HgMemoryVisualizerClass *klass) static void hg_memory_visualizer_instance_init(HgMemoryVisualizer *visual) { - visual->max_size = 0; + visual->block_size = 0.0L; + visual->pool2size = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL); + visual->pool2array = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, _heap2offset_free); +} + +static struct Heap2Offset * +_heap2offset_new(guint prealloc) +{ + struct Heap2Offset *retval; + + g_return_val_if_fail (prealloc > 0, NULL); + + retval = g_new(struct Heap2Offset, 1); + if (retval != NULL) { + retval->heap2offset = g_new(gsize, prealloc); + retval->bitmaps = NULL; + retval->alloc = prealloc; + retval->total_size = 0; + } + + return retval; +} + +static void +_heap2offset_free(gpointer data) +{ + struct Heap2Offset *p = data; + + if (p->heap2offset) + g_free(p->heap2offset); + if (p->bitmaps) + g_free(p->bitmaps); + g_free(data); } /* @@ -299,15 +356,36 @@ hg_memory_visualizer_new(void) void hg_memory_visualizer_set_max_size(HgMemoryVisualizer *visual, - glong size) + const gchar *name, + gsize size) { - glong area; + gsize area; gdouble scale; + struct Heap2Offset *h2o; g_return_if_fail (HG_IS_MEMORY_VISUALIZER (visual)); + g_return_if_fail (name != NULL); area = visual->parent_instance.width * visual->parent_instance.height; - visual->max_size = size; + g_hash_table_insert(visual->pool2size, g_strdup(name), GSIZE_TO_POINTER (size)); + if ((h2o = g_hash_table_lookup(visual->pool2array, name)) == NULL) { + h2o = _heap2offset_new(256); + g_hash_table_insert(visual->pool2array, g_strdup(name), h2o); + } + if (h2o->bitmaps) { + if (size > h2o->total_size) { + gpointer p = g_realloc(h2o->bitmaps, sizeof (gchar) * ((size + 8) / 8)); + if (p == NULL) { + g_warning("Failed to allocate a memory for bitmaps."); + return; + } + h2o->bitmaps = p; + memset((void *)((gsize)h2o->bitmaps + h2o->total_size), 0, size - h2o->total_size); + } + } else { + h2o->bitmaps = g_new0(gchar, (size + 8) / 8); + } + h2o->total_size = size; if (area > size) { scale = area / size; visual->block_size = sqrt(scale); @@ -316,19 +394,84 @@ hg_memory_visualizer_set_max_size(HgMemoryVisualizer *visual, } } -glong -hg_memory_visualizer_get_max_size(HgMemoryVisualizer *visual) +gsize +hg_memory_visualizer_get_max_size(HgMemoryVisualizer *visual, + const gchar *name) { g_return_val_if_fail (HG_IS_MEMORY_VISUALIZER (visual), 0); + g_return_val_if_fail (name != NULL, 0); + + return GPOINTER_TO_SIZE (g_hash_table_lookup(visual->pool2size, name)); +} + +void +hg_memory_visualizer_set_heap_state(HgMemoryVisualizer *visual, + const gchar *name, + HgHeap *heap) +{ + gsize current_size; + struct Heap2Offset *h2o; - return visual->max_size; + g_return_if_fail (HG_IS_MEMORY_VISUALIZER (visual)); + g_return_if_fail (name != NULL); + g_return_if_fail (heap != NULL); + + if ((h2o = g_hash_table_lookup(visual->pool2array, name)) == NULL) { + h2o = _heap2offset_new(256); + g_hash_table_insert(visual->pool2array, g_strdup(name), h2o); + } + current_size = hg_memory_visualizer_get_max_size(visual, name); + if (heap->serial >= h2o->alloc) { + gpointer p = g_realloc(h2o->heap2offset, + sizeof (gsize) * (heap->serial + 256)); + + if (p == NULL) { + g_warning("Failed to allocate a memory for heap."); + return; + } + h2o->heap2offset = p; + h2o->alloc = heap->serial + 256; + } + h2o->heap2offset[heap->serial] = current_size; + hg_memory_visualizer_set_max_size(visual, name, current_size + heap->total_heap_size); } void hg_memory_visualizer_set_chunk_state(HgMemoryVisualizer *visual, + const gchar *name, gint heap_id, - gpointer addr, + gsize offset, gsize size, HgMemoryChunkState state) { + struct Heap2Offset *h2o; + gsize base, location, start, end, i; + gint bit; + + g_return_if_fail (HG_IS_MEMORY_VISUALIZER (visual)); + g_return_if_fail (name != NULL); + + h2o = g_hash_table_lookup(visual->pool2array, name); + if (h2o == NULL) { + g_warning("Unknown pool found (pool: %s)\n", name); + return; + } + base = h2o->heap2offset[heap_id]; + start = base + offset; + end = start + size; + for (i = start; i < end; i++) { + location = i / 8; + bit = 7 - (i % 8); + switch (state) { + case HG_CHUNK_FREE: + h2o->bitmaps[location] &= ~(1 << bit); + break; + case HG_CHUNK_USED: + h2o->bitmaps[location] |= (1 << bit); + break; + default: + break; + } + } + /* FIXME: update window */ } diff --git a/src/visualizer.h b/src/visualizer.h index 70bd5ab..912238e 100644 --- a/src/visualizer.h +++ b/src/visualizer.h @@ -49,11 +49,17 @@ enum _HgMemoryChunkState { GType hg_memory_visualizer_get_type (void) G_GNUC_CONST; GtkWidget *hg_memory_visualizer_new (void); void hg_memory_visualizer_set_max_size (HgMemoryVisualizer *visual, - glong size); -glong hg_memory_visualizer_get_max_size (HgMemoryVisualizer *visual); + const gchar *name, + gsize size); +gsize hg_memory_visualizer_get_max_size (HgMemoryVisualizer *visual, + const gchar *name); +void hg_memory_visualizer_set_heap_state (HgMemoryVisualizer *visual, + const gchar *name, + HgHeap *heap); void hg_memory_visualizer_set_chunk_state(HgMemoryVisualizer *visual, + const gchar *name, gint heap_id, - gpointer addr, + gsize offset, gsize size, HgMemoryChunkState state); |