diff --git a/ast.c b/ast.c index 96116d43eb..8139fcd390 100644 --- a/ast.c +++ b/ast.c @@ -600,11 +600,11 @@ node_children(rb_ast_t *ast, const NODE *node) } case NODE_SCOPE: { - ID *tbl = node->nd_tbl; - int i, size = tbl ? (int)*tbl++ : 0; + rb_ast_id_table_t *tbl = node->nd_tbl; + int i, size = tbl ? tbl->size : 0; VALUE locals = rb_ary_new_capa(size); for (i = 0; i < size; i++) { - rb_ary_push(locals, var_name(tbl[i])); + rb_ary_push(locals, var_name(tbl->ids[i])); } return rb_ary_new_from_args(3, locals, NEW_CHILD(ast, node->nd_args), NEW_CHILD(ast, node->nd_body)); } diff --git a/common.mk b/common.mk index 7ba32ac6e8..6b7378eeb6 100644 --- a/common.mk +++ b/common.mk @@ -7937,6 +7937,7 @@ localeinit.$(OBJEXT): {$(VPATH)}st.h localeinit.$(OBJEXT): {$(VPATH)}subst.h main.$(OBJEXT): $(hdrdir)/ruby.h main.$(OBJEXT): $(hdrdir)/ruby/ruby.h +main.$(OBJEXT): $(top_srcdir)/internal/compilers.h main.$(OBJEXT): {$(VPATH)}assert.h main.$(OBJEXT): {$(VPATH)}backward.h main.$(OBJEXT): {$(VPATH)}backward/2/assume.h @@ -8463,6 +8464,7 @@ math.$(OBJEXT): {$(VPATH)}missing.h math.$(OBJEXT): {$(VPATH)}st.h math.$(OBJEXT): {$(VPATH)}subst.h memory_view.$(OBJEXT): $(hdrdir)/ruby/ruby.h +memory_view.$(OBJEXT): $(top_srcdir)/internal/compilers.h memory_view.$(OBJEXT): $(top_srcdir)/internal/hash.h memory_view.$(OBJEXT): $(top_srcdir)/internal/variable.h memory_view.$(OBJEXT): {$(VPATH)}assert.h diff --git a/compile.c b/compile.c index a6505f82d6..d3cb079562 100644 --- a/compile.c +++ b/compile.c @@ -482,7 +482,7 @@ static int iseq_setup_insn(rb_iseq_t *iseq, LINK_ANCHOR *const anchor); static int iseq_optimize(rb_iseq_t *iseq, LINK_ANCHOR *const anchor); static int iseq_insns_unification(rb_iseq_t *iseq, LINK_ANCHOR *const anchor); -static int iseq_set_local_table(rb_iseq_t *iseq, const ID *tbl); +static int iseq_set_local_table(rb_iseq_t *iseq, const rb_ast_id_table_t *tbl); static int iseq_set_exception_local_table(rb_iseq_t *iseq); static int iseq_set_arguments(rb_iseq_t *iseq, LINK_ANCHOR *const anchor, const NODE *const node); @@ -1946,21 +1946,13 @@ iseq_set_arguments(rb_iseq_t *iseq, LINK_ANCHOR *const optargs, const NODE *cons } static int -iseq_set_local_table(rb_iseq_t *iseq, const ID *tbl) +iseq_set_local_table(rb_iseq_t *iseq, const rb_ast_id_table_t *tbl) { - unsigned int size; - - if (tbl) { - size = (unsigned int)*tbl; - tbl++; - } - else { - size = 0; - } + unsigned int size = tbl ? tbl->size : 0; if (size > 0) { ID *ids = (ID *)ALLOC_N(ID, size); - MEMCPY(ids, tbl, ID, size); + MEMCPY(ids, tbl->ids, ID, size); iseq->body->local_table = ids; } iseq->body->local_table_size = size; @@ -7908,17 +7900,20 @@ compile_builtin_mandatory_only_method(rb_iseq_t *iseq, const NODE *node, const N // local table without non-mandatory parameters const int skip_local_size = iseq->body->param.size - iseq->body->param.lead_num; const int table_size = iseq->body->local_table_size - skip_local_size; - ID *tbl = ALLOCA_N(ID, table_size + 1); - tbl[0] = table_size; + + VALUE idtmp = 0; + rb_ast_id_table_t *tbl = ALLOCV(idtmp, sizeof(rb_ast_id_table_t) + table_size * sizeof(ID)); + tbl->size = table_size; + int i; // lead parameters for (i=0; ibody->param.lead_num; i++) { - tbl[i+1] = iseq->body->local_table[i]; + tbl->ids[i] = iseq->body->local_table[i]; } // local variables for (; ibody->local_table[i + skip_local_size]; + tbl->ids[i] = iseq->body->local_table[i + skip_local_size]; } NODE scope_node; @@ -7939,6 +7934,7 @@ compile_builtin_mandatory_only_method(rb_iseq_t *iseq, const NODE *node, const N ISEQ_TYPE_METHOD, ISEQ_COMPILE_DATA(iseq)->option); GET_VM()->builtin_inline_index = prev_inline_index; + ALLOCV_END(idtmp); return COMPILE_OK; } diff --git a/node.c b/node.c index 3dea7fe398..180142d089 100644 --- a/node.c +++ b/node.c @@ -1043,12 +1043,12 @@ dump_node(VALUE buf, VALUE indent, int comment, const NODE * node) ANN("new scope"); ANN("format: [nd_tbl]: local table, [nd_args]: arguments, [nd_body]: body"); F_CUSTOM1(nd_tbl, "local table") { - ID *tbl = node->nd_tbl; + rb_ast_id_table_t *tbl = node->nd_tbl; int i; - int size = tbl ? (int)*tbl++ : 0; + int size = tbl ? tbl->size : 0; if (size == 0) A("(empty)"); for (i = 0; i < size; i++) { - A_ID(tbl[i]); if (i < size - 1) A(","); + A_ID(tbl->ids[i]); if (i < size - 1) A(","); } } F_NODE(nd_args, "arguments"); @@ -1162,7 +1162,7 @@ typedef struct { struct node_buffer_struct { node_buffer_list_t unmarkable; node_buffer_list_t markable; - ID *local_tables; + struct rb_ast_local_table_link *local_tables; VALUE mark_hash; }; @@ -1205,15 +1205,22 @@ node_buffer_list_free(node_buffer_list_t * nb) } } +struct rb_ast_local_table_link { + struct rb_ast_local_table_link *next; + // struct rb_ast_id_table { + int size; + ID ids[FLEX_ARY_LEN]; + // } +}; + static void rb_node_buffer_free(node_buffer_t *nb) { node_buffer_list_free(&nb->unmarkable); node_buffer_list_free(&nb->markable); - ID * local_table = nb->local_tables; + struct rb_ast_local_table_link *local_table = nb->local_tables; while (local_table) { - unsigned int size = (unsigned int)*local_table; - ID * next_table = (ID *)local_table[size + 1]; + struct rb_ast_local_table_link *next_table = local_table->next; xfree(local_table); local_table = next_table; } @@ -1277,12 +1284,28 @@ rb_ast_node_type_change(NODE *n, enum node_type type) } } -void -rb_ast_add_local_table(rb_ast_t *ast, ID *buf) +rb_ast_id_table_t * +rb_ast_new_local_table(rb_ast_t *ast, int size) { - unsigned int size = (unsigned int)*buf; - buf[size + 1] = (ID)ast->node_buffer->local_tables; - ast->node_buffer->local_tables = buf; + size_t alloc_size = sizeof(struct rb_ast_local_table_link) + size * sizeof(ID); + struct rb_ast_local_table_link *link = ruby_xmalloc(alloc_size); + link->next = ast->node_buffer->local_tables; + ast->node_buffer->local_tables = link; + link->size = size; + + return (rb_ast_id_table_t *) &link->size; +} + +rb_ast_id_table_t * +rb_ast_resize_latest_local_table(rb_ast_t *ast, int size) +{ + struct rb_ast_local_table_link *link = ast->node_buffer->local_tables; + size_t alloc_size = sizeof(struct rb_ast_local_table_link) + size * sizeof(ID); + link = ruby_xrealloc(link, alloc_size); + ast->node_buffer->local_tables = link; + link->size = size; + + return (rb_ast_id_table_t *) &link->size; } void diff --git a/node.h b/node.h index 8450455624..bd1c9d1fbf 100644 --- a/node.h +++ b/node.h @@ -11,6 +11,8 @@ **********************************************************************/ +#include "internal/compilers.h" + #if defined(__cplusplus) extern "C" { #if 0 @@ -146,13 +148,18 @@ code_loc_gen(const rb_code_location_t *loc1, const rb_code_location_t *loc2) return loc; } +typedef struct rb_ast_id_table { + int size; + ID ids[FLEX_ARY_LEN]; +} rb_ast_id_table_t; + typedef struct RNode { VALUE flags; union { struct RNode *node; ID id; VALUE value; - ID *tbl; + rb_ast_id_table_t *tbl; } u1; union { struct RNode *node; @@ -411,13 +418,14 @@ typedef struct rb_ast_struct { rb_ast_t *rb_ast_new(void); void rb_ast_mark(rb_ast_t*); void rb_ast_update_references(rb_ast_t*); -void rb_ast_add_local_table(rb_ast_t*, ID *buf); void rb_ast_dispose(rb_ast_t*); 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*, enum node_type type); void rb_ast_delete_node(rb_ast_t*, NODE *n); +rb_ast_id_table_t *rb_ast_new_local_table(rb_ast_t*, int); +rb_ast_id_table_t *rb_ast_resize_latest_local_table(rb_ast_t*, int); VALUE rb_parser_new(void); VALUE rb_parser_end_seen_p(VALUE); diff --git a/parse.y b/parse.y index b6498651bf..d386561f6a 100644 --- a/parse.y +++ b/parse.y @@ -574,7 +574,7 @@ static NODE *symbol_append(struct parser_params *p, NODE *symbols, NODE *symbol) static NODE *match_op(struct parser_params*,NODE*,NODE*,const YYLTYPE*,const YYLTYPE*); -static ID *local_tbl(struct parser_params*); +static rb_ast_id_table_t *local_tbl(struct parser_params*); static VALUE reg_compile(struct parser_params*, VALUE, int); static void reg_fragment_setenc(struct parser_params*, VALUE, int); @@ -3172,9 +3172,8 @@ 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, 3); - tbl[0] = 1 /* length of local var table */; tbl[1] = id /* internal id */; - rb_ast_add_local_table(p->ast, tbl); + rb_ast_id_table_t *tbl = rb_ast_new_local_table(p->ast, 1); + tbl->ids[0] = id; /* internal id */ switch (nd_type($2)) { case NODE_LASGN: @@ -12585,38 +12584,36 @@ local_pop(struct parser_params *p) } #ifndef RIPPER -static ID* +static rb_ast_id_table_t * local_tbl(struct parser_params *p) { int cnt_args = vtable_size(p->lvtbl->args); int cnt_vars = vtable_size(p->lvtbl->vars); int cnt = cnt_args + cnt_vars; int i, j; - ID *buf; + rb_ast_id_table_t *tbl; if (cnt <= 0) return 0; - buf = ALLOC_N(ID, cnt + 2); - MEMCPY(buf+1, p->lvtbl->args->tbl, ID, cnt_args); + tbl = rb_ast_new_local_table(p->ast, cnt); + MEMCPY(tbl->ids, p->lvtbl->args->tbl, ID, cnt_args); /* remove IDs duplicated to warn shadowing */ - for (i = 0, j = cnt_args+1; i < cnt_vars; ++i) { + for (i = 0, j = cnt_args; i < cnt_vars; ++i) { ID id = p->lvtbl->vars->tbl[i]; if (!vtable_included(p->lvtbl->args, id)) { - buf[j++] = id; + tbl->ids[j++] = id; } } - if (--j < cnt) { - REALLOC_N(buf, ID, (cnt = j) + 2); + if (j < cnt) { + tbl = rb_ast_resize_latest_local_table(p->ast, j); } - buf[0] = cnt; - rb_ast_add_local_table(p->ast, buf); - return buf; + return tbl; } static NODE* node_newnode_with_locals(struct parser_params *p, enum node_type type, VALUE a1, VALUE a2, const rb_code_location_t *loc) { - ID *a0; + rb_ast_id_table_t *a0; NODE *n; a0 = local_tbl(p); diff --git a/vm.c b/vm.c index 5941329c4e..53f16275c3 100644 --- a/vm.c +++ b/vm.c @@ -1256,18 +1256,17 @@ rb_binding_add_dynavars(VALUE bindval, rb_binding_t *bind, int dyncount, const I const rb_iseq_t *base_iseq, *iseq; rb_ast_body_t ast; NODE tmp_node; - ID minibuf[4], *dyns = minibuf; - VALUE idtmp = 0; if (dyncount < 0) return 0; base_block = &bind->block; base_iseq = vm_block_iseq(base_block); - if (dyncount >= numberof(minibuf)) dyns = ALLOCV_N(ID, idtmp, dyncount + 1); + VALUE idtmp = 0; + rb_ast_id_table_t *dyns = ALLOCV(idtmp, sizeof(rb_ast_id_table_t) + dyncount * sizeof(ID)); + dyns->size = dyncount; + MEMCPY(dyns->ids, dynvars, ID, dyncount); - dyns[0] = dyncount; - MEMCPY(dyns + 1, dynvars, ID, dyncount); rb_node_init(&tmp_node, NODE_SCOPE, (VALUE)dyns, 0, 0); ast.root = &tmp_node; ast.compile_option = 0;