Do not convert NODE_STR to NODE_LIT when the string is hash key

parse.y converted NODE_STR when the string is hash key like

```
h1 = {"str1" => 1}
m1("str2" => 2)
m2({"str3" => 3})
```

This commit stop the conversion.
`static_literal_node_p` needs to know the node is for hash key or not
for the optimization.
This commit is contained in:
yui-knk 2024-01-08 14:03:54 +09:00 committed by Yuichiro Kaneko
parent 7ffff3e043
commit 41e2d180a3
2 changed files with 11 additions and 10 deletions

View File

@ -4706,7 +4706,7 @@ compile_args(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *node, NODE **k
} }
static inline int static inline int
static_literal_node_p(const NODE *node, const rb_iseq_t *iseq) static_literal_node_p(const NODE *node, const rb_iseq_t *iseq, bool hash_key)
{ {
switch (nd_type(node)) { switch (nd_type(node)) {
case NODE_LIT: case NODE_LIT:
@ -4721,7 +4721,7 @@ static_literal_node_p(const NODE *node, const rb_iseq_t *iseq)
return TRUE; return TRUE;
case NODE_STR: case NODE_STR:
case NODE_FILE: case NODE_FILE:
return ISEQ_COMPILE_DATA(iseq)->option->frozen_string_literal; return hash_key || ISEQ_COMPILE_DATA(iseq)->option->frozen_string_literal;
default: default:
return FALSE; return FALSE;
} }
@ -4841,10 +4841,10 @@ compile_array(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *node, int pop
int count = 1; int count = 1;
/* pre-allocation check (this branch can be omittable) */ /* pre-allocation check (this branch can be omittable) */
if (static_literal_node_p(RNODE_LIST(node)->nd_head, iseq)) { if (static_literal_node_p(RNODE_LIST(node)->nd_head, iseq, false)) {
/* count the elements that are optimizable */ /* count the elements that are optimizable */
const NODE *node_tmp = RNODE_LIST(node)->nd_next; const NODE *node_tmp = RNODE_LIST(node)->nd_next;
for (; node_tmp && static_literal_node_p(RNODE_LIST(node_tmp)->nd_head, iseq); node_tmp = RNODE_LIST(node_tmp)->nd_next) for (; node_tmp && static_literal_node_p(RNODE_LIST(node_tmp)->nd_head, iseq, false); node_tmp = RNODE_LIST(node_tmp)->nd_next)
count++; count++;
if ((first_chunk && stack_len == 0 && !node_tmp) || count >= min_tmp_ary_len) { if ((first_chunk && stack_len == 0 && !node_tmp) || count >= min_tmp_ary_len) {
@ -4899,7 +4899,7 @@ compile_array(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *node, int pop
static int static int
compile_array_1(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *node) compile_array_1(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *node)
{ {
if (static_literal_node_p(node, iseq)) { if (static_literal_node_p(node, iseq, false)) {
VALUE ary = rb_ary_hidden_new(1); VALUE ary = rb_ary_hidden_new(1);
rb_ary_push(ary, static_literal_value(node, iseq)); rb_ary_push(ary, static_literal_value(node, iseq));
OBJ_FREEZE(ary); OBJ_FREEZE(ary);
@ -4917,7 +4917,7 @@ compile_array_1(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *node)
static inline int static inline int
static_literal_node_pair_p(const NODE *node, const rb_iseq_t *iseq) static_literal_node_pair_p(const NODE *node, const rb_iseq_t *iseq)
{ {
return RNODE_LIST(node)->nd_head && static_literal_node_p(RNODE_LIST(node)->nd_head, iseq) && static_literal_node_p(RNODE_LIST(RNODE_LIST(node)->nd_next)->nd_head, iseq); return RNODE_LIST(node)->nd_head && static_literal_node_p(RNODE_LIST(node)->nd_head, iseq, true) && static_literal_node_p(RNODE_LIST(RNODE_LIST(node)->nd_next)->nd_head, iseq, true);
} }
static int static int

View File

@ -6877,10 +6877,6 @@ assocs : assoc
assoc : arg_value tASSOC arg_value assoc : arg_value tASSOC arg_value
{ {
/*%%%*/ /*%%%*/
if (nd_type_p($1, NODE_STR)) {
nd_set_type($1, NODE_LIT);
RB_OBJ_WRITE(p->ast, &RNODE_LIT($1)->nd_lit, rb_fstring(RNODE_LIT($1)->nd_lit));
}
$$ = list_append(p, NEW_LIST($1, &@$), $3); $$ = list_append(p, NEW_LIST($1, &@$), $3);
/*% %*/ /*% %*/
/*% ripper: assoc_new!($1, $3) %*/ /*% ripper: assoc_new!($1, $3) %*/
@ -14941,6 +14937,7 @@ nd_type_st_key_enable_p(NODE *node)
case NODE_FLOAT: case NODE_FLOAT:
case NODE_RATIONAL: case NODE_RATIONAL:
case NODE_IMAGINARY: case NODE_IMAGINARY:
case NODE_STR:
case NODE_LINE: case NODE_LINE:
case NODE_FILE: case NODE_FILE:
return true; return true;
@ -14955,6 +14952,8 @@ nd_st_key(struct parser_params *p, NODE *node)
switch (nd_type(node)) { switch (nd_type(node)) {
case NODE_LIT: case NODE_LIT:
return RNODE_LIT(node)->nd_lit; return RNODE_LIT(node)->nd_lit;
case NODE_STR:
return RNODE_STR(node)->nd_lit;
case NODE_INTEGER: case NODE_INTEGER:
case NODE_FLOAT: case NODE_FLOAT:
case NODE_RATIONAL: case NODE_RATIONAL:
@ -14974,6 +14973,8 @@ nd_st_key_val(struct parser_params *p, NODE *node)
switch (nd_type(node)) { switch (nd_type(node)) {
case NODE_LIT: case NODE_LIT:
return RNODE_LIT(node)->nd_lit; return RNODE_LIT(node)->nd_lit;
case NODE_STR:
return RNODE_STR(node)->nd_lit;
case NODE_INTEGER: case NODE_INTEGER:
return rb_node_integer_literal_val(node); return rb_node_integer_literal_val(node);
case NODE_FLOAT: case NODE_FLOAT: