@@ -1361,6 +1361,14 @@ mutable struct DoAllocWithField
1361
1361
end
1362
1362
end
1363
1363
end
1364
+ mutable struct DoAllocWithFieldInter
1365
+ x:: Int
1366
+ end
1367
+ function register_finalizer! (obj:: DoAllocWithFieldInter )
1368
+ finalizer (obj) do this
1369
+ add_finalization_count! (this. x)
1370
+ end
1371
+ end
1364
1372
1365
1373
function const_finalization (io)
1366
1374
for i = 1 : 1000
@@ -1378,86 +1386,98 @@ let
1378
1386
end
1379
1387
1380
1388
# tests finalizer inlining when def/uses involve control flow
1381
- Base. @assume_effects :nothrow safeprint (@nospecialize x... ) = print (x... )
1382
- mutable struct DoAllocWithField
1383
- x
1384
- function DoAllocWithField (x)
1385
- finalizer (new (x)) do this
1386
- nothrow_side_effect (nothing )
1389
+ function cfg_finalization1 (io)
1390
+ for i = - 999 : 1000
1391
+ o = DoAllocWithField (i)
1392
+ if i == 1000
1393
+ safeprint (io, o. x, ' \n ' )
1394
+ elseif i > 0
1395
+ safeprint (io, o. x)
1387
1396
end
1388
1397
end
1389
1398
end
1390
- mutable struct DoAllocWithFieldInter
1391
- x
1399
+ let src = code_typed1 (cfg_finalization1, (IO,))
1400
+ @test count ( isinvoke ( :add_finalization_count! ), src . code) == 1
1392
1401
end
1393
- function register_finalizer! (obj :: DoAllocWithFieldInter )
1394
- finalizer (obj) do this
1395
- nothrow_side_effect ( nothing )
1396
- end
1402
+ let
1403
+ init_finalization_count! ()
1404
+ cfg_finalization1 ( IOBuffer () )
1405
+ @test get_finalization_count () == 1000
1397
1406
end
1398
- let src = code_typed1 () do
1399
- for i = - 1000 : 1000
1400
- o = DoAllocWithField (i)
1401
- if i == 1000
1402
- safeprint (o. x, ' \n ' )
1403
- elseif i > 0
1404
- safeprint (o. x)
1405
- end
1407
+
1408
+ function cfg_finalization2 (io)
1409
+ for i = - 999 : 1000
1410
+ o = DoAllocWithField (0 )
1411
+ o. x = i # with `setfield!`
1412
+ if i == 1000
1413
+ safeprint (io, o. x, ' \n ' )
1414
+ elseif i > 0
1415
+ safeprint (io, o. x)
1406
1416
end
1407
1417
end
1408
- @test count (isinvoke (:nothrow_side_effect ), src. code) == 1
1409
1418
end
1410
- let src = code_typed1 () do
1411
- for i = - 1000 : 1000
1412
- o = DoAllocWithField (0 )
1413
- o. x = i # with `setfield!`
1414
- if i == 1000
1415
- safeprint (o. x, ' \n ' )
1416
- elseif i > 0
1417
- safeprint (o. x)
1418
- end
1419
- end
1420
- end
1421
- @test count (isinvoke (:nothrow_side_effect ), src. code) == 1
1419
+ let src = code_typed1 (cfg_finalization2, (IO,))
1420
+ @test count (isinvoke (:add_finalization_count! ), src. code) == 1
1422
1421
end
1423
- let src = code_typed1 () do
1424
- for i = - 1000 : 1000
1425
- o = DoAllocWithFieldInter (i)
1426
- register_finalizer! (o)
1427
- if i == 1000
1428
- safeprint (o. x, ' \n ' )
1429
- elseif i > 0
1430
- safeprint (o. x)
1431
- end
1422
+ let
1423
+ init_finalization_count! ()
1424
+ cfg_finalization2 (IOBuffer ())
1425
+ @test get_finalization_count () == 1000
1426
+ end
1427
+
1428
+ function cfg_finalization3 (io)
1429
+ for i = - 999 : 1000
1430
+ o = DoAllocWithFieldInter (i)
1431
+ register_finalizer! (o)
1432
+ if i == 1000
1433
+ safeprint (io, o. x, ' \n ' )
1434
+ elseif i > 0
1435
+ safeprint (io, o. x)
1432
1436
end
1433
1437
end
1434
- @test count (isinvoke (:nothrow_side_effect ), src. code) == 1
1435
1438
end
1436
- let src = code_typed1 () do
1437
- for i = - 1000 : 1000
1438
- o = DoAllocWithFieldInter (0 )
1439
- o. x = i # with `setfield!``
1440
- register_finalizer! (o)
1441
- if i == 1000
1442
- safeprint (o. x, ' \n ' )
1443
- elseif i > 0
1444
- safeprint (o. x)
1445
- end
1439
+ let src = code_typed1 (cfg_finalization3, (IO,))
1440
+ @test count (isinvoke (:add_finalization_count! ), src. code) == 1
1441
+ end
1442
+ let
1443
+ init_finalization_count! ()
1444
+ cfg_finalization3 (IOBuffer ())
1445
+ @test get_finalization_count () == 1000
1446
+ end
1447
+
1448
+ function cfg_finalization4 (io)
1449
+ for i = - 999 : 1000
1450
+ o = DoAllocWithFieldInter (0 )
1451
+ o. x = i # with `setfield!`
1452
+ register_finalizer! (o)
1453
+ if i == 1000
1454
+ safeprint (io, o. x, ' \n ' )
1455
+ elseif i > 0
1456
+ safeprint (io, o. x)
1446
1457
end
1447
1458
end
1448
- @test count (isinvoke (:nothrow_side_effect ), src. code) == 1
1449
1459
end
1450
- let src = code_typed1 () do
1451
- for i = - 1000 : 1000
1452
- o = DoAllocWithFieldInter (i)
1453
- if i == 1000
1454
- safeprint (o. x, ' \n ' )
1455
- elseif i > 0
1456
- safeprint (o. x)
1457
- end
1458
- register_finalizer! (o)
1460
+ let src = code_typed1 (cfg_finalization4, (IO,))
1461
+ @test count (isinvoke (:add_finalization_count! ), src. code) == 1
1462
+ end
1463
+ let
1464
+ init_finalization_count! ()
1465
+ cfg_finalization4 (IOBuffer ())
1466
+ @test get_finalization_count () == 1000
1467
+ end
1468
+
1469
+ function cfg_finalization5 (io)
1470
+ for i = - 999 : 1000
1471
+ o = DoAllocWithFieldInter (i)
1472
+ if i == 1000
1473
+ safeprint (io, o. x, ' \n ' )
1474
+ elseif i > 0
1475
+ safeprint (io, o. x)
1459
1476
end
1477
+ register_finalizer! (o)
1460
1478
end
1479
+ end
1480
+ let src = code_typed1 (cfg_finalization5, (IO,))
1461
1481
# TODO we can fix this case by checking a case when a finalizer block is post-dominated by all the def/uses
1462
1482
@test_broken count (isinvoke (:nothrow_side_effect ), src. code) == 1
1463
1483
end
0 commit comments