diff options
Diffstat (limited to 'gc.c')
-rw-r--r-- | gc.c | 48 |
1 files changed, 48 insertions, 0 deletions
@@ -428,6 +428,48 @@ init_mark_stack() static void rb_gc_mark_children(VALUE ptr); +static st_table *source_filenames; + +char * +rb_source_filename(f) + const char *f; +{ + char *name; + + if (!st_lookup(source_filenames, f, &name)) { + long len = strlen(f) + 1; + char *ptr = name = ALLOC_N(char, len + 1); + *ptr++ = 0; + MEMCPY(ptr, f, char, len); + st_add_direct(source_filenames, ptr, name); + return ptr; + } + return name + 1; +} + +static void +mark_source_filename(f) + char *f; +{ + if (f) { + f[-1] = 1; + } +} + +static enum st_retval +sweep_source_filename(key, value) + char *key, *value; +{ + if (*value) { + *value = 0; + return ST_CONTINUE; + } + else { + free(value); + return ST_DELETE; + } +} + static void gc_mark_all() { @@ -604,6 +646,7 @@ rb_gc_mark_children(ptr) break; case T_NODE: + mark_source_filename(obj->as.node.nd_file); switch (nd_type(obj)) { case NODE_IF: /* 1,2,3 */ case NODE_FOR: @@ -846,6 +889,9 @@ gc_sweep() } } + mark_source_filename(ruby_sourcefile); + st_foreach(source_filenames, sweep_source_filename, 0); + freelist = 0; final_list = deferred_final_list; deferred_final_list = 0; @@ -1510,4 +1556,6 @@ Init_GC() rb_global_variable(&finalizers); rb_gc_unregister_address(&rb_mObSpace); finalizers = rb_ary_new(); + + source_filenames = st_init_strtable(); } |