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, ref string s) {
555 // Liveness for param area
556 public static int test_0_liveness_12 () {
557 var f = new FooClass () { s = "A" };
558 // The ref argument should be passed on the stack
559 liveness_12_inner (1, 2, 3, 4, 5, 6, new object (), ref f.s);
567 struct BarStruct : IFace {
576 public static int test_0_liveness_unbox_trampoline () {
577 var s = new BarStruct ();
584 public static void liveness_13_inner (ref ArrayList arr) {
585 // The value of arr will be stored in a spill slot
586 arr.Add (alloc_obj_and_gc ());
589 // Liveness for byref arguments in spill slots
590 public static int test_0_liveness_13 () {
591 var arr = new ArrayList ();
592 liveness_13_inner (ref arr);
596 static ThreadLocal<object> tls;
598 [MethodImplAttribute (MethodImplOptions.NoInlining)]
599 static void alloc_tls_obj () {
600 tls = new ThreadLocal<object> ();
601 tls.Value = new object ();
604 public static int test_0_thread_local () {
607 Type t = tls.Value.GetType ();
608 if (t == typeof (object))
615 public object o1, o2, o3;
617 public object o4, o5, o6, o7, o9, o10, o11, o12, o13, o14, o15, o16, o17, o18, o19, o20, o21, o22, o23, o24, o25, o26, o27, o28, o29, o30, o31, o32;
620 public static int test_12_large_bitmap () {
621 LargeBitmap lb = new LargeBitmap ();
629 return (int)lb.o1 + (int)lb.o2 + (int)lb.o3 + (int)lb.o32;