Skip to content

Commit 0e5cb74

Browse files
authored
ZJIT: Don't push frame for String#empty? (ruby#14836)
lobsters before: ``` ***ZJIT: Printing ZJIT statistics on exit*** Top-20 not inlined C methods (71.9% of total 15,247,103): Hash#[]: 4,516,006 (29.6%) Class#current: 1,154,273 ( 7.6%) Kernel#is_a?: 1,027,952 ( 6.7%) Regexp#match?: 398,256 ( 2.6%) String#empty?: 353,775 ( 2.3%) Hash#key?: 349,154 ( 2.3%) Hash#[]=: 344,347 ( 2.3%) String#start_with?: 337,386 ( 2.2%) Kernel#respond_to?: 316,003 ( 2.1%) ObjectSpace::WeakKeyMap#[]: 238,978 ( 1.6%) TrueClass#===: 235,771 ( 1.5%) FalseClass#===: 231,144 ( 1.5%) Array#include?: 211,339 ( 1.4%) Hash#fetch: 204,702 ( 1.3%) Kernel#block_given?: 181,789 ( 1.2%) ActiveSupport::OrderedOptions#_get: 181,272 ( 1.2%) Kernel#dup: 179,336 ( 1.2%) BasicObject#!=: 174,429 ( 1.1%) Class#new: 168,079 ( 1.1%) Kernel#kind_of?: 165,600 ( 1.1%) Top-20 not annotated C methods (72.5% of total 15,409,355): Hash#[]: 4,516,016 (29.3%) Kernel#is_a?: 1,209,970 ( 7.9%) Class#current: 1,154,273 ( 7.5%) Regexp#match?: 398,256 ( 2.6%) String#empty?: 361,013 ( 2.3%) Hash#key?: 349,154 ( 2.3%) Hash#[]=: 344,347 ( 2.2%) String#start_with?: 337,386 ( 2.2%) Kernel#respond_to?: 316,003 ( 2.1%) ObjectSpace::WeakKeyMap#[]: 238,978 ( 1.6%) TrueClass#===: 235,771 ( 1.5%) FalseClass#===: 231,144 ( 1.5%) Array#include?: 211,339 ( 1.4%) Hash#fetch: 204,702 ( 1.3%) Kernel#block_given?: 191,658 ( 1.2%) ActiveSupport::OrderedOptions#_get: 181,272 ( 1.2%) Kernel#dup: 179,343 ( 1.2%) BasicObject#!=: 174,613 ( 1.1%) Class#new: 168,079 ( 1.1%) Kernel#kind_of?: 165,634 ( 1.1%) Top-2 not optimized method types for send (100.0% of total 71,083): cfunc: 47,637 (67.0%) iseq: 23,446 (33.0%) Top-6 not optimized method types for send_without_block (100.0% of total 4,482,446): iseq: 2,227,443 (49.7%) bmethod: 985,679 (22.0%) optimized: 952,914 (21.3%) alias: 310,750 ( 6.9%) null: 5,106 ( 0.1%) cfunc: 554 ( 0.0%) Top-13 not optimized instructions (100.0% of total 4,264,922): invokesuper: 2,346,296 (55.0%) invokeblock: 809,163 (19.0%) sendforward: 505,446 (11.9%) opt_eq: 454,244 (10.7%) opt_plus: 74,059 ( 1.7%) opt_minus: 36,227 ( 0.8%) opt_send_without_block: 21,396 ( 0.5%) opt_neq: 7,247 ( 0.2%) opt_mult: 6,752 ( 0.2%) opt_or: 3,617 ( 0.1%) opt_lt: 348 ( 0.0%) opt_ge: 91 ( 0.0%) opt_gt: 36 ( 0.0%) Top-9 send fallback reasons (100.0% of total 27,366,538): send_without_block_polymorphic: 9,222,828 (33.7%) send_no_profiles: 5,892,897 (21.5%) send_without_block_not_optimized_method_type: 4,482,446 (16.4%) not_optimized_instruction: 4,264,922 (15.6%) send_without_block_no_profiles: 3,407,046 (12.4%) send_not_optimized_method_type: 71,083 ( 0.3%) send_without_block_cfunc_array_variadic: 15,135 ( 0.1%) obj_to_string_not_string: 9,919 ( 0.0%) send_without_block_direct_too_many_args: 262 ( 0.0%) Top-9 unhandled YARV insns (100.0% of total 688,292): expandarray: 328,369 (47.7%) checkkeyword: 190,697 (27.7%) getclassvariable: 59,286 ( 8.6%) getblockparam: 48,651 ( 7.1%) invokesuperforward: 48,162 ( 7.0%) opt_duparray_send: 11,978 ( 1.7%) getconstant: 840 ( 0.1%) checkmatch: 290 ( 0.0%) once: 19 ( 0.0%) Top-2 compile error reasons (100.0% of total 3,675,808): register_spill_on_alloc: 3,459,950 (94.1%) register_spill_on_ccall: 215,858 ( 5.9%) Top-14 side exit reasons (100.0% of total 10,732,532): compile_error: 3,675,808 (34.2%) guard_type_failure: 2,616,693 (24.4%) guard_shape_failure: 1,902,102 (17.7%) unhandled_yarv_insn: 688,292 ( 6.4%) block_param_proxy_not_iseq_or_ifunc: 534,943 ( 5.0%) unhandled_kwarg: 421,996 ( 3.9%) patchpoint: 359,831 ( 3.4%) unknown_newarray_send: 314,665 ( 2.9%) unhandled_splat: 121,910 ( 1.1%) unhandled_hir_insn: 76,393 ( 0.7%) block_param_proxy_modified: 19,193 ( 0.2%) interrupt: 528 ( 0.0%) obj_to_string_fallback: 156 ( 0.0%) guard_type_not_failure: 22 ( 0.0%) send_count: 66,343,482 dynamic_send_count: 27,366,538 (41.2%) optimized_send_count: 38,976,944 (58.8%) iseq_optimized_send_count: 17,935,768 (27.0%) inline_cfunc_optimized_send_count: 5,794,073 ( 8.7%) non_variadic_cfunc_optimized_send_count: 12,588,582 (19.0%) variadic_cfunc_optimized_send_count: 2,658,521 ( 4.0%) dynamic_getivar_count: 7,321,990 dynamic_setivar_count: 7,231,183 compiled_iseq_count: 4,770 failed_iseq_count: 468 compile_time: 7,466ms profile_time: 52ms gc_time: 33ms invalidation_time: 116ms vm_write_pc_count: 64,768,186 vm_write_sp_count: 63,445,066 vm_write_locals_count: 63,445,066 vm_write_stack_count: 63,445,066 vm_write_to_parent_iseq_local_count: 292,445 vm_read_from_parent_iseq_local_count: 6,461,354 code_region_bytes: 22,446,080 side_exit_count: 10,732,532 total_insn_count: 515,600,654 vm_insn_count: 163,640,874 zjit_insn_count: 351,959,780 ratio_in_zjit: 68.3% ``` lobsters after: ``` ***ZJIT: Printing ZJIT statistics on exit*** Top-20 not inlined C methods (72.3% of total 14,893,304): Hash#[]: 4,515,997 (30.3%) Class#current: 1,154,273 ( 7.8%) Kernel#is_a?: 1,027,957 ( 6.9%) Regexp#match?: 398,259 ( 2.7%) Hash#key?: 349,149 ( 2.3%) Hash#[]=: 344,347 ( 2.3%) String#start_with?: 337,386 ( 2.3%) Kernel#respond_to?: 316,003 ( 2.1%) ObjectSpace::WeakKeyMap#[]: 238,978 ( 1.6%) TrueClass#===: 235,771 ( 1.6%) FalseClass#===: 231,144 ( 1.6%) Array#include?: 211,333 ( 1.4%) Hash#fetch: 204,703 ( 1.4%) Kernel#block_given?: 181,781 ( 1.2%) ActiveSupport::OrderedOptions#_get: 181,272 ( 1.2%) Kernel#dup: 179,337 ( 1.2%) BasicObject#!=: 174,429 ( 1.2%) Class#new: 168,079 ( 1.1%) Kernel#kind_of?: 165,600 ( 1.1%) String#==: 154,751 ( 1.0%) Top-20 not annotated C methods (72.9% of total 15,048,318): Hash#[]: 4,516,007 (30.0%) Kernel#is_a?: 1,209,975 ( 8.0%) Class#current: 1,154,273 ( 7.7%) Regexp#match?: 398,259 ( 2.6%) Hash#key?: 349,149 ( 2.3%) Hash#[]=: 344,347 ( 2.3%) String#start_with?: 337,386 ( 2.2%) Kernel#respond_to?: 316,003 ( 2.1%) ObjectSpace::WeakKeyMap#[]: 238,978 ( 1.6%) TrueClass#===: 235,771 ( 1.6%) FalseClass#===: 231,144 ( 1.5%) Array#include?: 211,333 ( 1.4%) Hash#fetch: 204,703 ( 1.4%) Kernel#block_given?: 191,650 ( 1.3%) ActiveSupport::OrderedOptions#_get: 181,272 ( 1.2%) Kernel#dup: 179,344 ( 1.2%) BasicObject#!=: 174,613 ( 1.2%) Class#new: 168,079 ( 1.1%) Kernel#kind_of?: 165,634 ( 1.1%) String#==: 160,682 ( 1.1%) Top-2 not optimized method types for send (100.0% of total 71,084): cfunc: 47,638 (67.0%) iseq: 23,446 (33.0%) Top-6 not optimized method types for send_without_block (100.0% of total 4,482,444): iseq: 2,227,440 (49.7%) bmethod: 985,679 (22.0%) optimized: 952,916 (21.3%) alias: 310,749 ( 6.9%) null: 5,106 ( 0.1%) cfunc: 554 ( 0.0%) Top-13 not optimized instructions (100.0% of total 4,264,913): invokesuper: 2,346,301 (55.0%) invokeblock: 809,153 (19.0%) sendforward: 505,445 (11.9%) opt_eq: 454,244 (10.7%) opt_plus: 74,056 ( 1.7%) opt_minus: 36,227 ( 0.8%) opt_send_without_block: 21,396 ( 0.5%) opt_neq: 7,247 ( 0.2%) opt_mult: 6,752 ( 0.2%) opt_or: 3,617 ( 0.1%) opt_lt: 348 ( 0.0%) opt_ge: 91 ( 0.0%) opt_gt: 36 ( 0.0%) Top-9 send fallback reasons (100.0% of total 27,366,491): send_without_block_polymorphic: 9,222,820 (33.7%) send_no_profiles: 5,892,885 (21.5%) send_without_block_not_optimized_method_type: 4,482,444 (16.4%) not_optimized_instruction: 4,264,913 (15.6%) send_without_block_no_profiles: 3,407,030 (12.4%) send_not_optimized_method_type: 71,084 ( 0.3%) send_without_block_cfunc_array_variadic: 15,134 ( 0.1%) obj_to_string_not_string: 9,919 ( 0.0%) send_without_block_direct_too_many_args: 262 ( 0.0%) Top-9 unhandled YARV insns (100.0% of total 688,291): expandarray: 328,368 (47.7%) checkkeyword: 190,697 (27.7%) getclassvariable: 59,286 ( 8.6%) getblockparam: 48,651 ( 7.1%) invokesuperforward: 48,162 ( 7.0%) opt_duparray_send: 11,978 ( 1.7%) getconstant: 840 ( 0.1%) checkmatch: 290 ( 0.0%) once: 19 ( 0.0%) Top-2 compile error reasons (100.0% of total 3,675,807): register_spill_on_alloc: 3,459,949 (94.1%) register_spill_on_ccall: 215,858 ( 5.9%) Top-14 side exit reasons (100.0% of total 10,732,546): compile_error: 3,675,807 (34.2%) guard_type_failure: 2,616,699 (24.4%) guard_shape_failure: 1,902,100 (17.7%) unhandled_yarv_insn: 688,291 ( 6.4%) block_param_proxy_not_iseq_or_ifunc: 534,950 ( 5.0%) unhandled_kwarg: 421,993 ( 3.9%) patchpoint: 359,837 ( 3.4%) unknown_newarray_send: 314,667 ( 2.9%) unhandled_splat: 121,913 ( 1.1%) unhandled_hir_insn: 76,393 ( 0.7%) block_param_proxy_modified: 19,193 ( 0.2%) interrupt: 525 ( 0.0%) obj_to_string_fallback: 156 ( 0.0%) guard_type_not_failure: 22 ( 0.0%) send_count: 66,343,388 dynamic_send_count: 27,366,491 (41.2%) optimized_send_count: 38,976,897 (58.8%) iseq_optimized_send_count: 17,935,730 (27.0%) inline_cfunc_optimized_send_count: 6,147,863 ( 9.3%) non_variadic_cfunc_optimized_send_count: 12,234,780 (18.4%) variadic_cfunc_optimized_send_count: 2,658,524 ( 4.0%) dynamic_getivar_count: 7,321,987 dynamic_setivar_count: 7,231,160 compiled_iseq_count: 4,770 failed_iseq_count: 468 compile_time: 7,223ms profile_time: 51ms gc_time: 32ms invalidation_time: 107ms vm_write_pc_count: 64,414,293 vm_write_sp_count: 63,091,183 vm_write_locals_count: 63,091,183 vm_write_stack_count: 63,091,183 vm_write_to_parent_iseq_local_count: 292,443 vm_read_from_parent_iseq_local_count: 6,461,326 code_region_bytes: 22,446,080 side_exit_count: 10,732,546 total_insn_count: 515,600,823 vm_insn_count: 163,641,263 zjit_insn_count: 351,959,560 ratio_in_zjit: 68.3% ```
1 parent 5298e97 commit 0e5cb74

File tree

2 files changed

+60
-0
lines changed

2 files changed

+60
-0
lines changed

zjit/src/cruby_methods.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,7 @@ pub fn init() -> Annotations {
191191
annotate!(rb_cString, "bytesize", types::Fixnum, no_gc, leaf);
192192
annotate!(rb_cString, "to_s", types::StringExact);
193193
annotate!(rb_cString, "getbyte", inline_string_getbyte);
194+
annotate!(rb_cString, "empty?", types::BoolExact, no_gc, leaf, elidable);
194195
annotate!(rb_cModule, "name", types::StringExact.union(types::NilClass), no_gc, leaf, elidable);
195196
annotate!(rb_cModule, "===", types::BoolExact, no_gc, leaf);
196197
annotate!(rb_cArray, "length", types::Fixnum, no_gc, leaf, elidable);

zjit/src/hir.rs

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13255,6 +13255,65 @@ mod opt_tests {
1325513255
");
1325613256
}
1325713257

13258+
#[test]
13259+
fn test_specialize_string_empty() {
13260+
eval(r#"
13261+
def test(s)
13262+
s.empty?
13263+
end
13264+
test("asdf")
13265+
"#);
13266+
assert_snapshot!(hir_string("test"), @r"
13267+
fn test@<compiled>:3:
13268+
bb0():
13269+
EntryPoint interpreter
13270+
v1:BasicObject = LoadSelf
13271+
v2:BasicObject = GetLocal l0, SP@4
13272+
Jump bb2(v1, v2)
13273+
bb1(v5:BasicObject, v6:BasicObject):
13274+
EntryPoint JIT(0)
13275+
Jump bb2(v5, v6)
13276+
bb2(v8:BasicObject, v9:BasicObject):
13277+
PatchPoint MethodRedefined(String@0x1000, empty?@0x1008, cme:0x1010)
13278+
PatchPoint NoSingletonClass(String@0x1000)
13279+
v25:StringExact = GuardType v9, StringExact
13280+
IncrCounter inline_cfunc_optimized_send_count
13281+
v27:BoolExact = CCall empty?@0x1038, v25
13282+
CheckInterrupts
13283+
Return v27
13284+
");
13285+
}
13286+
13287+
#[test]
13288+
fn test_eliminate_string_empty() {
13289+
eval(r#"
13290+
def test(s)
13291+
s.empty?
13292+
4
13293+
end
13294+
test("this should get removed")
13295+
"#);
13296+
assert_snapshot!(hir_string("test"), @r"
13297+
fn test@<compiled>:3:
13298+
bb0():
13299+
EntryPoint interpreter
13300+
v1:BasicObject = LoadSelf
13301+
v2:BasicObject = GetLocal l0, SP@4
13302+
Jump bb2(v1, v2)
13303+
bb1(v5:BasicObject, v6:BasicObject):
13304+
EntryPoint JIT(0)
13305+
Jump bb2(v5, v6)
13306+
bb2(v8:BasicObject, v9:BasicObject):
13307+
PatchPoint MethodRedefined(String@0x1000, empty?@0x1008, cme:0x1010)
13308+
PatchPoint NoSingletonClass(String@0x1000)
13309+
v28:StringExact = GuardType v9, StringExact
13310+
IncrCounter inline_cfunc_optimized_send_count
13311+
v19:Fixnum[4] = Const Value(4)
13312+
CheckInterrupts
13313+
Return v19
13314+
");
13315+
}
13316+
1325813317
#[test]
1325913318
fn test_inline_integer_succ_with_fixnum() {
1326013319
eval("

0 commit comments

Comments
 (0)