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:
12 * The above copyright notice and this permission notice shall be
13 * included in all copies or substantial portions of the Software.
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.
28 #include "utils/mono-counters.h"
29 #include "metadata/sgen-gc.h"
30 #include "utils/lock-free-alloc.h"
31 #include "metadata/sgen-memory-governor.h"
33 /* keep each size a multiple of ALLOC_ALIGN */
34 static const int allocator_sizes [] = {
35 8, 16, 24, 32, 40, 48, 64, 80,
36 96, 128, 160, 192, 224, 248, 320, 384,
37 448, 528, 584, 680, 816, 1088, 1360, 2040,
38 2336, 2728, 3272, 4088, 5456, 8184 };
40 #define NUM_ALLOCATORS (sizeof (allocator_sizes) / sizeof (int))
42 static MonoLockFreeAllocSizeClass size_classes [NUM_ALLOCATORS];
43 static MonoLockFreeAllocator allocators [NUM_ALLOCATORS];
46 * Find the allocator index for memory chunks that can contain @size
50 index_for_size (size_t size)
53 /* do a binary search or lookup table later. */
54 for (slot = 0; slot < NUM_ALLOCATORS; ++slot) {
55 if (allocator_sizes [slot] >= size)
58 g_assert_not_reached ();
63 * Allocator indexes for the fixed INTERNAL_MEM_XXX types. -1 if that
66 static int fixed_type_allocator_indexes [INTERNAL_MEM_MAX];
69 sgen_register_fixed_internal_mem_type (int type, size_t size)
73 g_assert (type >= 0 && type < INTERNAL_MEM_MAX);
75 slot = index_for_size (size);
78 if (fixed_type_allocator_indexes [type] == -1)
79 fixed_type_allocator_indexes [type] = slot;
81 g_assert (fixed_type_allocator_indexes [type] == slot);
85 description_for_type (int type)
88 case INTERNAL_MEM_PIN_QUEUE: return "pin-queue";
89 case INTERNAL_MEM_FRAGMENT: return "fragment";
90 case INTERNAL_MEM_SECTION: return "section";
91 case INTERNAL_MEM_SCAN_STARTS: return "scan-starts";
92 case INTERNAL_MEM_FIN_TABLE: return "fin-table";
93 case INTERNAL_MEM_FINALIZE_ENTRY: return "finalize-entry";
94 case INTERNAL_MEM_FINALIZE_READY_ENTRY: return "finalize-ready-entry";
95 case INTERNAL_MEM_DISLINK_TABLE: return "dislink-table";
96 case INTERNAL_MEM_DISLINK: return "dislink";
97 case INTERNAL_MEM_ROOTS_TABLE: return "roots-table";
98 case INTERNAL_MEM_ROOT_RECORD: return "root-record";
99 case INTERNAL_MEM_STATISTICS: return "statistics";
100 case INTERNAL_MEM_STAT_PINNED_CLASS: return "pinned-class";
101 case INTERNAL_MEM_STAT_REMSET_CLASS: return "remset-class";
102 case INTERNAL_MEM_REMSET: return "remset";
103 case INTERNAL_MEM_GRAY_QUEUE: return "gray-queue";
104 case INTERNAL_MEM_STORE_REMSET: return "store-remset";
105 case INTERNAL_MEM_MS_TABLES: return "marksweep-tables";
106 case INTERNAL_MEM_MS_BLOCK_INFO: return "marksweep-block-info";
107 case INTERNAL_MEM_EPHEMERON_LINK: return "ephemeron-link";
108 case INTERNAL_MEM_WORKER_DATA: return "worker-data";
109 case INTERNAL_MEM_BRIDGE_DATA: return "bridge-data";
110 case INTERNAL_MEM_JOB_QUEUE_ENTRY: return "job-queue-entry";
111 case INTERNAL_MEM_TOGGLEREF_DATA: return "toggleref-data";
113 g_assert_not_reached ();
118 sgen_alloc_internal_dynamic (size_t size, int type, gboolean assert_on_failure)
123 if (size > allocator_sizes [NUM_ALLOCATORS - 1]) {
124 p = sgen_alloc_os_memory (size, TRUE, NULL);
126 sgen_assert_memory_alloc (NULL, description_for_type (type));
130 index = index_for_size (size);
132 p = mono_lock_free_alloc (&allocators [index]);
134 sgen_assert_memory_alloc (NULL, description_for_type (type));
140 sgen_free_internal_dynamic (void *addr, size_t size, int type)
147 if (size > allocator_sizes [NUM_ALLOCATORS - 1])
148 return sgen_free_os_memory (addr, size);
150 index = index_for_size (size);
152 mono_lock_free_free (addr);
156 sgen_alloc_internal (int type)
158 int index = fixed_type_allocator_indexes [type];
160 g_assert (index >= 0 && index < NUM_ALLOCATORS);
161 p = mono_lock_free_alloc (&allocators [index]);
162 memset (p, 0, allocator_sizes [index]);
167 sgen_free_internal (void *addr, int type)
174 index = fixed_type_allocator_indexes [type];
175 g_assert (index >= 0 && index < NUM_ALLOCATORS);
177 mono_lock_free_free (addr);
181 sgen_dump_internal_mem_usage (FILE *heap_dump_file)
186 fprintf (heap_dump_file, "<other-mem-usage type=\"large-internal\" size=\"%lld\"/>\n", large_internal_bytes_alloced);
187 fprintf (heap_dump_file, "<other-mem-usage type=\"pinned-chunks\" size=\"%lld\"/>\n", pinned_chunk_bytes_alloced);
188 for (i = 0; i < INTERNAL_MEM_MAX; ++i) {
189 fprintf (heap_dump_file, "<other-mem-usage type=\"%s\" size=\"%ld\"/>\n",
190 description_for_type (i), unmanaged_allocator.small_internal_mem_bytes [i]);
196 sgen_report_internal_mem_usage (void)
198 /* FIXME: implement */
199 printf ("not implemented yet\n");
203 sgen_init_internal_allocator (void)
207 for (i = 0; i < INTERNAL_MEM_MAX; ++i)
208 fixed_type_allocator_indexes [i] = -1;
210 for (i = 0; i < NUM_ALLOCATORS; ++i) {
211 mono_lock_free_allocator_init_size_class (&size_classes [i], allocator_sizes [i]);
212 mono_lock_free_allocator_init_allocator (&allocators [i], &size_classes [i]);