Skip to content

Commit c57307a

Browse files
committed
ZJIT: Assert no side exits in assert_compiles()
Most of the time, we want to assert that we compile and the compiled code runs without exiting. A small number of tests trigger side exits, and those are changed to use assert_compiles_allowing_exits(). ```console $ rg -F 'assert_compiles(' -o | wc 289 289 11862 $ rg -F 'assert_compiles_allowing_exits(' -o | wc 38 38 2196 ```
1 parent 678b2c1 commit c57307a

File tree

5 files changed

+65
-39
lines changed

5 files changed

+65
-39
lines changed

zjit/src/backend/lir.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2750,12 +2750,12 @@ impl Assembler
27502750
}).unwrap_or(false);
27512751

27522752
// If enabled, instrument exits first, and then jump to a shared exit.
2753-
let counted_exit = if get_option!(stats) || should_record_exit {
2753+
let counted_exit = if get_option!(stats) || should_record_exit || cfg!(test) {
27542754
let counted_exit = self.new_label("counted_exit");
27552755
self.write_label(counted_exit.clone());
27562756
asm_comment!(self, "Counted Exit: {reason}");
27572757

2758-
if get_option!(stats) {
2758+
if get_option!(stats) || cfg!(test) {
27592759
asm_comment!(self, "increment a side exit counter");
27602760
self.incr_counter(Opnd::const_ptr(exit_counter_ptr(reason)), 1.into());
27612761

zjit/src/codegen_tests.rs

Lines changed: 37 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -2119,7 +2119,7 @@ fn test_opt_empty_p() {
21192119
def test(x) = x.empty?
21202120
");
21212121
assert_contains_opcode("test", YARVINSN_opt_empty_p);
2122-
assert_snapshot!(assert_compiles("[test([1]), test(\"1\"), test({})]"), @"[false, false, true]");
2122+
assert_snapshot!(assert_compiles_allowing_exits("[test([1]), test(\"1\"), test({})]"), @"[false, false, true]");
21232123
}
21242124

21252125
#[test]
@@ -2128,7 +2128,7 @@ fn test_opt_succ() {
21282128
def test(obj) = obj.succ
21292129
");
21302130
assert_contains_opcode("test", YARVINSN_opt_succ);
2131-
assert_snapshot!(assert_compiles(r#"[test(-1), test("A")]"#), @r#"[0, "B"]"#);
2131+
assert_snapshot!(assert_compiles_allowing_exits(r#"[test(-1), test("A")]"#), @r#"[0, "B"]"#);
21322132
}
21332133

21342134
#[test]
@@ -2137,7 +2137,7 @@ fn test_opt_and() {
21372137
def test(x, y) = x & y
21382138
");
21392139
assert_contains_opcode("test", YARVINSN_opt_and);
2140-
assert_snapshot!(assert_compiles("[test(0b1101, 3), test([3, 2, 1, 4], [8, 1, 2, 3])]"), @"[1, [3, 2, 1]]");
2140+
assert_snapshot!(assert_compiles_allowing_exits("[test(0b1101, 3), test([3, 2, 1, 4], [8, 1, 2, 3])]"), @"[1, [3, 2, 1]]");
21412141
}
21422142

21432143
#[test]
@@ -2146,7 +2146,7 @@ fn test_opt_or() {
21462146
def test(x, y) = x | y
21472147
");
21482148
assert_contains_opcode("test", YARVINSN_opt_or);
2149-
assert_snapshot!(assert_compiles("[test(0b1000, 3), test([3, 2, 1], [1, 2, 3])]"), @"[11, [3, 2, 1]]");
2149+
assert_snapshot!(assert_compiles_allowing_exits("[test(0b1000, 3), test([3, 2, 1], [1, 2, 3])]"), @"[11, [3, 2, 1]]");
21502150
}
21512151

21522152
#[test]
@@ -2170,7 +2170,7 @@ fn test_fixnum_and_side_exit() {
21702170
def test(a, b) = a & b
21712171
");
21722172
assert_contains_opcode("test", YARVINSN_opt_and);
2173-
assert_snapshot!(assert_compiles("
2173+
assert_snapshot!(assert_compiles_allowing_exits("
21742174
[
21752175
test(2, 2),
21762176
test(0b011, 0b110),
@@ -2200,7 +2200,7 @@ fn test_fixnum_or_side_exit() {
22002200
def test(a, b) = a | b
22012201
");
22022202
assert_contains_opcode("test", YARVINSN_opt_or);
2203-
assert_snapshot!(assert_compiles("
2203+
assert_snapshot!(assert_compiles_allowing_exits("
22042204
[
22052205
test(1, 2),
22062206
test(2, 2),
@@ -2273,7 +2273,7 @@ fn test_opt_not() {
22732273
def test(obj) = !obj
22742274
");
22752275
assert_contains_opcode("test", YARVINSN_opt_not);
2276-
assert_snapshot!(assert_compiles("[test(nil), test(false), test(0)]"), @"[true, true, false]");
2276+
assert_snapshot!(assert_compiles_allowing_exits("[test(nil), test(false), test(0)]"), @"[true, true, false]");
22772277
}
22782278

22792279
#[test]
@@ -2369,7 +2369,7 @@ fn test_opt_newarray_send_include_p_redefined() {
23692369
end
23702370
");
23712371
assert_contains_opcode("test", YARVINSN_opt_newarray_send);
2372-
assert_snapshot!(assert_compiles("
2372+
assert_snapshot!(assert_compiles_allowing_exits("
23732373
def test(x)
23742374
[:y, 1, Object.new].include?(x)
23752375
end
@@ -2404,7 +2404,7 @@ fn test_opt_duparray_send_include_p_redefined() {
24042404
end
24052405
");
24062406
assert_contains_opcode("test", YARVINSN_opt_duparray_send);
2407-
assert_snapshot!(assert_compiles("
2407+
assert_snapshot!(assert_compiles_allowing_exits("
24082408
def test(x)
24092409
[:y, 1].include?(x)
24102410
end
@@ -2441,7 +2441,7 @@ fn test_opt_newarray_send_pack_redefined() {
24412441
end
24422442
"#);
24432443
assert_contains_opcode("test", YARVINSN_opt_newarray_send);
2444-
assert_snapshot!(assert_compiles(r#"
2444+
assert_snapshot!(assert_compiles_allowing_exits(r#"
24452445
[test(65), test(66), test(67)]
24462446
"#), @r#"["override:A", "override:B", "override:C"]"#);
24472447
}
@@ -2476,7 +2476,7 @@ fn test_opt_newarray_send_pack_buffer_redefined() {
24762476
end
24772477
"#);
24782478
assert_contains_opcode("test", YARVINSN_opt_newarray_send);
2479-
assert_snapshot!(assert_compiles(r#"
2479+
assert_snapshot!(assert_compiles_allowing_exits(r#"
24802480
def test(num, buffer)
24812481
[num].pack('C', buffer:)
24822482
end
@@ -2509,7 +2509,7 @@ fn test_opt_newarray_send_hash_redefined() {
25092509
test(20)
25102510
");
25112511
assert_contains_opcode("test", YARVINSN_opt_newarray_send);
2512-
assert_snapshot!(assert_compiles("test(20)"), @"42");
2512+
assert_snapshot!(assert_compiles_allowing_exits("test(20)"), @"42");
25132513
}
25142514

25152515
#[test]
@@ -2534,7 +2534,7 @@ fn test_opt_newarray_send_max_redefined() {
25342534
def test(a,b) = [a,b].max
25352535
");
25362536
assert_contains_opcode("test", YARVINSN_opt_newarray_send);
2537-
assert_snapshot!(assert_compiles("
2537+
assert_snapshot!(assert_compiles_allowing_exits("
25382538
def test(a,b) = [a,b].max
25392539
test(15, 30)
25402540
[test(15, 30), test(45, 35)]
@@ -2694,7 +2694,7 @@ fn test_opt_hash_freeze_rewritten() {
26942694
test
26952695
");
26962696
assert_contains_opcode("test", YARVINSN_opt_hash_freeze);
2697-
assert_snapshot!(assert_compiles("test"), @"5");
2697+
assert_snapshot!(assert_compiles_allowing_exits("test"), @"5");
26982698
}
26992699

27002700
#[test]
@@ -2799,7 +2799,7 @@ fn test_opt_ary_freeze_rewritten() {
27992799
test
28002800
");
28012801
assert_contains_opcode("test", YARVINSN_opt_ary_freeze);
2802-
assert_snapshot!(assert_compiles("test"), @"5");
2802+
assert_snapshot!(assert_compiles_allowing_exits("test"), @"5");
28032803
}
28042804

28052805
#[test]
@@ -2828,7 +2828,7 @@ fn test_opt_str_freeze_rewritten() {
28282828
test
28292829
");
28302830
assert_contains_opcode("test", YARVINSN_opt_str_freeze);
2831-
assert_snapshot!(assert_compiles("test"), @"5");
2831+
assert_snapshot!(assert_compiles_allowing_exits("test"), @"5");
28322832
}
28332833

28342834
#[test]
@@ -2857,7 +2857,7 @@ fn test_opt_str_uminus_rewritten() {
28572857
test
28582858
");
28592859
assert_contains_opcode("test", YARVINSN_opt_str_uminus);
2860-
assert_snapshot!(assert_compiles("test"), @"5");
2860+
assert_snapshot!(assert_compiles_allowing_exits("test"), @"5");
28612861
}
28622862

28632863
#[test]
@@ -2928,7 +2928,7 @@ fn test_array_fixnum_aref_out_of_bounds_positive() {
29282928
test(10)
29292929
");
29302930
assert_contains_opcode("test", YARVINSN_opt_aref);
2931-
assert_snapshot!(assert_compiles("test(10)"), @"nil");
2931+
assert_snapshot!(assert_compiles_allowing_exits("test(10)"), @"nil");
29322932
}
29332933

29342934
#[test]
@@ -2938,7 +2938,7 @@ fn test_array_fixnum_aref_out_of_bounds_negative() {
29382938
test(-10)
29392939
");
29402940
assert_contains_opcode("test", YARVINSN_opt_aref);
2941-
assert_snapshot!(assert_compiles("test(-10)"), @"nil");
2941+
assert_snapshot!(assert_compiles_allowing_exits("test(-10)"), @"nil");
29422942
}
29432943

29442944
#[test]
@@ -3666,7 +3666,7 @@ fn test_getivar_t_data_then_string() {
36663666
end
36673667
OBJ.test; OBJ.test # profile and compile for Thread (T_DATA)
36683668
"#);
3669-
assert_snapshot!(assert_compiles("[STR.test, STR.test]"), @"[1000, 1000]");
3669+
assert_snapshot!(assert_compiles_allowing_exits("[STR.test, STR.test]"), @"[1000, 1000]");
36703670
}
36713671

36723672
#[test]
@@ -3694,7 +3694,7 @@ fn test_getivar_t_object_then_string() {
36943694
end
36953695
OBJ.test; OBJ.test # profile and compile for MyObject
36963696
"#);
3697-
assert_snapshot!(assert_compiles("[STR.test, STR.test]"), @"[1000, 1000]");
3697+
assert_snapshot!(assert_compiles_allowing_exits("[STR.test, STR.test]"), @"[1000, 1000]");
36983698
}
36993699

37003700
#[test]
@@ -3725,7 +3725,7 @@ fn test_getivar_t_class_then_string() {
37253725
p MyClass.test; p MyClass.test # profile and compile for MyClass
37263726
p STR.test
37273727
"#);
3728-
assert_snapshot!(assert_compiles("[STR.test, STR.test]"), @"[1000, 1000]");
3728+
assert_snapshot!(assert_compiles_allowing_exits("[STR.test, STR.test]"), @"[1000, 1000]");
37293729
}
37303730

37313731

@@ -3806,7 +3806,7 @@ fn test_expandarray_splat() {
38063806
test [3, 4]
38073807
");
38083808
assert_contains_opcode("test", YARVINSN_expandarray);
3809-
assert_snapshot!(assert_compiles("test [3, 4]"), @"[3, [4]]");
3809+
assert_snapshot!(assert_compiles_allowing_exits("test [3, 4]"), @"[3, [4]]");
38103810
}
38113811

38123812
#[test]
@@ -3819,7 +3819,7 @@ fn test_expandarray_splat_post() {
38193819
test [3, 4, 5]
38203820
");
38213821
assert_contains_opcode("test", YARVINSN_expandarray);
3822-
assert_snapshot!(assert_compiles("test [3, 4, 5]"), @"[3, [4], 5]");
3822+
assert_snapshot!(assert_compiles_allowing_exits("test [3, 4, 5]"), @"[3, [4], 5]");
38233823
}
38243824

38253825
#[test]
@@ -3876,7 +3876,7 @@ fn test_dupn() {
38763876
test([1, 1])
38773877
");
38783878
assert_contains_opcode("test", YARVINSN_dupn);
3879-
assert_snapshot!(assert_compiles("
3879+
assert_snapshot!(assert_compiles_allowing_exits("
38803880
one = [1, 1]
38813881
start_empty = []
38823882
[test(one), one, test(start_empty), start_empty]
@@ -4438,7 +4438,7 @@ fn test_nil_value_nil_opt_with_guard_side_exit() {
44384438
test(nil)
44394439
");
44404440
assert_contains_opcode("test", YARVINSN_opt_nil_p);
4441-
assert_snapshot!(assert_compiles("test(1)"), @"false");
4441+
assert_snapshot!(assert_compiles_allowing_exits("test(1)"), @"false");
44424442
}
44434443

44444444
#[test]
@@ -4459,7 +4459,7 @@ fn test_true_nil_opt_with_guard_side_exit() {
44594459
test(true)
44604460
");
44614461
assert_contains_opcode("test", YARVINSN_opt_nil_p);
4462-
assert_snapshot!(assert_compiles("test(nil)"), @"true");
4462+
assert_snapshot!(assert_compiles_allowing_exits("test(nil)"), @"true");
44634463
}
44644464

44654465
#[test]
@@ -4480,7 +4480,7 @@ fn test_false_nil_opt_with_guard_side_exit() {
44804480
test(false)
44814481
");
44824482
assert_contains_opcode("test", YARVINSN_opt_nil_p);
4483-
assert_snapshot!(assert_compiles("test(nil)"), @"true");
4483+
assert_snapshot!(assert_compiles_allowing_exits("test(nil)"), @"true");
44844484
}
44854485

44864486
#[test]
@@ -4501,7 +4501,7 @@ fn test_integer_nil_opt_with_guard_side_exit() {
45014501
test(2)
45024502
");
45034503
assert_contains_opcode("test", YARVINSN_opt_nil_p);
4504-
assert_snapshot!(assert_compiles("test(nil)"), @"true");
4504+
assert_snapshot!(assert_compiles_allowing_exits("test(nil)"), @"true");
45054505
}
45064506

45074507
#[test]
@@ -4522,7 +4522,7 @@ fn test_float_nil_opt_with_guard_side_exit() {
45224522
test(2.0)
45234523
");
45244524
assert_contains_opcode("test", YARVINSN_opt_nil_p);
4525-
assert_snapshot!(assert_compiles("test(nil)"), @"true");
4525+
assert_snapshot!(assert_compiles_allowing_exits("test(nil)"), @"true");
45264526
}
45274527

45284528
#[test]
@@ -4543,7 +4543,7 @@ fn test_symbol_nil_opt_with_guard_side_exit() {
45434543
test(:bar)
45444544
");
45454545
assert_contains_opcode("test", YARVINSN_opt_nil_p);
4546-
assert_snapshot!(assert_compiles("test(nil)"), @"true");
4546+
assert_snapshot!(assert_compiles_allowing_exits("test(nil)"), @"true");
45474547
}
45484548

45494549
#[test]
@@ -4553,7 +4553,7 @@ fn test_class_nil_opt_with_guard() {
45534553
test(String)
45544554
");
45554555
assert_contains_opcode("test", YARVINSN_opt_nil_p);
4556-
assert_snapshot!(assert_compiles("test(Integer)"), @"false");
4556+
assert_snapshot!(assert_compiles_allowing_exits("test(Integer)"), @"false");
45574557
}
45584558

45594559
#[test]
@@ -4564,7 +4564,7 @@ fn test_class_nil_opt_with_guard_side_exit() {
45644564
test(Integer)
45654565
");
45664566
assert_contains_opcode("test", YARVINSN_opt_nil_p);
4567-
assert_snapshot!(assert_compiles("test(nil)"), @"true");
4567+
assert_snapshot!(assert_compiles_allowing_exits("test(nil)"), @"true");
45684568
}
45694569

45704570
#[test]
@@ -4574,7 +4574,7 @@ fn test_module_nil_opt_with_guard() {
45744574
test(Enumerable)
45754575
");
45764576
assert_contains_opcode("test", YARVINSN_opt_nil_p);
4577-
assert_snapshot!(assert_compiles("test(Kernel)"), @"false");
4577+
assert_snapshot!(assert_compiles_allowing_exits("test(Kernel)"), @"false");
45784578
}
45794579

45804580
#[test]
@@ -4585,7 +4585,7 @@ fn test_module_nil_opt_with_guard_side_exit() {
45854585
test(Kernel)
45864586
");
45874587
assert_contains_opcode("test", YARVINSN_opt_nil_p);
4588-
assert_snapshot!(assert_compiles("test(nil)"), @"true");
4588+
assert_snapshot!(assert_compiles_allowing_exits("test(nil)"), @"true");
45894589
}
45904590

45914591
#[test]
@@ -4923,7 +4923,7 @@ fn test_allocating_in_hir_c_method_is() {
49234923
second
49244924
");
49254925
assert_contains_opcode("test", YARVINSN_opt_new);
4926-
assert_snapshot!(assert_compiles("a(Foo)"), @":k");
4926+
assert_snapshot!(assert_compiles_allowing_exits("a(Foo)"), @":k");
49274927
}
49284928

49294929
#[test]
@@ -5050,7 +5050,7 @@ fn test_fixnum_div_zero() {
50505050
test(0)
50515051
");
50525052
assert_contains_opcode("test", YARVINSN_opt_div);
5053-
assert_snapshot!(assert_compiles(r#"test(0)"#), @r#""divided by 0""#);
5053+
assert_snapshot!(assert_compiles_allowing_exits(r#"test(0)"#), @r#""divided by 0""#);
50545054
}
50555055

50565056
#[test]

zjit/src/cruby.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1280,11 +1280,23 @@ pub mod test_utils {
12801280
}
12811281

12821282
/// Like inspect, but also asserts that all compilations triggered by this program succeed.
1283+
pub fn assert_compiles_allowing_exits(program: &str) -> String {
1284+
use crate::state::ZJITState;
1285+
ZJITState::enable_assert_compiles();
1286+
let result = inspect(program);
1287+
ZJITState::disable_assert_compiles();
1288+
result
1289+
}
1290+
1291+
/// Like inspect, but also asserts that all compilations triggered by this program succeed and
1292+
/// no side exits occurr during the program.
12831293
pub fn assert_compiles(program: &str) -> String {
12841294
use crate::state::ZJITState;
1295+
let exits_before = crate::stats::total_exit_count();
12851296
ZJITState::enable_assert_compiles();
12861297
let result = inspect(program);
12871298
ZJITState::disable_assert_compiles();
1299+
assert_eq!(exits_before, crate::stats::total_exit_count(), "Program side-exited");
12881300
result
12891301
}
12901302

zjit/src/hir/opt_tests.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7510,6 +7510,15 @@ mod hir_opt_tests {
75107510
");
75117511
}
75127512

7513+
#[test]
7514+
fn test_no_side_exit_assertion() {
7515+
eval("
7516+
def side_exit = ::RubyVM::ZJIT.induce_side_exit!
7517+
side_exit
7518+
");
7519+
std::panic::catch_unwind(|| assert_compiles("side_exit")).expect_err("Should panic because the program should side exit");
7520+
}
7521+
75137522
#[test]
75147523
fn test_optimize_getivar_on_class_embedded() {
75157524
eval("
@@ -7519,6 +7528,7 @@ mod hir_opt_tests {
75197528
end
75207529
C.test
75217530
");
7531+
assert_snapshot!(assert_compiles("C.test"), @"42");
75227532
assert_snapshot!(hir_string_proc("C.method(:test)"), @"
75237533
fn test@<compiled>:4:
75247534
bb1():

0 commit comments

Comments
 (0)