summaryrefslogtreecommitdiff
path: root/gc.c
diff options
context:
space:
mode:
Diffstat (limited to 'gc.c')
-rw-r--r--gc.c161
1 files changed, 77 insertions, 84 deletions
diff --git a/gc.c b/gc.c
index 667e0209426..e3c809cded5 100644
--- a/gc.c
+++ b/gc.c
@@ -14,6 +14,7 @@
#include "env.h"
#include "st.h"
#include "node.h"
+#include "re.h"
#include <stdio.h>
#include <setjmp.h>
@@ -115,16 +116,16 @@ Cambridge, MA 02138
static int dont_gc;
VALUE
-Sgc_enable()
+gc_s_enable()
{
int old = dont_gc;
- dont_gc = Qnil;
+ dont_gc = FALSE;
return old;
}
VALUE
-Sgc_disable()
+gc_s_disable()
{
int old = dont_gc;
@@ -132,22 +133,7 @@ Sgc_disable()
return old;
}
-#include <sys/types.h>
-#include <sys/times.h>
-
-static
-Fgc_begin()
-{
- return Qnil;
-}
-
-static
-Fgc_end()
-{
- return Qnil;
-}
-
-VALUE M_GC;
+VALUE mGC;
static struct gc_list {
int n;
@@ -161,7 +147,7 @@ rb_global_variable(var)
{
struct gc_list *tmp;
- tmp = (struct gc_list*)xmalloc(sizeof(struct gc_list));
+ tmp = ALLOC(struct gc_list);
tmp->next = Global_List;
tmp->varptr = var;
tmp->n = 1;
@@ -186,12 +172,13 @@ typedef struct RVALUE {
struct RStruct rstruct;
struct RBignum bignum;
struct RNode node;
- struct RAssoc assoc;
+ struct RMatch match;
+ struct RVarmap varmap;
struct SCOPE scope;
} as;
} RVALUE;
-RVALUE *freelist = Qnil;
+RVALUE *freelist = 0;
#define HEAPS_INCREMENT 10
static RVALUE **heaps;
@@ -201,6 +188,8 @@ static int heaps_used = 0;
#define HEAP_SLOTS 10000
#define FREE_MIN 512
+static RVALUE *himem, *lomem;
+
static void
add_heap()
{
@@ -212,12 +201,14 @@ add_heap()
heaps = (heaps_used)?
(RVALUE**)realloc(heaps, heaps_length*sizeof(RVALUE)):
(RVALUE**)malloc(heaps_length*sizeof(RVALUE));
- if (heaps == Qnil) Fatal("can't alloc memory");
+ if (heaps == 0) Fatal("can't alloc memory");
}
p = heaps[heaps_used++] = (RVALUE*)malloc(sizeof(RVALUE)*HEAP_SLOTS);
- if (p == Qnil) Fatal("can't alloc memory");
+ if (p == 0) Fatal("can't alloc memory");
pend = p + HEAP_SLOTS;
+ if (lomem == 0 || lomem > p) lomem = p;
+ if (himem < pend) himem = pend;
while (p < pend) {
p->as.free.flag = 0;
@@ -245,15 +236,15 @@ newobj()
}
VALUE
-data_new(datap, dfree, dmark)
- VALUE *datap;
+data_new(datap, dmark, dfree)
+ void *datap;
void (*dfree)();
void (*dmark)();
{
- extern VALUE C_Data;
+ extern VALUE cData;
struct RData *data = (struct RData*)newobj();
- OBJSETUP(data, C_Data, T_DATA);
+ OBJSETUP(data, cData, T_DATA);
data->data = datap;
data->dfree = dfree;
data->dmark = dmark;
@@ -271,7 +262,10 @@ looks_pointerp(p)
register RVALUE *heap_org;
register long i;
- /* if p looks as a SCM pointer mark location */
+ if (p < lomem) return FALSE;
+ if (p > himem) return FALSE;
+
+ /* check if p looks like a pointer */
for (i=0; i < heaps_used; i++) {
heap_org = heaps[i];
if (heap_org <= p && p < heap_org + HEAP_SLOTS
@@ -310,7 +304,7 @@ mark_locations(start, end)
mark_locations_array(start,n);
}
-static
+static int
mark_entry(key, value)
ID key;
VALUE value;
@@ -319,14 +313,14 @@ mark_entry(key, value)
return ST_CONTINUE;
}
-static
+static int
mark_tbl(tbl)
st_table *tbl;
{
st_foreach(tbl, mark_entry, 0);
}
-static
+static int
mark_hashentry(key, value)
ID key;
VALUE value;
@@ -336,7 +330,7 @@ mark_hashentry(key, value)
return ST_CONTINUE;
}
-static
+static int
mark_hash(tbl)
st_table *tbl;
{
@@ -393,8 +387,8 @@ gc_mark(obj)
break;
case T_CLASS:
- gc_mark(obj->as.class.super);
case T_MODULE:
+ gc_mark(obj->as.class.super);
mark_tbl(obj->as.class.m_tbl);
if (obj->as.class.iv_tbl) mark_tbl(obj->as.class.iv_tbl);
break;
@@ -405,7 +399,7 @@ gc_mark(obj)
VALUE *ptr = obj->as.array.ptr;
for (i=0; i < len; i++)
- gc_mark(ptr[i]);
+ gc_mark(*ptr++);
}
break;
@@ -425,40 +419,37 @@ gc_mark(obj)
if (obj->as.object.iv_tbl) mark_tbl(obj->as.object.iv_tbl);
break;
+ case T_MATCH:
case T_REGEXP:
case T_FLOAT:
case T_BIGNUM:
break;
- case T_STRUCT:
- {
- int i, len = obj->as.rstruct.len;
- struct kv_pair *ptr = obj->as.rstruct.tbl;
-
- for (i=0; i < len; i++)
- gc_mark(ptr[i].value);
- }
+ case T_VARMAP:
+ gc_mark(obj->as.varmap.next);
break;
case T_SCOPE:
- {
- struct SCOPE *scope = (struct SCOPE*)obj;
- if (scope->local_vars) {
- int n = scope->local_tbl[0];
- VALUE *tbl = scope->local_vars;
-
- while (n--) {
- gc_mark(*tbl);
- tbl++;
- }
+ if (obj->as.scope.local_vars) {
+ int n = obj->as.scope.local_tbl[0];
+ VALUE *tbl = obj->as.scope.local_vars;
+
+ while (n--) {
+ gc_mark(*tbl);
+ tbl++;
}
}
break;
- case T_ASSOC:
- gc_mark(obj->as.assoc.car);
- obj = (RVALUE*)obj->as.assoc.cdr;
- goto Top;
+ case T_STRUCT:
+ {
+ int i, len = obj->as.rstruct.len;
+ VALUE *ptr = obj->as.rstruct.ptr;
+
+ for (i=0; i < len; i++)
+ gc_mark(*ptr++);
+ }
+ break;
default:
Bug("gc_mark(): unknown data type %d", obj->as.basic.flags & T_MASK);
@@ -475,7 +466,7 @@ gc_sweep()
int freed = 0;
int i;
- freelist = Qnil;
+ freelist = 0;
for (i = 0; i < heaps_used; i++) {
RVALUE *p, *pend;
RVALUE *nfreelist;
@@ -542,14 +533,15 @@ obj_free(obj)
if (obj->as.data.dfree) (*obj->as.data.dfree)(DATA_PTR(obj));
free(DATA_PTR(obj));
break;
+ case T_MATCH:
+ re_free_registers(obj->as.match.regs);
+ free(obj->as.match.regs);
+ if (obj->as.match.ptr) free(obj->as.match.ptr);
+ break;
case T_ICLASS:
/* iClass shares table with the module */
case T_FLOAT:
- case T_ASSOC:
- break;
- case T_STRUCT:
- free(obj->as.rstruct.name);
- free(obj->as.rstruct.tbl);
+ case T_VARMAP:
break;
case T_BIGNUM:
free(obj->as.bignum.digits);
@@ -561,13 +553,14 @@ obj_free(obj)
return; /* no need to free iv_tbl */
case T_SCOPE:
- {
- struct SCOPE *scope = (struct SCOPE*)obj;
- if (scope->local_vars)
- free(scope->local_vars);
- if (scope->local_tbl)
- free(scope->local_tbl);
- }
+ if (obj->as.scope.local_vars)
+ free(obj->as.scope.local_vars);
+ if (obj->as.scope.local_tbl)
+ free(obj->as.scope.local_tbl);
+ break;
+
+ case T_STRUCT:
+ free(obj->as.rstruct.ptr);
break;
default:
@@ -576,11 +569,11 @@ obj_free(obj)
}
void
-gc_mark_env(env)
- struct ENVIRON *env;
+gc_mark_frame(frame)
+ struct FRAME *frame;
{
- int n = env->argc;
- VALUE *tbl = env->argv;
+ int n = frame->argc;
+ VALUE *tbl = frame->argv;
while (n--) {
gc_mark(*tbl);
@@ -592,7 +585,7 @@ void
gc()
{
struct gc_list *list;
- struct ENVIRON *env;
+ struct FRAME *frame;
jmp_buf save_regs_gc_mark;
VALUE stack_end;
@@ -603,9 +596,9 @@ gc()
alloca(0);
#endif
- /* mark env stack */
- for (env = the_env; env; env = env->prev) {
- gc_mark_env(env);
+ /* mark frame stack */
+ for (frame = the_frame; frame; frame = frame->prev) {
+ gc_mark_frame(frame);
}
gc_mark(the_scope);
@@ -627,7 +620,6 @@ gc()
gc_mark_global_tbl();
mark_tbl(rb_class_tbl);
-
gc_mark_trap_list();
gc_sweep();
@@ -649,11 +641,12 @@ init_heap()
add_heap();
}
+void
Init_GC()
{
- M_GC = rb_define_module("GC");
- rb_define_single_method(M_GC, "start", gc, 0);
- rb_define_single_method(M_GC, "enable", Sgc_enable, 0);
- rb_define_single_method(M_GC, "disable", Sgc_disable, 0);
- rb_define_method(M_GC, "garbage_collect", gc, 0);
+ mGC = rb_define_module("GC");
+ rb_define_singleton_method(mGC, "start", gc, 0);
+ rb_define_singleton_method(mGC, "enable", gc_s_enable, 0);
+ rb_define_singleton_method(mGC, "disable", gc_s_disable, 0);
+ rb_define_method(mGC, "garbage_collect", gc, 0);
}