aboutsummaryrefslogtreecommitdiffstats
path: root/node.h
diff options
context:
space:
mode:
authormame <mame@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2017-10-27 15:59:02 +0000
committermame <mame@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2017-10-27 15:59:02 +0000
commit1bd40a61900d166126b6b6dbe7c06449207d456e (patch)
treec044b1a92b6349639976dcf864dccf504a01ebc8 /node.h
parent799487abb89956781474b6fa39326a2a1b0291fc (diff)
downloadruby-1bd40a61900d166126b6b6dbe7c06449207d456e.tar.gz
Manage AST NODEs out of GC
NODEs in AST are no longer objects managed by GC. This change will remove the restriction imposed by the GC. For example, a NODE can use more than five words (this is my primary purpose; we want to store the position data for each NODE, for coverage library), or even a NODE can have variable length (some kinds of NODEs have unused fields). To do this, however, we need more work, since Ripper still uses T_NODE objects managed by the GC. The life time of NODEs is more obvious than other kinds of objects; they are created at parsing, and they become disused immediately after compilation. This change releases all NODEs by a few `xfree`s after compilation, so performance will be improved a bit. In extreme example, `eval("x=1;" * 10000000)` runs much faster (40 sec. -> 7.8 sec. on my machine). The most important part of this change is `ast_t` struct, which has three contents: (1) NODE buffer (malloc'ed memory), (2) a reference to the root NODE, and (3) an array that contains objects that must be marked during parsing (such as literal objects). Some functions that had received `NODE*` arguments, must now receive `ast_t*`. * node.c, node.h: defines `ast_t` struct and related operations. * gc.c, internal.h: defines `imemo_ast`. * parse.y: makes `parser_params` struct have a reference to `ast_t`. Instead of `rb_node_newnode`, use `rb_ast_newnode` to create a NODE. * iseq.c, load.c, ruby.c, template/prelude.c.tmpl: modifies some functions to handle `ast_t*` instead of `NODE*`. * test/ruby/test_gc.rb: ad-hoc fix for a failed test. The test assumes GC eden is increased at startup by NODE object creation. However, this change now create no NODE object, so GC eden is not necessarily increased. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@60485 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'node.h')
-rw-r--r--node.h34
1 files changed, 26 insertions, 8 deletions
diff --git a/node.h b/node.h
index 2fb0d53875..23b2bb11f8 100644
--- a/node.h
+++ b/node.h
@@ -439,6 +439,24 @@ typedef struct RNode {
RUBY_SYMBOL_EXPORT_BEGIN
+typedef struct node_buffer_struct node_buffer_t;
+/* T_IMEMO/ast */
+typedef struct ast_struct {
+ VALUE flags;
+ VALUE reserved1;
+ NODE *root;
+ node_buffer_t *node_buffer;
+ VALUE mark_ary;
+} ast_t;
+ast_t *rb_ast_new();
+void rb_ast_mark(ast_t*);
+void rb_ast_dispose(ast_t*);
+void rb_ast_free(ast_t*);
+void rb_ast_add_mark_object(ast_t*, VALUE);
+void rb_ast_delete_mark_object(ast_t*, VALUE);
+NODE *rb_ast_newnode(ast_t*);
+void rb_ast_delete_node(ast_t*, NODE *n);
+
VALUE rb_parser_new(void);
VALUE rb_parser_end_seen_p(VALUE);
VALUE rb_parser_encoding(VALUE);
@@ -447,15 +465,15 @@ VALUE rb_parser_set_yydebug(VALUE, VALUE);
VALUE rb_parser_dump_tree(NODE *node, int comment);
void rb_parser_set_options(VALUE, int, int, int, int);
-NODE *rb_parser_compile_cstr(VALUE, const char*, const char*, int, int);
-NODE *rb_parser_compile_string(VALUE, const char*, VALUE, int);
-NODE *rb_parser_compile_file(VALUE, const char*, VALUE, int);
-NODE *rb_parser_compile_string_path(VALUE vparser, VALUE fname, VALUE src, int line);
-NODE *rb_parser_compile_file_path(VALUE vparser, VALUE fname, VALUE input, int line);
+ast_t *rb_parser_compile_cstr(VALUE, const char*, const char*, int, int);
+ast_t *rb_parser_compile_string(VALUE, const char*, VALUE, int);
+ast_t *rb_parser_compile_file(VALUE, const char*, VALUE, int);
+ast_t *rb_parser_compile_string_path(VALUE vparser, VALUE fname, VALUE src, int line);
+ast_t *rb_parser_compile_file_path(VALUE vparser, VALUE fname, VALUE input, int line);
-NODE *rb_compile_cstr(const char*, const char*, int, int);
-NODE *rb_compile_string(const char*, VALUE, int);
-NODE *rb_compile_file(const char*, VALUE, int);
+ast_t *rb_compile_cstr(const char*, const char*, int, int);
+ast_t *rb_compile_string(const char*, VALUE, int);
+ast_t *rb_compile_file(const char*, VALUE, int);
void rb_node_init(NODE *n, enum node_type type, VALUE a0, VALUE a1, VALUE a2);
NODE *rb_node_newnode(enum node_type,VALUE,VALUE,VALUE);