From: nobu.nakada@... Date: 2001-12-31T01:33:18+09:00 Subject: [ruby-dev:15610] Re: filename within eval なかだです。 At Mon, 31 Dec 2001 00:48:17 +0900, Nobuyoshi-Nakada wrote: > もうちょっとマシ…かどうかはともかく、新しい手を考えてみました。 > たぶんGCもそれほど遅くはならないと思います。 失敗。ruby_sourcefileに直接代入してるところがあるのを忘れてまし た。 # やっぱり結構大きくなってしまった。 Index: eval.c =================================================================== RCS file: /cvs/ruby/src/ruby/eval.c,v retrieving revision 1.237 diff -u -2 -p -u -r1.237 eval.c --- eval.c 2001/12/20 18:19:42 1.237 +++ eval.c 2001/12/30 16:12:34 @@ -1243,4 +1243,6 @@ compile_error(at) } +extern char *rb_source_filename _((const char *)); + VALUE rb_eval_string(str) @@ -1250,5 +1252,5 @@ rb_eval_string(str) char *oldsrc = ruby_sourcefile; - ruby_sourcefile = "(eval)"; + ruby_sourcefile = rb_source_filename("(eval)"); v = eval(ruby_top_self, rb_str_new2(str), Qnil, 0, 0); ruby_sourcefile = oldsrc; Index: gc.c =================================================================== RCS file: /cvs/ruby/src/ruby/gc.c,v retrieving revision 1.82 diff -u -2 -p -u -r1.82 gc.c --- gc.c 2001/12/11 03:48:08 1.82 +++ gc.c 2001/12/30 16:00:44 @@ -430,4 +430,34 @@ init_mark_stack() static void rb_gc_mark_children(VALUE ptr); +static st_table *source_filenames; + +char * +rb_source_filename(f) + const char *f; +{ + VALUE name; + + if (!st_lookup(source_filenames, f, &name)) { + long len = strlen(f); + VALUE *ptr = (VALUE *)RSTRING(name = rb_str_new(0, sizeof(VALUE) + len))->ptr; + *ptr++ = name; + MEMCPY(ptr, f, char, len); + OBJ_FREEZE(name); + st_add_direct(source_filenames, ptr, name); + return (char *)ptr; + } + return RSTRING(name)->ptr + sizeof(VALUE); +} + +static void +mark_source_filename(f) + const char *f; +{ + if (f) { + VALUE name = ((VALUE *)f)[-1]; + FL_SET(name, FL_MARK); + } +} + static void gc_mark_all() @@ -606,4 +636,5 @@ rb_gc_mark_children(ptr) case T_NODE: + mark_source_filename(obj->as.node.nd_file); switch (nd_type(obj)) { case NODE_IF: /* 1,2,3 */ @@ -830,4 +861,11 @@ rb_gc_mark_children(ptr) static void obj_free _((VALUE)); +static enum st_retval +sweep_tbl_value(key, value) + VALUE key, value; +{ + return FL_TEST(value, FL_MARK) ? ST_CONTINUE : ST_DELETE; +} + static void gc_sweep() @@ -849,4 +887,6 @@ gc_sweep() } + st_foreach(source_filenames, sweep_tbl_value, 0); + freelist = 0; final_list = deferred_final_list; @@ -1514,3 +1554,5 @@ Init_GC() rb_gc_unregister_address(&rb_mObSpace); finalizers = rb_ary_new(); + + source_filenames = st_init_strtable(); } Index: intern.h =================================================================== RCS file: /cvs/ruby/src/ruby/intern.h,v retrieving revision 1.74 diff -u -2 -p -u -r1.74 intern.h --- intern.h 2001/12/17 07:52:34 1.74 +++ intern.h 2001/12/30 16:13:57 @@ -192,4 +192,5 @@ VALUE rb_find_file _((VALUE)); int ruby_stack_check _((void)); int ruby_stack_length _((VALUE**)); +char *rb_source_filename _((const char *)); void rb_gc_mark_locations _((VALUE*, VALUE*)); void rb_mark_tbl _((struct st_table*)); Index: parse.y =================================================================== RCS file: /cvs/ruby/src/ruby/parse.y,v retrieving revision 1.137 diff -u -2 -p -u -r1.137 parse.y --- parse.y 2001/12/22 02:51:00 1.137 +++ parse.y 2001/12/30 16:13:35 @@ -2119,4 +2119,6 @@ yycompile(f, line) NODE *node = 0; + f = rb_source_filename(f); + if (!compile_for_eval && rb_safe_level() == 0 && rb_const_defined(rb_cObject, rb_intern("SCRIPT_LINES__"))) { @@ -2229,5 +2231,5 @@ rb_compile_file(f, file, start) ruby_sourceline = start - 1; - return yycompile(strdup(f), start); + return yycompile(f, start); } Index: ruby.c =================================================================== RCS file: /cvs/ruby/src/ruby/ruby.c,v retrieving revision 1.55 diff -u -2 -p -u -r1.55 ruby.c --- ruby.c 2001/12/17 07:52:35 1.55 +++ ruby.c 2001/12/30 16:15:45 @@ -718,5 +718,5 @@ proc_options(argc, argv) ruby_init_loadpath(); - ruby_sourcefile = argv0; + ruby_sourcefile = rb_source_filename(argv0); if (e_script) { require_libraries(); @@ -825,5 +825,5 @@ load_file(fname, script) execv(path, argv); - ruby_sourcefile = fname; + ruby_sourcefile = rb_source_filename(fname); ruby_sourceline = 1; rb_fatal("Can't exec %s", path); @@ -951,5 +951,5 @@ ruby_script(name) if (name) { rb_progname = rb_tainted_str_new2(name); - ruby_sourcefile = name; + ruby_sourcefile = rb_source_filename(name); } } @@ -990,5 +990,5 @@ ruby_prog_init() init_ids(); - ruby_sourcefile = "ruby"; + ruby_sourcefile = rb_source_filename("ruby"); rb_define_variable("$VERBOSE", &ruby_verbose); rb_define_variable("$-v", &ruby_verbose); -- --- 僕の前にBugはない。 --- 僕の後ろにBugはできる。 中田 伸悦