Changes GC.cs
[mono-project.git] / mono / sgen / sgen-pointer-queue.c
blob8e1a65bc474c26f1d630671a37d5ee72d23f14e6
1 /**
2 * \file
3 * A pointer queue that can be sorted.
5 * Copyright (C) 2014 Xamarin Inc
7 * Licensed under the MIT license. See LICENSE file in the project root for full license information.
8 */
10 #ifdef HAVE_SGEN_GC
12 #include <string.h>
14 #include "mono/sgen/sgen-gc.h"
15 #include "mono/sgen/sgen-pointer-queue.h"
17 void
18 sgen_pointer_queue_clear (SgenPointerQueue *queue)
20 queue->next_slot = 0;
23 void
24 sgen_pointer_queue_init (SgenPointerQueue *queue, int mem_type)
26 queue->next_slot = 0;
27 queue->size = 0;
28 queue->data = NULL;
29 queue->mem_type = mem_type;
32 static void
33 realloc_queue (SgenPointerQueue *queue)
35 size_t new_size = queue->size ? queue->size + queue->size/2 : 1024;
36 void **new_data = (void **)sgen_alloc_internal_dynamic (sizeof (void*) * new_size, queue->mem_type, TRUE);
38 memcpy (new_data, queue->data, sizeof (void*) * queue->next_slot);
39 sgen_free_internal_dynamic (queue->data, sizeof (void*) * queue->size, queue->mem_type);
40 queue->data = new_data;
41 queue->size = new_size;
42 SGEN_LOG (4, "Reallocated pointer queue to size: %lu", (unsigned long)new_size);
45 gboolean
46 sgen_pointer_queue_will_grow (SgenPointerQueue *queue)
48 return queue->next_slot >= queue->size;
51 void
52 sgen_pointer_queue_add (SgenPointerQueue *queue, void *ptr)
54 if (sgen_pointer_queue_will_grow (queue))
55 realloc_queue (queue);
57 queue->data [queue->next_slot++] = ptr;
60 void*
61 sgen_pointer_queue_pop (SgenPointerQueue *queue)
63 g_assert (queue->next_slot);
65 return queue->data [--queue->next_slot];
68 size_t
69 sgen_pointer_queue_search (SgenPointerQueue *queue, void *addr)
71 size_t first = 0, last = queue->next_slot;
72 while (first < last) {
73 size_t middle = first + ((last - first) >> 1);
74 if (addr <= queue->data [middle])
75 last = middle;
76 else
77 first = middle + 1;
79 g_assert (first == last);
80 return first;
84 * Removes all NULL pointers from the queue.
86 void
87 sgen_pointer_queue_remove_nulls (SgenPointerQueue *queue)
89 void **start, **cur, **end;
90 start = cur = queue->data;
91 end = queue->data + queue->next_slot;
92 while (cur < end) {
93 if (*cur)
94 *start++ = *cur++;
95 else
96 ++cur;
98 queue->next_slot = start - queue->data;
102 * Sorts the pointers in the queue, then removes duplicates.
104 void
105 sgen_pointer_queue_sort_uniq (SgenPointerQueue *queue)
107 void **start, **cur, **end;
108 /* sort and uniq pin_queue: we just sort and we let the rest discard multiple values */
109 /* it may be better to keep ranges of pinned memory instead of individually pinning objects */
110 SGEN_LOG (5, "Sorting pointer queue, size: %lu", (unsigned long)queue->next_slot);
111 if (queue->next_slot > 1)
112 sgen_sort_addresses (queue->data, queue->next_slot);
113 start = cur = queue->data;
114 end = queue->data + queue->next_slot;
115 while (cur < end) {
116 *start = *cur++;
117 while (cur < end && *start == *cur)
118 cur++;
119 start++;
121 queue->next_slot = start - queue->data;
122 SGEN_LOG (5, "Pointer queue reduced to size: %lu", (unsigned long)queue->next_slot);
126 * Does a linear search through the pointer queue to find `ptr`. Returns the index if
127 * found, otherwise (size_t)-1.
129 size_t
130 sgen_pointer_queue_find (SgenPointerQueue *queue, void *ptr)
132 size_t i;
133 for (i = 0; i < queue->next_slot; ++i)
134 if (queue->data [i] == ptr)
135 return i;
136 return (size_t)-1;
139 gboolean
140 sgen_pointer_queue_is_empty (SgenPointerQueue *queue)
142 return !queue->next_slot;
145 void
146 sgen_pointer_queue_free (SgenPointerQueue *queue)
148 sgen_free_internal_dynamic (queue->data, sizeof (void*) * queue->size, queue->mem_type);
151 #endif