Merge pull request #5714 from alexischr/update_bockbuild
[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 #ifdef SGEN_CONCURRENT_MAJOR
23 #define SERIAL_SCAN_OBJECT simple_par_nursery_serial_with_concurrent_major_scan_object
24 #define SERIAL_SCAN_VTYPE simple_par_nursery_serial_with_concurrent_major_scan_vtype
25 #define SERIAL_SCAN_PTR_FIELD simple_par_nursery_serial_with_concurrent_major_scan_ptr_field
26 #define SERIAL_DRAIN_GRAY_STACK simple_par_nursery_serial_with_concurrent_major_drain_gray_stack
27 #else
28 #define SERIAL_SCAN_OBJECT simple_par_nursery_serial_scan_object
29 #define SERIAL_SCAN_VTYPE simple_par_nursery_serial_scan_vtype
30 #define SERIAL_SCAN_PTR_FIELD simple_par_nursery_serial_scan_ptr_field
31 #define SERIAL_DRAIN_GRAY_STACK simple_par_nursery_serial_drain_gray_stack
32 #endif
33 #else
34 #ifdef SGEN_CONCURRENT_MAJOR
35 #define SERIAL_SCAN_OBJECT simple_nursery_serial_with_concurrent_major_scan_object
36 #define SERIAL_SCAN_VTYPE simple_nursery_serial_with_concurrent_major_scan_vtype
37 #define SERIAL_SCAN_PTR_FIELD simple_nursery_serial_with_concurrent_major_scan_ptr_field
38 #define SERIAL_DRAIN_GRAY_STACK simple_nursery_serial_with_concurrent_major_drain_gray_stack
39 #else
40 #define SERIAL_SCAN_OBJECT simple_nursery_serial_scan_object
41 #define SERIAL_SCAN_VTYPE simple_nursery_serial_scan_vtype
42 #define SERIAL_SCAN_PTR_FIELD simple_nursery_serial_scan_ptr_field
43 #define SERIAL_DRAIN_GRAY_STACK simple_nursery_serial_drain_gray_stack
44 #endif
45 #endif
46
47 #elif defined (SGEN_SPLIT_NURSERY)
48
49 #ifdef SGEN_CONCURRENT_MAJOR
50 #define SERIAL_SCAN_OBJECT split_nursery_serial_with_concurrent_major_scan_object
51 #define SERIAL_SCAN_VTYPE split_nursery_serial_with_concurrent_major_scan_vtype
52 #define SERIAL_SCAN_PTR_FIELD split_nursery_serial_with_concurrent_major_scan_ptr_field
53 #define SERIAL_DRAIN_GRAY_STACK split_nursery_serial_with_concurrent_major_drain_gray_stack
54 #else
55 #define SERIAL_SCAN_OBJECT split_nursery_serial_scan_object
56 #define SERIAL_SCAN_VTYPE split_nursery_serial_scan_vtype
57 #define SERIAL_SCAN_PTR_FIELD split_nursery_serial_scan_ptr_field
58 #define SERIAL_DRAIN_GRAY_STACK split_nursery_serial_drain_gray_stack
59 #endif
60
61 #else
62 #error "No nursery configuration specified"
63 #endif
64
65 #undef HANDLE_PTR
66 /* Global remsets are handled in SERIAL_COPY_OBJECT_FROM_OBJ */
67 #define HANDLE_PTR(ptr,obj)     do {    \
68                 void *__old = *(ptr);   \
69                 SGEN_OBJECT_LAYOUT_STATISTICS_MARK_BITMAP ((obj), (ptr)); \
70                 binary_protocol_scan_process_reference ((full_object), (ptr), __old); \
71                 if (__old) {    \
72                         SERIAL_COPY_OBJECT_FROM_OBJ ((ptr), queue);     \
73                         SGEN_COND_LOG (9, __old != *(ptr), "Overwrote field at %p with %p (was: %p)", (ptr), *(ptr), __old); \
74                 }       \
75         } while (0)
76
77 static void
78 SERIAL_SCAN_OBJECT (GCObject *full_object, SgenDescriptor desc, SgenGrayQueue *queue)
79 {
80         char *start = (char*)full_object;
81
82         SGEN_OBJECT_LAYOUT_STATISTICS_DECLARE_BITMAP;
83
84 #ifdef HEAVY_STATISTICS
85         sgen_descriptor_count_scanned_object (desc);
86 #endif
87
88         SGEN_ASSERT (9, sgen_get_current_collection_generation () == GENERATION_NURSERY, "Must not use minor scan during major collection.");
89
90 #define SCAN_OBJECT_PROTOCOL
91 #include "sgen-scan-object.h"
92
93         SGEN_OBJECT_LAYOUT_STATISTICS_COMMIT_BITMAP;
94         HEAVY_STAT (++stat_scan_object_called_nursery);
95 }
96
97 static void
98 SERIAL_SCAN_VTYPE (GCObject *full_object, char *start, SgenDescriptor desc, SgenGrayQueue *queue BINARY_PROTOCOL_ARG (size_t size))
99 {
100         SGEN_OBJECT_LAYOUT_STATISTICS_DECLARE_BITMAP;
101
102         SGEN_ASSERT (9, sgen_get_current_collection_generation () == GENERATION_NURSERY, "Must not use minor scan during major collection.");
103
104         /* The descriptors include info about the MonoObject header as well */
105         start -= SGEN_CLIENT_OBJECT_HEADER_SIZE;
106
107 #define SCAN_OBJECT_NOVTABLE
108 #define SCAN_OBJECT_PROTOCOL
109 #include "sgen-scan-object.h"
110 }
111
112 static void
113 SERIAL_SCAN_PTR_FIELD (GCObject *full_object, GCObject **ptr, SgenGrayQueue *queue)
114 {
115         HANDLE_PTR (ptr, NULL);
116 }
117
118 static gboolean
119 SERIAL_DRAIN_GRAY_STACK (SgenGrayQueue *queue)
120 {
121 #ifdef SGEN_SIMPLE_PAR_NURSERY
122         int i;
123         /*
124          * We do bounded iteration so we can switch to optimized context
125          * when we are the last worker remaining.
126          */
127         for (i = 0; i < 32; i++) {
128 #else
129         for (;;) {
130 #endif
131                 GCObject *obj;
132                 SgenDescriptor desc;
133
134 #ifdef SGEN_SIMPLE_PAR_NURSERY
135                 GRAY_OBJECT_DEQUEUE_PARALLEL (queue, &obj, &desc);
136 #else
137                 GRAY_OBJECT_DEQUEUE_SERIAL (queue, &obj, &desc);
138 #endif
139                 if (!obj)
140                         return TRUE;
141
142                 SERIAL_SCAN_OBJECT (obj, desc, queue);
143         }
144
145         return FALSE;
146 }
147
148 #define FILL_MINOR_COLLECTOR_SCAN_OBJECT(ops)   do {                    \
149                 (ops)->scan_object = SERIAL_SCAN_OBJECT;                        \
150                 (ops)->scan_vtype = SERIAL_SCAN_VTYPE;                  \
151                 (ops)->scan_ptr_field = SERIAL_SCAN_PTR_FIELD;          \
152                 (ops)->drain_gray_stack = SERIAL_DRAIN_GRAY_STACK;      \
153         } while (0)