From: Minero Aoki Date: 2002-09-02T16:01:44+09:00 Subject: [ruby-dev:18145] Re: autoload patch for ruby-1.7 あおきです。 In mail "[ruby-dev:18139] Re: autoload patch for ruby-1.7" "Yoshinori K. Okuji" wrote: > > なり遅くなるんです。Bison が使えるなら ruby.c の load_file() に > > ある rb_gc() を消してみてください。一気にロードしてもかなり速く > > なると思います。(ただし Bison 以外でこれをやると最悪 SEGV します) > > なるほど。試してみると、おっしゃる通り、相当速くなりますね! よく事情が > 分かってないんですが、Bisonでコンパイルしたparse.cを配布する、あるいは、 > Bisonでコンパイルすることを前提にするのは良くないんでしょうか?Bisonは > 1.24から出力には何の制限もしないという方針に変更したので、ライセンス的 > には問題ないように思えるのですけど。 ライセンス的には問題ないと思います。ただ、なにかのはずみで yacc が動いてしまうと酷いめにあう、ということからサポート コードは外せないのでしょう。 ちなみにGCしている理由を簡単に説明すると、 * RubyのGCはマシンスタックをスキャンしてRubyオブジェクトを探す (ので、マシンスタック上にあるオブジェクトは安全。) * しかしヒープはまずい * yaccのセマンティックスタックには構文木のノード (Rubyオブジェクト NODE) が入ることがある * bisonはセマンティックスタックをallocaでスタックに取るが 他のyaccはそうとも限らない → ノードが回収される危険がある * そこでコンパイル中はノードは回収せず、 かわりにコンパイルのあとに明示的にGCする ということです。 そういえば前にぼくがうだうだ言ったときに中田さんがパッチを 作ってくれたな…… [ruby-dev:16215] か。でもあのパッチの 方向だと まつもとさんが躊躇しそうな気がするので、思いきり 単純なパッチを作ってみました。 ------------------------------------------------------------------- 青木峰郎 Index: gc.c =================================================================== RCS file: /home/aamine/cvs/ruby/ruby/gc.c,v retrieving revision 1.99 diff -u -p -r1.99 gc.c --- gc.c 29 Aug 2002 09:08:16 -0000 1.99 +++ gc.c 2 Sep 2002 06:32:18 -0000 @@ -863,7 +863,7 @@ gc_sweep() int freed = 0; int i, used = heaps_used; - if (ruby_in_compile) { + if (ruby_in_compile && !rb_parser_use_alloca()) { /* should not reclaim nodes during compilation */ for (i = 0; i < used; i++) { p = heaps[i]; pend = p + heaps_limits[i]; Index: intern.h =================================================================== RCS file: /home/aamine/cvs/ruby/ruby/intern.h,v retrieving revision 1.92 diff -u -p -r1.92 intern.h --- intern.h 19 Aug 2002 05:56:05 -0000 1.92 +++ intern.h 2 Sep 2002 06:27:42 -0000 @@ -291,6 +291,7 @@ int yyparse _((void)); ID rb_id_attrset _((ID)); void rb_parser_append_print _((void)); void rb_parser_while_loop _((int, int)); +int rb_parser_use_alloca _((void)); int rb_is_const_id _((ID)); int rb_is_instance_id _((ID)); int rb_is_class_id _((ID)); Index: parse.y =================================================================== RCS file: /home/aamine/cvs/ruby/ruby/parse.y,v retrieving revision 1.206 diff -u -p -r1.206 parse.y --- parse.y 21 Aug 2002 15:47:54 -0000 1.206 +++ parse.y 2 Sep 2002 06:23:02 -0000 @@ -2284,6 +2284,16 @@ static char *lex_pbeg; static char *lex_p; static char *lex_pend; +int +rb_parser_use_alloca() +{ +#if defined(YYBISON) && !defined(C_ALLOCA) + return Qtrue; +#else + return Qfalse; +#endif +} + static int yyerror(msg) char *msg; Index: ruby.c =================================================================== RCS file: /home/aamine/cvs/ruby/ruby/ruby.c,v retrieving revision 1.65 diff -u -p -r1.65 ruby.c --- ruby.c 27 Aug 2002 11:00:24 -0000 1.65 +++ ruby.c 2 Sep 2002 06:26:40 -0000 @@ -856,7 +856,10 @@ load_file(fname, script) else if (f != rb_stdin) { rb_io_close(f); } - rb_gc(); + + if (!rb_parser_use_alloca()) { + rb_gc(); + } } void