summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--zjit/src/cruby_methods.rs1
-rw-r--r--zjit/src/hir.rs59
2 files changed, 60 insertions, 0 deletions
diff --git a/zjit/src/cruby_methods.rs b/zjit/src/cruby_methods.rs
index ea9f1beffc..f6c439ad98 100644
--- a/zjit/src/cruby_methods.rs
+++ b/zjit/src/cruby_methods.rs
@@ -191,6 +191,7 @@ pub fn init() -> Annotations {
annotate!(rb_cString, "bytesize", types::Fixnum, no_gc, leaf);
annotate!(rb_cString, "to_s", types::StringExact);
annotate!(rb_cString, "getbyte", inline_string_getbyte);
+ annotate!(rb_cString, "empty?", types::BoolExact, no_gc, leaf, elidable);
annotate!(rb_cModule, "name", types::StringExact.union(types::NilClass), no_gc, leaf, elidable);
annotate!(rb_cModule, "===", types::BoolExact, no_gc, leaf);
annotate!(rb_cArray, "length", types::Fixnum, no_gc, leaf, elidable);
diff --git a/zjit/src/hir.rs b/zjit/src/hir.rs
index 48011bd088..f0ada408e3 100644
--- a/zjit/src/hir.rs
+++ b/zjit/src/hir.rs
@@ -13256,6 +13256,65 @@ mod opt_tests {
}
#[test]
+ fn test_specialize_string_empty() {
+ eval(r#"
+ def test(s)
+ s.empty?
+ end
+ test("asdf")
+ "#);
+ assert_snapshot!(hir_string("test"), @r"
+ fn test@<compiled>:3:
+ bb0():
+ EntryPoint interpreter
+ v1:BasicObject = LoadSelf
+ v2:BasicObject = GetLocal l0, SP@4
+ Jump bb2(v1, v2)
+ bb1(v5:BasicObject, v6:BasicObject):
+ EntryPoint JIT(0)
+ Jump bb2(v5, v6)
+ bb2(v8:BasicObject, v9:BasicObject):
+ PatchPoint MethodRedefined(String@0x1000, empty?@0x1008, cme:0x1010)
+ PatchPoint NoSingletonClass(String@0x1000)
+ v25:StringExact = GuardType v9, StringExact
+ IncrCounter inline_cfunc_optimized_send_count
+ v27:BoolExact = CCall empty?@0x1038, v25
+ CheckInterrupts
+ Return v27
+ ");
+ }
+
+ #[test]
+ fn test_eliminate_string_empty() {
+ eval(r#"
+ def test(s)
+ s.empty?
+ 4
+ end
+ test("this should get removed")
+ "#);
+ assert_snapshot!(hir_string("test"), @r"
+ fn test@<compiled>:3:
+ bb0():
+ EntryPoint interpreter
+ v1:BasicObject = LoadSelf
+ v2:BasicObject = GetLocal l0, SP@4
+ Jump bb2(v1, v2)
+ bb1(v5:BasicObject, v6:BasicObject):
+ EntryPoint JIT(0)
+ Jump bb2(v5, v6)
+ bb2(v8:BasicObject, v9:BasicObject):
+ PatchPoint MethodRedefined(String@0x1000, empty?@0x1008, cme:0x1010)
+ PatchPoint NoSingletonClass(String@0x1000)
+ v28:StringExact = GuardType v9, StringExact
+ IncrCounter inline_cfunc_optimized_send_count
+ v19:Fixnum[4] = Const Value(4)
+ CheckInterrupts
+ Return v19
+ ");
+ }
+
+ #[test]
fn test_inline_integer_succ_with_fixnum() {
eval("
def test(x) = x.succ