+2010-04-27 Mark Probst <mark.probst@gmail.com>
+
+ * scripts/mono-heapviz: If the major sections are too small, use a
+ larger width.
+
2010-04-27 Zoltan Varga <vargaz@gmail.com>
* configure.in: Switch to eglib by default.
+2010-04-27 Mark Probst <mark.probst@gmail.com>
+
+ * sgen-gc.c, sgen-marksweep.c, sgen-major-copying.c: Support
+ heap-dump for mark&sweep.
+
2010-04-27 Zoltan Varga <vargaz@gmail.com>
* loader.c (mono_method_get_header): Move the is_inflated case before the
static long pinned_chunk_bytes_alloced = 0;
static long large_internal_bytes_alloced = 0;
+/* Keep in sync with internal_mem_names in dump_heap()! */
enum {
INTERNAL_MEM_PIN_QUEUE,
INTERNAL_MEM_FRAGMENT,
static void check_section_scan_starts (GCMemSection *section);
static void check_scan_starts (void);
static void check_for_xdomain_refs (void);
+static void dump_occupied (char *start, char *end, char *section_start);
static void dump_section (GCMemSection *section, const char *type);
static void dump_heap (const char *type, int num, const char *reason);
static void commit_stats (int generation);
} \
} while (0)
-//#include "sgen-major-copying.c"
-#include "sgen-marksweep.c"
+#include "sgen-major-copying.c"
+//#include "sgen-marksweep.c"
static gboolean
is_xdomain_ref_allowed (gpointer *ptr, char *obj, MonoDomain *domain)
static char const *internal_mem_names [] = { "pin-queue", "fragment", "section", "scan-starts",
"fin-table", "finalize-entry", "dislink-table",
"dislink", "roots-table", "root-record", "statistics",
- "remset", "gray-queue", "store-remset" };
+ "remset", "gray-queue", "store-remset", "marksweep-tables",
+ "marksweep-block-info" };
ObjectList *list;
LOSObject *bigobj;
dump_section (nursery_section, "nursery");
- major_dump_non_pinned_sections ();
+ major_dump_heap ();
fprintf (heap_dump_file, "<los>\n");
for (bigobj = los_object_list; bigobj; bigobj = bigobj->next)
}
static void
-major_dump_non_pinned_sections (void)
+major_dump_heap (void)
{
GCMemSection *section;
for (section = section_list; section; section = section->block.next)
dump_section (section, "old");
+ /* FIXME: dump pinned sections, too */
}
static gint64
#define major_check_scan_starts()
static void
-major_dump_non_pinned_sections (void)
+major_dump_heap (void)
{
- g_assert_not_reached ();
+ MSBlockInfo *block;
+
+ for (block = all_blocks; block; block = block->next) {
+ int count = MS_BLOCK_FREE / block->obj_size;
+ int i;
+ int start = -1;
+
+ fprintf (heap_dump_file, "<section type=\"%s\" size=\"%zu\">\n", "old", (size_t)MS_BLOCK_FREE);
+
+ for (i = 0; i <= count; ++i) {
+ if ((i < count) && MS_OBJ_ALLOCED (MS_BLOCK_OBJ (block, i), block)) {
+ if (start < 0)
+ start = i;
+ } else {
+ if (start >= 0) {
+ dump_occupied (MS_BLOCK_OBJ (block, start), MS_BLOCK_OBJ (block, i), block->block);
+ start = -1;
+ }
+ }
+ }
+
+ fprintf (heap_dump_file, "</section>\n");
+ }
}
#define MS_MARK_INDEX_IN_BLOCK_AND_ENQUEUE_CHECKED(obj,block,index) do { \
assert kind == 'old'
if self.width <= 0:
self.width = (size + chunk_size - 1) / chunk_size
- else:
- assert self.width == (size + chunk_size - 1) / chunk_size
+ if self.width < 128:
+ self.width = 512
+ self.current_section_size = size
+ else:
+ self.current_section_size = self.width * chunk_size
self.size += size
def add_object (self, klass, offset, size):
SectionHandler.add_occupied (self, self.offset + offset, size)
def end_section (self):
- self.offset += self.width * chunk_size
+ self.offset += self.current_section_size
def header (self):
return 'old sections'
class LargeSectionHandler (SectionHandler):
def __init__ (self):
- SectionHandler.__init__ (self, 500)
+ SectionHandler.__init__ (self, 512)
def start_section (self, kind, size):
self.kind = kind