2 using System.Reflection;
3 using System.Runtime.CompilerServices;
4 using System.Collections;
5 using System.Threading;
8 * Regression tests for the GC support in the JIT
14 return TestDriver.RunTests (typeof (Tests));
17 public static int test_36_simple () {
18 // Overflow the registers
28 /* Prevent the variables from being local to a bb */
33 return (int)o1 + (int)o2 + (int)o3 + (int)o4 + (int)o5 + (int)o6 + (int)o7 + (int)o8;
38 public static int test_36_liveness () {
40 object o1, o2, o3, o4, o5, o6, o7, o8;
56 return (int)o1 + (int)o2 + (int)o3 + (int)o4 + (int)o5 + (int)o6 + (int)o7 + (int)o8;
66 public FooStruct (int i1, int i, int i2) {
73 public static int test_4_vtype () {
74 FooStruct s = new FooStruct (1, 2, 3);
78 return (int)s.o1 + (int)s.o2;
82 public object o1, o2, o3, o4, o5, o6, o7, o8, o9, o10;
83 public object o11, o12, o13, o14, o15, o16, o17, o18, o19, o20;
84 public object o21, o22, o23, o24, o25, o26, o27, o28, o29, o30;
85 public object o31, o32;
88 static void set_fields (BigClass b) {
124 // Test marking of objects with > 32 fields
125 public static int test_528_mark_runlength_large () {
126 BigClass b = new BigClass ();
129 * Do the initialization in a separate method so no object refs remain in
137 (int)b.o1 + (int)b.o2 + (int)b.o3 + (int)b.o4 + (int)b.o5 +
138 (int)b.o6 + (int)b.o7 + (int)b.o8 + (int)b.o9 + (int)b.o10 +
139 (int)b.o11 + (int)b.o12 + (int)b.o13 + (int)b.o14 + (int)b.o15 +
140 (int)b.o16 + (int)b.o17 + (int)b.o18 + (int)b.o19 + (int)b.o20 +
141 (int)b.o21 + (int)b.o22 + (int)b.o23 + (int)b.o24 + (int)b.o25 +
142 (int)b.o26 + (int)b.o27 + (int)b.o28 + (int)b.o29 + (int)b.o30 +
143 (int)b.o31 + (int)b.o32;
147 * Test liveness and loops.
149 public static int test_0_liveness_2 () {
150 object o = new object ();
151 for (int n = 0; n < 10; ++n) {
152 /* Exhaust all registers so 'o' is stack allocated */
153 int sum = 0, i, j, k, l, m;
154 for (i = 0; i < 100; ++i)
156 for (j = 0; j < 100; ++j)
158 for (k = 0; k < 100; ++k)
160 for (l = 0; l < 100; ++l)
162 for (m = 0; m < 100; ++m)
182 * Test liveness and stack slot sharing
183 * This doesn't work yet, its hard to make the JIT share the stack slots of the
186 public static int test_0_liveness_3 () {
190 /* Exhaust all registers so 'o' is stack allocated */
191 int sum = 0, i, j, k, l, m, n, s;
192 for (i = 0; i < 100; ++i)
194 for (j = 0; j < 100; ++j)
196 for (k = 0; k < 100; ++k)
198 for (l = 0; l < 100; ++l)
200 for (m = 0; m < 100; ++m)
202 for (n = 0; n < 100; ++n)
204 for (s = 0; s < 100; ++s)
208 object o = new object ();
210 /* Make sure o is global */
212 Console.WriteLine ();
220 object o = new object ();
222 /* Make sure o is global */
224 Console.WriteLine ();
229 sum += i + j + k + l + m + n + s;
235 * Test liveness of variables used to handle items on the IL stack.
237 [MethodImplAttribute (MethodImplOptions.NoInlining)]
238 static string call1 () {
242 [MethodImplAttribute (MethodImplOptions.NoInlining)]
243 static string call2 () {
248 public static int test_0_liveness_4 () {
252 /* Exhaust all registers so 'o' is stack allocated */
253 int sum = 0, i, j, k, l, m, n, s;
254 for (i = 0; i < 100; ++i)
256 for (j = 0; j < 100; ++j)
258 for (k = 0; k < 100; ++k)
260 for (l = 0; l < 100; ++l)
262 for (m = 0; m < 100; ++m)
264 for (n = 0; n < 100; ++n)
266 for (s = 0; s < 100; ++s)
269 string o = b ? call1 () : call2 ();
273 sum += i + j + k + l + m + n + s;
280 * Test liveness of volatile variables
282 [MethodImplAttribute (MethodImplOptions.NoInlining)]
283 static void liveness_5_1 (out object o) {
287 public static int test_0_liveness_5 () {
291 /* Exhaust all registers so 'o' is stack allocated */
292 int sum = 0, i, j, k, l, m, n, s;
293 for (i = 0; i < 100; ++i)
295 for (j = 0; j < 100; ++j)
297 for (k = 0; k < 100; ++k)
299 for (l = 0; l < 100; ++l)
301 for (m = 0; m < 100; ++m)
303 for (n = 0; n < 100; ++n)
305 for (s = 0; s < 100; ++s)
310 liveness_5_1 (out o);
312 for (int x = 0; x < 10; ++x) {
319 sum += i + j + k + l + m + n + s;
325 * Test the case when a stack slot becomes dead, then live again due to a backward
329 [MethodImplAttribute (MethodImplOptions.NoInlining)]
330 static object alloc_obj () {
331 return new object ();
334 [MethodImplAttribute (MethodImplOptions.NoInlining)]
335 static bool return_true () {
339 [MethodImplAttribute (MethodImplOptions.NoInlining)]
340 static bool return_false () {
344 public static int test_0_liveness_6 () {
348 /* Exhaust all registers so 'o' is stack allocated */
349 int sum = 0, i, j, k, l, m, n, s;
350 for (i = 0; i < 100; ++i)
352 for (j = 0; j < 100; ++j)
354 for (k = 0; k < 100; ++k)
356 for (l = 0; l < 100; ++l)
358 for (m = 0; m < 100; ++m)
360 for (n = 0; n < 100; ++n)
362 for (s = 0; s < 100; ++s)
365 for (int x = 0; x < 10; ++x) {
369 object o = alloc_obj ();
376 sum += i + j + k + l + m + n + s;
381 public static int test_0_multi_dim_ref_array_wbarrier () {
382 string [,] arr = new string [256, 256];
383 for (int i = 0; i < 256; ++i) {
384 for (int j = 0; j < 100; ++j)
385 arr [i, j] = "" + i + " " + j;
393 * Liveness + out of line bblocks
395 public static int test_0_liveness_7 () {
396 /* Exhaust all registers so 'o' is stack allocated */
397 int sum = 0, i, j, k, l, m, n, s;
398 for (i = 0; i < 100; ++i)
400 for (j = 0; j < 100; ++j)
402 for (k = 0; k < 100; ++k)
404 for (l = 0; l < 100; ++l)
406 for (m = 0; m < 100; ++m)
408 for (n = 0; n < 100; ++n)
410 for (s = 0; s < 100; ++s)
416 if (return_false ()) {
417 // This bblock is in-line
418 object o = alloc_obj ();
420 if (return_false ()) {
421 // This bblock is out-of-line, and o is live here
422 throw new Exception (o.ToString ());
426 // o is dead here too
432 // Liveness + finally clauses
433 public static int test_0_liveness_8 () {
434 /* Exhaust all registers so 'o' is stack allocated */
435 int sum = 0, i, j, k, l, m, n, s;
436 for (i = 0; i < 100; ++i)
438 for (j = 0; j < 100; ++j)
440 for (k = 0; k < 100; ++k)
442 for (l = 0; l < 100; ++l)
444 for (m = 0; m < 100; ++m)
446 for (n = 0; n < 100; ++n)
448 for (s = 0; s < 100; ++s)
462 [MethodImplAttribute (MethodImplOptions.NoInlining)]
463 static object alloc_string () {
467 [MethodImplAttribute (MethodImplOptions.NoInlining)]
468 static object alloc_obj_and_gc () {
470 return new object ();
473 [MethodImplAttribute (MethodImplOptions.NoInlining)]
474 static void clobber_regs_and_gc () {
475 int sum = 0, i, j, k, l, m, n, s;
476 for (i = 0; i < 100; ++i)
478 for (j = 0; j < 100; ++j)
480 for (k = 0; k < 100; ++k)
482 for (l = 0; l < 100; ++l)
484 for (m = 0; m < 100; ++m)
486 for (n = 0; n < 100; ++n)
488 for (s = 0; s < 100; ++s)
493 [MethodImplAttribute (MethodImplOptions.NoInlining)]
494 static void liveness_9_call1 (object o1, object o2, object o3) {
500 // Liveness + JIT temporaries
501 public static int test_0_liveness_9 () {
502 // the result of alloc_obj () goes into a vreg, which gets converted to a
503 // JIT temporary because of the branching introduced by the cast
504 // FIXME: This doesn't crash if MONO_TYPE_I is not treated as a GC ref
505 liveness_9_call1 (alloc_obj (), (string)alloc_string (), alloc_obj_and_gc ());
509 // Liveness for registers
510 public static int test_0_liveness_10 () {
511 // Make sure this goes into a register
512 object o = alloc_obj ();
519 // Break the bblock so o doesn't become a local vreg
521 // Clobber it with a call and run a GC
522 clobber_regs_and_gc ();
528 // Liveness for spill slots holding managed pointers
529 public static int test_0_liveness_11 () {
530 Tests[] arr = new Tests [10];
531 // This uses an ldelema internally
532 // FIXME: This doesn't crash if mp-s are not correctly tracked, just writes to
539 public static Tests operator >> (Tests bi1, int shiftVal) {
540 clobber_regs_and_gc ();
544 [MethodImplAttribute (MethodImplOptions.NoInlining)]
545 public static void liveness_12_inner (int a, int b, int c, int d, int e, int f, object o) {
550 // Liveness for param area
551 public static int test_0_liveness_12 () {
552 // The ref argument should be passed on the stack
553 liveness_12_inner (1, 2, 3, 4, 5, 6, new object ());
557 public static void liveness_13_inner (ref ArrayList arr) {
558 // The value of arr will be stored in a spill slot
559 arr.Add (alloc_obj_and_gc ());
562 // Liveness for byref arguments in spill slots
563 public static int test_0_liveness_13 () {
564 var arr = new ArrayList ();
565 liveness_13_inner (ref arr);
569 static ThreadLocal<object> tls;
571 [MethodImplAttribute (MethodImplOptions.NoInlining)]
572 static void alloc_tls_obj () {
573 tls = new ThreadLocal<object> ();
574 tls.Value = new object ();
577 public static int test_0_thread_local () {
580 Type t = tls.Value.GetType ();
581 if (t == typeof (object))