diff options
author | mame <mame@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2017-10-27 16:44:57 +0000 |
---|---|---|
committer | mame <mame@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2017-10-27 16:44:57 +0000 |
commit | e35fe8d11b889a5646a23df06bbecf16f88c518a (patch) | |
tree | d4346b34db86ab7c09ccb2db3f0e2803664e9421 /node.c | |
parent | 15270f48a9f3ccd7e57798d7eff4dd8d5d83c259 (diff) | |
download | bundler-e35fe8d11b889a5646a23df06bbecf16f88c518a.tar.gz |
Revert "Revert "Manage AST NODEs out of GC""
This re-introduces r60485.
This reverts commit 5a176b75b1187cbd3861c387bde65ff66396a07c.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@60488 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'node.c')
-rw-r--r-- | node.c | 104 |
1 files changed, 104 insertions, 0 deletions
@@ -1211,3 +1211,107 @@ rb_gc_mark_node(NODE *obj) } return 0; } + +typedef struct node_buffer_elem_struct { + struct node_buffer_elem_struct *next; + NODE buf[1]; +} node_buffer_elem_t; + +typedef struct node_buffer_struct { + long idx, len; + node_buffer_elem_t *head; + node_buffer_elem_t body; +} node_buffer_t; + +node_buffer_t * +rb_node_buffer_new() +{ + node_buffer_t *nb = xmalloc(sizeof(node_buffer_t) + 16 * sizeof(NODE)); + nb->idx = 0; + nb->len = 16; + nb->head = &nb->body; + nb->head->next = NULL; + return nb; +} + +void +rb_node_buffer_free(node_buffer_t *nb) +{ + node_buffer_elem_t *nbe = nb->head; + + while (nbe != &nb->body) { + void *buf = nbe; + nbe = nbe->next; + xfree(buf); + } + xfree(nb); +} + +NODE * +rb_ast_newnode(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(sizeof(node_buffer_elem_t) + n * sizeof(NODE)); + nb->idx = 0; + nb->len = n; + nbe->next = nb->head; + nb->head = nbe; + } + return &nb->head->buf[nb->idx++]; +} + +void +rb_ast_delete_node(ast_t *ast, NODE *n) +{ + (void)ast; + (void)n; + /* should we implement freelist? */ +} + +ast_t * +rb_ast_new(void) +{ + return (ast_t *)rb_imemo_new(imemo_ast, 0, (VALUE)rb_node_buffer_new(), rb_ary_tmp_new(0), 0); +} + +void +rb_ast_mark(ast_t *ast) +{ + if (ast->node_buffer) rb_gc_mark(ast->mark_ary); +} + +void +rb_ast_free(ast_t *ast) +{ + if (ast->node_buffer) rb_node_buffer_free(ast->node_buffer); + ast->node_buffer = 0; + ast->root = 0; + ast->mark_ary = 0; +} + +void +rb_ast_dispose(ast_t *ast) +{ + rb_ast_free(ast); + rb_gc_writebarrier_remember((VALUE)ast); +} + +void +rb_ast_add_mark_object(ast_t *ast, VALUE obj) +{ + rb_ary_push(ast->mark_ary, obj); +} + +void +rb_ast_delete_mark_object(ast_t *ast, VALUE obj) +{ + long i; + for (i = 0; i < RARRAY_LEN(ast->mark_ary); i++) { + if (obj == RARRAY_AREF(ast->mark_ary, i)) { + RARRAY_ASET(ast->mark_ary, i, Qnil); + } + } +} |