PageRenderTime 50ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 0ms

/src/Compilers/Core/CodeAnalysisTest/InternalUtilities/WeakListTests.cs

https://gitlab.com/sharadag/Roslyn
C# | 340 lines | 273 code | 65 blank | 2 comment | 27 complexity | ef6bce71b513923fabbf742490e4abc0 MD5 | raw file
  1. // Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
  2. using System;
  3. using System.Collections.Generic;
  4. using System.Linq;
  5. using System.Runtime.CompilerServices;
  6. using System.Text;
  7. using System.Threading.Tasks;
  8. using Microsoft.CodeAnalysis.Text;
  9. using Roslyn.Test.Utilities;
  10. using Roslyn.Utilities;
  11. using Xunit;
  12. namespace Microsoft.CodeAnalysis.UnitTests.InternalUtilities
  13. {
  14. public class WeakListTests : TestBase
  15. {
  16. private class C
  17. {
  18. private readonly string _value;
  19. public C(string value)
  20. {
  21. _value = value;
  22. }
  23. public override string ToString()
  24. {
  25. return _value;
  26. }
  27. }
  28. [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
  29. private ObjectReference Create(string value)
  30. {
  31. return new ObjectReference(new C(value));
  32. }
  33. [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
  34. private void Add(WeakList<object> list, ObjectReference value)
  35. {
  36. list.Add(value.Strong);
  37. }
  38. [Fact]
  39. public void EnumeratorCompacts()
  40. {
  41. var a = Create("a");
  42. var b = Create("B");
  43. var c = Create("C");
  44. var d = Create("D");
  45. var e = Create("E");
  46. var list = new WeakList<object>();
  47. Assert.Equal(0, list.TestOnly_UnderlyingArray.Length);
  48. Add(list, a);
  49. Assert.Equal(4, list.TestOnly_UnderlyingArray.Length);
  50. Add(list, b);
  51. Assert.Equal(4, list.TestOnly_UnderlyingArray.Length);
  52. Add(list, c);
  53. Assert.Equal(4, list.TestOnly_UnderlyingArray.Length);
  54. Add(list, d);
  55. Assert.Equal(4, list.TestOnly_UnderlyingArray.Length);
  56. Add(list, e);
  57. Assert.Equal(2 * 4 + 1, list.TestOnly_UnderlyingArray.Length);
  58. Assert.Equal(5, list.WeakCount);
  59. a.Strong = null;
  60. c.Strong = null;
  61. d.Strong = null;
  62. e.Strong = null;
  63. while (a.Weak.IsAlive || c.Weak.IsAlive || d.Weak.IsAlive || e.Weak.IsAlive)
  64. {
  65. GC.Collect(2, GCCollectionMode.Forced);
  66. }
  67. Assert.Equal(5, list.WeakCount);
  68. Assert.Same(null, list.GetWeakReference(0).GetTarget());
  69. Assert.Same(b.Strong, list.GetWeakReference(1).GetTarget());
  70. Assert.Same(null, list.GetWeakReference(2).GetTarget());
  71. Assert.Same(null, list.GetWeakReference(3).GetTarget());
  72. Assert.Same(null, list.GetWeakReference(4).GetTarget());
  73. var array = list.ToArray();
  74. Assert.Equal(1, array.Length);
  75. Assert.Same(b.Strong, array[0]);
  76. // list was compacted:
  77. Assert.Equal(1, list.WeakCount);
  78. Assert.Same(b.Strong, list.GetWeakReference(0).GetTarget());
  79. Assert.Equal(4, list.TestOnly_UnderlyingArray.Length);
  80. GC.KeepAlive(b.Strong);
  81. }
  82. [Fact]
  83. public void ResizeCompactsAllDead()
  84. {
  85. var a = Create("A");
  86. var list = new WeakList<object>();
  87. for (int i = 0; i < 9; i++)
  88. {
  89. Add(list, a);
  90. }
  91. Assert.Equal(list.WeakCount, list.TestOnly_UnderlyingArray.Length); // full
  92. a.Strong = null;
  93. while (a.Weak.IsAlive)
  94. {
  95. GC.Collect(2, GCCollectionMode.Forced);
  96. }
  97. Add(list, a); // shrinks, #alive < length/4
  98. Assert.Equal(4, list.TestOnly_UnderlyingArray.Length);
  99. Assert.Equal(1, list.WeakCount);
  100. list.ToArray(); // shrinks, #alive == 0
  101. Assert.Equal(0, list.TestOnly_UnderlyingArray.Length);
  102. Assert.Equal(0, list.WeakCount);
  103. }
  104. [Fact]
  105. public void ResizeCompactsFirstFourth()
  106. {
  107. var a = Create("A");
  108. var b = Create("B");
  109. var list = new WeakList<object>();
  110. for (int i = 0; i < 8; i++)
  111. {
  112. Add(list, a);
  113. }
  114. Add(list, b);
  115. Assert.Equal(list.WeakCount, list.TestOnly_UnderlyingArray.Length); // full
  116. a.Strong = null;
  117. while (a.Weak.IsAlive)
  118. {
  119. GC.Collect(2, GCCollectionMode.Forced);
  120. }
  121. Add(list, b); // shrinks, #alive < length/4
  122. Assert.Equal(4, list.TestOnly_UnderlyingArray.Length);
  123. Assert.Equal(2, list.WeakCount);
  124. b.Strong = null;
  125. while (b.Weak.IsAlive)
  126. {
  127. GC.Collect(2, GCCollectionMode.Forced);
  128. }
  129. list.ToArray(); // shrinks, #alive == 0
  130. Assert.Equal(0, list.TestOnly_UnderlyingArray.Length);
  131. Assert.Equal(0, list.WeakCount);
  132. }
  133. [Fact]
  134. public void ResizeCompactsSecondFourth()
  135. {
  136. var a = Create("A");
  137. var b = Create("B");
  138. var list = new WeakList<object>();
  139. for (int i = 0; i < 6; i++)
  140. {
  141. Add(list, a);
  142. }
  143. for (int i = 0; i < 3; i++)
  144. {
  145. Add(list, b);
  146. }
  147. Assert.Equal(list.WeakCount, list.TestOnly_UnderlyingArray.Length); // full
  148. a.Strong = null;
  149. while (a.Weak.IsAlive)
  150. {
  151. GC.Collect(2, GCCollectionMode.Forced);
  152. }
  153. Add(list, b); // just compacts, length/4 < #alive < 3/4 length
  154. Assert.Equal(9, list.TestOnly_UnderlyingArray.Length);
  155. Assert.Equal(4, list.WeakCount);
  156. for (int i = 0; i < list.TestOnly_UnderlyingArray.Length; i++)
  157. {
  158. if (i < 4)
  159. {
  160. Assert.Same(b.Strong, list.TestOnly_UnderlyingArray[i].GetTarget());
  161. }
  162. else
  163. {
  164. Assert.Null(list.TestOnly_UnderlyingArray[i]);
  165. }
  166. }
  167. GC.KeepAlive(b.Strong);
  168. }
  169. [Fact]
  170. public void ResizeCompactsThirdFourth()
  171. {
  172. var a = Create("A");
  173. var b = Create("B");
  174. var list = new WeakList<object>();
  175. for (int i = 0; i < 4; i++)
  176. {
  177. Add(list, a);
  178. }
  179. for (int i = 0; i < 5; i++)
  180. {
  181. Add(list, b);
  182. }
  183. Assert.Equal(list.WeakCount, list.TestOnly_UnderlyingArray.Length); // full
  184. a.Strong = null;
  185. while (a.Weak.IsAlive)
  186. {
  187. GC.Collect(2, GCCollectionMode.Forced);
  188. }
  189. Add(list, b); // compacts #alive < 3/4 length
  190. Assert.Equal(9, list.TestOnly_UnderlyingArray.Length);
  191. Assert.Equal(6, list.WeakCount);
  192. for (int i = 0; i < list.TestOnly_UnderlyingArray.Length; i++)
  193. {
  194. if (i < 6)
  195. {
  196. Assert.Same(b.Strong, list.TestOnly_UnderlyingArray[i].GetTarget());
  197. }
  198. else
  199. {
  200. Assert.Null(list.TestOnly_UnderlyingArray[i]);
  201. }
  202. }
  203. GC.KeepAlive(b.Strong);
  204. }
  205. [Fact]
  206. public void ResizeCompactsLastFourth()
  207. {
  208. var a = Create("A");
  209. var b = Create("B");
  210. var list = new WeakList<object>();
  211. for (int i = 0; i < 2; i++)
  212. {
  213. Add(list, a);
  214. }
  215. for (int i = 0; i < 7; i++)
  216. {
  217. Add(list, b);
  218. }
  219. Assert.Equal(list.WeakCount, list.TestOnly_UnderlyingArray.Length); // full
  220. a.Strong = null;
  221. while (a.Weak.IsAlive)
  222. {
  223. GC.Collect(2, GCCollectionMode.Forced);
  224. }
  225. Add(list, b); // expands #alive > 3/4 length
  226. Assert.Equal(9 * 2 + 1, list.TestOnly_UnderlyingArray.Length);
  227. Assert.Equal(8, list.WeakCount);
  228. for (int i = 0; i < list.TestOnly_UnderlyingArray.Length; i++)
  229. {
  230. if (i < 8)
  231. {
  232. Assert.Same(b.Strong, list.TestOnly_UnderlyingArray[i].GetTarget());
  233. }
  234. else
  235. {
  236. Assert.Null(list.TestOnly_UnderlyingArray[i]);
  237. }
  238. }
  239. GC.KeepAlive(b.Strong);
  240. }
  241. [Fact]
  242. public void ResizeCompactsAllAlive()
  243. {
  244. var b = Create("B");
  245. var list = new WeakList<object>();
  246. for (int i = 0; i < 9; i++)
  247. {
  248. Add(list, b);
  249. }
  250. Assert.Equal(list.WeakCount, list.TestOnly_UnderlyingArray.Length); // full
  251. Add(list, b); // expands #alive > 3/4 length
  252. Assert.Equal(9 * 2 + 1, list.TestOnly_UnderlyingArray.Length);
  253. Assert.Equal(10, list.WeakCount);
  254. for (int i = 0; i < list.TestOnly_UnderlyingArray.Length; i++)
  255. {
  256. if (i < 10)
  257. {
  258. Assert.Same(b.Strong, list.TestOnly_UnderlyingArray[i].GetTarget());
  259. }
  260. else
  261. {
  262. Assert.Null(list.TestOnly_UnderlyingArray[i]);
  263. }
  264. }
  265. GC.KeepAlive(b.Strong);
  266. }
  267. [Fact]
  268. public void Errors()
  269. {
  270. var list = new WeakList<object>();
  271. Assert.Throws<ArgumentOutOfRangeException>(() => list.GetWeakReference(-1));
  272. Assert.Throws<ArgumentOutOfRangeException>(() => list.GetWeakReference(0));
  273. }
  274. }
  275. }