2 * sgen-pointer-queue.c: A pointer queue that can be sorted.
4 * Copyright (C) 2014 Xamarin Inc
6 * Licensed under the MIT license. See LICENSE file in the project root for full license information.
13 #include "mono/sgen/sgen-gc.h"
14 #include "mono/sgen/sgen-pointer-queue.h"
17 sgen_pointer_queue_clear (SgenPointerQueue *queue)
23 sgen_pointer_queue_init (SgenPointerQueue *queue, int mem_type)
28 queue->mem_type = mem_type;
32 realloc_queue (SgenPointerQueue *queue)
34 size_t new_size = queue->size ? queue->size + queue->size/2 : 1024;
35 void **new_data = (void **)sgen_alloc_internal_dynamic (sizeof (void*) * new_size, queue->mem_type, TRUE);
37 memcpy (new_data, queue->data, sizeof (void*) * queue->next_slot);
38 sgen_free_internal_dynamic (queue->data, sizeof (void*) * queue->size, queue->mem_type);
39 queue->data = new_data;
40 queue->size = new_size;
41 SGEN_LOG (4, "Reallocated pointer queue to size: %lu", new_size);
45 sgen_pointer_queue_will_grow (SgenPointerQueue *queue)
47 return queue->next_slot >= queue->size;
51 sgen_pointer_queue_add (SgenPointerQueue *queue, void *ptr)
53 if (sgen_pointer_queue_will_grow (queue))
54 realloc_queue (queue);
56 queue->data [queue->next_slot++] = ptr;
60 sgen_pointer_queue_pop (SgenPointerQueue *queue)
62 g_assert (queue->next_slot);
64 return queue->data [--queue->next_slot];
68 sgen_pointer_queue_search (SgenPointerQueue *queue, void *addr)
70 size_t first = 0, last = queue->next_slot;
71 while (first < last) {
72 size_t middle = first + ((last - first) >> 1);
73 if (addr <= queue->data [middle])
78 g_assert (first == last);
83 * Removes all NULL pointers from the queue.
86 sgen_pointer_queue_remove_nulls (SgenPointerQueue *queue)
88 void **start, **cur, **end;
89 start = cur = queue->data;
90 end = queue->data + queue->next_slot;
97 queue->next_slot = start - queue->data;
101 * Sorts the pointers in the queue, then removes duplicates.
104 sgen_pointer_queue_sort_uniq (SgenPointerQueue *queue)
106 void **start, **cur, **end;
107 /* sort and uniq pin_queue: we just sort and we let the rest discard multiple values */
108 /* it may be better to keep ranges of pinned memory instead of individually pinning objects */
109 SGEN_LOG (5, "Sorting pointer queue, size: %lu", queue->next_slot);
110 if (queue->next_slot > 1)
111 sgen_sort_addresses (queue->data, queue->next_slot);
112 start = cur = queue->data;
113 end = queue->data + queue->next_slot;
116 while (cur < end && *start == *cur)
120 queue->next_slot = start - queue->data;
121 SGEN_LOG (5, "Pointer queue reduced to size: %lu", queue->next_slot);
125 * Does a linear search through the pointer queue to find `ptr`. Returns the index if
126 * found, otherwise (size_t)-1.
129 sgen_pointer_queue_find (SgenPointerQueue *queue, void *ptr)
132 for (i = 0; i < queue->next_slot; ++i)
133 if (queue->data [i] == ptr)
139 sgen_pointer_queue_is_empty (SgenPointerQueue *queue)
141 return !queue->next_slot;
145 sgen_pointer_queue_free (SgenPointerQueue *queue)
147 sgen_free_internal_dynamic (queue->data, sizeof (void*) * queue->size, queue->mem_type);