Fix potential crash for Encoder.Convert (#20522)
[mono-project.git] / mono / sgen / sgen-simple-nursery.c
blob1db3b081f1952f282e0aa2a7408fae07f2850c87
1 /**
2 * \file
3 * Simple always promote nursery.
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
10 * Licensed under the MIT license. See LICENSE file in the project root for full license information.
13 #include "config.h"
14 #ifdef HAVE_SGEN_GC
16 #include <string.h>
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"
26 static GCObject*
27 alloc_for_promotion (GCVTable vtable, GCObject *obj, size_t objsize, gboolean has_references)
29 sgen_total_promoted_size += objsize;
30 return sgen_major_collector.alloc_object (vtable, objsize, has_references);
33 static GCObject*
34 alloc_for_promotion_par (GCVTable vtable, GCObject *obj, size_t objsize, gboolean has_references)
37 * FIXME
38 * Note that the stat is not precise. sgen_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.
42 sgen_total_promoted_size += objsize;
43 return sgen_major_collector.alloc_object_par (vtable, objsize, has_references);
46 static SgenFragment*
47 build_fragments_get_exclude_head (void)
49 return NULL;
52 static void
53 build_fragments_release_exclude_head (void)
57 static void
58 build_fragments_finish (SgenFragmentAllocator *allocator)
62 static void
63 prepare_to_space (char *to_space_bitmap, size_t space_bitmap_size)
67 static void
68 clear_fragments (void)
72 static void
73 init_nursery (SgenFragmentAllocator *allocator, char *start, char *end)
75 char *nursery_limit = sgen_nursery_start + sgen_nursery_size;
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);
86 /******************************************Copy/Scan functins ************************************************/
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
92 #define COPY_OR_MARK_PARALLEL
93 #include "sgen-copy-object.h"
95 #define SGEN_SIMPLE_NURSERY
97 #include "sgen-minor-copy-object.h"
98 #include "sgen-minor-scan-object.h"
100 static void
101 fill_serial_ops (SgenObjectOperations *ops)
103 ops->copy_or_mark_object = SERIAL_COPY_OBJECT;
104 FILL_MINOR_COLLECTOR_SCAN_OBJECT (ops);
107 #ifndef DISABLE_SGEN_MAJOR_MARKSWEEP_CONC
109 #define SGEN_SIMPLE_PAR_NURSERY
111 #include "sgen-minor-copy-object.h"
112 #include "sgen-minor-scan-object.h"
114 static void
115 fill_parallel_ops (SgenObjectOperations *ops)
117 ops->copy_or_mark_object = SERIAL_COPY_OBJECT;
118 FILL_MINOR_COLLECTOR_SCAN_OBJECT (ops);
121 #undef SGEN_SIMPLE_PAR_NURSERY
122 #define SGEN_CONCURRENT_MAJOR
124 #include "sgen-minor-copy-object.h"
125 #include "sgen-minor-scan-object.h"
127 static void
128 fill_serial_with_concurrent_major_ops (SgenObjectOperations *ops)
130 ops->copy_or_mark_object = SERIAL_COPY_OBJECT;
131 FILL_MINOR_COLLECTOR_SCAN_OBJECT (ops);
134 #define SGEN_SIMPLE_PAR_NURSERY
136 #include "sgen-minor-copy-object.h"
137 #include "sgen-minor-scan-object.h"
139 static void
140 fill_parallel_with_concurrent_major_ops (SgenObjectOperations *ops)
142 ops->copy_or_mark_object = SERIAL_COPY_OBJECT;
143 FILL_MINOR_COLLECTOR_SCAN_OBJECT (ops);
146 #endif
148 void
149 sgen_simple_nursery_init (SgenMinorCollector *collector, gboolean parallel)
151 if (mono_cpu_count () <= 1)
152 parallel = FALSE;
154 #ifdef DISABLE_SGEN_MAJOR_MARKSWEEP_CONC
155 g_assert (parallel == FALSE);
156 #endif
158 collector->is_split = FALSE;
159 collector->is_parallel = parallel;
161 collector->alloc_for_promotion = alloc_for_promotion;
162 collector->alloc_for_promotion_par = alloc_for_promotion_par;
164 collector->prepare_to_space = prepare_to_space;
165 collector->clear_fragments = clear_fragments;
166 collector->build_fragments_get_exclude_head = build_fragments_get_exclude_head;
167 collector->build_fragments_release_exclude_head = build_fragments_release_exclude_head;
168 collector->build_fragments_finish = build_fragments_finish;
169 collector->init_nursery = init_nursery;
171 fill_serial_ops (&collector->serial_ops);
172 #ifndef DISABLE_SGEN_MAJOR_MARKSWEEP_CONC
173 fill_serial_with_concurrent_major_ops (&collector->serial_ops_with_concurrent_major);
175 fill_parallel_ops (&collector->parallel_ops);
176 fill_parallel_with_concurrent_major_ops (&collector->parallel_ops_with_concurrent_major);
179 * The nursery worker context is created first so it will have priority over
180 * concurrent mark and concurrent sweep.
182 if (parallel)
183 sgen_workers_create_context (GENERATION_NURSERY, mono_cpu_count ());
184 #endif
189 #endif