summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authornobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2013-12-13 15:22:18 +0000
committernobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2013-12-13 15:22:18 +0000
commit26d147c733d87d3f671c331b8fd98bf6c5d4b7d5 (patch)
tree301898bcce0808d3d495abf26722f7df048f9f86
parent569ab987049a72bf940f718bef03382e1025994c (diff)
thread.c: reduce tags and stack
* thread.c: (exec_recursive): use rb_catch_protect() instead of rb_catch_obj() and PUSH_TAG(), and reduce pushing tags and machine stack usage. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@44181 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-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 <nobu@ruby-lang.org>
+
+ * 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 <nobu@ruby-lang.org>
* 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;