summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAaron Patterson <tenderlove@ruby-lang.org>2019-09-04 16:00:19 -0700
committerAaron Patterson <tenderlove@ruby-lang.org>2019-09-05 10:13:50 -0700
commitf0fd1c0cd8d34b870a3011a36f5179d1b5f3547d (patch)
tree5965f256497951f0ca70fbf6e927880d915c0e8a
parent64817a7cfd4a258b45356e6da8fbdd0040b3231b (diff)
downloadruby-f0fd1c0cd8d34b870a3011a36f5179d1b5f3547d.tar.gz
Stash the imemo buf at the end of the ID list
Now we can reach the ID table buffer from the id table itself, so when SCOPE nodes are marked we can keep the buffers alive. This eliminates the need for the "mark array" during normal parse / compile (IOW *not* Ripper).
-rw-r--r--node.c10
-rw-r--r--parse.y24
2 files changed, 17 insertions, 17 deletions
diff --git a/node.c b/node.c
index 8a519f2947..064ce006ad 100644
--- a/node.c
+++ b/node.c
@@ -1218,6 +1218,15 @@ 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_LIT:
case NODE_STR:
case NODE_XSTR:
@@ -1226,7 +1235,6 @@ mark_ast_value(void *ctx, NODE * node)
case NODE_DREGX:
case NODE_DSYM:
case NODE_ARGS:
- case NODE_FOR:
case NODE_ARYPTN:
rb_gc_mark(node->nd_lit);
break;
diff --git a/parse.y b/parse.y
index 08bedd2e51..b230ddb183 100644
--- a/parse.y
+++ b/parse.y
@@ -298,9 +298,6 @@ struct parser_params {
#endif
};
-#define new_tmpbuf() \
- (rb_imemo_tmpbuf_t *)add_tmpbuf_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)
@@ -337,13 +334,6 @@ rb_discard_node(struct parser_params *p, NODE *n)
{
rb_ast_delete_node(p->ast, n);
}
-
-static inline VALUE
-add_tmpbuf_mark_object(struct parser_params *p, VALUE obj)
-{
- rb_ast_add_mark_object(p->ast, obj);
- return obj;
-}
#endif
static inline VALUE
@@ -2797,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);
- 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 */;
+ tbl[2] = tmpbuf;
switch (nd_type($2)) {
case NODE_LASGN:
@@ -2821,7 +2812,6 @@ primary : literal
args = new_args(p, m, 0, id, 0, new_args_tail(p, 0, 0, 0, &@2), &@2);
scope = NEW_NODE(NODE_SCOPE, tbl, $5, args, &@$);
$$ = NEW_FOR($4, scope, &@$);
- $$->nd_lit = tmpbuf;
fixpos($$, $2);
/*% %*/
/*% ripper: for!($2, $4, $5) %*/
@@ -11635,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) {
@@ -11648,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