1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

* parse.y (rb_parser_malloc, rb_parser_free): manage parser stack on

heap.  [ruby-list:41199]


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_1_8@9355 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
nobu 2005-10-08 09:57:12 +00:00
parent 1e3a6c4d55
commit 3b4216d2b5
4 changed files with 89 additions and 7 deletions

View file

@ -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

4
gc.c
View file

@ -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 */

2
node.h
View file

@ -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,

85
parse.y
View file

@ -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