summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAaron Patterson <tenderlove@ruby-lang.org>2019-09-05 12:44:23 -0700
committerAaron Patterson <tenderlove@ruby-lang.org>2019-09-05 12:44:23 -0700
commit092f31e7e23c0ee04df987f0c0f979d036971804 (patch)
tree235b1fa372c8007aaca62c6bc205d5c23054951f
parentf211ab20157a840770567ea182b1372e339cd82a (diff)
Reverting node marking until I can fix GC problem.
Looks like we're getting WB misses during stressful GC on startup. I am investigating.
-rw-r--r--node.c157
-rw-r--r--node.h4
-rw-r--r--parse.y40
3 files changed, 36 insertions, 165 deletions
diff --git a/node.c b/node.c
index 64e2d8f43d..f4df845d2c 100644
--- a/node.c
+++ b/node.c
@@ -1116,45 +1116,30 @@ 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;
-typedef struct {
+struct node_buffer_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)
+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 = head;
- nb->head->len = nb->len;
+ nb->head = nb->last = (node_buffer_elem_t*) &nb[1];
nb->head->next = NULL;
-}
-
-static node_buffer_t *
-rb_node_buffer_new(void)
-{
- 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;
+ nb->mark_ary = rb_ary_tmp_new(0);
return nb;
}
static void
-node_buffer_list_free(node_buffer_list_t * nb)
+rb_node_buffer_free(node_buffer_t *nb)
{
node_buffer_elem_t *nbe = nb->head;
@@ -1163,24 +1148,17 @@ node_buffer_list_free(node_buffer_list_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);
}
-static NODE *
-ast_newnode_in_bucket(node_buffer_list_t *nb)
+NODE *
+rb_ast_newnode(rb_ast_t *ast)
{
+ 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;
@@ -1189,27 +1167,6 @@ ast_newnode_in_bucket(node_buffer_list_t *nb)
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)
{
@@ -1222,85 +1179,17 @@ 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
@@ -1312,18 +1201,6 @@ 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)
{
@@ -1332,8 +1209,11 @@ 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);
- size += buffer_list_size(&nb->unmarkable);
- size += buffer_list_size(&nb->markable);
+ 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;
}
@@ -1347,8 +1227,5 @@ 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);
}
diff --git a/node.h b/node.h
index 220438e182..dbc3162512 100644
--- a/node.h
+++ b/node.h
@@ -409,7 +409,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*, enum node_type type);
+NODE *rb_ast_newnode(rb_ast_t*);
void rb_ast_delete_node(rb_ast_t*, NODE *n);
VALUE rb_parser_new(void);
@@ -452,14 +452,12 @@ 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;
diff --git a/parse.y b/parse.y
index 29b8628e39..63d8f53c1d 100644
--- a/parse.y
+++ b/parse.y
@@ -298,6 +298,9 @@ 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)
@@ -344,11 +347,7 @@ 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;
}
@@ -2787,11 +2786,10 @@ 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);
- ID *tbl = ALLOC_N(ID, 3);
- VALUE tmpbuf = rb_imemo_tmpbuf_auto_free_pointer(tbl);
- RB_OBJ_WRITTEN(p->ast, Qnil, tmpbuf);
+ rb_imemo_tmpbuf_t *tmpbuf = new_tmpbuf();
+ ID *tbl = ALLOC_N(ID, 2);
tbl[0] = 1 /* length of local var table */; tbl[1] = id /* internal id */;
- tbl[2] = tmpbuf;
+ tmpbuf->ptr = (VALUE *)tbl;
switch (nd_type($2)) {
case NODE_LASGN:
@@ -9357,7 +9355,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, type);
+ NODE *n = rb_ast_newnode(p->ast);
rb_node_init(n, type, a0, a1, a2);
@@ -9611,7 +9609,9 @@ literal_concat(struct parser_params *p, NODE *head, NODE *tail, const YYLTYPE *l
goto append;
}
else {
- list_concat(head, NEW_NODE(NODE_ARRAY, NEW_STR(tail->nd_lit, loc), tail->nd_alen, tail->nd_next, loc));
+ nd_set_type(tail, NODE_ARRAY);
+ tail->nd_head = NEW_STR(tail->nd_lit, loc);
+ list_concat(head, tail);
}
break;
@@ -11125,11 +11125,10 @@ 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);
- VALUE tmpbuf = rb_imemo_tmpbuf_auto_free_pointer(args);
- args->imemo = tmpbuf;
- RB_OBJ_WRITTEN(p->ast, Qnil, tmpbuf);
+ tmpbuf->ptr = (VALUE *)args;
node = NEW_NODE(NODE_ARGS, 0, 0, args, &NULL_LOC);
if (p->error_p) return node;
@@ -11235,12 +11234,11 @@ 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);
- VALUE tmpbuf = rb_imemo_tmpbuf_auto_free_pointer(apinfo);
+ tmpbuf->ptr = (VALUE *)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;
@@ -11625,9 +11623,11 @@ 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 + 2);
+ buf = ALLOC_N(ID, cnt + 1);
+ tmpbuf->ptr = (void *)buf;
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,13 +11636,9 @@ local_tbl(struct parser_params *p)
buf[j++] = id;
}
}
- if (--j < cnt) REALLOC_N(buf, ID, (cnt = j) + 2);
+ if (--j < cnt) tmpbuf->ptr = (void *)REALLOC_N(buf, ID, (cnt = j) + 1);
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