summaryrefslogtreecommitdiff
path: root/tests/src/baseservices/compilerservices/FixedAddressValueType/FixedAddressValueType.cs
blob: bf10d817e59c56091aa3593f47f568b5562712e2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
//
using System;
using System.Runtime.CompilerServices;

public struct Age {
   public int years;
   public int months;
}

public class FreeClass
{
   public static Age FreeAge;

   public static unsafe IntPtr AddressOfFreeAge()
   { 
      fixed (Age* pointer = &FreeAge) 
      { return (IntPtr) pointer; } 
   }
}

public class FixedClass
{
   [FixedAddressValueType]
   public static Age FixedAge;

   public static unsafe IntPtr AddressOfFixedAge()
   { 
      fixed (Age* pointer = &FixedAge) 
      { return (IntPtr) pointer; } 
   }   
}

public class Example
{
   public static int Main()
   {
      // Get addresses of static Age fields.
      IntPtr freePtr1 = FreeClass.AddressOfFreeAge();

      IntPtr fixedPtr1 = FixedClass.AddressOfFixedAge();

      // Garbage collection.
      GC.Collect(3, GCCollectionMode.Forced, true, true);
      GC.WaitForPendingFinalizers();
      
      // Get addresses of static Age fields after garbage collection.
      IntPtr freePtr2 = FreeClass.AddressOfFreeAge();
      IntPtr fixedPtr2 = FixedClass.AddressOfFixedAge();

      if(freePtr1 != freePtr2 && fixedPtr1 == fixedPtr2)
      {
          return 100;
      }

      return -1;
   }
}