summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authornobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2005-10-08 09:57:12 +0000
committernobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2005-10-08 09:57:12 +0000
commit2f7f565d68461650fe435014f82e6f6658d018b5 (patch)
treea2767d742958b3f92eb58b42877d6d1603c43dc2
parent46d8d022a2d086b2b73b5e1df4c3a2d6214b39b6 (diff)
downloadruby-2f7f565d68461650fe435014f82e6f6658d018b5.tar.gz
ruby-2f7f565d68461650fe435014f82e6f6658d018b5.tar.xz
ruby-2f7f565d68461650fe435014f82e6f6658d018b5.zip
* parse.y (rb_parser_malloc, rb_parser_free): manage parser stack on
heap. [ruby-list:41199] git-svn-id: http://svn.ruby-lang.org/repos/ruby/branches/ruby_1_8@9355 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r--ChangeLog5
-rw-r--r--gc.c4
-rw-r--r--node.h2
-rw-r--r--parse.y85
4 files changed, 89 insertions, 7 deletions
diff --git a/ChangeLog b/ChangeLog
index 5fdac2cc3..db7239f9f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+Sat Oct 8 18:56:37 2005 Nobuyoshi Nakada <nobu@ruby-lang.org>
+
+ * parse.y (rb_parser_malloc, rb_parser_free): manage parser stack on
+ heap. [ruby-list:41199]
+
Fri Oct 7 09:54:00 2005 Yukihiro Matsumoto <matz@ruby-lang.org>
* lib/cgi.rb (CGI::Cookie::parse): Cookies from Nokia devices may
diff --git a/gc.c b/gc.c
index ca3862f0b..06c4420df 100644
--- a/gc.c
+++ b/gc.c
@@ -880,13 +880,11 @@ gc_mark_children(ptr, lev)
case NODE_BLOCK_ARG:
case NODE_POSTEXE:
break;
-#ifdef C_ALLOCA
case NODE_ALLOCA:
mark_locations_array((VALUE*)obj->as.node.u1.value,
obj->as.node.u3.cnt);
ptr = (VALUE)obj->as.node.u2.node;
goto again;
-#endif
default: /* unlisted NODE */
if (is_pointer_to_heap(obj->as.node.u1.node)) {
@@ -1230,11 +1228,9 @@ obj_free(obj)
RUBY_CRITICAL(free(RANY(obj)->as.node.u1.tbl));
}
break;
-#ifdef C_ALLOCA
case NODE_ALLOCA:
RUBY_CRITICAL(free(RANY(obj)->as.node.u1.node));
break;
-#endif
}
return; /* no need to free iv_tbl */
diff --git a/node.h b/node.h
index 505977985..fe5b5f56f 100644
--- a/node.h
+++ b/node.h
@@ -115,9 +115,7 @@ enum node_type {
NODE_DEFINED,
NODE_NEWLINE,
NODE_POSTEXE,
-#ifdef C_ALLOCA
NODE_ALLOCA,
-#endif
NODE_DMETHOD,
NODE_BMETHOD,
NODE_MEMO,
diff --git a/parse.y b/parse.y
index fe2cd0685..12a1cca4f 100644
--- a/parse.y
+++ b/parse.y
@@ -13,6 +13,10 @@
%{
#define YYDEBUG 1
+#define YYERROR_VERBOSE 1
+#ifndef YYSTACK_USE_ALLOCA
+#define YYSTACK_USE_ALLOCA 0
+#endif
#include "ruby.h"
#include "env.h"
@@ -23,6 +27,19 @@
#include <errno.h>
#include <ctype.h>
+#define YYMALLOC rb_parser_malloc
+#define YYREALLOC rb_parser_realloc
+#define YYCALLOC rb_parser_calloc
+#define YYFREE rb_parser_free
+#define malloc YYMALLOC
+#define realloc YYREALLOC
+#define calloc YYCALLOC
+#define free YYFREE
+static void *rb_parser_malloc _((size_t));
+static void *rb_parser_realloc _((void *, size_t));
+static void *rb_parser_calloc _((size_t, size_t));
+static void rb_parser_free _((void *));
+
#define yyparse ruby_yyparse
#define yylex ruby_yylex
#define yyerror ruby_yyerror
@@ -2528,6 +2545,7 @@ int ruby_in_compile = 0;
int ruby__end__seen;
static VALUE ruby_debug_lines;
+static NODE *parser_heap;
static NODE*
yycompile(f, line)
@@ -2567,6 +2585,7 @@ yycompile(f, line)
lex_strterm = 0;
ruby_current_node = 0;
ruby_sourcefile = rb_source_filename(f);
+ parser_heap = 0;
n = yyparse();
ruby_debug_lines = 0;
compile_for_eval = 0;
@@ -2578,6 +2597,7 @@ yycompile(f, line)
in_single = 0;
in_def = 0;
cur_mid = 0;
+ parser_heap = 0;
vp = ruby_dyna_vars;
ruby_dyna_vars = vars;
@@ -5726,7 +5746,7 @@ dyna_init(node, pre)
int
ruby_parser_stack_on_heap()
{
-#if defined(YYBISON) && !defined(C_ALLOCA)
+#if defined(YYMALLOC)
return Qfalse;
#else
return Qtrue;
@@ -5743,6 +5763,7 @@ rb_gc_mark_parser()
rb_gc_mark(lex_lastline);
rb_gc_mark(lex_input);
rb_gc_mark((VALUE)lex_strterm);
+ rb_gc_mark((VALUE)parser_heap);
}
void
@@ -6085,3 +6106,65 @@ rb_lastline_set(val)
special_local_set('_', val);
}
}
+
+#ifdef YYMALLOC
+#define HEAPCNT(n, size) ((size) % sizeof(YYSTYPE) ? 0 : (n) * (size) / sizeof(YYSTYPE))
+#define NEWHEAP(cnt) rb_node_newnode(NODE_ALLOCA, 0, (VALUE)parser_heap, cnt)
+#define ADD2HEAP(n, ptr) ((parser_heap = (n))->u1.node = (ptr))
+
+static void *
+rb_parser_malloc(size)
+ size_t size;
+{
+ NODE *n = NEWHEAP(HEAPCNT(1, size));
+
+ return ADD2HEAP(n, xmalloc(size));
+}
+
+static void *
+rb_parser_calloc(nelem, size)
+ size_t nelem, size;
+{
+ NODE *n = NEWHEAP(HEAPCNT(nelem, size));
+
+ return ADD2HEAP(n, xcalloc(nelem, size));
+}
+
+static void *
+rb_parser_realloc(ptr, size)
+ void *ptr;
+ size_t size;
+{
+ NODE *n;
+ size_t cnt = HEAPCNT(1, size);
+
+ if (ptr && (n = parser_heap) != NULL) {
+ do {
+ if (n->u1.node == ptr) {
+ n->u1.node = ptr = xrealloc(ptr, size);
+ if (n->u3.cnt) n->u3.cnt = cnt;
+ return ptr;
+ }
+ } while ((n = n->u2.node) != NULL);
+ }
+ n = NEWHEAP(cnt);
+ return ADD2HEAP(n, xrealloc(ptr, size));
+}
+
+static void
+rb_parser_free(ptr)
+ void *ptr;
+{
+ NODE **prev = &parser_heap, *n;
+
+ while (n = *prev) {
+ if (n->u1.node == ptr) {
+ *prev = n->u2.node;
+ rb_gc_force_recycle((VALUE)n);
+ break;
+ }
+ prev = &n->u2.node;
+ }
+ xfree(ptr);
+}
+#endif