Skip to content

Commit 5c57f2c

Browse files
authored
Make ReRegisterForFinalize GC test more robust (#67896)
There is no guarantee that the JIT does not introduce a temporary for the read of the fields `obj1` and `obj2` when they are passed to the function calls, which might keep them alive even when nulling out the fields. This happens when CFG is enabled, causing the test to fail. Change the test to access the fields in separate methods marked as noinline to fix the problem.
1 parent 7eb5d7b commit 5c57f2c

File tree

1 file changed

+19
-10
lines changed

1 file changed

+19
-10
lines changed

src/tests/GC/API/GC/ReRegisterForFinalize.cs

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,15 @@
44
// Tests ReRegisterForFinalize()
55

66
using System;
7+
using System.Runtime.CompilerServices;
78

89
public class Test_ReRegisterForFinalize {
910

1011
public class Dummy {
11-
12+
1213
public static int flag;
1314
~Dummy() {
14-
Console.WriteLine("In Finalize() of Dummy");
15+
Console.WriteLine("In Finalize() of Dummy");
1516
if(flag == 0) flag=1; // one object has visited;
1617
else flag=0; //error-- both objects have visited
1718
}
@@ -21,24 +22,32 @@ public class CreateObj{
2122
Dummy obj1;
2223
Dummy obj2;
2324

25+
[MethodImpl(MethodImplOptions.NoInlining)]
2426
public CreateObj() {
2527
obj1 = new Dummy();
2628
obj2 = new Dummy();
2729

28-
30+
2931
GC.SuppressFinalize(obj1); // should not call the Finalize() for obj1
3032
GC.SuppressFinalize(obj2); // should not call the Finalize() for obj2
3133
}
3234

33-
public bool RunTest() {
34-
35+
// Make sure we have no references left to obj1 by doing this in a
36+
// non-inlined separate function.
37+
[MethodImpl(MethodImplOptions.NoInlining)]
38+
private void ReRegisterAndNullFields()
39+
{
3540
GC.ReRegisterForFinalize(obj1); // should call Finalize() for obj1 now.
36-
41+
3742
obj1=null;
3843
obj2=null;
44+
}
45+
46+
public bool RunTest() {
47+
ReRegisterAndNullFields();
3948

4049
GC.Collect();
41-
50+
4251
GC.WaitForPendingFinalizers(); // call all Finalizers.
4352

4453
if(Dummy.flag==1) {
@@ -48,19 +57,19 @@ public bool RunTest() {
4857
return false;
4958
}
5059
}
51-
60+
5261
}
5362
public static int Main() {
5463
CreateObj temp = new CreateObj();
5564
bool passed = temp.RunTest();
56-
65+
5766
if(passed) {
5867
Console.WriteLine("Test for ReRegisterForFinalize() passed!");
5968
return 100;
6069
}
6170
else {
6271
Console.WriteLine("Test for ReRegisterForFinalize() failed!");
63-
return 1;
72+
return 1;
6473
}
6574
}
6675
}

0 commit comments

Comments
 (0)