From b08dacfea39ad8da3f1fd7fdd0e4538cc892ec44 Mon Sep 17 00:00:00 2001 From: Jeremy Evans Date: Thu, 18 Nov 2021 15:10:20 -0800 Subject: Optimize dynamic string interpolation for symbol/true/false/nil/0-9 This provides a significant speedup for symbol, true, false, nil, and 0-9, class/module, and a small speedup in most other cases. Speedups (using included benchmarks): :symbol :: 60% 0-9 :: 50% Class/Module :: 50% nil/true/false :: 20% integer :: 10% [] :: 10% "" :: 3% One reason this approach is faster is it reduces the number of VM instructions for each interpolated value. Initial idea, approach, and benchmarks from Eric Wong. I applied the same approach against the master branch, updating it to handle the significant internal changes since this was first proposed 4 years ago (such as CALL_INFO/CALL_CACHE -> CALL_DATA). I also expanded it to optimize true/false/nil/0-9/class/module, and added handling of missing methods, refined methods, and RUBY_DEBUG. This renames the tostring insn to anytostring, and adds an objtostring insn that implements the optimization. This requires making a few functions non-static, and adding some non-static functions. This disables 4 YJIT tests. Those tests should be reenabled after YJIT optimizes the new objtostring insn. Implements [Feature #13715] Co-authored-by: Eric Wong Co-authored-by: Alan Wu Co-authored-by: Yusuke Endoh Co-authored-by: Koichi Sasada --- insns.def | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) (limited to 'insns.def') diff --git a/insns.def b/insns.def index 371361512f..f759c1a5c5 100644 --- a/insns.def +++ b/insns.def @@ -381,9 +381,10 @@ concatstrings val = rb_str_concat_literals(num, STACK_ADDR_FROM_TOP(num)); } -/* push the result of to_s. */ +/* Convert the result to string if not already a string. + This is used as a backup if to_s does not return a string. */ DEFINE_INSN -tostring +anytostring () (VALUE val, VALUE str) (VALUE val) @@ -781,6 +782,21 @@ opt_send_without_block } } +/* Convert object to string using to_s or equivalent. */ +DEFINE_INSN +objtostring +(CALL_DATA cd) +(VALUE recv) +(VALUE val) +// attr bool leaf = false; +{ + val = vm_objtostring(GET_ISEQ(), recv, cd); + + if (val == Qundef) { + CALL_SIMPLE_METHOD(); + } +} + DEFINE_INSN opt_str_freeze (VALUE str, CALL_DATA cd) -- cgit v1.2.3