From: nobu.nakada@... Date: 2002-02-15T19:50:39+09:00 Subject: [ruby-dev:15894] Re: GC after load なかだです。 At Fri, 15 Feb 2002 11:58:06 +0900, Nobuyoshi-Nakada wrote: > あるいは、parse.yのmalloc()とかを置き換えてマークするとか。 激しく使い物にならなかったので、parse.yだけ再度。byaccでmake testとrubiconまでは一応確認済み。 Index: parse.y =================================================================== RCS file: /cvs/ruby/src/ruby/parse.y,v retrieving revision 1.153 diff -u -2 -p -r1.153 parse.y --- parse.y 2002/02/14 08:47:58 1.153 +++ parse.y 2002/02/15 10:29:44 @@ -149,4 +149,87 @@ static void top_local_init(); static void top_local_setup(); +#if !(defined YYBISON && defined HAVE_ALLOCA) + +static struct { + void **ptr; + int count; +} stacks; + +static void ** +stack_holder(ptr) + void *ptr; +{ + int i; + if (!stacks.ptr) { + stacks.count = 4; + stacks.ptr = ALLOC_N(void*, stacks.count); + MEMZERO(stacks.ptr, void*, stacks.count); + return stacks.ptr; + } + for (i = 0; i < stacks.count; ++i) { + if (stacks.ptr[i] == ptr) return &stacks.ptr[i]; + } + if (ptr) { + for (i = 0; i < stacks.count; ++i) { + if (!stacks.ptr[i]) return &stacks.ptr[i]; + } + } + i = stacks.count << 1; + REALLOC_N(stacks.ptr, void*, i); + MEMZERO(stacks.ptr + stacks.count, void*, i - stacks.count); + stacks.count = i; + return &stacks.ptr[i]; +} + +static inline void * +parser_malloc(size) + int size; +{ +#if defined YYBISON && defined YYSTACK_USE_ALLOCA + return xmalloc(size); +#else + void **holder = stack_holder(0); + VALUE *p = (VALUE *)xmalloc(size + sizeof(VALUE)); + memset(p + 1, 0, size); + *holder = p; + *p = size; + return p + 1; +#endif +} + +static inline void * +parser_realloc(ptr, size) + void *ptr; + int size; +{ +#if defined YYBISON && defined YYSTACK_USE_ALLOCA + return xrealloc(ptr, size); +#else + void **holder = stack_holder(ptr); + VALUE oldsize = *holder ? *(VALUE *)*holder : 0; + VALUE *p = (VALUE *)xrealloc(ptr, size + sizeof(VALUE)); + if (size > oldsize) memset(p + 1 + oldsize, 0, size - oldsize); + *holder = p; + *p = size; + return p + 1; +#endif +} + +static inline void +parser_free(ptr) + void *ptr; +{ +#if !(defined YYBISON && defined YYSTACK_USE_ALLOCA) + *stack_holder(ptr) = 0; +#endif + xfree(ptr); +} + +#define malloc(size) parser_malloc(size) +#define calloc(size) parser_calloc(size) +#define realloc(ptr, size) parser_realloc(ptr, size) +#define free(ptr) parser_free(ptr) +#endif + %} @@ -2115,4 +2198,22 @@ int ruby__end__seen; static VALUE ruby_debug_lines; +void +rb_gc_mark_parser() +{ +#if defined YYBISON && defined HAVE_ALLOCA + if (!ruby_in_compile) return; + rb_gc_mark_maybe(yylval.val); +#else + int i; + if (!ruby_in_compile || !stacks.ptr) return; + rb_gc_mark_maybe(yylval.val); + for (i = 0; i < stacks.count; ++i) { + VALUE *p = stacks.ptr[i]; + if (!p || !*p) continue; + rb_gc_mark_locations(p + 1, (VALUE *)((char *)p + *p)); + } +#endif +} + static NODE* yycompile(f, line) @@ -2162,4 +2263,6 @@ yycompile(f, line) cur_mid = 0; + rb_gc_finalize_deferred(); + if (n == 0) node = ruby_eval_tree; return node; @@ -2890,5 +2993,5 @@ here_document(term, indent) ruby_sourceline = linesave; rb_compile_error("can't find string \"%s\" anywhere before EOF", eos); - free(eos); + xfree(eos); return 0; } @@ -2941,5 +3044,5 @@ here_document(term, indent) } } - free(eos); + xfree(eos); lex_lastline = lastline_save; lex_pbeg = RSTRING(lex_lastline)->ptr; @@ -4915,8 +5018,8 @@ local_pop() if (lvtbl->tbl) { - if (!lvtbl->nofree) free(lvtbl->tbl); + if (!lvtbl->nofree) xfree(lvtbl->tbl); else lvtbl->tbl[0] = lvtbl->cnt; } - free(lvtbl); + xfree(lvtbl); lvtbl = local; } @@ -5026,5 +5139,5 @@ top_local_setup() } if (ruby_scope->local_tbl && ruby_scope->local_vars[-1] == 0) { - free(ruby_scope->local_tbl); + xfree(ruby_scope->local_tbl); } ruby_scope->local_vars[-1] = 0; -- --- 僕の前にBugはない。 --- 僕の後ろにBugはできる。 中田 伸悦