Skip to content

Commit a9f24aa

Browse files
authored
ZJIT: Specialize string length, bytesize, and size (ruby#14928)
Don't push frame for String#size, String#bytesize, and String#length.
1 parent f8ccc0a commit a9f24aa

File tree

2 files changed

+180
-0
lines changed

2 files changed

+180
-0
lines changed

zjit/src/cruby_methods.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,9 @@ pub fn init() -> Annotations {
190190
annotate!(rb_mKernel, "itself", inline_kernel_itself);
191191
annotate!(rb_mKernel, "block_given?", inline_kernel_block_given_p);
192192
annotate!(rb_cString, "bytesize", types::Fixnum, no_gc, leaf);
193+
annotate!(rb_cString, "bytesize", types::Fixnum, no_gc, leaf, elidable);
194+
annotate!(rb_cString, "size", types::Fixnum, no_gc, leaf, elidable);
195+
annotate!(rb_cString, "length", types::Fixnum, no_gc, leaf, elidable);
193196
annotate!(rb_cString, "to_s", types::StringExact);
194197
annotate!(rb_cString, "getbyte", inline_string_getbyte);
195198
annotate!(rb_cString, "empty?", types::BoolExact, no_gc, leaf, elidable);

zjit/src/hir.rs

Lines changed: 177 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15499,4 +15499,181 @@ mod opt_tests {
1549915499
Return v28
1550015500
");
1550115501
}
15502+
15503+
#[test]
15504+
fn test_specialize_string_size() {
15505+
eval(r#"
15506+
def test(s)
15507+
s.size
15508+
end
15509+
test("asdf")
15510+
"#);
15511+
assert_snapshot!(hir_string("test"), @r"
15512+
fn test@<compiled>:3:
15513+
bb0():
15514+
EntryPoint interpreter
15515+
v1:BasicObject = LoadSelf
15516+
v2:BasicObject = GetLocal l0, SP@4
15517+
Jump bb2(v1, v2)
15518+
bb1(v5:BasicObject, v6:BasicObject):
15519+
EntryPoint JIT(0)
15520+
Jump bb2(v5, v6)
15521+
bb2(v8:BasicObject, v9:BasicObject):
15522+
PatchPoint MethodRedefined(String@0x1000, size@0x1008, cme:0x1010)
15523+
PatchPoint NoSingletonClass(String@0x1000)
15524+
v25:StringExact = GuardType v9, StringExact
15525+
IncrCounter inline_cfunc_optimized_send_count
15526+
v27:Fixnum = CCall size@0x1038, v25
15527+
CheckInterrupts
15528+
Return v27
15529+
");
15530+
}
15531+
15532+
#[test]
15533+
fn test_elide_string_size() {
15534+
eval(r#"
15535+
def test(s)
15536+
s.size
15537+
5
15538+
end
15539+
test("asdf")
15540+
"#);
15541+
assert_snapshot!(hir_string("test"), @r"
15542+
fn test@<compiled>:3:
15543+
bb0():
15544+
EntryPoint interpreter
15545+
v1:BasicObject = LoadSelf
15546+
v2:BasicObject = GetLocal l0, SP@4
15547+
Jump bb2(v1, v2)
15548+
bb1(v5:BasicObject, v6:BasicObject):
15549+
EntryPoint JIT(0)
15550+
Jump bb2(v5, v6)
15551+
bb2(v8:BasicObject, v9:BasicObject):
15552+
PatchPoint MethodRedefined(String@0x1000, size@0x1008, cme:0x1010)
15553+
PatchPoint NoSingletonClass(String@0x1000)
15554+
v28:StringExact = GuardType v9, StringExact
15555+
IncrCounter inline_cfunc_optimized_send_count
15556+
v19:Fixnum[5] = Const Value(5)
15557+
CheckInterrupts
15558+
Return v19
15559+
");
15560+
}
15561+
15562+
#[test]
15563+
fn test_specialize_string_bytesize() {
15564+
eval(r#"
15565+
def test(s)
15566+
s.bytesize
15567+
end
15568+
test("asdf")
15569+
"#);
15570+
assert_snapshot!(hir_string("test"), @r"
15571+
fn test@<compiled>:3:
15572+
bb0():
15573+
EntryPoint interpreter
15574+
v1:BasicObject = LoadSelf
15575+
v2:BasicObject = GetLocal l0, SP@4
15576+
Jump bb2(v1, v2)
15577+
bb1(v5:BasicObject, v6:BasicObject):
15578+
EntryPoint JIT(0)
15579+
Jump bb2(v5, v6)
15580+
bb2(v8:BasicObject, v9:BasicObject):
15581+
PatchPoint MethodRedefined(String@0x1000, bytesize@0x1008, cme:0x1010)
15582+
PatchPoint NoSingletonClass(String@0x1000)
15583+
v23:StringExact = GuardType v9, StringExact
15584+
IncrCounter inline_cfunc_optimized_send_count
15585+
v25:Fixnum = CCall bytesize@0x1038, v23
15586+
CheckInterrupts
15587+
Return v25
15588+
");
15589+
}
15590+
15591+
#[test]
15592+
fn test_elide_string_bytesize() {
15593+
eval(r#"
15594+
def test(s)
15595+
s.bytesize
15596+
5
15597+
end
15598+
test("asdf")
15599+
"#);
15600+
assert_snapshot!(hir_string("test"), @r"
15601+
fn test@<compiled>:3:
15602+
bb0():
15603+
EntryPoint interpreter
15604+
v1:BasicObject = LoadSelf
15605+
v2:BasicObject = GetLocal l0, SP@4
15606+
Jump bb2(v1, v2)
15607+
bb1(v5:BasicObject, v6:BasicObject):
15608+
EntryPoint JIT(0)
15609+
Jump bb2(v5, v6)
15610+
bb2(v8:BasicObject, v9:BasicObject):
15611+
PatchPoint MethodRedefined(String@0x1000, bytesize@0x1008, cme:0x1010)
15612+
PatchPoint NoSingletonClass(String@0x1000)
15613+
v26:StringExact = GuardType v9, StringExact
15614+
IncrCounter inline_cfunc_optimized_send_count
15615+
v17:Fixnum[5] = Const Value(5)
15616+
CheckInterrupts
15617+
Return v17
15618+
");
15619+
}
15620+
15621+
#[test]
15622+
fn test_specialize_string_length() {
15623+
eval(r#"
15624+
def test(s)
15625+
s.length
15626+
end
15627+
test("asdf")
15628+
"#);
15629+
assert_snapshot!(hir_string("test"), @r"
15630+
fn test@<compiled>:3:
15631+
bb0():
15632+
EntryPoint interpreter
15633+
v1:BasicObject = LoadSelf
15634+
v2:BasicObject = GetLocal l0, SP@4
15635+
Jump bb2(v1, v2)
15636+
bb1(v5:BasicObject, v6:BasicObject):
15637+
EntryPoint JIT(0)
15638+
Jump bb2(v5, v6)
15639+
bb2(v8:BasicObject, v9:BasicObject):
15640+
PatchPoint MethodRedefined(String@0x1000, length@0x1008, cme:0x1010)
15641+
PatchPoint NoSingletonClass(String@0x1000)
15642+
v25:StringExact = GuardType v9, StringExact
15643+
IncrCounter inline_cfunc_optimized_send_count
15644+
v27:Fixnum = CCall length@0x1038, v25
15645+
CheckInterrupts
15646+
Return v27
15647+
");
15648+
}
15649+
15650+
#[test]
15651+
fn test_elide_string_length() {
15652+
eval(r#"
15653+
def test(s)
15654+
s.length
15655+
4
15656+
end
15657+
test("this should get removed")
15658+
"#);
15659+
assert_snapshot!(hir_string("test"), @r"
15660+
fn test@<compiled>:3:
15661+
bb0():
15662+
EntryPoint interpreter
15663+
v1:BasicObject = LoadSelf
15664+
v2:BasicObject = GetLocal l0, SP@4
15665+
Jump bb2(v1, v2)
15666+
bb1(v5:BasicObject, v6:BasicObject):
15667+
EntryPoint JIT(0)
15668+
Jump bb2(v5, v6)
15669+
bb2(v8:BasicObject, v9:BasicObject):
15670+
PatchPoint MethodRedefined(String@0x1000, length@0x1008, cme:0x1010)
15671+
PatchPoint NoSingletonClass(String@0x1000)
15672+
v28:StringExact = GuardType v9, StringExact
15673+
IncrCounter inline_cfunc_optimized_send_count
15674+
v19:Fixnum[4] = Const Value(4)
15675+
CheckInterrupts
15676+
Return v19
15677+
");
15678+
}
1550215679
}

0 commit comments

Comments
 (0)