mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
Revert "Reverting node marking until I can fix GC problem."
This reverts commit 092f31e7e2
.
This commit is contained in:
parent
9b53a69d57
commit
4524780d17
3 changed files with 166 additions and 37 deletions
159
node.c
159
node.c
|
@ -1116,30 +1116,45 @@ rb_node_init(NODE *n, enum node_type type, VALUE a0, VALUE a1, VALUE a2)
|
|||
|
||||
typedef struct node_buffer_elem_struct {
|
||||
struct node_buffer_elem_struct *next;
|
||||
long len;
|
||||
NODE buf[FLEX_ARY_LEN];
|
||||
} node_buffer_elem_t;
|
||||
|
||||
struct node_buffer_struct {
|
||||
typedef struct {
|
||||
long idx, len;
|
||||
node_buffer_elem_t *head;
|
||||
node_buffer_elem_t *last;
|
||||
} node_buffer_list_t;
|
||||
|
||||
struct node_buffer_struct {
|
||||
node_buffer_list_t unmarkable;
|
||||
node_buffer_list_t markable;
|
||||
VALUE mark_ary;
|
||||
};
|
||||
|
||||
static void
|
||||
init_node_buffer_list(node_buffer_list_t * nb, node_buffer_elem_t *head)
|
||||
{
|
||||
nb->idx = 0;
|
||||
nb->len = NODE_BUF_DEFAULT_LEN;
|
||||
nb->head = nb->last = head;
|
||||
nb->head->len = nb->len;
|
||||
nb->head->next = NULL;
|
||||
}
|
||||
|
||||
static node_buffer_t *
|
||||
rb_node_buffer_new(void)
|
||||
{
|
||||
node_buffer_t *nb = xmalloc(sizeof(node_buffer_t) + offsetof(node_buffer_elem_t, buf) + NODE_BUF_DEFAULT_LEN * sizeof(NODE));
|
||||
nb->idx = 0;
|
||||
nb->len = NODE_BUF_DEFAULT_LEN;
|
||||
nb->head = nb->last = (node_buffer_elem_t*) &nb[1];
|
||||
nb->head->next = NULL;
|
||||
nb->mark_ary = rb_ary_tmp_new(0);
|
||||
size_t bucket_size = offsetof(node_buffer_elem_t, buf) + NODE_BUF_DEFAULT_LEN * sizeof(NODE);
|
||||
node_buffer_t *nb = xmalloc(sizeof(node_buffer_t) + (bucket_size * 2));
|
||||
init_node_buffer_list(&nb->unmarkable, (node_buffer_elem_t*)&nb[1]);
|
||||
init_node_buffer_list(&nb->markable, (node_buffer_elem_t*)((size_t)nb->unmarkable.head + bucket_size));
|
||||
nb->mark_ary = Qnil;
|
||||
return nb;
|
||||
}
|
||||
|
||||
static void
|
||||
rb_node_buffer_free(node_buffer_t *nb)
|
||||
node_buffer_list_free(node_buffer_list_t * nb)
|
||||
{
|
||||
node_buffer_elem_t *nbe = nb->head;
|
||||
|
||||
|
@ -1148,17 +1163,24 @@ rb_node_buffer_free(node_buffer_t *nb)
|
|||
nbe = nbe->next;
|
||||
xfree(buf);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
rb_node_buffer_free(node_buffer_t *nb)
|
||||
{
|
||||
node_buffer_list_free(&nb->unmarkable);
|
||||
node_buffer_list_free(&nb->markable);
|
||||
xfree(nb);
|
||||
}
|
||||
|
||||
NODE *
|
||||
rb_ast_newnode(rb_ast_t *ast)
|
||||
static NODE *
|
||||
ast_newnode_in_bucket(node_buffer_list_t *nb)
|
||||
{
|
||||
node_buffer_t *nb = ast->node_buffer;
|
||||
if (nb->idx >= nb->len) {
|
||||
long n = nb->len * 2;
|
||||
node_buffer_elem_t *nbe;
|
||||
nbe = xmalloc(offsetof(node_buffer_elem_t, buf) + n * sizeof(NODE));
|
||||
nbe->len = n;
|
||||
nb->idx = 0;
|
||||
nb->len = n;
|
||||
nbe->next = nb->head;
|
||||
|
@ -1167,6 +1189,27 @@ rb_ast_newnode(rb_ast_t *ast)
|
|||
return &nb->head->buf[nb->idx++];
|
||||
}
|
||||
|
||||
NODE *
|
||||
rb_ast_newnode(rb_ast_t *ast, enum node_type type)
|
||||
{
|
||||
node_buffer_t *nb = ast->node_buffer;
|
||||
switch (type) {
|
||||
case NODE_LIT:
|
||||
case NODE_STR:
|
||||
case NODE_XSTR:
|
||||
case NODE_DSTR:
|
||||
case NODE_DXSTR:
|
||||
case NODE_DREGX:
|
||||
case NODE_DSYM:
|
||||
case NODE_ARGS:
|
||||
case NODE_SCOPE:
|
||||
case NODE_ARYPTN:
|
||||
return ast_newnode_in_bucket(&nb->markable);
|
||||
default:
|
||||
return ast_newnode_in_bucket(&nb->unmarkable);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
rb_ast_delete_node(rb_ast_t *ast, NODE *n)
|
||||
{
|
||||
|
@ -1179,17 +1222,85 @@ rb_ast_t *
|
|||
rb_ast_new(void)
|
||||
{
|
||||
node_buffer_t *nb = rb_node_buffer_new();
|
||||
VALUE mark_ary = nb->mark_ary;
|
||||
rb_ast_t *ast = (rb_ast_t *)rb_imemo_new(imemo_ast, 0, 0, 0, (VALUE)nb);
|
||||
RB_OBJ_WRITTEN(ast, Qnil, mark_ary);
|
||||
return ast;
|
||||
}
|
||||
|
||||
typedef void node_itr_t(void *ctx, NODE * node);
|
||||
|
||||
static void
|
||||
iterate_buffer_elements(node_buffer_elem_t *nbe, long len, node_itr_t *func, void *ctx)
|
||||
{
|
||||
long cursor;
|
||||
for (cursor = 0; cursor < len; cursor++) {
|
||||
func(ctx, &nbe->buf[cursor]);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
iterate_node_values(node_buffer_list_t *nb, node_itr_t * func, void *ctx)
|
||||
{
|
||||
node_buffer_elem_t *nbe = nb->head;
|
||||
|
||||
/* iterate over the head first because it's not full */
|
||||
iterate_buffer_elements(nbe, nb->idx, func, ctx);
|
||||
|
||||
nbe = nbe->next;
|
||||
while (nbe) {
|
||||
iterate_buffer_elements(nbe, nbe->len, func, ctx);
|
||||
nbe = nbe->next;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
mark_ast_value(void *ctx, NODE * node)
|
||||
{
|
||||
switch (nd_type(node)) {
|
||||
case NODE_SCOPE:
|
||||
{
|
||||
ID *buf = node->nd_tbl;
|
||||
if (buf) {
|
||||
unsigned int size = (unsigned int)*buf;
|
||||
rb_gc_mark((VALUE)buf[size + 1]);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case NODE_ARYPTN:
|
||||
{
|
||||
struct rb_ary_pattern_info *apinfo = node->nd_apinfo;
|
||||
rb_gc_mark(apinfo->imemo);
|
||||
break;
|
||||
}
|
||||
case NODE_ARGS:
|
||||
{
|
||||
struct rb_args_info *args = node->nd_ainfo;
|
||||
rb_gc_mark(args->imemo);
|
||||
break;
|
||||
}
|
||||
case NODE_LIT:
|
||||
case NODE_STR:
|
||||
case NODE_XSTR:
|
||||
case NODE_DSTR:
|
||||
case NODE_DXSTR:
|
||||
case NODE_DREGX:
|
||||
case NODE_DSYM:
|
||||
rb_gc_mark(node->nd_lit);
|
||||
break;
|
||||
default:
|
||||
rb_bug("unreachable");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
rb_ast_mark(rb_ast_t *ast)
|
||||
{
|
||||
if (ast->node_buffer) rb_gc_mark(ast->node_buffer->mark_ary);
|
||||
if (ast->body.compile_option) rb_gc_mark(ast->body.compile_option);
|
||||
if (ast->node_buffer) {
|
||||
node_buffer_t *nb = ast->node_buffer;
|
||||
|
||||
iterate_node_values(&nb->markable, mark_ast_value, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -1201,6 +1312,18 @@ rb_ast_free(rb_ast_t *ast)
|
|||
}
|
||||
}
|
||||
|
||||
static size_t
|
||||
buffer_list_size(node_buffer_list_t *nb)
|
||||
{
|
||||
size_t size = 0;
|
||||
node_buffer_elem_t *nbe = nb->head;
|
||||
while (nbe != nb->last) {
|
||||
nbe = nbe->next;
|
||||
size += offsetof(node_buffer_elem_t, buf) + nb->len * sizeof(NODE);
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
size_t
|
||||
rb_ast_memsize(const rb_ast_t *ast)
|
||||
{
|
||||
|
@ -1209,11 +1332,8 @@ rb_ast_memsize(const rb_ast_t *ast)
|
|||
|
||||
if (nb) {
|
||||
size += sizeof(node_buffer_t) + offsetof(node_buffer_elem_t, buf) + NODE_BUF_DEFAULT_LEN * sizeof(NODE);
|
||||
node_buffer_elem_t *nbe = nb->head;
|
||||
while (nbe != nb->last) {
|
||||
nbe = nbe->next;
|
||||
size += offsetof(node_buffer_elem_t, buf) + nb->len * sizeof(NODE);
|
||||
}
|
||||
size += buffer_list_size(&nb->unmarkable);
|
||||
size += buffer_list_size(&nb->markable);
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
@ -1227,5 +1347,8 @@ rb_ast_dispose(rb_ast_t *ast)
|
|||
void
|
||||
rb_ast_add_mark_object(rb_ast_t *ast, VALUE obj)
|
||||
{
|
||||
if (NIL_P(ast->node_buffer->mark_ary)) {
|
||||
RB_OBJ_WRITE(ast, &ast->node_buffer->mark_ary, rb_ary_tmp_new(0));
|
||||
}
|
||||
rb_ary_push(ast->node_buffer->mark_ary, obj);
|
||||
}
|
||||
|
|
4
node.h
4
node.h
|
@ -408,7 +408,7 @@ void rb_ast_dispose(rb_ast_t*);
|
|||
void rb_ast_free(rb_ast_t*);
|
||||
size_t rb_ast_memsize(const rb_ast_t*);
|
||||
void rb_ast_add_mark_object(rb_ast_t*, VALUE);
|
||||
NODE *rb_ast_newnode(rb_ast_t*);
|
||||
NODE *rb_ast_newnode(rb_ast_t*, enum node_type type);
|
||||
void rb_ast_delete_node(rb_ast_t*, NODE *n);
|
||||
|
||||
VALUE rb_parser_new(void);
|
||||
|
@ -451,12 +451,14 @@ struct rb_args_info {
|
|||
|
||||
NODE *opt_args;
|
||||
int no_kwarg;
|
||||
VALUE imemo;
|
||||
};
|
||||
|
||||
struct rb_ary_pattern_info {
|
||||
NODE *pre_args;
|
||||
NODE *rest_arg;
|
||||
NODE *post_args;
|
||||
VALUE imemo;
|
||||
};
|
||||
|
||||
struct parser_params;
|
||||
|
|
40
parse.y
40
parse.y
|
@ -298,9 +298,6 @@ struct parser_params {
|
|||
#endif
|
||||
};
|
||||
|
||||
#define new_tmpbuf() \
|
||||
(rb_imemo_tmpbuf_t *)add_mark_object(p, rb_imemo_tmpbuf_auto_free_pointer(NULL))
|
||||
|
||||
#define intern_cstr(n,l,en) rb_intern3(n,l,en)
|
||||
|
||||
#define STR_NEW(ptr,len) rb_enc_str_new((ptr),(len),p->enc)
|
||||
|
@ -347,7 +344,11 @@ add_mark_object(struct parser_params *p, VALUE obj)
|
|||
&& !RB_TYPE_P(obj, T_NODE) /* Ripper jumbles NODE objects and other objects... */
|
||||
#endif
|
||||
) {
|
||||
#ifdef RIPPER
|
||||
rb_ast_add_mark_object(p->ast, obj);
|
||||
#else
|
||||
RB_OBJ_WRITTEN(p->ast, Qundef, obj);
|
||||
#endif
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
|
@ -2786,10 +2787,11 @@ primary : literal
|
|||
ID id = internal_id(p);
|
||||
NODE *m = NEW_ARGS_AUX(0, 0, &NULL_LOC);
|
||||
NODE *args, *scope, *internal_var = NEW_DVAR(id, &@2);
|
||||
rb_imemo_tmpbuf_t *tmpbuf = new_tmpbuf();
|
||||
ID *tbl = ALLOC_N(ID, 2);
|
||||
ID *tbl = ALLOC_N(ID, 3);
|
||||
VALUE tmpbuf = rb_imemo_tmpbuf_auto_free_pointer(tbl);
|
||||
RB_OBJ_WRITTEN(p->ast, Qnil, tmpbuf);
|
||||
tbl[0] = 1 /* length of local var table */; tbl[1] = id /* internal id */;
|
||||
tmpbuf->ptr = (VALUE *)tbl;
|
||||
tbl[2] = tmpbuf;
|
||||
|
||||
switch (nd_type($2)) {
|
||||
case NODE_LASGN:
|
||||
|
@ -9355,7 +9357,7 @@ yylex(YYSTYPE *lval, YYLTYPE *yylloc, struct parser_params *p)
|
|||
static NODE*
|
||||
node_newnode(struct parser_params *p, enum node_type type, VALUE a0, VALUE a1, VALUE a2, const rb_code_location_t *loc)
|
||||
{
|
||||
NODE *n = rb_ast_newnode(p->ast);
|
||||
NODE *n = rb_ast_newnode(p->ast, type);
|
||||
|
||||
rb_node_init(n, type, a0, a1, a2);
|
||||
|
||||
|
@ -9609,9 +9611,7 @@ literal_concat(struct parser_params *p, NODE *head, NODE *tail, const YYLTYPE *l
|
|||
goto append;
|
||||
}
|
||||
else {
|
||||
nd_set_type(tail, NODE_LIST);
|
||||
tail->nd_head = NEW_STR(tail->nd_lit, loc);
|
||||
list_concat(head, tail);
|
||||
list_concat(head, NEW_NODE(NODE_LIST, NEW_STR(tail->nd_lit, loc), tail->nd_alen, tail->nd_next, loc));
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -11125,10 +11125,11 @@ new_args_tail(struct parser_params *p, NODE *kw_args, ID kw_rest_arg, ID block,
|
|||
int saved_line = p->ruby_sourceline;
|
||||
struct rb_args_info *args;
|
||||
NODE *node;
|
||||
rb_imemo_tmpbuf_t *tmpbuf = new_tmpbuf();
|
||||
|
||||
args = ZALLOC(struct rb_args_info);
|
||||
tmpbuf->ptr = (VALUE *)args;
|
||||
VALUE tmpbuf = rb_imemo_tmpbuf_auto_free_pointer(args);
|
||||
args->imemo = tmpbuf;
|
||||
RB_OBJ_WRITTEN(p->ast, Qnil, tmpbuf);
|
||||
node = NEW_NODE(NODE_ARGS, 0, 0, args, &NULL_LOC);
|
||||
if (p->error_p) return node;
|
||||
|
||||
|
@ -11234,11 +11235,12 @@ new_array_pattern_tail(struct parser_params *p, NODE *pre_args, int has_rest, ID
|
|||
int saved_line = p->ruby_sourceline;
|
||||
struct rb_ary_pattern_info *apinfo;
|
||||
NODE *node;
|
||||
rb_imemo_tmpbuf_t *tmpbuf = new_tmpbuf();
|
||||
|
||||
apinfo = ZALLOC(struct rb_ary_pattern_info);
|
||||
tmpbuf->ptr = (VALUE *)apinfo;
|
||||
VALUE tmpbuf = rb_imemo_tmpbuf_auto_free_pointer(apinfo);
|
||||
node = NEW_NODE(NODE_ARYPTN, 0, 0, apinfo, loc);
|
||||
apinfo->imemo = tmpbuf;
|
||||
RB_OBJ_WRITTEN(p->ast, Qnil, tmpbuf);
|
||||
|
||||
apinfo->pre_args = pre_args;
|
||||
|
||||
|
@ -11623,11 +11625,9 @@ local_tbl(struct parser_params *p)
|
|||
int cnt = cnt_args + cnt_vars;
|
||||
int i, j;
|
||||
ID *buf;
|
||||
rb_imemo_tmpbuf_t *tmpbuf = new_tmpbuf();
|
||||
|
||||
if (cnt <= 0) return 0;
|
||||
buf = ALLOC_N(ID, cnt + 1);
|
||||
tmpbuf->ptr = (void *)buf;
|
||||
buf = ALLOC_N(ID, cnt + 2);
|
||||
MEMCPY(buf+1, p->lvtbl->args->tbl, ID, cnt_args);
|
||||
/* remove IDs duplicated to warn shadowing */
|
||||
for (i = 0, j = cnt_args+1; i < cnt_vars; ++i) {
|
||||
|
@ -11636,9 +11636,13 @@ local_tbl(struct parser_params *p)
|
|||
buf[j++] = id;
|
||||
}
|
||||
}
|
||||
if (--j < cnt) tmpbuf->ptr = (void *)REALLOC_N(buf, ID, (cnt = j) + 1);
|
||||
if (--j < cnt) REALLOC_N(buf, ID, (cnt = j) + 2);
|
||||
buf[0] = cnt;
|
||||
|
||||
VALUE tmpbuf = rb_imemo_tmpbuf_auto_free_pointer(buf);
|
||||
buf[cnt + 1] = (ID)tmpbuf;
|
||||
RB_OBJ_WRITTEN(p->ast, Qnil, tmpbuf);
|
||||
|
||||
return buf;
|
||||
}
|
||||
#endif
|
||||
|
|
Loading…
Add table
Reference in a new issue