Skip to content

Commit 403f493

Browse files
committed
[rewrite commit message] per-iseq AND per-class. Down to zero fallbacks on lobsters
1 parent e11995e commit 403f493

2 files changed

Lines changed: 10 additions & 6 deletions

File tree

zjit/src/hir.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2537,7 +2537,7 @@ impl Function {
25372537
// No patchpoint needed.
25382538
return true;
25392539
}
2540-
if self.was_invalidated_for_singleton_class_creation {
2540+
if self.was_invalidated_for_singleton_class_creation && invariants::has_singleton_class_of(klass) {
25412541
// A previous compilation of this ISEQ was invalidated for singleton class
25422542
// creation. Avoid repeating the invalidation.
25432543
return false;

zjit/src/hir/opt_tests.rs

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13237,7 +13237,8 @@ mod hir_opt_tests {
1323713237
test("hi", -> {})
1323813238
test("hi", -> {})
1323913239
"#);
13240-
assert!(hir_string("test").contains("NoSingletonClass"));
13240+
let hir = hir_string("test");
13241+
assert!(hir.contains("NoSingletonClass(String"));
1324113242

1324213243
// Now we break the assumption by defining a singleton method on a string.
1324313244
eval(r#"
@@ -13248,7 +13249,7 @@ mod hir_opt_tests {
1324813249
// The output should NOT have NoSingletonClass patchpoint for String, and should
1324913250
// fall back to SendWithoutBlock instead of the optimized CCall path.
1325013251
let hir = hir_string("test");
13251-
assert!(! hir.contains("NoSingletonClass"));
13252+
assert!(! hir.contains("NoSingletonClass(String"), "{hir}");
1325213253
assert_snapshot!(hir, @"
1325313254
fn test@<compiled>:3:
1325413255
bb1():
@@ -13266,7 +13267,10 @@ mod hir_opt_tests {
1326613267
Jump bb3(v7, v8, v9)
1326713268
bb3(v11:BasicObject, v12:BasicObject, v13:BasicObject):
1326813269
v19:BasicObject = Send v12, :length # SendFallbackReason: Singleton class previously created for receiver class
13269-
v24:BasicObject = Send v13, :call # SendFallbackReason: Singleton class previously created for receiver class
13270+
PatchPoint NoSingletonClass(Proc@0x1008)
13271+
PatchPoint MethodRedefined(Proc@0x1008, call@0x1010, cme:0x1018)
13272+
v40:ObjectSubclass[class_exact:Proc] = GuardType v13, ObjectSubclass[class_exact:Proc]
13273+
v41:BasicObject = InvokeProc v40
1327013274
PatchPoint NoEPEscape(test)
1327113275
v32:BasicObject = Send v12, :length # SendFallbackReason: Singleton class previously created for receiver class
1327213276
CheckInterrupts
@@ -13289,14 +13293,14 @@ mod hir_opt_tests {
1328913293
will_bust("hi", -> {})
1329013294
will_bust("hi", -> {})
1329113295
"#);
13292-
assert!(hir_string("will_bust").contains("NoSingletonClass"));
13296+
assert!(hir_string("will_bust").contains("NoSingletonClass(String"));
1329313297

1329413298
// Now we break the assumption by defining a singleton method on a string.
1329513299
eval(r#"
1329613300
special_string = +""
1329713301
will_bust(special_string, -> { def special_string.length = -1 })
1329813302
"#);
13299-
assert!(! hir_string("will_bust").contains("NoSingletonClass"));
13303+
assert!(! hir_string("will_bust").contains("NoSingletonClas(String"));
1330013304

1330113305
// But, the unrelated call_length() should still use NoSingletonClass
1330213306
eval("call_length('profile')");

0 commit comments

Comments
 (0)