[#35719] Windows-31J <-> UTF-8 roundtrip — Tanaka Akira <akr@...>
以下のように Windows-31J と UTF-8 が roundtrip するかどうか
成瀬です。
In article <48932335.7010209@airemix.jp>,
成瀬です。
In article <48935EBD.3010603@airemix.jp>,
成瀬です。
[#35724] $SAFE=4の場合のReadline::HISTORY.each — Takao Kouji <kouji@...7.net>
knu さんへ
[#35726] "\x01\x00\x00\x00\x00\x00\x00\x21".encode("utf-8", "utf-32be", :invalid=>:replace) — Tanaka Akira <akr@...>
UTF-32BE で、文字として正しくない 4バイトと、文字として正し
[#35733] Re: [ruby-core:18078] We'll release 1.8.6/1.8.7 this Friday, #2 — Urabe Shyouhei <shyouhei@...>
というわけでそろそろリリースしようと思います。予定日は8月8日です。問題点
[#35745] [Bug:1.9] default_external depends on the order of -K and -E — sheepman <sh@...>
こんにちは sheepman です。
成瀬です。
Yuguiです。
[#35763] 文字コードがシンボルでないのは何故? — take_tk <ggb03124@...>
たけ(tk)です。
なかだです。
たけ(tk)です
[#35789] [Ruby 1.9 - Bug #407] (Open) String#<< — Shyouhei Urabe <redmine@...>
チケット #407 が報告されました。 (by Shyouhei Urabe)
まつもと ゆきひろです
Yukihiro Matsumoto さんは書きました:
まつもと ゆきひろです
成瀬です。
At 08:00 08/09/20, NARUSE, Yui wrote:
まつもと ゆきひろです
[#35811] fail to build extension libraries that includes some ruby header files — "Yusuke ENDOH" <mame@...>
遠藤です。
[#35834] 「サポートレベル」の定義、1.9.1のサポート予定プラットフォーム、メンテナ募集 — "Yugui (Yuki Sonoda)" <yugui@...>
Yuguiです。
[#35845] [Bug #437] test_strftime(TestTime) fails on Solaris — Shugo Maeda <redmine@...>
Bug #437: test_strftime(TestTime) fails on Solaris
前田です。
さとうふみやす @ OSS テクノロジです。
まつもと ゆきひろです
前田です。
まつもと ゆきひろです
前田です。
前田です。
まつもと ゆきひろです
前田です。
[#35851] [Feature:1.9] name referencing in sprintf — "Yusuke ENDOH" <mame@...>
遠藤です。
[#35863] Refactoring of enumerating prime numbers — "Yugui (Yuki Sonoda)" <yugui@...>
Yuguiです。
けいじゅ@いしつかです.
Yuguiです。
けいじゅ@いしつかです.
なかだです。
けいじゅ@いしつかです.
なかだです。
けいじゅ@いしつかです.
Yuguiです。
けいじゅ@いしつかです.
[#35899] [Bug #466] test_str_crypt(TestM17NComb) failed — Kazuhiro NISHIYAMA <redmine@...>
Bug #466: test_str_crypt(TestM17NComb) failed
[#35904] [Feature:1.9] pack format 'm' based on RFC 4648 — "Yusuke ENDOH" <mame@...>
遠藤です。
チケット #471 が更新されました。 (by Yuki Sonoda)
遠藤です。
In article <e0b1e5700809220338g5f3b5627p95e94744d5c10505@mail.gmail.com>,
遠藤です。
In article <e0b1e5700809231144n376fd4eencfe06c49ed66665e@mail.gmail.com>,
遠藤です。
[#35906] %N for Time#strftime — "Shugo Maeda" <shugo@...>
前田です。
In article <704d5db90808210811p7f3aef73h97913ade156323f3@mail.gmail.com>,
なかだです。
まつもと ゆきひろです
[#35922] [Bug #475] cgi.rbにNKFに依存したコードが入っている — Takeyuki Fujioka <redmine@...>
Bug #475: cgi.rbにNKFに依存したコードが入っている
[#35945] Re: [ruby-list:45386] Re: [ANN] REXMLのDoS脆弱性 — "Shugo Maeda" <shugo@...>
前田です。
前田です。
In message <704d5db90809010656k2042969bx3d8a4abdafeeea8e@mail.gmail.com>
[#35954] Re: [ruby-cvs:26052] Ruby:r18834 (trunk): * compile.c (defined_expr): should handle NODE_{AND,OR} as — SASADA Koichi <ko1@...>
ささだです.
まつもと ゆきひろです
ささだです.
まつもと ゆきひろです
ささだです.
まつもと ゆきひろです
[#35977] block parameter for Delagator — keiju@... (Keiju ISHITSUKA)
けいじゅ@いしつかです.
[#35986] 1.9と1.8で、delegateのインスタンスのクラス名の違う — Fujioka <fuj@...>
xibbarこと藤岡です。
まつもと ゆきひろです
けいじゅ@いしつかです.
藤岡です。
けいじゅ@いしつかです.
こんにちは、なかむら(う)です。
[#36008] [Bug #505] 1.upto 2 {|i| p i } — Shyouhei Urabe <redmine@...>
Bug #505: 1.upto 2 {|i| p i }
[#36028] [Bug #513] Tempfile yields [BUG] Stack consistency error — Shyouhei Urabe <redmine@...>
Bug #513: Tempfile yields [BUG] Stack consistency error
[#36033] [Bug #515] String#rindexが期待通りに動かない — Takeyuki Fujioka <redmine@...>
Bug #515: String#rindexが期待通りに動かない
[#36048] TypeError from Encoding.compatible? (r18920) — Yukihiro Matsumoto <matz@...>
まつもと ゆきひろです
[#36066] Numeric#scalar? — Tadayoshi Funaba <tadf@...>
1.9 の Numeric#scalar? について、適当でないのでは (real? などのほうがい
原です。
> やはり、scalar? はずれているんじゃないかな。real? の方がいい
原です。
> ここで、scalar? を疑問視する理由を復習すると、たとえば、「複
1.9.1 までに時間がないので scalar? だけ何とかしたいと思っていましたが、
前田です。
原です。
[ruby-dev:35850] Re: rb_yield の高速版
まつもと ゆきひろです
In message "Re: [ruby-dev:34560] rb_yield の高速版"
on Thu, 1 May 2008 19:27:02 +0900, wanabe <s.wanabe@gmail.com> writes:
|
|ワナベと申します。
|
|rb_yield を連続で呼び出すときに、積んだフレームを使いまわす関数を書きました。
|試験的に Fixnum#times にだけ組み込んでいますが、ほかにも
|Array#each, Range#each などで使えると思います。
|
|ruby -e 'GC.disable;t=Time.now;(10**7).times {};p Time.now - t'
|こんな感じの簡単な計測では 4.9秒から 3.5 秒ほどに縮まりました。
|一応手元では make test と make test-all の動作を確認してあります。
これを取り込んでみようと作業してみました。結論からいうと
* 全然速くならなかった
* しかもtest-allで落ちる
ということで、全然ダメです。これが、5月から今までにcoreに入っ
た改善のため有効な最適化でなくなったのか、それとも私の作った
パッチに不備があるのかはまだ分かりません。また、test-allで落
ちる原因もまだ分かりません。自分のダメさ加減が実感できて悲し
いのですが、せっかく作業したので、現状のパッチを投稿しておき
ます。
diff --git a/array.c b/array.c
index e7eb280..a91fcb1 100644
--- a/array.c
+++ b/array.c
@@ -19,6 +19,9 @@ VALUE rb_cArray;
static ID id_cmp;
+VALUE rb_fast_yield_loop(VALUE (*i_proc)(ANYARGS), VALUE val);
+VALUE rb_fast_yield(VALUE val, void *block);
+
#define ARY_DEFAULT_SIZE 16
#define ARY_MAX_SIZE (LONG_MAX / sizeof(VALUE))
@@ -1116,6 +1119,17 @@ rb_ary_insert(int argc, VALUE *argv, VALUE ary)
return ary;
}
+static VALUE
+each_i(VALUE ary, void *block)
+{
+ long i;
+
+ for (i=0; i<RARRAY_LEN(ary); i++) {
+ rb_fast_yield(RARRAY_PTR(ary)[i], block);
+ }
+ return Qnil;
+}
+
/*
* call-seq:
* array.each {|item| block } -> array
@@ -1134,12 +1148,8 @@ rb_ary_insert(int argc, VALUE *argv, VALUE ary)
VALUE
rb_ary_each(VALUE ary)
{
- long i;
-
RETURN_ENUMERATOR(ary, 0, 0);
- for (i=0; i<RARRAY_LEN(ary); i++) {
- rb_yield(RARRAY_PTR(ary)[i]);
- }
+ rb_fast_yield_loop(each_i, ary);
return ary;
}
diff --git a/eval.c b/eval.c
index b39da54..fd08d0a 100644
--- a/eval.c
+++ b/eval.c
@@ -950,6 +950,32 @@ rb_obj_extend(int argc, VALUE *argv, VALUE obj)
* in each module to the receiver.
*/
+const rb_block_t *vm_yield_fast_setup(rb_thread_t *th, int argc); /* vm.c */
+void vm_yield_fast_finish(rb_thread_t *th, const rb_block_t *block); /* vm.c */
+VALUE vm_yield_fast(rb_thread_t *th, rb_block_t *block, int argc, VALUE *argv); /* vm.c */
+
+VALUE
+rb_fast_yield_loop(VALUE (*i_proc)(ANYARGS), VALUE val)
+{
+ rb_thread_t *th = GET_THREAD();
+ const rb_block_t *block = vm_yield_fast_setup(th, 1);
+ val = i_proc(val, (void*)block);
+ vm_yield_fast_finish(th, block);
+ return val;
+}
+
+VALUE
+rb_fast_yield(VALUE val, void *block)
+{
+ return vm_yield_fast(GET_THREAD(), (rb_block_t *)block, 1, &val);
+}
+
+VALUE
+rb_fast_yield_argv(int argc, VALUE *argv, void *block)
+{
+ return vm_yield_fast(GET_THREAD(), (rb_block_t *)block, argc, argv);
+}
+
static VALUE
top_include(int argc, VALUE *argv, VALUE self)
{
diff --git a/numeric.c b/numeric.c
index 745a217..fbd6498 100644
--- a/numeric.c
+++ b/numeric.c
@@ -80,6 +80,9 @@ round(double x)
}
#endif
+VALUE rb_fast_yield_loop(VALUE (*i_proc)(ANYARGS), VALUE val);
+VALUE rb_fast_yield(VALUE val, void *block);
+
static ID id_coerce, id_to_i, id_eq;
VALUE rb_cNumeric;
@@ -2992,17 +2995,24 @@ int_downto(VALUE from, VALUE to)
*/
static VALUE
+int_dotimes_i(VALUE num, void *block)
+{
+ long i, end;
+
+ end = FIX2LONG(num);
+ for (i=0; i<end; i++) {
+ rb_fast_yield(LONG2FIX(i), block);
+ }
+ return Qnil;
+}
+
+static VALUE
int_dotimes(VALUE num)
{
RETURN_ENUMERATOR(num, 0, 0);
if (FIXNUM_P(num)) {
- long i, end;
-
- end = FIX2LONG(num);
- for (i=0; i<end; i++) {
- rb_yield(LONG2FIX(i));
- }
+ rb_fast_yield_loop(int_dotimes_i, num);
}
else {
VALUE i = INT2FIX(0);
diff --git a/vm.c b/vm.c
index f06ba0e..6942462 100644
--- a/vm.c
+++ b/vm.c
@@ -437,10 +437,10 @@ vm_make_proc(rb_thread_t *th,
/* C -> Ruby: block */
-static inline VALUE
-invoke_block_from_c(rb_thread_t *th, const rb_block_t *block,
+static inline void
+setup_block(rb_thread_t *th, const rb_block_t *block,
VALUE self, int argc, const VALUE *argv,
- const rb_block_t *blockptr, const NODE *cref)
+ const rb_block_t *blockptr)
{
if (BUILTIN_TYPE(block->iseq) != T_NODE) {
const rb_iseq_t *iseq = block->iseq;
@@ -453,8 +453,14 @@ invoke_block_from_c(rb_thread_t *th, const rb_block_t *block,
CHECK_STACK_OVERFLOW(cfp, argc + iseq->stack_max);
- for (i=0; i<argc; i++) {
- cfp->sp[i] = argv[i];
+ if (argv) {
+ for (i=0; i<argc; i++) {
+ cfp->sp[i] = argv[i];
+ }
+ } else {
+ for (i=0; i<argc; i++) {
+ cfp->sp[i] = Qnil;
+ }
}
opt_pc = vm_yield_setup_args(th, iseq, argc, cfp->sp, blockptr,
@@ -464,11 +470,18 @@ invoke_block_from_c(rb_thread_t *th, const rb_block_t *block,
self, GC_GUARDED_PTR(block->dfp),
iseq->iseq_encoded + opt_pc, cfp->sp + arg_size, block->lfp,
iseq->local_size - arg_size);
+ }
+}
+static inline VALUE
+invoke_block_fast(rb_thread_t *th, const rb_block_t *block,
+ VALUE self, int argc, const VALUE *argv,
+ const rb_block_t *blockptr, const NODE *cref)
+{
+ if (BUILTIN_TYPE(block->iseq) != T_NODE) {
if (cref) {
th->cfp->dfp[-1] = (VALUE)cref;
}
-
return vm_eval_body(th);
}
else {
@@ -476,6 +489,16 @@ invoke_block_from_c(rb_thread_t *th, const rb_block_t *block,
}
}
+static inline VALUE
+invoke_block_from_c(rb_thread_t *th, const rb_block_t *block,
+ VALUE self, int argc, const VALUE *argv,
+ const rb_block_t *blockptr, const NODE *cref)
+{
+ setup_block(th, block, self, argc, argv, blockptr);
+ return invoke_block_fast(th, block, self, argc, argv, blockptr, cref);
+}
+
+
static inline const rb_block_t *
check_block(rb_thread_t *th)
{
@@ -502,6 +525,56 @@ vm_yield(rb_thread_t *th, int argc, const VALUE *argv)
return invoke_block_from_c(th, blockptr, blockptr->self, argc, argv, 0, 0);
}
+const rb_block_t *
+vm_yield_fast_setup(rb_thread_t *th, int argc)
+{
+ const rb_block_t *block = check_block(th);
+ setup_block(th, block, block->self, argc, 0, 0);
+ return block;
+}
+
+VALUE
+vm_yield_fast(rb_thread_t *th, rb_block_t *block, int argc, VALUE *argv)
+{
+ int i;
+ int opt_pc;
+ VALUE retval;
+
+ if (BUILTIN_TYPE(block->iseq) != T_NODE) {
+ CHECK_STACK_OVERFLOW(th->cfp, argc + block->iseq->stack_max);
+ for (i=0; i<argc; i++) {
+ th->cfp->sp[i] = argv[i];
+ }
+ opt_pc = vm_yield_setup_args(th, block->iseq, argc, th->cfp->sp, 0,
+ block_proc_is_lambda(block->proc));
+ for (i=0; i<block->iseq->arg_size; i++) {
+ th->cfp[2].sp[i] = th->cfp->sp[i];
+ }
+ th->cfp->pc = block->iseq->iseq_encoded + opt_pc;
+ th->cfp->dfp[0] = GC_GUARDED_PTR(block->dfp);
+ }
+ retval = invoke_block_fast(th, block, block->self, argc, argv, 0, 0);
+ if (BUILTIN_TYPE(block->iseq) != T_NODE) {
+ for (i=0; i<block->iseq->local_size; i++) {
+ th->cfp->sp[i] = Qnil;
+ }
+ th->cfp--;
+ th->cfp->pc--;
+ th->cfp--;
+ }
+ return retval;
+}
+
+void
+vm_yield_fast_finish(rb_thread_t *th, const rb_block_t *block)
+{
+ if (BUILTIN_TYPE(block->iseq) != T_NODE) {
+ th->cfp++;
+ th->cfp->pc++;
+ th->cfp++;
+ }
+}
+
VALUE
vm_invoke_proc(rb_thread_t *th, rb_proc_t *proc, VALUE self,
int argc, const VALUE *argv, rb_block_t * blockptr)
diff --git a/vm_eval.c b/vm_eval.c
index 1de5371..1c318e6 100644
--- a/vm_eval.c
+++ b/vm_eval.c
@@ -535,15 +535,25 @@ rb_yield_splat(VALUE values)
return v;
}
+VALUE rb_fast_yield_loop(VALUE (*i_proc)(ANYARGS), VALUE val);
+VALUE rb_fast_yield_argv(int argc, VALUE *argv, void *block);
+
static VALUE
-loop_i(void)
+loop_ii(VALUE dummy, void *block)
{
for (;;) {
- rb_yield_0(0, 0);
+ rb_fast_yield_argv(0, 0, block);
}
return Qnil;
}
+static VALUE
+loop_i(void)
+{
+ rb_fast_yield_loop(loop_ii, Qnil);
+ return Qnil;
+}
+
/*
* call-seq:
* loop {|| block }