summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog6
-rw-r--r--thread.c30
2 files changed, 21 insertions, 15 deletions
diff --git a/ChangeLog b/ChangeLog
index 34fb7d26b0..ecddcdc68c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+Sat Dec 14 00:22:16 2013 Nobuyoshi Nakada <[email protected]>
+
+ * thread.c: (exec_recursive): use rb_catch_protect() instead of
+ rb_catch_obj() and PUSH_TAG(), and reduce pushing tags and
+ machine stack usage.
+
Sat Dec 14 00:18:08 2013 Nobuyoshi Nakada <[email protected]>
* proc.c (mnew_from_me): achieve the original defined_class from
diff --git a/thread.c b/thread.c
index 2ee530f6b6..0e743c68e0 100644
--- a/thread.c
+++ b/thread.c
@@ -4880,19 +4880,7 @@ static VALUE
exec_recursive_i(RB_BLOCK_CALL_FUNC_ARGLIST(tag, data))
{
struct exec_recursive_params *p = (void *)data;
- VALUE result = Qundef;
- int state;
-
- recursive_push(p->list, p->objid, p->pairid);
- PUSH_TAG();
- if ((state = EXEC_TAG()) == 0) {
- result = (*p->func)(p->obj, p->arg, FALSE);
- }
- POP_TAG();
- recursive_pop(p->list, p->objid, p->pairid);
- if (state)
- JUMP_TAG(state);
- return result;
+ return (*p->func)(p->obj, p->arg, FALSE);
}
/*
@@ -4926,18 +4914,30 @@ exec_recursive(VALUE (*func) (VALUE, VALUE, int), VALUE obj, VALUE pairid, VALUE
return (*func)(obj, arg, TRUE);
}
else {
+ int state;
+
p.func = func;
if (outermost) {
recursive_push(p.list, ID2SYM(recursive_key), 0);
- result = rb_catch_obj(p.list, exec_recursive_i, (VALUE)&p);
+ recursive_push(p.list, p.objid, p.pairid);
+ result = rb_catch_protect(p.list, exec_recursive_i, (VALUE)&p, &state);
+ recursive_pop(p.list, p.objid, p.pairid);
recursive_pop(p.list, ID2SYM(recursive_key), 0);
+ if (state) JUMP_TAG(state);
if (result == p.list) {
result = (*func)(obj, arg, TRUE);
}
}
else {
- result = exec_recursive_i(0, (VALUE)&p, 0, 0, Qnil);
+ recursive_push(p.list, p.objid, p.pairid);
+ PUSH_TAG();
+ if ((state = EXEC_TAG()) == 0) {
+ result = (*func)(obj, arg, FALSE);
+ }
+ POP_TAG();
+ recursive_pop(p.list, p.objid, p.pairid);
+ if (state) JUMP_TAG(state);
}
}
*(volatile struct exec_recursive_params *)&p;