[sgen] Include config.h in all of SGen's compilation units.
[mono.git] / mono / metadata / sgen-internal.c
1 /*
2  * sgen-internal.c
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining
5  * a copy of this software and associated documentation files (the
6  * "Software"), to deal in the Software without restriction, including
7  * without limitation the rights to use, copy, modify, merge, publish,
8  * distribute, sublicense, and/or sell copies of the Software, and to
9  * permit persons to whom the Software is furnished to do so, subject to
10  * the following conditions:
11  * 
12  * The above copyright notice and this permission notice shall be
13  * included in all copies or substantial portions of the Software.
14  * 
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19  * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20  * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21  * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22  */
23
24 #include "config.h"
25
26 #ifdef HAVE_SGEN_GC
27
28 #include "utils/mono-counters.h"
29 #include "metadata/sgen-gc.h"
30 #include "utils/lock-free-alloc.h"
31
32 /* keep each size a multiple of ALLOC_ALIGN */
33 static const int allocator_sizes [] = {
34            8,   16,   24,   32,   40,   48,   64,   80,
35           96,  128,  160,  192,  224,  248,  320,  384,
36          448,  528,  584,  680,  816, 1088, 1360, 2040,
37         2336, 2728, 3272, 4088, 5456, 8184 };
38
39 #define NUM_ALLOCATORS  (sizeof (allocator_sizes) / sizeof (int))
40
41 static MonoLockFreeAllocSizeClass size_classes [NUM_ALLOCATORS];
42 static MonoLockFreeAllocator allocators [NUM_ALLOCATORS];
43
44 /*
45  * Find the allocator index for memory chunks that can contain @size
46  * objects.
47  */
48 static int
49 index_for_size (size_t size)
50 {
51         int slot;
52         /* do a binary search or lookup table later. */
53         for (slot = 0; slot < NUM_ALLOCATORS; ++slot) {
54                 if (allocator_sizes [slot] >= size)
55                         return slot;
56         }
57         g_assert_not_reached ();
58         return -1;
59 }
60
61 /*
62  * Allocator indexes for the fixed INTERNAL_MEM_XXX types.  -1 if that
63  * type is dynamic.
64  */
65 static int fixed_type_allocator_indexes [INTERNAL_MEM_MAX];
66
67 void
68 mono_sgen_register_fixed_internal_mem_type (int type, size_t size)
69 {
70         int slot;
71
72         g_assert (type >= 0 && type < INTERNAL_MEM_MAX);
73         g_assert (fixed_type_allocator_indexes [type] == -1);
74
75         slot = index_for_size (size);
76         g_assert (slot >= 0);
77
78         fixed_type_allocator_indexes [type] = slot;
79 }
80
81 void*
82 mono_sgen_alloc_internal_dynamic (size_t size, int type)
83 {
84         int index;
85         void *p;
86
87         if (size > allocator_sizes [NUM_ALLOCATORS - 1])
88                 return mono_sgen_alloc_os_memory (size, TRUE);
89
90         index = index_for_size (size);
91
92         p = mono_lock_free_alloc (&allocators [index]);
93         memset (p, 0, size);
94         return p;
95 }
96
97 void
98 mono_sgen_free_internal_dynamic (void *addr, size_t size, int type)
99 {
100         int index;
101
102         if (!addr)
103                 return;
104
105         if (size > allocator_sizes [NUM_ALLOCATORS - 1])
106                 return mono_sgen_free_os_memory (addr, size);
107
108         index = index_for_size (size);
109
110         mono_lock_free_free (addr);
111 }
112
113 void*
114 mono_sgen_alloc_internal (int type)
115 {
116         int index = fixed_type_allocator_indexes [type];
117         void *p;
118         g_assert (index >= 0 && index < NUM_ALLOCATORS);
119         p = mono_lock_free_alloc (&allocators [index]);
120         memset (p, 0, allocator_sizes [index]);
121         return p;
122 }
123
124 void
125 mono_sgen_free_internal (void *addr, int type)
126 {
127         int index;
128
129         if (!addr)
130                 return;
131
132         index = fixed_type_allocator_indexes [type];
133         g_assert (index >= 0 && index < NUM_ALLOCATORS);
134
135         mono_lock_free_free (addr);
136 }
137
138 void
139 mono_sgen_dump_internal_mem_usage (FILE *heap_dump_file)
140 {
141         /*
142         static char const *internal_mem_names [] = { "pin-queue", "fragment", "section", "scan-starts",
143                                                      "fin-table", "finalize-entry", "dislink-table",
144                                                      "dislink", "roots-table", "root-record", "statistics",
145                                                      "remset", "gray-queue", "store-remset", "marksweep-tables",
146                                                      "marksweep-block-info", "ephemeron-link", "worker-data",
147                                                      "bridge-data", "job-queue-entry" };
148
149         int i;
150
151         fprintf (heap_dump_file, "<other-mem-usage type=\"large-internal\" size=\"%lld\"/>\n", large_internal_bytes_alloced);
152         fprintf (heap_dump_file, "<other-mem-usage type=\"pinned-chunks\" size=\"%lld\"/>\n", pinned_chunk_bytes_alloced);
153         for (i = 0; i < INTERNAL_MEM_MAX; ++i) {
154                 fprintf (heap_dump_file, "<other-mem-usage type=\"%s\" size=\"%ld\"/>\n",
155                                 internal_mem_names [i], unmanaged_allocator.small_internal_mem_bytes [i]);
156         }
157         */
158 }
159
160 void
161 mono_sgen_report_internal_mem_usage (void)
162 {
163         /* FIXME: implement */
164         printf ("not implemented yet\n");
165 }
166
167 void
168 mono_sgen_init_internal_allocator (void)
169 {
170         int i;
171
172         for (i = 0; i < INTERNAL_MEM_MAX; ++i)
173                 fixed_type_allocator_indexes [i] = -1;
174
175         for (i = 0; i < NUM_ALLOCATORS; ++i) {
176                 mono_lock_free_allocator_init_size_class (&size_classes [i], allocator_sizes [i]);
177                 mono_lock_free_allocator_init_allocator (&allocators [i], &size_classes [i]);
178         }
179 }
180
181 #endif