Merge pull request #5714 from alexischr/update_bockbuild
[mono.git] / mono / sgen / sgen-simple-nursery.c
1 /**
2  * \file
3  * Simple always promote nursery.
4  *
5  * Copyright 2001-2003 Ximian, Inc
6  * Copyright 2003-2010 Novell, Inc.
7  * Copyright 2011 Xamarin Inc (http://www.xamarin.com)
8  * Copyright (C) 2012 Xamarin Inc
9  *
10  * Licensed under the MIT license. See LICENSE file in the project root for full license information.
11  */
12
13 #include "config.h"
14 #ifdef HAVE_SGEN_GC
15
16 #include <string.h>
17
18 #include "mono/sgen/sgen-gc.h"
19 #include "mono/sgen/sgen-protocol.h"
20 #include "mono/sgen/sgen-layout-stats.h"
21 #include "mono/sgen/sgen-client.h"
22 #include "mono/sgen/sgen-workers.h"
23 #include "mono/utils/mono-memory-model.h"
24 #include "mono/utils/mono-proclib.h"
25
26 static inline GCObject*
27 alloc_for_promotion (GCVTable vtable, GCObject *obj, size_t objsize, gboolean has_references)
28 {
29         total_promoted_size += objsize;
30         return major_collector.alloc_object (vtable, objsize, has_references);
31 }
32
33 static inline GCObject*
34 alloc_for_promotion_par (GCVTable vtable, GCObject *obj, size_t objsize, gboolean has_references)
35 {
36         /*
37          * FIXME
38          * Note that the stat is not precise. total_promoted_size incrementing is not atomic and
39          * even in that case, the same object might be promoted simultaneously by different workers
40          * leading to one of the allocated major object to be discarded.
41          */
42         total_promoted_size += objsize;
43         return major_collector.alloc_object_par (vtable, objsize, has_references);
44 }
45
46 static SgenFragment*
47 build_fragments_get_exclude_head (void)
48 {
49         return NULL;
50 }
51
52 static void
53 build_fragments_release_exclude_head (void)
54 {
55 }
56
57 static void
58 build_fragments_finish (SgenFragmentAllocator *allocator)
59 {
60 }
61
62 static void
63 prepare_to_space (char *to_space_bitmap, size_t space_bitmap_size)
64 {
65 }
66
67 static void
68 clear_fragments (void)
69 {       
70 }
71
72 static void
73 init_nursery (SgenFragmentAllocator *allocator, char *start, char *end)
74 {
75         char *nursery_limit = sgen_nursery_start + sgen_nursery_size;
76
77         if (start < nursery_limit && end > nursery_limit) {
78                 sgen_fragment_allocator_add (allocator, start, nursery_limit);
79                 sgen_fragment_allocator_add (allocator, nursery_limit, end);
80         } else {
81                 sgen_fragment_allocator_add (allocator, start, end);
82         }
83 }
84
85
86 /******************************************Copy/Scan functins ************************************************/
87
88 #define collector_pin_object(obj, queue) sgen_pin_object (obj, queue);
89 #define COLLECTOR_SERIAL_ALLOC_FOR_PROMOTION alloc_for_promotion
90 #define COLLECTOR_PARALLEL_ALLOC_FOR_PROMOTION alloc_for_promotion_par
91
92 #define COPY_OR_MARK_PARALLEL
93 #include "sgen-copy-object.h"
94
95 #define SGEN_SIMPLE_NURSERY
96
97 #include "sgen-minor-copy-object.h"
98 #include "sgen-minor-scan-object.h"
99
100 static void
101 fill_serial_ops (SgenObjectOperations *ops)
102 {
103         ops->copy_or_mark_object = SERIAL_COPY_OBJECT;
104         FILL_MINOR_COLLECTOR_SCAN_OBJECT (ops);
105 }
106
107 #define SGEN_SIMPLE_PAR_NURSERY
108
109 #include "sgen-minor-copy-object.h"
110 #include "sgen-minor-scan-object.h"
111
112 static void
113 fill_parallel_ops (SgenObjectOperations *ops)
114 {
115         ops->copy_or_mark_object = SERIAL_COPY_OBJECT;
116         FILL_MINOR_COLLECTOR_SCAN_OBJECT (ops);
117 }
118
119 #undef SGEN_SIMPLE_PAR_NURSERY
120 #define SGEN_CONCURRENT_MAJOR
121
122 #include "sgen-minor-copy-object.h"
123 #include "sgen-minor-scan-object.h"
124
125 static void
126 fill_serial_with_concurrent_major_ops (SgenObjectOperations *ops)
127 {
128         ops->copy_or_mark_object = SERIAL_COPY_OBJECT;
129         FILL_MINOR_COLLECTOR_SCAN_OBJECT (ops);
130 }
131
132 #define SGEN_SIMPLE_PAR_NURSERY
133
134 #include "sgen-minor-copy-object.h"
135 #include "sgen-minor-scan-object.h"
136
137 static void
138 fill_parallel_with_concurrent_major_ops (SgenObjectOperations *ops)
139 {
140         ops->copy_or_mark_object = SERIAL_COPY_OBJECT;
141         FILL_MINOR_COLLECTOR_SCAN_OBJECT (ops);
142 }
143
144 void
145 sgen_simple_nursery_init (SgenMinorCollector *collector, gboolean parallel)
146 {
147         if (mono_cpu_count () <= 1)
148                 parallel = FALSE;
149
150         collector->is_split = FALSE;
151         collector->is_parallel = parallel;
152
153         collector->alloc_for_promotion = alloc_for_promotion;
154         collector->alloc_for_promotion_par = alloc_for_promotion_par;
155
156         collector->prepare_to_space = prepare_to_space;
157         collector->clear_fragments = clear_fragments;
158         collector->build_fragments_get_exclude_head = build_fragments_get_exclude_head;
159         collector->build_fragments_release_exclude_head = build_fragments_release_exclude_head;
160         collector->build_fragments_finish = build_fragments_finish;
161         collector->init_nursery = init_nursery;
162
163         fill_serial_ops (&collector->serial_ops);
164         fill_serial_with_concurrent_major_ops (&collector->serial_ops_with_concurrent_major);
165         fill_parallel_ops (&collector->parallel_ops);
166         fill_parallel_with_concurrent_major_ops (&collector->parallel_ops_with_concurrent_major);
167
168         /*
169          * The nursery worker context is created first so it will have priority over
170          * concurrent mark and concurrent sweep.
171          */
172         if (parallel)
173                 sgen_workers_create_context (GENERATION_NURSERY, mono_cpu_count ());
174 }
175
176
177 #endif