2009-08-25 Rodrigo Kumpera <rkumpera@novell.com>
[mono.git] / mono / metadata / sgen-scan-object.h
1 /*
2  * Scans one object, using the OBJ_XXX macros.  The start of the
3  * object must be given in the variable "char* start".  Afterwards,
4  * "start" will point to the start of the next object.
5  *
6  * Modifiers (automatically undefined):
7  *
8  * SCAN_OBJECT_NOSCAN - if defined, don't actually scan the object,
9  * i.e. don't invoke the OBJ_XXX macros.
10  *
11  * SCAN_OBJECT_ACTION - is invoked after an object has been scanned.
12  * The object's start is "start", its length in bytes (including
13  * padding at the end) is "skip_size".  "desc" is the object's GC
14  * descriptor.
15  */
16
17 #ifndef SCAN_OBJECT_ACTION
18 #define SCAN_OBJECT_ACTION
19 #endif
20
21 {
22         GCVTable *vt;
23         size_t skip_size;
24         mword desc;
25
26         vt = (GCVTable*)LOAD_VTABLE (start);
27         //type = vt->desc & 0x7;
28
29         /* gcc should be smart enough to remove the bounds check, but it isn't:( */
30         desc = vt->desc;
31         switch (desc & 0x7) {
32         case DESC_TYPE_STRING:
33                 STRING_SIZE (skip_size, start);
34                 SCAN_OBJECT_ACTION;
35                 start += skip_size;
36                 break;
37         case DESC_TYPE_RUN_LENGTH:
38                 OBJ_RUN_LEN_SIZE (skip_size, desc, start);
39                 g_assert (skip_size);
40 #ifndef SCAN_OBJECT_NOSCAN
41                 OBJ_RUN_LEN_FOREACH_PTR (desc, start);
42 #endif
43                 SCAN_OBJECT_ACTION;
44                 start += skip_size;
45                 break;
46         case DESC_TYPE_ARRAY:
47         case DESC_TYPE_VECTOR:
48                 skip_size = safe_object_get_size ((MonoObject*)start);
49                 skip_size += (ALLOC_ALIGN - 1);
50                 skip_size &= ~(ALLOC_ALIGN - 1);
51 #ifndef SCAN_OBJECT_NOSCAN
52                 OBJ_VECTOR_FOREACH_PTR (vt, start);
53 #endif
54                 SCAN_OBJECT_ACTION;
55                 start += skip_size;
56                 break;
57         case DESC_TYPE_SMALL_BITMAP:
58                 OBJ_BITMAP_SIZE (skip_size, desc, start);
59                 g_assert (skip_size);
60 #ifndef SCAN_OBJECT_NOSCAN
61                 OBJ_BITMAP_FOREACH_PTR (desc, start);
62 #endif
63                 SCAN_OBJECT_ACTION;
64                 start += skip_size;
65                 break;
66         case DESC_TYPE_LARGE_BITMAP:
67                 skip_size = safe_object_get_size ((MonoObject*)start);
68                 skip_size += (ALLOC_ALIGN - 1);
69                 skip_size &= ~(ALLOC_ALIGN - 1);
70 #ifndef SCAN_OBJECT_NOSCAN
71                 OBJ_LARGE_BITMAP_FOREACH_PTR (vt,start);
72 #endif
73                 SCAN_OBJECT_ACTION;
74                 start += skip_size;
75                 break;
76         case DESC_TYPE_COMPLEX:
77                 /* this is a complex object */
78                 skip_size = safe_object_get_size ((MonoObject*)start);
79                 skip_size += (ALLOC_ALIGN - 1);
80                 skip_size &= ~(ALLOC_ALIGN - 1);
81 #ifndef SCAN_OBJECT_NOSCAN
82                 OBJ_COMPLEX_FOREACH_PTR (vt, start);
83 #endif
84                 SCAN_OBJECT_ACTION;
85                 start += skip_size;
86                 break;
87         case DESC_TYPE_COMPLEX_ARR:
88                 /* this is an array of complex structs */
89                 skip_size = safe_object_get_size ((MonoObject*)start);
90                 skip_size += (ALLOC_ALIGN - 1);
91                 skip_size &= ~(ALLOC_ALIGN - 1);
92 #ifndef SCAN_OBJECT_NOSCAN
93                 OBJ_COMPLEX_ARR_FOREACH_PTR (vt, start);
94 #endif
95                 SCAN_OBJECT_ACTION;
96                 start += skip_size;
97                 break;
98         default:
99                 g_assert_not_reached ();
100         }
101 }
102
103 #undef SCAN_OBJECT_NOSCAN
104 #undef SCAN_OBJECT_ACTION