Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

compile.c: use rb_enc_interned_str to reduce allocations #10494

Merged
merged 1 commit into from
Apr 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
32 changes: 13 additions & 19 deletions compile.c
Original file line number Diff line number Diff line change
Expand Up @@ -4338,7 +4338,7 @@ compile_dstr_fragments(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *cons
while (list) {
const NODE *const head = list->nd_head;
if (nd_type_p(head, NODE_STR)) {
lit = rb_fstring(rb_node_str_string_val(head));
lit = rb_node_str_string_val(head);
ADD_INSN1(ret, head, putobject, lit);
RB_OBJ_WRITTEN(iseq, Qundef, lit);
lit = Qnil;
Expand Down Expand Up @@ -4377,7 +4377,7 @@ compile_dstr(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node)
{
int cnt;
if (!RNODE_DSTR(node)->nd_next) {
VALUE lit = rb_fstring(rb_node_dstr_string_val(node));
VALUE lit = rb_node_dstr_string_val(node);
ADD_INSN1(ret, node, putstring, lit);
RB_OBJ_WRITTEN(iseq, Qundef, lit);
}
Expand Down Expand Up @@ -4765,14 +4765,13 @@ static_literal_value(const NODE *node, rb_iseq_t *iseq)
case NODE_FILE:
case NODE_STR:
if (ISEQ_COMPILE_DATA(iseq)->option->debug_frozen_string_literal || RTEST(ruby_debug)) {
VALUE lit;
VALUE debug_info = rb_ary_new_from_args(2, rb_iseq_path(iseq), INT2FIX((int)nd_line(node)));
lit = rb_str_dup(get_string_value(node));
VALUE lit = rb_str_dup(get_string_value(node));
rb_ivar_set(lit, id_debug_created_info, rb_obj_freeze(debug_info));
return rb_str_freeze(lit);
}
else {
return rb_fstring(get_string_value(node));
return get_string_value(node);
}
default:
rb_bug("unexpected node: %s", ruby_node_name(nd_type(node)));
Expand Down Expand Up @@ -5142,9 +5141,9 @@ rb_node_case_when_optimizable_literal(const NODE *const node)
case NODE_LINE:
return rb_node_line_lineno_val(node);
case NODE_STR:
return rb_fstring(rb_node_str_string_val(node));
return rb_node_str_string_val(node);
case NODE_FILE:
return rb_fstring(rb_node_file_path_val(node));
return rb_node_file_path_val(node);
}
return Qundef;
}
Expand All @@ -5166,7 +5165,7 @@ when_vals(rb_iseq_t *iseq, LINK_ANCHOR *const cond_seq, const NODE *vals,

if (nd_type_p(val, NODE_STR) || nd_type_p(val, NODE_FILE)) {
debugp_param("nd_lit", get_string_value(val));
lit = rb_fstring(get_string_value(val));
lit = get_string_value(val);
ADD_INSN1(cond_seq, val, putobject, lit);
RB_OBJ_WRITTEN(iseq, Qundef, lit);
}
Expand Down Expand Up @@ -8445,7 +8444,7 @@ compile_call_precheck_freeze(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE
get_nd_args(node) == NULL &&
ISEQ_COMPILE_DATA(iseq)->current_block == NULL &&
ISEQ_COMPILE_DATA(iseq)->option->specialized_instruction) {
VALUE str = rb_fstring(get_string_value(get_nd_recv(node)));
VALUE str = get_string_value(get_nd_recv(node));
if (get_node_call_nd_mid(node) == idUMinus) {
ADD_INSN2(ret, line_node, opt_str_uminus, str,
new_callinfo(iseq, idUMinus, 0, 0, NULL, FALSE));
Expand All @@ -8469,7 +8468,7 @@ compile_call_precheck_freeze(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE
ISEQ_COMPILE_DATA(iseq)->current_block == NULL &&
!frozen_string_literal_p(iseq) &&
ISEQ_COMPILE_DATA(iseq)->option->specialized_instruction) {
VALUE str = rb_fstring(get_string_value(RNODE_LIST(get_nd_args(node))->nd_head));
VALUE str = get_string_value(RNODE_LIST(get_nd_args(node))->nd_head);
CHECK(COMPILE(ret, "recv", get_nd_recv(node)));
ADD_INSN2(ret, line_node, opt_aref_with, str,
new_callinfo(iseq, idAREF, 1, 0, NULL, FALSE));
Expand Down Expand Up @@ -9746,7 +9745,7 @@ compile_attrasgn(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node
!frozen_string_literal_p(iseq) &&
ISEQ_COMPILE_DATA(iseq)->option->specialized_instruction)
{
VALUE str = rb_fstring(get_string_value(RNODE_LIST(RNODE_ATTRASGN(node)->nd_args)->nd_head));
VALUE str = get_string_value(RNODE_LIST(RNODE_ATTRASGN(node)->nd_args)->nd_head);
CHECK(COMPILE(ret, "recv", RNODE_ATTRASGN(node)->nd_recv));
CHECK(COMPILE(ret, "value", RNODE_LIST(RNODE_LIST(RNODE_ATTRASGN(node)->nd_args)->nd_next)->nd_head));
if (!popped) {
Expand Down Expand Up @@ -9971,7 +9970,7 @@ compile_shareable_literal_constant(rb_iseq_t *iseq, LINK_ANCHOR *ret, enum rb_pa
return COMPILE_OK;

case NODE_STR:{
VALUE lit = rb_fstring(rb_node_str_string_val(node));
VALUE lit = rb_node_str_string_val(node);
ADD_INSN1(ret, node, putobject, lit);
RB_OBJ_WRITTEN(iseq, Qundef, lit);
*value_p = lit;
Expand All @@ -9981,7 +9980,7 @@ compile_shareable_literal_constant(rb_iseq_t *iseq, LINK_ANCHOR *ret, enum rb_pa
}

case NODE_FILE:{
VALUE lit = rb_fstring(rb_node_file_path_val(node));
VALUE lit = rb_node_file_path_val(node);
ADD_INSN1(ret, node, putobject, lit);
RB_OBJ_WRITTEN(iseq, Qundef, lit);
*value_p = lit;
Expand Down Expand Up @@ -10576,12 +10575,10 @@ iseq_compile_each0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const no
VALUE lit = get_string_value(node);
switch (ISEQ_COMPILE_DATA(iseq)->option->frozen_string_literal) {
case ISEQ_FROZEN_STRING_LITERAL_UNSET:
lit = rb_fstring(lit);
ADD_INSN1(ret, node, putchilledstring, lit);
RB_OBJ_WRITTEN(iseq, Qundef, lit);
break;
case ISEQ_FROZEN_STRING_LITERAL_DISABLED:
lit = rb_fstring(lit);
ADD_INSN1(ret, node, putstring, lit);
RB_OBJ_WRITTEN(iseq, Qundef, lit);
break;
Expand All @@ -10592,9 +10589,6 @@ iseq_compile_each0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const no
rb_ivar_set(lit, id_debug_created_info, rb_obj_freeze(debug_info));
lit = rb_str_freeze(lit);
}
else {
lit = rb_fstring(lit);
}
ADD_INSN1(ret, node, putobject, lit);
RB_OBJ_WRITTEN(iseq, Qundef, lit);
break;
Expand All @@ -10614,7 +10608,7 @@ iseq_compile_each0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const no
}
case NODE_XSTR:{
ADD_CALL_RECEIVER(ret, node);
VALUE str = rb_fstring(rb_node_str_string_val(node));
VALUE str = rb_node_str_string_val(node);
ADD_INSN1(ret, node, putobject, str);
RB_OBJ_WRITTEN(iseq, Qundef, str);
ADD_CALL(ret, node, idBackquote, INT2FIX(1));
Expand Down
1 change: 1 addition & 0 deletions internal/ruby_parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ VALUE rb_parser_set_context(VALUE, const struct rb_iseq_struct *, int);
VALUE rb_parser_new(void);
rb_ast_t *rb_parser_compile_string_path(VALUE vparser, VALUE fname, VALUE src, int line);
VALUE rb_str_new_parser_string(rb_parser_string_t *str);
VALUE rb_str_new_mutable_parser_string(rb_parser_string_t *str);

VALUE rb_node_str_string_val(const NODE *);
VALUE rb_node_sym_string_val(const NODE *);
Expand Down
2 changes: 1 addition & 1 deletion parse.y
Original file line number Diff line number Diff line change
Expand Up @@ -7959,7 +7959,7 @@ nextline(struct parser_params *p, int set_encoding)
}
#ifndef RIPPER
if (p->debug_lines) {
VALUE v = rb_str_new_parser_string(str);
VALUE v = rb_str_new_mutable_parser_string(str);
if (set_encoding) rb_enc_associate(v, p->enc);
rb_ary_push(p->debug_lines, v);
}
Expand Down
8 changes: 8 additions & 0 deletions ruby_parser.c
Original file line number Diff line number Diff line change
Expand Up @@ -741,6 +741,14 @@ rb_parser_set_yydebug(VALUE vparser, VALUE flag)

VALUE
rb_str_new_parser_string(rb_parser_string_t *str)
{
VALUE string = rb_enc_interned_str(str->ptr, str->len, str->enc);
rb_enc_str_coderange(string);
return string;
}

VALUE
rb_str_new_mutable_parser_string(rb_parser_string_t *str)
{
return rb_enc_str_new(str->ptr, str->len, str->enc);
}
Expand Down
2 changes: 1 addition & 1 deletion test/ruby/test_shapes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1006,7 +1006,7 @@ def test_freezing_and_cloning_object_with_ivars
end

def test_freezing_and_cloning_string
str = "str".freeze
str = ("str" + "str").freeze
str2 = str.clone(freeze: true)
assert_predicate(str2, :frozen?)
assert_shape_equal(RubyVM::Shape.of(str), RubyVM::Shape.of(str2))
Expand Down