[sgen] Evacuate from emptier blocks to fuller ones
[mono.git] / mono / tests / sgen-toggleref.cs
1 using System;
2 using System.Collections;
3 using System.Collections.Generic;
4 using System.Threading;
5 using System.Runtime.InteropServices;
6
7 public class Toggleref {
8         public int __test;
9         public string id;
10         public List<object> link = new List<object> ();
11         public const int DROP = 0;
12         public const int STRONG = 1;
13         public const int WEAK = 2;
14         
15         ~Toggleref () {
16
17         }
18 }
19
20 [StructLayout (LayoutKind.Explicit)]
21 public struct Helper {
22         [FieldOffset(0)]
23         IntPtr ptr;
24         [FieldOffset(0)]
25         object obj;
26         public static IntPtr ObjToPtr (object obj)
27         {
28                 Helper h = default (Helper);
29                 h.obj = obj;
30                 return h.ptr;
31         }
32 }
33
34 class Driver {
35         static WeakReference<Toggleref> root, child;
36
37         [DllImport ("__Internal", EntryPoint="mono_gc_toggleref_add")]
38         static extern int mono_gc_toggleref_add (IntPtr ptr, bool strong_ref);
39
40         static void Register (object obj)
41         {
42                 mono_gc_toggleref_add (Helper.ObjToPtr (obj), true);
43         }
44
45         static void SetupLinks () {
46                 var a = new Toggleref () { id = "root" };
47                 var b = new Toggleref () { id = "child" };
48                 a.link.Add (b);
49                 a.__test = Toggleref.STRONG;
50                 b.__test = Toggleref.WEAK;
51                 Register (a);
52                 Register (b);
53                 root = new WeakReference<Toggleref> (a, false);
54                 child = new WeakReference<Toggleref> (b, false);
55         }
56
57         static Toggleref a, b;
58
59         static int Main ()
60         {
61                 
62                 var t = new Thread (SetupLinks);
63                 t.Start ();
64                 t.Join ();
65                 
66                 GC.Collect ();
67                 GC.WaitForPendingFinalizers ();
68
69                 Console.WriteLine ("try get A {0}", root.TryGetTarget (out a));
70                 Console.WriteLine ("try get B {0}", child.TryGetTarget (out b));
71                 Console.WriteLine ("a is null {0}", a == null);
72                 Console.WriteLine ("b is null {0}", b == null);
73                 if (a == null || b == null)
74                         return 1;
75                 Console.WriteLine ("a test {0}", a.__test);
76                 Console.WriteLine ("b test {0}", b.__test);
77
78                 //now we break the link and switch b to strong
79                 a.link.Clear ();
80                 b.__test = Toggleref.STRONG;
81                 a = b = null;
82
83                 GC.Collect ();
84                 GC.WaitForPendingFinalizers ();
85
86                 Console.WriteLine ("try get A {0}", root.TryGetTarget (out a));
87                 Console.WriteLine ("try get B {0}", child.TryGetTarget (out b));
88                 Console.WriteLine ("a is null {0}", a == null);
89                 Console.WriteLine ("b is null {0}", b == null);
90                 if (a == null || b == null)
91                         return 2;
92                 Console.WriteLine ("a test {0}", a.__test);
93                 Console.WriteLine ("b test {0}", b.__test);
94
95
96                 return 0;
97
98         }
99 }