e$B%A%1%C%He(B #982 e$B$,99?7$5$l$^$7$?!#e(B (by Yusuke E.)
e$B1sF#$G$9!#e(B
e$B<!$N%9%/%j%W%H$,e(B stack level too deep (SystemStackError) e$B$G=*$o$j$^$9!#e(B
ruby -e ‘puts “A=[”; 0.upto(1000000) { puts " [22, 55]," }; puts “]”’ | ruby
e$B$I$&$$$&$H$-$K$3$l$,I,MW$K$J$C$?$N$+6=L#$,$"$j$^$9!#e(B
e$B$=$l$O$=$l$H$7$F!"%Q%C%A$r=q$$$F$_$^$7$?!#e(B
- concatarray e$BL?Na$rGQ;_$7$F!"0z?t$r$H$ke(B concatarrays
e$BL?Na$rF3F~$7$?e(B
- checkints e$BL?Na$rF3F~$7$?e(B
- e$B5pBg$JG[Ns%j%F%i%k$Oe(B 1000 e$B8D$4$H$Ke(B newarray
e$B$7$F:G8e$Ke(B concatarrays e$B$9$ke(B
e$B$H$j$"$($:G[Ns$@$1$NBP=h$J$N$G!"5pBg$J%O%C%7%e%j%F%i%k$r=q$/$H$?$V$sMn$A$^$9!#e(B
Index: insns.def
— insns.def (revision 21356)
+++ insns.def (working copy)
@@ -40,6 +40,20 @@
/* none */
}
+/**
-
@c check interrupts
-
@e check interrupts
- @j
- */
+DEFINE_INSN
+checkints
+()
+()
+()
+{
- RUBY_VM_CHECK_INTS();
+}
-
//
/ deal with variables /
//
@@ -486,31 +500,27 @@
/**
@c put
-
@e concat two arrays
-
@j e$BFs$D$NG[Nse(B ary1, ary2 e$B$rO"7k$7%9%?%C%/$X%W%C%7%e$9$k!#e(B
-
@e put concatenate arrays
-
@j e$B%9%?%C%/%H%C%W$NG[Ns$re(B n
e$B8DO"7k$7!$7k2L$r%9%?%C%/$K%W%C%7%e$9$k!#e(B
*/
DEFINE_INSN
-concatarray
-()
-(VALUE ary1, VALUE ary2st)
-(VALUE ary)
+concatarrays
+(rb_num_t num)
+(…)
+(VALUE val) // inc += 1 - num;
{
- const VALUE ary2 = ary2st;
- VALUE tmp1 = rb_check_convert_type(ary1, T_ARRAY, “Array”, “to_a”);
- VALUE tmp2 = rb_check_convert_type(ary2, T_ARRAY, “Array”, “to_a”);
- if (NIL_P(tmp1)) {
- tmp1 = rb_ary_new3(1, ary1);
- val = rb_ary_new();
- for (i = num - 1; i >= 0; i–) {
- const VALUE v = TOPN(i);
- VALUE tmp = rb_check_convert_type(v, T_ARRAY, “Array”, “to_a”);
- if (NIL_P(tmp)) {
-
tmp = rb_ary_new3(1, v);
- }
- rb_ary_concat(val, tmp);
}
-
- if (NIL_P(tmp2)) {
- tmp2 = rb_ary_new3(1, ary2);
- }
-
- if (tmp1 == ary1) {
- tmp1 = rb_ary_dup(ary1);
- }
- ary = rb_ary_concat(tmp1, tmp2);
/**
Index: compile.c
— compile.c (revision 21356)
+++ compile.c (working copy)
@@ -2195,12 +2195,14 @@
return COMPILE_OK;
}
+#define ARRAY_LITERAL_SPLIT_THRESHOLD 1000
+
static int
-compile_array_(rb_iseq_t *iseq, LINK_ANCHOR ret, NODE node_root,
+compile_array(rb_iseq_t *iseq, LINK_ANCHOR ret, NODE node_root, int
poped)
{
NODE *node = node_root;
- int len = node->nd_alen, line = nd_line(node), i=0;
-
int len = node->nd_alen, line = nd_line(node), i=0, split = 0;
-
VALUE opt_p = Qtrue;
DECL_ANCHOR(anchor);
INIT_ANCHOR(anchor);
@@ -2211,6 +2213,11 @@
ruby_node_name(nd_type(node)));
}
-
if (i > 0 && i % ARRAY_LITERAL_SPLIT_THRESHOLD == 0 && !poped) {
-
ADD_INSN1(anchor, line, newarray,
INT2FIX(ARRAY_LITERAL_SPLIT_THRESHOLD));
-
ADD_INSN(anchor, line, checkints);
-
split++;
-
}
i++;
if (opt_p && nd_type(node->nd_head) != NODE_LIT) {
opt_p = Qfalse;
@@ -2243,17 +2250,36 @@
}
else {
if (!poped) {
-
if (len % ARRAY_LITERAL_SPLIT_THRESHOLD) {
- ADD_INSN1(anchor, line, newarray, INT2FIX(len %
ARRAY_LITERAL_SPLIT_THRESHOLD));
- split++;
-
}
-
if (split >= 2) ADD_INSN1(anchor, line, concatarrays,
INT2FIX(split));
}
APPEND_LIST(ret, anchor);
}
return len;
}
-static VALUE
-compile_array(rb_iseq_t *iseq, LINK_ANCHOR ret, NODE node_root, VALUE
opt_p)
+static long
+compile_list(rb_iseq_t *iseq, LINK_ANCHOR ret, NODE node_root)
{
- return compile_array_(iseq, ret, node_root, opt_p, 0);
- NODE *node = node_root;
- int i = 0;
-
- if (nd_type(node) != NODE_ZARRAY) {
- while (node) {
-
if (nd_type(node) != NODE_ARRAY) {
- rb_bug(“compile_list: This node is not NODE_ARRAY, but %s”,
-
ruby_node_name(nd_type(node)));
-
}
-
i++;
-
COMPILE(ret, "list element", node->nd_head);
-
node = node->nd_next;
- }
- }
-
- return i;
}
static VALUE
@@ -2841,8 +2867,7 @@
*flag |= VM_CALL_ARGS_SPLAT_BIT;
if (next_is_array) {
- argc = INT2FIX(compile_array(iseq, args, argn->nd_head, Qfalse) +
1);
- POP_ELEMENT(args);
- argc = INT2FIX(compile_list(iseq, args, argn->nd_head) + 1);
}
else {
argn = argn->nd_head;
@@ -2851,8 +2876,7 @@
break;
}
case NODE_ARRAY: {
-
argc = INT2FIX(compile_list(iseq, args, argn));
break;
}
default: {
@@ -2862,10 +2886,7 @@
}
if (nsplat > 1) {
-
ADD_INSN1(args_splat, nd_line(args), concatarrays, INT2FIX(nsplat));
}
if (!LIST_SIZE_ZERO(args_splat)) {
@@ -3746,7 +3767,7 @@
COMPILE(ret, "NODE_OP_ASGN1 args->head: ",
node->nd_args->nd_head);
if (flag & VM_CALL_ARGS_SPLAT_BIT) {
ADD_INSN1(ret, nd_line(node), newarray, INT2FIX(1));
- ADD_INSN(ret, nd_line(node), concatarray);
- ADD_INSN1(ret, nd_line(node), concatarrays, INT2FIX(2));
ADD_SEND_R(ret, nd_line(node), ID2SYM(idASET),
argc, Qfalse, LONG2FIX(flag));
}
@@ -3769,7 +3790,7 @@
ADD_SEND(ret, nd_line(node), ID2SYM(id), INT2FIX(1));
if (flag & VM_CALL_ARGS_SPLAT_BIT) {
ADD_INSN1(ret, nd_line(node), newarray, INT2FIX(1));
- ADD_INSN(ret, nd_line(node), concatarray);
- ADD_INSN1(ret, nd_line(node), concatarrays, INT2FIX(2));
ADD_SEND_R(ret, nd_line(node), ID2SYM(idASET),
argc, Qfalse, LONG2FIX(flag));
}
@@ -4070,7 +4091,7 @@
ADD_INSN1(args, nd_line(node), getlocal, INT2FIX(idx));
}
ADD_INSN1(args, nd_line(node), newarray, INT2FIX(j));
@@ -4098,7 +4119,7 @@
break;
}
case NODE_ARRAY:{
- compile_array_(iseq, ret, node, Qtrue, poped);
- compile_array(iseq, ret, node, poped);
break;
}
case NODE_ZARRAY:{
@@ -4127,8 +4148,7 @@
INIT_ANCHOR(list);
switch (type) {
case NODE_ARRAY:{
-
compile_array(iseq, list, node->nd_head, Qfalse);
-
size = OPERAND_AT(POP_ELEMENT(list), 0);
- ADD_INSN(ret, nd_line(node), concatarray);
- ADD_INSN1(ret, nd_line(node), concatarrays, INT2FIX(2));
break;
}
case NODE_ARGSPUSH:{
COMPILE(ret, “arsgpush head”, node->nd_head);
COMPILE(ret, “argspush body”, node->nd_body);
ADD_INSN1(ret, nd_line(node), newarray, INT2FIX(1));
- ADD_INSN(ret, nd_line(node), concatarray);
- ADD_INSN1(ret, nd_line(node), concatarrays, INT2FIX(2));
break;
}
case NODE_SPLAT:{
–
Yusuke ENDOH [email protected]
http://redmine.ruby-lang.org/issues/show/982