summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--benchmark/vm2_freezestring.yml10
-rw-r--r--compile.c8
-rw-r--r--insns.def22
-rw-r--r--vm_insnhelper.c2
4 files changed, 35 insertions, 7 deletions
diff --git a/benchmark/vm2_freezestring.yml b/benchmark/vm2_freezestring.yml
new file mode 100644
index 0000000000..b78af91a20
--- /dev/null
+++ b/benchmark/vm2_freezestring.yml
@@ -0,0 +1,10 @@
+prelude: |
+ class String
+ def freeze
+ -self
+ end
+ end
+benchmark:
+ vm2_freezestring: |
+ "tXnL1BP5T1WPXMjuFNLQtallEtRcay1t2lHtJSrlVsDgvunlbtfpr/DGdH0NGYE9".freeze
+loop_count: 6000000
diff --git a/compile.c b/compile.c
index c16721e080..9ce89bccf1 100644
--- a/compile.c
+++ b/compile.c
@@ -6384,10 +6384,14 @@ iseq_compile_each0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *node, in
ISEQ_COMPILE_DATA(iseq)->option->specialized_instruction) {
VALUE str = freeze_literal(iseq, node->nd_recv->nd_lit);
if (node->nd_mid == idUMinus) {
- ADD_INSN1(ret, line, opt_str_uminus, str);
+ ADD_INSN3(ret, line, opt_str_uminus, str,
+ new_callinfo(iseq, idUMinus, 0, 0, NULL, FALSE),
+ Qundef /* CALL_CACHE */);
}
else {
- ADD_INSN1(ret, line, opt_str_freeze, str);
+ ADD_INSN3(ret, line, opt_str_freeze, str,
+ new_callinfo(iseq, idFreeze, 0, 0, NULL, FALSE),
+ Qundef /* CALL_CACHE */);
}
if (popped) {
ADD_INSN(ret, line, pop);
diff --git a/insns.def b/insns.def
index ced6054cce..d606fa722b 100644
--- a/insns.def
+++ b/insns.def
@@ -753,22 +753,36 @@ send
DEFINE_INSN
opt_str_freeze
-(VALUE str)
+(VALUE str, CALL_INFO ci, CALL_CACHE cc)
()
(VALUE val)
-// attr bool leaf = BASIC_OP_UNREDEFINED_P(BOP_FREEZE, STRING_REDEFINED_OP_FLAG);
{
val = vm_opt_str_freeze(str, BOP_FREEZE, idFreeze);
+
+ if (val == Qundef) {
+ PUSH(str);
+#ifndef MJIT_HEADER
+ ADD_PC(-WIDTH_OF_opt_send_without_block);
+#endif
+ DISPATCH_ORIGINAL_INSN(opt_send_without_block);
+ }
}
DEFINE_INSN
opt_str_uminus
-(VALUE str)
+(VALUE str, CALL_INFO ci, CALL_CACHE cc)
()
(VALUE val)
-// attr bool leaf = BASIC_OP_UNREDEFINED_P(BOP_UMINUS, STRING_REDEFINED_OP_FLAG);
{
val = vm_opt_str_freeze(str, BOP_UMINUS, idUMinus);
+
+ if (val == Qundef) {
+ PUSH(str);
+#ifndef MJIT_HEADER
+ ADD_PC(-WIDTH_OF_opt_send_without_block);
+#endif
+ DISPATCH_ORIGINAL_INSN(opt_send_without_block);
+ }
}
DEFINE_INSN
diff --git a/vm_insnhelper.c b/vm_insnhelper.c
index 50d95610c3..bf886f71f8 100644
--- a/vm_insnhelper.c
+++ b/vm_insnhelper.c
@@ -3219,7 +3219,7 @@ vm_opt_str_freeze(VALUE str, int bop, ID id)
return str;
}
else {
- return rb_funcall(rb_str_resurrect(str), id, 0);
+ return Qundef;
}
}