[sgen] Remove some redundancy with nursery section
[mono.git] / mono / sgen / sgen-nursery-allocator.c
index ab12803f10813400c506a49e71ed198e3f4ab0ec..8442ac525d32509eb7b8b61f7b036dd7af1b3d81 100644 (file)
@@ -1,5 +1,6 @@
-/*
- * sgen-nursery-allocator.c: Nursery allocation code.
+/**
+ * \file
+ * Nursery allocation code.
  *
  * Copyright 2009-2010 Novell, Inc.
  *           2011 Rodrigo Kumpera
@@ -7,18 +8,7 @@
  * Copyright 2011 Xamarin Inc  (http://www.xamarin.com)
  * Copyright (C) 2012 Xamarin Inc
  *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License 2.0 as published by the Free Software Foundation;
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License 2.0 along with this library; if not, write to the Free
- * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * Licensed under the MIT license. See LICENSE file in the project root for full license information.
  */
 
 /*
@@ -82,10 +72,10 @@ static char *nursery_last_pinned_end = NULL;
 char *sgen_nursery_start;
 char *sgen_nursery_end;
 
-#ifdef USER_CONFIG
+/* good sizes are 512KB-1MB: larger ones increase a lot memzeroing time */
 size_t sgen_nursery_size = (1 << 22);
+/* The number of trailing 0 bits in sgen_nursery_size */
 int sgen_nursery_bits = 22;
-#endif
 
 char *sgen_space_bitmap;
 size_t sgen_space_bitmap_size;
@@ -253,7 +243,7 @@ sgen_fragment_allocator_alloc (void)
                frag->next = frag->next_in_order = NULL;
                return frag;
        }
-       frag = sgen_alloc_internal (INTERNAL_MEM_FRAGMENT);
+       frag = (SgenFragment *)sgen_alloc_internal (INTERNAL_MEM_FRAGMENT);
        frag->next = frag->next_in_order = NULL;
        return frag;
 }
@@ -267,7 +257,7 @@ sgen_fragment_allocator_add (SgenFragmentAllocator *allocator, char *start, char
        fragment->fragment_start = start;
        fragment->fragment_next = start;
        fragment->fragment_end = end;
-       fragment->next_in_order = fragment->next = unmask (allocator->region_head);
+       fragment->next_in_order = fragment->next = (SgenFragment *)unmask (allocator->region_head);
 
        allocator->region_head = allocator->alloc_head = fragment;
        g_assert (fragment->fragment_end > fragment->fragment_start);
@@ -304,7 +294,7 @@ try_again:
                printf ("retry count for fppf is %d\n", count);
 #endif
 
-       cur = unmask (*prev);
+       cur = (SgenFragment *)unmask (*prev);
 
        while (1) {
                if (cur == NULL)
@@ -326,14 +316,14 @@ try_again:
                                return prev;
                        prev = &cur->next;
                } else {
-                       next = unmask (next);
+                       next = (SgenFragment *)unmask (next);
                        if (InterlockedCompareExchangePointer ((volatile gpointer*)prev, next, cur) != cur)
                                goto try_again;
                        /*we must make sure that the next from cur->next happens after*/
                        mono_memory_write_barrier ();
                }
 
-               cur = unmask (next);
+               cur = (SgenFragment *)unmask (next);
        }
        return NULL;
 }
@@ -375,7 +365,7 @@ par_alloc_from_fragment (SgenFragmentAllocator *allocator, SgenFragment *frag, s
                 */
                if ((sgen_get_nursery_clear_policy () == CLEAR_AT_TLAB_CREATION || sgen_get_nursery_clear_policy () == CLEAR_AT_TLAB_CREATION_DEBUG) && claim_remaining_size (frag, end)) {
                        sgen_clear_range (end, frag->fragment_end);
-                       HEAVY_STAT (InterlockedExchangeAdd (&stat_wasted_bytes_trailer, frag->fragment_end - end));
+                       HEAVY_STAT (stat_wasted_bytes_trailer += frag->fragment_end - end);
 #ifdef NALLOC_DEBUG
                        add_alloc_record (end, frag->fragment_end - end, BLOCK_ZEROING);
 #endif
@@ -448,13 +438,13 @@ sgen_fragment_allocator_par_alloc (SgenFragmentAllocator *allocator, size_t size
 #endif
 
 restart:
-       for (frag = unmask (allocator->alloc_head); unmask (frag); frag = unmask (frag->next)) {
-               HEAVY_STAT (InterlockedIncrement (&stat_alloc_iterations));
+       for (frag = (SgenFragment *)unmask (allocator->alloc_head); unmask (frag); frag = (SgenFragment *)unmask (frag->next)) {
+               HEAVY_STAT (++stat_alloc_iterations);
 
                if (size <= (size_t)(frag->fragment_end - frag->fragment_next)) {
                        void *p = par_alloc_from_fragment (allocator, frag, size);
                        if (!p) {
-                               HEAVY_STAT (InterlockedIncrement (&stat_alloc_retries));
+                               HEAVY_STAT (++stat_alloc_retries);
                                goto restart;
                        }
 #ifdef NALLOC_DEBUG
@@ -478,9 +468,9 @@ sgen_fragment_allocator_serial_alloc (SgenFragmentAllocator *allocator, size_t s
        previous = &allocator->alloc_head;
 
        for (frag = *previous; frag; frag = *previous) {
-               char *p = serial_alloc_from_fragment (previous, frag, size);
+               char *p = (char *)serial_alloc_from_fragment (previous, frag, size);
 
-               HEAVY_STAT (InterlockedIncrement (&stat_alloc_iterations));
+               HEAVY_STAT (++stat_alloc_iterations);
 
                if (p) {
 #ifdef NALLOC_DEBUG
@@ -508,7 +498,7 @@ sgen_fragment_allocator_serial_range_alloc (SgenFragmentAllocator *allocator, si
        for (frag = *previous; frag; frag = *previous) {
                size_t frag_size = frag->fragment_end - frag->fragment_next;
 
-               HEAVY_STAT (InterlockedIncrement (&stat_alloc_range_iterations));
+               HEAVY_STAT (++stat_alloc_range_iterations);
 
                if (desired_size <= frag_size) {
                        void *p;
@@ -558,10 +548,10 @@ restart:
        InterlockedIncrement (&alloc_count);
 #endif
 
-       for (frag = unmask (allocator->alloc_head); frag; frag = unmask (frag->next)) {
+       for (frag = (SgenFragment *)unmask (allocator->alloc_head); frag; frag = (SgenFragment *)unmask (frag->next)) {
                size_t frag_size = frag->fragment_end - frag->fragment_next;
 
-               HEAVY_STAT (InterlockedIncrement (&stat_alloc_range_iterations));
+               HEAVY_STAT (++stat_alloc_range_iterations);
 
                if (desired_size <= frag_size) {
                        void *p;
@@ -569,7 +559,7 @@ restart:
 
                        p = par_alloc_from_fragment (allocator, frag, desired_size);
                        if (!p) {
-                               HEAVY_STAT (InterlockedIncrement (&stat_alloc_range_retries));
+                               HEAVY_STAT (++stat_alloc_range_retries);
                                goto restart;
                        }
 #ifdef NALLOC_DEBUG
@@ -601,7 +591,7 @@ restart:
 
                /*XXX restarting here is quite dubious given this is already second chance allocation. */
                if (!p) {
-                       HEAVY_STAT (InterlockedIncrement (&stat_alloc_retries));
+                       HEAVY_STAT (++stat_alloc_retries);
                        goto restart;
                }
 #ifdef NALLOC_DEBUG
@@ -618,7 +608,7 @@ sgen_clear_allocator_fragments (SgenFragmentAllocator *allocator)
 {
        SgenFragment *frag;
 
-       for (frag = unmask (allocator->alloc_head); frag; frag = unmask (frag->next)) {
+       for (frag = (SgenFragment *)unmask (allocator->alloc_head); frag; frag = (SgenFragment *)unmask (frag->next)) {
                SGEN_LOG (4, "Clear nursery frag %p-%p", frag->fragment_next, frag->fragment_end);
                sgen_clear_range (frag->fragment_next, frag->fragment_end);
 #ifdef NALLOC_DEBUG
@@ -696,7 +686,7 @@ add_nursery_frag (SgenFragmentAllocator *allocator, size_t frag_size, char* frag
        } else {
                /* Clear unused fragments, pinning depends on this */
                sgen_clear_range (frag_start, frag_end);
-               HEAVY_STAT (InterlockedExchangeAdd (&stat_wasted_bytes_small_areas, frag_size));
+               HEAVY_STAT (stat_wasted_bytes_small_areas += frag_size);
        }
 }
 
@@ -747,13 +737,13 @@ sgen_build_nursery_fragments (GCMemSection *nursery_section, SgenGrayQueue *unpi
 
                addr0 = addr1 = sgen_nursery_end;
                if (pin_entry < pin_end)
-                       addr0 = *pin_entry;
+                       addr0 = (char *)*pin_entry;
                if (frags_ranges)
                        addr1 = frags_ranges->fragment_start;
 
                if (addr0 < addr1) {
                        if (unpin_queue)
-                               GRAY_OBJECT_ENQUEUE (unpin_queue, addr0, sgen_obj_get_descriptor_safe (addr0));
+                               GRAY_OBJECT_ENQUEUE_SERIAL (unpin_queue, (GCObject*)addr0, sgen_obj_get_descriptor_safe ((GCObject*)addr0));
                        else
                                SGEN_UNPIN_OBJECT (addr0);
                        size = SGEN_ALIGN_UP (sgen_safe_object_get_size ((GCObject*)addr0));
@@ -802,25 +792,18 @@ sgen_build_nursery_fragments (GCMemSection *nursery_section, SgenGrayQueue *unpi
        if (!unmask (mutator_allocator.alloc_head)) {
                SGEN_LOG (1, "Nursery fully pinned");
                for (pin_entry = pin_start; pin_entry < pin_end; ++pin_entry) {
-                       void *p = *pin_entry;
+                       GCObject *p = (GCObject *)*pin_entry;
                        SGEN_LOG (3, "Bastard pinning obj %p (%s), size: %zd", p, sgen_client_vtable_get_name (SGEN_LOAD_VTABLE (p)), sgen_safe_object_get_size (p));
                }
        }
        return fragment_total;
 }
 
-char *
-sgen_nursery_alloc_get_upper_alloc_bound (void)
-{
-       /*FIXME we need to calculate the collector upper bound as well, but this must be done in the previous GC. */
-       return sgen_nursery_end;
-}
-
 /*** Nursery memory allocation ***/
 void
 sgen_nursery_retire_region (void *address, ptrdiff_t size)
 {
-       HEAVY_STAT (InterlockedExchangeAdd (&stat_wasted_bytes_discarded_fragments, size));
+       HEAVY_STAT (stat_wasted_bytes_discarded_fragments += size);
 }
 
 gboolean
@@ -833,7 +816,7 @@ sgen_can_alloc_size (size_t size)
 
        size = SGEN_ALIGN_UP (size);
 
-       for (frag = unmask (mutator_allocator.alloc_head); frag; frag = unmask (frag->next)) {
+       for (frag = (SgenFragment *)unmask (mutator_allocator.alloc_head); frag; frag = (SgenFragment *)unmask (frag->next)) {
                if ((size_t)(frag->fragment_end - frag->fragment_next) >= size)
                        return TRUE;
        }
@@ -848,7 +831,7 @@ sgen_nursery_alloc (size_t size)
        SGEN_LOG (4, "Searching nursery for size: %zd", size);
        size = SGEN_ALIGN_UP (size);
 
-       HEAVY_STAT (InterlockedIncrement (&stat_nursery_alloc_requests));
+       HEAVY_STAT (++stat_nursery_alloc_requests);
 
        return sgen_fragment_allocator_par_alloc (&mutator_allocator, size);
 }
@@ -858,7 +841,7 @@ sgen_nursery_alloc_range (size_t desired_size, size_t minimum_size, size_t *out_
 {
        SGEN_LOG (4, "Searching for byte range desired size: %zd minimum size %zd", desired_size, minimum_size);
 
-       HEAVY_STAT (InterlockedIncrement (&stat_nursery_alloc_range_requests));
+       HEAVY_STAT (++stat_nursery_alloc_range_requests);
 
        return sgen_fragment_allocator_par_range_alloc (&mutator_allocator, desired_size, minimum_size, out_alloc_size);
 }
@@ -918,7 +901,7 @@ sgen_nursery_allocator_set_nursery_bounds (char *start, char *end)
         * since the nursery size must be a power of 2.
         */
        sgen_space_bitmap_size = (end - start + SGEN_TO_SPACE_GRANULE_IN_BYTES * 8 - 1) / (SGEN_TO_SPACE_GRANULE_IN_BYTES * 8);
-       sgen_space_bitmap = g_malloc0 (sgen_space_bitmap_size);
+       sgen_space_bitmap = (char *)g_malloc0 (sgen_space_bitmap_size);
 
        /* Setup the single first large fragment */
        sgen_minor_collector.init_nursery (&mutator_allocator, start, end);