b92d309f4ec1228d02086deb5d856902459c94cc
[mono.git] / mono / sgen / sgen-minor-scan-object.h
1 /**
2  * \file
3  * Object scanning in the nursery collectors.
4  *
5  * Copyright 2001-2003 Ximian, Inc
6  * Copyright 2003-2010 Novell, Inc.
7  * Copyright (C) 2012 Xamarin Inc
8  *
9  * Licensed under the MIT license. See LICENSE file in the project root for full license information.
10  */
11
12 extern guint64 stat_scan_object_called_nursery;
13
14 #undef SERIAL_SCAN_OBJECT
15 #undef SERIAL_SCAN_VTYPE
16 #undef SERIAL_SCAN_PTR_FIELD
17 #undef SERIAL_DRAIN_GRAY_STACK
18
19 #if defined(SGEN_SIMPLE_NURSERY)
20
21 #ifdef SGEN_SIMPLE_PAR_NURSERY
22 #define SERIAL_SCAN_OBJECT simple_par_nursery_serial_scan_object
23 #define SERIAL_SCAN_VTYPE simple_par_nursery_serial_scan_vtype
24 #define SERIAL_SCAN_PTR_FIELD simple_par_nursery_serial_scan_ptr_field
25 #define SERIAL_DRAIN_GRAY_STACK simple_par_nursery_serial_drain_gray_stack
26 #else
27 #ifdef SGEN_CONCURRENT_MAJOR
28 #define SERIAL_SCAN_OBJECT simple_nursery_serial_with_concurrent_major_scan_object
29 #define SERIAL_SCAN_VTYPE simple_nursery_serial_with_concurrent_major_scan_vtype
30 #define SERIAL_SCAN_PTR_FIELD simple_nursery_serial_with_concurrent_major_scan_ptr_field
31 #define SERIAL_DRAIN_GRAY_STACK simple_nursery_serial_with_concurrent_major_drain_gray_stack
32 #else
33 #define SERIAL_SCAN_OBJECT simple_nursery_serial_scan_object
34 #define SERIAL_SCAN_VTYPE simple_nursery_serial_scan_vtype
35 #define SERIAL_SCAN_PTR_FIELD simple_nursery_serial_scan_ptr_field
36 #define SERIAL_DRAIN_GRAY_STACK simple_nursery_serial_drain_gray_stack
37 #endif
38 #endif
39
40 #elif defined (SGEN_SPLIT_NURSERY)
41
42 #ifdef SGEN_CONCURRENT_MAJOR
43 #define SERIAL_SCAN_OBJECT split_nursery_serial_with_concurrent_major_scan_object
44 #define SERIAL_SCAN_VTYPE split_nursery_serial_with_concurrent_major_scan_vtype
45 #define SERIAL_SCAN_PTR_FIELD split_nursery_serial_with_concurrent_major_scan_ptr_field
46 #define SERIAL_DRAIN_GRAY_STACK split_nursery_serial_with_concurrent_major_drain_gray_stack
47 #else
48 #define SERIAL_SCAN_OBJECT split_nursery_serial_scan_object
49 #define SERIAL_SCAN_VTYPE split_nursery_serial_scan_vtype
50 #define SERIAL_SCAN_PTR_FIELD split_nursery_serial_scan_ptr_field
51 #define SERIAL_DRAIN_GRAY_STACK split_nursery_serial_drain_gray_stack
52 #endif
53
54 #else
55 #error "No nursery configuration specified"
56 #endif
57
58 #undef HANDLE_PTR
59 /* Global remsets are handled in SERIAL_COPY_OBJECT_FROM_OBJ */
60 #define HANDLE_PTR(ptr,obj)     do {    \
61                 void *__old = *(ptr);   \
62                 SGEN_OBJECT_LAYOUT_STATISTICS_MARK_BITMAP ((obj), (ptr)); \
63                 binary_protocol_scan_process_reference ((full_object), (ptr), __old); \
64                 if (__old) {    \
65                         SERIAL_COPY_OBJECT_FROM_OBJ ((ptr), queue);     \
66                         SGEN_COND_LOG (9, __old != *(ptr), "Overwrote field at %p with %p (was: %p)", (ptr), *(ptr), __old); \
67                 }       \
68         } while (0)
69
70 static void
71 SERIAL_SCAN_OBJECT (GCObject *full_object, SgenDescriptor desc, SgenGrayQueue *queue)
72 {
73         char *start = (char*)full_object;
74
75         SGEN_OBJECT_LAYOUT_STATISTICS_DECLARE_BITMAP;
76
77 #ifdef HEAVY_STATISTICS
78         sgen_descriptor_count_scanned_object (desc);
79 #endif
80
81         SGEN_ASSERT (9, sgen_get_current_collection_generation () == GENERATION_NURSERY, "Must not use minor scan during major collection.");
82
83 #define SCAN_OBJECT_PROTOCOL
84 #include "sgen-scan-object.h"
85
86         SGEN_OBJECT_LAYOUT_STATISTICS_COMMIT_BITMAP;
87         HEAVY_STAT (++stat_scan_object_called_nursery);
88 }
89
90 static void
91 SERIAL_SCAN_VTYPE (GCObject *full_object, char *start, SgenDescriptor desc, SgenGrayQueue *queue BINARY_PROTOCOL_ARG (size_t size))
92 {
93         SGEN_OBJECT_LAYOUT_STATISTICS_DECLARE_BITMAP;
94
95         SGEN_ASSERT (9, sgen_get_current_collection_generation () == GENERATION_NURSERY, "Must not use minor scan during major collection.");
96
97         /* The descriptors include info about the MonoObject header as well */
98         start -= SGEN_CLIENT_OBJECT_HEADER_SIZE;
99
100 #define SCAN_OBJECT_NOVTABLE
101 #define SCAN_OBJECT_PROTOCOL
102 #include "sgen-scan-object.h"
103 }
104
105 static void
106 SERIAL_SCAN_PTR_FIELD (GCObject *full_object, GCObject **ptr, SgenGrayQueue *queue)
107 {
108         HANDLE_PTR (ptr, NULL);
109 }
110
111 static gboolean
112 SERIAL_DRAIN_GRAY_STACK (SgenGrayQueue *queue)
113 {
114 #ifdef SGEN_SIMPLE_PAR_NURSERY
115         int i;
116         /*
117          * We do bounded iteration so we can switch to optimized context
118          * when we are the last worker remaining.
119          */
120         for (i = 0; i < 32; i++) {
121 #else
122         for (;;) {
123 #endif
124                 GCObject *obj;
125                 SgenDescriptor desc;
126
127 #ifdef SGEN_SIMPLE_PAR_NURSERY
128                 GRAY_OBJECT_DEQUEUE_PARALLEL (queue, &obj, &desc);
129 #else
130                 GRAY_OBJECT_DEQUEUE_SERIAL (queue, &obj, &desc);
131 #endif
132                 if (!obj)
133                         return TRUE;
134
135                 SERIAL_SCAN_OBJECT (obj, desc, queue);
136         }
137
138         return FALSE;
139 }
140
141 #define FILL_MINOR_COLLECTOR_SCAN_OBJECT(ops)   do {                    \
142                 (ops)->scan_object = SERIAL_SCAN_OBJECT;                        \
143                 (ops)->scan_vtype = SERIAL_SCAN_VTYPE;                  \
144                 (ops)->scan_ptr_field = SERIAL_SCAN_PTR_FIELD;          \
145                 (ops)->drain_gray_stack = SERIAL_DRAIN_GRAY_STACK;      \
146         } while (0)