Directly free structure managed by imemo tmpbuf
NODE_ARGS, NODE_ARYPTN, NODE_FNDPTN manage memory of their structure by imemo tmpbuf Object. However rb_ast_struct has reference to NODE. Then these memory can be freed directly when rb_ast_struct is freed. This commit reduces parser's dependency on CRuby functions.
This commit is contained in:
parent
bf129370d3
commit
fb7a2ddb4b
45
node.c
45
node.c
@ -44,6 +44,9 @@
|
|||||||
|
|
||||||
#define NODE_BUF_DEFAULT_LEN 16
|
#define NODE_BUF_DEFAULT_LEN 16
|
||||||
|
|
||||||
|
typedef void node_itr_t(rb_ast_t *ast, void *ctx, NODE * node);
|
||||||
|
static void iterate_node_values(rb_ast_t *ast, node_buffer_list_t *nb, node_itr_t * func, void *ctx);
|
||||||
|
|
||||||
/* Setup NODE structure.
|
/* Setup NODE structure.
|
||||||
* NODE is not an object managed by GC, but it imitates an object
|
* NODE is not an object managed by GC, but it imitates an object
|
||||||
* so that it can work with `RB_TYPE_P(obj, T_NODE)`.
|
* so that it can work with `RB_TYPE_P(obj, T_NODE)`.
|
||||||
@ -161,9 +164,26 @@ struct rb_ast_local_table_link {
|
|||||||
// }
|
// }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static void
|
||||||
|
free_ast_value(rb_ast_t *ast, void *ctx, NODE * node)
|
||||||
|
{
|
||||||
|
switch (nd_type(node)) {
|
||||||
|
case NODE_ARGS:
|
||||||
|
xfree(node->nd_ainfo);
|
||||||
|
break;
|
||||||
|
case NODE_ARYPTN:
|
||||||
|
xfree(node->nd_apinfo);
|
||||||
|
break;
|
||||||
|
case NODE_FNDPTN:
|
||||||
|
xfree(node->nd_fpinfo);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
rb_node_buffer_free(rb_ast_t *ast, node_buffer_t *nb)
|
rb_node_buffer_free(rb_ast_t *ast, node_buffer_t *nb)
|
||||||
{
|
{
|
||||||
|
iterate_node_values(ast, &nb->unmarkable, free_ast_value, NULL);
|
||||||
node_buffer_list_free(ast, &nb->unmarkable);
|
node_buffer_list_free(ast, &nb->unmarkable);
|
||||||
node_buffer_list_free(ast, &nb->markable);
|
node_buffer_list_free(ast, &nb->markable);
|
||||||
struct rb_ast_local_table_link *local_table = nb->local_tables;
|
struct rb_ast_local_table_link *local_table = nb->local_tables;
|
||||||
@ -204,9 +224,6 @@ nodetype_markable_p(enum node_type type)
|
|||||||
case NODE_DXSTR:
|
case NODE_DXSTR:
|
||||||
case NODE_DREGX:
|
case NODE_DREGX:
|
||||||
case NODE_DSYM:
|
case NODE_DSYM:
|
||||||
case NODE_ARGS:
|
|
||||||
case NODE_ARYPTN:
|
|
||||||
case NODE_FNDPTN:
|
|
||||||
return true;
|
return true;
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
@ -284,8 +301,6 @@ rb_ast_new(void)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
typedef void node_itr_t(rb_ast_t *ast, void *ctx, NODE * node);
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
iterate_buffer_elements(rb_ast_t *ast, node_buffer_elem_t *nbe, long len, node_itr_t *func, void *ctx)
|
iterate_buffer_elements(rb_ast_t *ast, node_buffer_elem_t *nbe, long len, node_itr_t *func, void *ctx)
|
||||||
{
|
{
|
||||||
@ -318,12 +333,6 @@ mark_ast_value(rb_ast_t *ast, void *ctx, NODE * node)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
switch (nd_type(node)) {
|
switch (nd_type(node)) {
|
||||||
case NODE_ARGS:
|
|
||||||
{
|
|
||||||
struct rb_args_info *args = node->nd_ainfo;
|
|
||||||
rb_gc_mark_movable(args->imemo);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case NODE_MATCH:
|
case NODE_MATCH:
|
||||||
case NODE_LIT:
|
case NODE_LIT:
|
||||||
case NODE_STR:
|
case NODE_STR:
|
||||||
@ -334,10 +343,6 @@ mark_ast_value(rb_ast_t *ast, void *ctx, NODE * node)
|
|||||||
case NODE_DSYM:
|
case NODE_DSYM:
|
||||||
rb_gc_mark_movable(node->nd_lit);
|
rb_gc_mark_movable(node->nd_lit);
|
||||||
break;
|
break;
|
||||||
case NODE_ARYPTN:
|
|
||||||
case NODE_FNDPTN:
|
|
||||||
rb_gc_mark_movable(node->nd_rval);
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
rb_bug("unreachable node %s", ruby_node_name(nd_type(node)));
|
rb_bug("unreachable node %s", ruby_node_name(nd_type(node)));
|
||||||
}
|
}
|
||||||
@ -351,12 +356,6 @@ update_ast_value(rb_ast_t *ast, void *ctx, NODE * node)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
switch (nd_type(node)) {
|
switch (nd_type(node)) {
|
||||||
case NODE_ARGS:
|
|
||||||
{
|
|
||||||
struct rb_args_info *args = node->nd_ainfo;
|
|
||||||
args->imemo = rb_gc_location(args->imemo);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case NODE_MATCH:
|
case NODE_MATCH:
|
||||||
case NODE_LIT:
|
case NODE_LIT:
|
||||||
case NODE_STR:
|
case NODE_STR:
|
||||||
@ -367,10 +366,6 @@ update_ast_value(rb_ast_t *ast, void *ctx, NODE * node)
|
|||||||
case NODE_DSYM:
|
case NODE_DSYM:
|
||||||
node->nd_lit = rb_gc_location(node->nd_lit);
|
node->nd_lit = rb_gc_location(node->nd_lit);
|
||||||
break;
|
break;
|
||||||
case NODE_ARYPTN:
|
|
||||||
case NODE_FNDPTN:
|
|
||||||
node->nd_rval = rb_gc_location(node->nd_rval);
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
rb_bug("unreachable");
|
rb_bug("unreachable");
|
||||||
}
|
}
|
||||||
|
22
parse.y
22
parse.y
@ -12721,13 +12721,9 @@ static NODE*
|
|||||||
new_args_tail(struct parser_params *p, NODE *kw_args, ID kw_rest_arg, ID block, const YYLTYPE *kw_rest_loc)
|
new_args_tail(struct parser_params *p, NODE *kw_args, ID kw_rest_arg, ID block, const YYLTYPE *kw_rest_loc)
|
||||||
{
|
{
|
||||||
int saved_line = p->ruby_sourceline;
|
int saved_line = p->ruby_sourceline;
|
||||||
NODE *node;
|
NODE *node = NEW_NODE(NODE_ARGS, 0, 0, 0, &NULL_LOC);
|
||||||
VALUE tmpbuf = rb_imemo_tmpbuf_auto_free_pointer();
|
|
||||||
struct rb_args_info *args = ZALLOC(struct rb_args_info);
|
struct rb_args_info *args = ZALLOC(struct rb_args_info);
|
||||||
rb_imemo_tmpbuf_set_ptr(tmpbuf, args);
|
node->nd_ainfo = args;
|
||||||
args->imemo = tmpbuf;
|
|
||||||
node = NEW_NODE(NODE_ARGS, 0, 0, args, &NULL_LOC);
|
|
||||||
RB_OBJ_WRITTEN(p->ast, Qnil, tmpbuf);
|
|
||||||
if (p->error_p) return node;
|
if (p->error_p) return node;
|
||||||
|
|
||||||
args->block_arg = block;
|
args->block_arg = block;
|
||||||
@ -12818,12 +12814,9 @@ static NODE*
|
|||||||
new_array_pattern_tail(struct parser_params *p, NODE *pre_args, int has_rest, NODE *rest_arg, NODE *post_args, const YYLTYPE *loc)
|
new_array_pattern_tail(struct parser_params *p, NODE *pre_args, int has_rest, NODE *rest_arg, NODE *post_args, const YYLTYPE *loc)
|
||||||
{
|
{
|
||||||
int saved_line = p->ruby_sourceline;
|
int saved_line = p->ruby_sourceline;
|
||||||
NODE *node;
|
NODE *node = NEW_NODE(NODE_ARYPTN, 0, 0, 0, loc);
|
||||||
VALUE tmpbuf = rb_imemo_tmpbuf_auto_free_pointer();
|
|
||||||
struct rb_ary_pattern_info *apinfo = ZALLOC(struct rb_ary_pattern_info);
|
struct rb_ary_pattern_info *apinfo = ZALLOC(struct rb_ary_pattern_info);
|
||||||
rb_imemo_tmpbuf_set_ptr(tmpbuf, apinfo);
|
node->nd_apinfo = apinfo;
|
||||||
node = NEW_NODE(NODE_ARYPTN, 0, tmpbuf, apinfo, loc);
|
|
||||||
RB_OBJ_WRITTEN(p->ast, Qnil, tmpbuf);
|
|
||||||
|
|
||||||
apinfo->pre_args = pre_args;
|
apinfo->pre_args = pre_args;
|
||||||
|
|
||||||
@ -12852,12 +12845,9 @@ static NODE*
|
|||||||
new_find_pattern_tail(struct parser_params *p, NODE *pre_rest_arg, NODE *args, NODE *post_rest_arg, const YYLTYPE *loc)
|
new_find_pattern_tail(struct parser_params *p, NODE *pre_rest_arg, NODE *args, NODE *post_rest_arg, const YYLTYPE *loc)
|
||||||
{
|
{
|
||||||
int saved_line = p->ruby_sourceline;
|
int saved_line = p->ruby_sourceline;
|
||||||
NODE *node;
|
NODE *node = NEW_NODE(NODE_FNDPTN, 0, 0, 0, loc);
|
||||||
VALUE tmpbuf = rb_imemo_tmpbuf_auto_free_pointer();
|
|
||||||
struct rb_fnd_pattern_info *fpinfo = ZALLOC(struct rb_fnd_pattern_info);
|
struct rb_fnd_pattern_info *fpinfo = ZALLOC(struct rb_fnd_pattern_info);
|
||||||
rb_imemo_tmpbuf_set_ptr(tmpbuf, fpinfo);
|
node->nd_fpinfo = fpinfo;
|
||||||
node = NEW_NODE(NODE_FNDPTN, 0, tmpbuf, fpinfo, loc);
|
|
||||||
RB_OBJ_WRITTEN(p->ast, Qnil, tmpbuf);
|
|
||||||
|
|
||||||
fpinfo->pre_rest_arg = pre_rest_arg ? pre_rest_arg : NODE_SPECIAL_NO_NAME_REST;
|
fpinfo->pre_rest_arg = pre_rest_arg ? pre_rest_arg : NODE_SPECIAL_NO_NAME_REST;
|
||||||
fpinfo->args = args;
|
fpinfo->args = args;
|
||||||
|
@ -566,8 +566,6 @@ rb_parser_config_initialize(rb_parser_config_t *config)
|
|||||||
|
|
||||||
config->new_strterm = new_strterm;
|
config->new_strterm = new_strterm;
|
||||||
config->strterm_is_heredoc = strterm_is_heredoc;
|
config->strterm_is_heredoc = strterm_is_heredoc;
|
||||||
config->tmpbuf_auto_free_pointer = rb_imemo_tmpbuf_auto_free_pointer;
|
|
||||||
config->tmpbuf_set_ptr = rb_imemo_tmpbuf_set_ptr;
|
|
||||||
config->tmpbuf_parser_heap = tmpbuf_parser_heap;
|
config->tmpbuf_parser_heap = tmpbuf_parser_heap;
|
||||||
config->ast_new = ast_new;
|
config->ast_new = ast_new;
|
||||||
|
|
||||||
|
@ -292,8 +292,6 @@ struct rb_args_info {
|
|||||||
unsigned int no_kwarg: 1;
|
unsigned int no_kwarg: 1;
|
||||||
unsigned int ruby2_keywords: 1;
|
unsigned int ruby2_keywords: 1;
|
||||||
unsigned int forwarding: 1;
|
unsigned int forwarding: 1;
|
||||||
|
|
||||||
VALUE imemo;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct rb_ary_pattern_info {
|
struct rb_ary_pattern_info {
|
||||||
@ -364,8 +362,6 @@ typedef struct rb_parser_config_struct {
|
|||||||
// TODO: Should it return `rb_strterm_t *'?
|
// TODO: Should it return `rb_strterm_t *'?
|
||||||
VALUE (*new_strterm)(VALUE v1, VALUE v2, VALUE v3, VALUE v0, int heredoc);
|
VALUE (*new_strterm)(VALUE v1, VALUE v2, VALUE v3, VALUE v0, int heredoc);
|
||||||
int (*strterm_is_heredoc)(VALUE strterm);
|
int (*strterm_is_heredoc)(VALUE strterm);
|
||||||
VALUE (*tmpbuf_auto_free_pointer)(void);
|
|
||||||
void *(*tmpbuf_set_ptr)(VALUE v, void *ptr);
|
|
||||||
rb_imemo_tmpbuf_t *(*tmpbuf_parser_heap)(void *buf, rb_imemo_tmpbuf_t *old_heap, size_t cnt);
|
rb_imemo_tmpbuf_t *(*tmpbuf_parser_heap)(void *buf, rb_imemo_tmpbuf_t *old_heap, size_t cnt);
|
||||||
rb_ast_t *(*ast_new)(VALUE nb);
|
rb_ast_t *(*ast_new)(VALUE nb);
|
||||||
|
|
||||||
|
@ -113,8 +113,6 @@ struct rb_imemo_tmpbuf_struct {
|
|||||||
|
|
||||||
#define new_strterm p->config->new_strterm
|
#define new_strterm p->config->new_strterm
|
||||||
#define strterm_is_heredoc p->config->strterm_is_heredoc
|
#define strterm_is_heredoc p->config->strterm_is_heredoc
|
||||||
#define rb_imemo_tmpbuf_auto_free_pointer p->config->tmpbuf_auto_free_pointer
|
|
||||||
#define rb_imemo_tmpbuf_set_ptr p->config->tmpbuf_set_ptr
|
|
||||||
#define rb_imemo_tmpbuf_parser_heap p->config->tmpbuf_parser_heap
|
#define rb_imemo_tmpbuf_parser_heap p->config->tmpbuf_parser_heap
|
||||||
|
|
||||||
#define compile_callback p->config->compile_callback
|
#define compile_callback p->config->compile_callback
|
||||||
|
Loading…
x
Reference in New Issue
Block a user