#include "metadata/sgen-gc.h"
#include "utils/mono-counters.h"
+#include "sgen-protocol.h"
#define GRAY_QUEUE_LENGTH_LIMIT 64
{
GrayQueueSection *section;
+ HEAVY_STAT (gc_stats.gray_queue_section_alloc ++);
+
if (queue->alloc_prepare_func)
queue->alloc_prepare_func (queue);
STATE_SET (section, GRAY_QUEUE_SECTION_STATE_FLOATING);
}
- section->end = 0;
+ section->size = SGEN_GRAY_QUEUE_SECTION_SIZE;
STATE_TRANSITION (section, GRAY_QUEUE_SECTION_STATE_FLOATING, GRAY_QUEUE_SECTION_STATE_ENQUEUED);
/* Link it with the others */
section->next = queue->first;
queue->first = section;
+ queue->cursor = (char**)section->objects - 1;
}
void
sgen_gray_object_free_queue_section (GrayQueueSection *section)
{
+ HEAVY_STAT (gc_stats.gray_queue_section_free ++);
+
STATE_TRANSITION (section, GRAY_QUEUE_SECTION_STATE_FLOATING, GRAY_QUEUE_SECTION_STATE_FREED);
sgen_free_internal (section, INTERNAL_MEM_GRAY_QUEUE);
}
void
sgen_gray_object_enqueue (SgenGrayQueue *queue, char *obj)
{
+ HEAVY_STAT (gc_stats.gray_queue_enqueue_slow_path ++);
+
SGEN_ASSERT (9, obj, "enqueueing a null object");
//sgen_check_objref (obj);
queue->enqueue_check_func (obj);
#endif
- if (G_UNLIKELY (!queue->first || queue->first->end == SGEN_GRAY_QUEUE_SECTION_SIZE))
+ if (G_UNLIKELY (!queue->first || queue->cursor == GRAY_LAST_CURSOR_POSITION (queue->first))) {
+ if (queue->first) {
+ /* Set the current section size back to default, might have been changed by sgen_gray_object_dequeue_section */
+ queue->first->size = SGEN_GRAY_QUEUE_SECTION_SIZE;
+ }
+
sgen_gray_object_alloc_queue_section (queue);
+ }
STATE_ASSERT (queue->first, GRAY_QUEUE_SECTION_STATE_ENQUEUED);
- SGEN_ASSERT (9, queue->first->end < SGEN_GRAY_QUEUE_SECTION_SIZE, "gray queue %p overflow, first %p, end %d", queue, queue->first, queue->first->end);
- queue->first->objects [queue->first->end++] = obj;
+ SGEN_ASSERT (9, queue->cursor <= GRAY_LAST_CURSOR_POSITION (queue->first), "gray queue %p overflow, first %p, cursor %p", queue, queue->first, queue->cursor);
+ *++queue->cursor = obj;
+
+#ifdef SGEN_HEAVY_BINARY_PROTOCOL
+ binary_protocol_gray_enqueue (queue, queue->cursor, obj);
+#endif
}
char*
{
char *obj;
+ HEAVY_STAT (gc_stats.gray_queue_dequeue_slow_path ++);
+
if (sgen_gray_object_queue_is_empty (queue))
return NULL;
STATE_ASSERT (queue->first, GRAY_QUEUE_SECTION_STATE_ENQUEUED);
- SGEN_ASSERT (9, queue->first->end, "gray queue %p underflow, first %p, end %d", queue, queue->first, queue->first->end);
+ SGEN_ASSERT (9, queue->cursor >= (char**)queue->first->objects, "gray queue %p underflow, first %p, cursor %d", queue, queue->first, queue->cursor);
+
+ obj = *queue->cursor--;
- obj = queue->first->objects [--queue->first->end];
+#ifdef SGEN_HEAVY_BINARY_PROTOCOL
+ binary_protocol_gray_dequeue (queue, queue->cursor + 1, obj);
+#endif
- if (G_UNLIKELY (queue->first->end == 0)) {
+ if (G_UNLIKELY (queue->cursor == (char**)queue->first->objects - 1)) {
GrayQueueSection *section = queue->first;
queue->first = section->next;
section->next = queue->free_list;
STATE_TRANSITION (section, GRAY_QUEUE_SECTION_STATE_ENQUEUED, GRAY_QUEUE_SECTION_STATE_FREE_LIST);
queue->free_list = section;
+ queue->cursor = queue->first ? (char**)queue->first->objects + queue->first->size - 1 : NULL;
}
return obj;
queue->first = section->next;
section->next = NULL;
+ section->size = queue->cursor - (char**)section->objects + 1;
+
+ queue->cursor = queue->first ? (char**)queue->first->objects + queue->first->size - 1 : NULL;
STATE_TRANSITION (section, GRAY_QUEUE_SECTION_STATE_ENQUEUED, GRAY_QUEUE_SECTION_STATE_FLOATING);
{
STATE_TRANSITION (section, GRAY_QUEUE_SECTION_STATE_FLOATING, GRAY_QUEUE_SECTION_STATE_ENQUEUED);
+ if (queue->first)
+ queue->first->size = queue->cursor - (char**)queue->first->objects + 1;
+
section->next = queue->first;
queue->first = section;
+ queue->cursor = (char**)queue->first->objects + queue->first->size - 1;
#ifdef SGEN_CHECK_GRAY_OBJECT_ENQUEUE
if (queue->enqueue_check_func) {
int i;
- for (i = 0; i < section->end; ++i)
+ for (i = 0; i < section->size; ++i)
queue->enqueue_check_func (section->objects [i]);
}
#endif
#ifdef SGEN_CHECK_GRAY_OBJECT_ENQUEUE
if (queue->enqueue_check_func) {
int i;
- for (i = 0; i < section->end; ++i)
+ for (i = 0; i < section->size; ++i)
queue->enqueue_check_func (section->objects [i]);
}
#endif