Initial sgen mips port.
[mono.git] / mono / metadata / sgen-gray.c
index cccb996800c05eeeaec10055663b8f406d29e975..958e86e961775e1ca137fbd9113abee72b2bda56 100644 (file)
  * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  */
-#define GRAY_QUEUE_SECTION_SIZE        (128 - 3)
 #define GRAY_QUEUE_LENGTH_LIMIT        64
 
-/*
- * This is a stack now instead of a queue, so the most recently added items are removed
- * first, improving cache locality, and keeping the stack size manageable.
- */
-typedef struct _GrayQueueSection GrayQueueSection;
-struct _GrayQueueSection {
-       int end;
-       GrayQueueSection *next;
-       char *objects [GRAY_QUEUE_SECTION_SIZE];
-};
-
-struct _GrayQueue {
-       GrayQueueSection *first;
-       GrayQueueSection *free_list;
-       int balance;
-};
-
 static GrayQueue gray_queue;
 
 static void
@@ -48,6 +30,9 @@ gray_object_alloc_queue_section (GrayQueue *queue)
 {
        GrayQueueSection *section;
 
+       if (queue->alloc_prepare_func)
+               queue->alloc_prepare_func (queue);
+
        if (queue->free_list) {
                /* Use the previously allocated queue sections if possible */
                section = queue->free_list;
@@ -79,23 +64,23 @@ gray_object_queue_is_empty (GrayQueue *queue)
 /*
  * The following two functions are called in the inner loops of the
  * collector, so they need to be as fast as possible.  We have macros
- * for them below.
+ * for them in sgen-gc.h.
  */
 
-static inline void
-gray_object_enqueue (GrayQueue *queue, char *obj)
+void
+mono_sgen_gray_object_enqueue (GrayQueue *queue, char *obj)
 {
        DEBUG (9, g_assert (obj));
-       if (G_UNLIKELY (!queue->first || queue->first->end == GRAY_QUEUE_SECTION_SIZE))
+       if (G_UNLIKELY (!queue->first || queue->first->end == SGEN_GRAY_QUEUE_SECTION_SIZE))
                gray_object_alloc_queue_section (queue);
-       DEBUG (9, g_assert (queue->first && queue->first->end < GRAY_QUEUE_SECTION_SIZE));
+       DEBUG (9, g_assert (queue->first && queue->first->end < SGEN_GRAY_QUEUE_SECTION_SIZE));
        queue->first->objects [queue->first->end++] = obj;
 
        DEBUG (9, ++queue->balance);
 }
 
-static inline char*
-gray_object_dequeue (GrayQueue *queue)
+char*
+mono_sgen_gray_object_dequeue (GrayQueue *queue)
 {
        char *obj;
 
@@ -118,24 +103,28 @@ gray_object_dequeue (GrayQueue *queue)
        return obj;
 }
 
-#if MAX_DEBUG_LEVEL >= 9
-#define GRAY_OBJECT_ENQUEUE gray_object_enqueue
-#define GRAY_OBJECT_DEQUEUE(queue,o) ((o) = gray_object_dequeue ((queue)))
-#else
-#define GRAY_OBJECT_ENQUEUE(queue,o) do {                              \
-               if (G_UNLIKELY (!(queue)->first || (queue)->first->end == GRAY_QUEUE_SECTION_SIZE)) \
-                       gray_object_alloc_queue_section ((queue));      \
-               (queue)->first->objects [(queue)->first->end++] = (o);  \
-       } while (0)
-#define GRAY_OBJECT_DEQUEUE(queue,o) do {                              \
-               if (!(queue)->first)                                    \
-                       (o) = NULL;                                     \
-               else if (G_UNLIKELY ((queue)->first->end == 1))         \
-                       (o) = gray_object_dequeue ((queue));            \
-               else                                                    \
-                       (o) = (queue)->first->objects [--(queue)->first->end]; \
-       } while (0)
-#endif
+static GrayQueueSection*
+gray_object_dequeue_section (GrayQueue *queue)
+{
+       GrayQueueSection *section;
+
+       if (!queue->first)
+               return NULL;
+
+       section = queue->first;
+       queue->first = section->next;
+
+       section->next = NULL;
+
+       return section;
+}
+
+static void
+gray_object_enqueue_section (GrayQueue *queue, GrayQueueSection *section)
+{
+       section->next = queue->first;
+       queue->first = section;
+}
 
 static void
 gray_object_queue_init (GrayQueue *queue)
@@ -158,3 +147,11 @@ gray_object_queue_init (GrayQueue *queue)
                gray_object_free_queue_section (next);
        }
 }
+
+static void
+gray_object_queue_init_with_alloc_prepare (GrayQueue *queue, GrayQueueAllocPrepareFunc func, void *data)
+{
+       gray_object_queue_init (queue);
+       queue->alloc_prepare_func = func;
+       queue->alloc_prepare_data = data;
+}