Author: yamakenz
Date: Mon Aug 6 08:58:59 2007
New Revision: 4793
Modified:
sigscheme-trunk/src/storage-gc.c
Log:
* src/storage-gc.c
- (SCM_BEGIN_GC_SUBCONTEXT, SCM_END_GC_SUBCONTEXT): New macro
- (l_gcing, l_allocating): New static variables
- (scm_ensure_proper_freelist): New static function
- (scm_init_gc): Add initialization for the variables
- (scm_alloc_cell, add_heap, gc_mark_and_sweep, gc_mark_protected_var,
gc_mark_locations_n, gc_mark_definite_locations_n, gc_mark_locations,
gc_mark, gc_mark_global_vars, gc_sweep): Add assertions for proper cell
allocation
Modified: sigscheme-trunk/src/storage-gc.c
==============================================================================
--- sigscheme-trunk/src/storage-gc.c (original)
+++ sigscheme-trunk/src/storage-gc.c Mon Aug 6 08:58:59 2007
@@ -68,6 +68,15 @@
File Local Macro Definitions
=======================================*/
#define SCMOBJ_ALIGNEDP(ptr) (!((uintptr_t)(ptr) % sizeof(ScmObj)))
+#if SCM_DEBUG
+#define SCM_BEGIN_GC_SUBCONTEXT() (scm_ensure_proper_freelist(l_freelist), \
+ ++l_gcing)
+#define SCM_END_GC_SUBCONTEXT() (scm_ensure_proper_freelist(l_freelist), \
+ --l_gcing)
+#else /* not SCM_DEBUG */
+#define SCM_BEGIN_GC_SUBCONTEXT() SCM_EMPTY_EXPR
+#define SCM_END_GC_SUBCONTEXT() SCM_EMPTY_EXPR
+#endif /* not SCM_DEBUG */
/*=======================================
File Local Type Definitions
@@ -93,6 +102,10 @@
static ScmObj **l_protected_vars;
static size_t l_protected_vars_size, l_n_empty_protected_vars;
static GCROOTS_context *l_gcroots_ctx;
+#if SCM_DEBUG
+static size_t l_gcing;
+static scm_bool l_allocating;
+#endif /* SCM_DEBUG */
#undef static
SCM_GLOBAL_VARS_END(static_gc);
#define l_heap_size SCM_GLOBAL_VAR(static_gc, l_heap_size)
@@ -108,6 +121,10 @@
#define l_n_empty_protected_vars \
SCM_GLOBAL_VAR(static_gc, l_n_empty_protected_vars)
#define l_gcroots_ctx SCM_GLOBAL_VAR(static_gc, l_gcroots_ctx)
+#if SCM_DEBUG
+#define l_gcing SCM_GLOBAL_VAR(static_gc, l_gcing)
+#define l_allocating SCM_GLOBAL_VAR(static_gc, l_allocating)
+#endif /* SCM_DEBUG */
SCM_DEFINE_STATIC_VARS(static_gc);
/*=======================================
@@ -139,14 +156,38 @@
static void finalize_protected_var(void);
+#if SCM_DEBUG
+static void scm_ensure_proper_freelist(ScmObj flst); /* FIXME */
+#endif
+
/*=======================================
Function Definitions
=======================================*/
+#if SCM_DEBUG
+static void
+scm_ensure_proper_freelist(ScmObj flst)
+{
+ size_t len;
+ ScmObj c;
+
+ for (c = flst, len = 0; !SCM_NULLP(c); c = SCM_FREECELL_NEXT(c), len++) {
+ assert(SCM_FREECELLP(c));
+ assert(len <= SCM_INT_MAX); /* not circular list */
+ }
+ SCM_ASSERT(SCM_NULLP(c));
+}
+#endif
+
SCM_EXPORT void
scm_init_gc(const ScmStorageConf *conf)
{
SCM_GLOBAL_VARS_INIT(static_gc);
+#if SCM_DEBUG
+ l_gcing = 0;
+ l_allocating = scm_false;
+#endif
+
l_gcroots_ctx = GCROOTS_init(scm_malloc,
(GCROOTS_mark_proc)gc_mark_locations,
scm_false);
@@ -171,12 +212,23 @@
{
ScmObj ret;
+#if SCM_DEBUG
+ SCM_ASSERT(!l_gcing);
+ SCM_ASSERT(!l_allocating);
+ l_allocating = scm_true;
+#endif
+
if (NULLP(l_freelist))
gc_mark_and_sweep();
+ SCM_ASSERT(SCM_FREECELLP(l_freelist));
ret = l_freelist;
l_freelist = SCM_FREECELL_NEXT(l_freelist);
+#if SCM_DEBUG
+ l_allocating = scm_false;
+#endif
+
return ret;
}
@@ -354,6 +406,8 @@
ScmObjHeap heap;
ScmCell *cell;
+ SCM_BEGIN_GC_SUBCONTEXT();
+
if (l_n_heaps_max <= l_n_heaps)
scm_fatal_error("heap exhausted");
@@ -371,8 +425,10 @@
for (cell = &heap[0]; cell < &heap[l_heap_size - 1]; cell++)
SCM_CELL_RECLAIM_CELL(cell, (ScmObj)(cell + 1));
SCM_CELL_RECLAIM_CELL(cell, l_freelist);
- /* assumes that (ScmCell *) can be being ScmObj */
+ /* FIXME: assumes that (ScmCell *) can be being ScmObj */
l_freelist = (ScmObj)heap;
+
+ SCM_END_GC_SUBCONTEXT();
}
static void
@@ -396,6 +452,8 @@
{
size_t n_collected;
+ SCM_BEGIN_GC_SUBCONTEXT();
+
CDBG((SCM_DBG_GC, "[ gc start ]"));
gc_mark();
@@ -405,6 +463,8 @@
CDBG((SCM_DBG_GC, "enough number of free cells cannot be collected.
allocating new heap."));
add_heap();
}
+
+ SCM_END_GC_SUBCONTEXT();
}
@@ -604,6 +664,8 @@
{
ScmObj **slot;
+ SCM_BEGIN_GC_SUBCONTEXT();
+
if (l_protected_vars) {
for (slot = l_protected_vars;
slot < &l_protected_vars[l_protected_vars_size];
@@ -613,6 +675,8 @@
mark_obj(**slot);
}
}
+
+ SCM_END_GC_SUBCONTEXT();
}
/* mark a contiguous region such as stack */
@@ -621,12 +685,16 @@
{
ScmObj *objp;
+ SCM_BEGIN_GC_SUBCONTEXT();
+
SCM_ASSERT(SCMOBJ_ALIGNEDP(start));
for (objp = start; objp < &start[n]; objp++) {
if (within_heapp(*objp))
mark_obj(*objp);
}
+
+ SCM_END_GC_SUBCONTEXT();
}
static void
@@ -634,10 +702,14 @@
{
ScmObj *objp;
+ SCM_BEGIN_GC_SUBCONTEXT();
+
SCM_ASSERT(SCMOBJ_ALIGNEDP(start));
for (objp = start; objp < &start[n]; objp++)
mark_obj(*objp);
+
+ SCM_END_GC_SUBCONTEXT();
}
static void
@@ -647,6 +719,8 @@
ptrdiff_t len;
unsigned int offset;
+ SCM_BEGIN_GC_SUBCONTEXT();
+
/* swap end and start if (end < start) */
if (end < start) {
tmp = end - 1;
@@ -678,24 +752,34 @@
if (is_aligned)
break;
}
+
+ SCM_END_GC_SUBCONTEXT();
}
static void
gc_mark(void)
{
+ SCM_BEGIN_GC_SUBCONTEXT();
+
/* Mark stack and all machine-dependent contexts such as registers,
* register windows (SPARC), register stack backing store (IA-64) etc. */
GCROOTS_mark(l_gcroots_ctx);
gc_mark_global_vars();
+
+ SCM_END_GC_SUBCONTEXT();
}
static void
gc_mark_global_vars(void)
{
+ SCM_BEGIN_GC_SUBCONTEXT();
+
gc_mark_protected_var();
if (scm_symbol_hash)
gc_mark_definite_locations_n(scm_symbol_hash, scm_symbol_hash_size);
+
+ SCM_END_GC_SUBCONTEXT();
}
static void
@@ -802,6 +886,8 @@
ScmCell *cell;
ScmObj obj, new_freelist;
+ SCM_BEGIN_GC_SUBCONTEXT();
+
/* Because l_freelist may not be exhausted on an user-instructed GC, do not
* assume that l_freelist is null here. -- YamaKen */
new_freelist = l_freelist;
@@ -833,6 +919,8 @@
CDBG((SCM_DBG_GC, "heap[~ZU] swept = ~ZU", i, n_collected));
}
l_freelist = new_freelist;
+
+ SCM_END_GC_SUBCONTEXT();
return sum_collected;
}