6c4b62ab30cf73c16dcf1c49221bf9c78780b6de
[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.  The action can use the macro
15  * "SCAN" to scan the object.
16  */
17
18 #ifndef SCAN_OBJECT_ACTION
19 #define SCAN_OBJECT_ACTION
20 #endif
21
22 {
23         GCVTable *vt;
24         size_t skip_size;
25         mword desc;
26
27         vt = (GCVTable*)LOAD_VTABLE (start);
28         //type = vt->desc & 0x7;
29
30         /* gcc should be smart enough to remove the bounds check, but it isn't:( */
31         desc = vt->desc;
32         switch (desc & 0x7) {
33         case DESC_TYPE_STRING:
34                 STRING_SIZE (skip_size, start);
35 #define SCAN
36                 SCAN_OBJECT_ACTION;
37 #undef SCAN
38                 start += skip_size;
39                 break;
40         case DESC_TYPE_RUN_LENGTH:
41                 OBJ_RUN_LEN_SIZE (skip_size, desc, start);
42                 g_assert (skip_size);
43 #define SCAN OBJ_RUN_LEN_FOREACH_PTR (desc, start)
44 #ifndef SCAN_OBJECT_NOSCAN
45                 SCAN;
46 #endif
47                 SCAN_OBJECT_ACTION;
48 #undef SCAN
49                 start += skip_size;
50                 break;
51         case DESC_TYPE_ARRAY:
52         case DESC_TYPE_VECTOR:
53                 skip_size = safe_object_get_size ((MonoObject*)start);
54                 skip_size += (ALLOC_ALIGN - 1);
55                 skip_size &= ~(ALLOC_ALIGN - 1);
56 #define SCAN OBJ_VECTOR_FOREACH_PTR (vt, start)
57 #ifndef SCAN_OBJECT_NOSCAN
58                 SCAN;
59 #endif
60                 SCAN_OBJECT_ACTION;
61 #undef SCAN
62                 start += skip_size;
63                 break;
64         case DESC_TYPE_SMALL_BITMAP:
65                 OBJ_BITMAP_SIZE (skip_size, desc, start);
66                 g_assert (skip_size);
67 #define SCAN OBJ_BITMAP_FOREACH_PTR (desc, start)
68 #ifndef SCAN_OBJECT_NOSCAN
69                 SCAN;
70 #endif
71                 SCAN_OBJECT_ACTION;
72 #undef SCAN
73                 start += skip_size;
74                 break;
75         case DESC_TYPE_LARGE_BITMAP:
76                 skip_size = safe_object_get_size ((MonoObject*)start);
77                 skip_size += (ALLOC_ALIGN - 1);
78                 skip_size &= ~(ALLOC_ALIGN - 1);
79 #define SCAN OBJ_LARGE_BITMAP_FOREACH_PTR (vt,start)
80 #ifndef SCAN_OBJECT_NOSCAN
81                 SCAN;
82 #endif
83                 SCAN_OBJECT_ACTION;
84 #undef SCAN
85                 start += skip_size;
86                 break;
87         case DESC_TYPE_COMPLEX:
88                 /* this is a complex object */
89                 skip_size = safe_object_get_size ((MonoObject*)start);
90                 skip_size += (ALLOC_ALIGN - 1);
91                 skip_size &= ~(ALLOC_ALIGN - 1);
92 #define SCAN OBJ_COMPLEX_FOREACH_PTR (vt, start)
93 #ifndef SCAN_OBJECT_NOSCAN
94                 SCAN;
95 #endif
96                 SCAN_OBJECT_ACTION;
97 #undef SCAN
98                 start += skip_size;
99                 break;
100         case DESC_TYPE_COMPLEX_ARR:
101                 /* this is an array of complex structs */
102                 skip_size = safe_object_get_size ((MonoObject*)start);
103                 skip_size += (ALLOC_ALIGN - 1);
104                 skip_size &= ~(ALLOC_ALIGN - 1);
105 #define SCAN OBJ_COMPLEX_ARR_FOREACH_PTR (vt, start)
106 #ifndef SCAN_OBJECT_NOSCAN
107                 SCAN;
108 #endif
109                 SCAN_OBJECT_ACTION;
110 #undef SCAN
111                 start += skip_size;
112                 break;
113         default:
114                 g_assert_not_reached ();
115         }
116 }
117
118 #undef SCAN_OBJECT_NOSCAN
119 #undef SCAN_OBJECT_ACTION