[前][次][番号順一覧][スレッド一覧]

ruby-changes:57691

From: Aaron <ko1@a...>
Date: Tue, 10 Sep 2019 06:28:05 +0900 (JST)
Subject: [ruby-changes:57691] 4524780d17 (master): Revert "Reverting node marking until I can fix GC problem."

https://git.ruby-lang.org/ruby.git/commit/?id=4524780d17

From 4524780d1795e750e23896866eb447be2670ddcd Mon Sep 17 00:00:00 2001
From: Aaron Patterson <tenderlove@r...>
Date: Mon, 9 Sep 2019 09:37:06 -0700
Subject: Revert "Reverting node marking until I can fix GC problem."

This reverts commit 092f31e7e23c0ee04df987f0c0f979d036971804.

diff --git a/node.c b/node.c
index 7cd238a..0e1b04b 100644
--- a/node.c
+++ b/node.c
@@ -1116,30 +1116,45 @@ rb_node_init(NODE *n, enum node_type type, VALUE a0, VALUE a1, VALUE a2) https://github.com/ruby/ruby/blob/trunk/node.c#L1116
 
 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 node_buffer_t *
-rb_node_buffer_new(void)
+static void
+init_node_buffer_list(node_buffer_list_t * nb, node_buffer_elem_t *head)
 {
-    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 = nb->last = head;
+    nb->head->len = nb->len;
     nb->head->next = NULL;
-    nb->mark_ary = rb_ary_tmp_new(0);
+}
+
+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;
     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) https://github.com/ruby/ruby/blob/trunk/node.c#L1163
 	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) https://github.com/ruby/ruby/blob/trunk/node.c#L1189
     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 * https://github.com/ruby/ruby/blob/trunk/node.c#L1222
 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) https://github.com/ruby/ruby/blob/trunk/node.c#L1312
     }
 }
 
+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) https://github.com/ruby/ruby/blob/trunk/node.c#L1332
 
     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) https://github.com/ruby/ruby/blob/trunk/node.c#L1347
 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 22d10a2..d39cae8 100644
--- a/node.h
+++ b/node.h
@@ -408,7 +408,7 @@ void rb_ast_dispose(rb_ast_t*); https://github.com/ruby/ruby/blob/trunk/node.h#L408
 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 { https://github.com/ruby/ruby/blob/trunk/node.h#L451
 
     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 a3b3cd7..7e2cfe0 100644
--- a/parse.y
+++ b/parse.y
@@ -298,9 +298,6 @@ struct parser_params { https://github.com/ruby/ruby/blob/trunk/parse.y#L298
 #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) https://github.com/ruby/ruby/blob/trunk/parse.y#L344
 	&& !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 https://github.com/ruby/ruby/blob/trunk/parse.y#L2787
 			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) https://github.com/ruby/ruby/blob/trunk/parse.y#L9357
 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 https://github.com/ruby/ruby/blob/trunk/parse.y#L9611
 	  (... truncated)

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]