Merge pull request #495 from nicolas-raoul/fix-for-issue2907-with-no-formatting-changes
[mono.git] / mono / metadata / sgen-pinned-allocator.c
index 3be32c0213deee1c90b63f75a7c147d09790e5a9..275e750cb305cab96f5cbdc666c38a101b21d2d0 100644 (file)
@@ -1,5 +1,6 @@
 /*
- * sgen-pinned-allocator.c: Simple generational GC.
+ * sgen-pinned-allocator.c: Allocator for small pinned objects.
+ * Only used in the copying major collector.
  *
  * Author:
  *     Paolo Molaro (lupus@ximian.com)
  * Copyright (c) 1996 by Silicon Graphics.  All rights reserved.
  * Copyright (c) 1998 by Fergus Henderson.  All rights reserved.
  * Copyright (c) 2000-2004 by Hewlett-Packard Company.  All rights reserved.
+ * Copyright 2001-2003 Ximian, Inc
+ * Copyright 2003-2010 Novell, Inc.
+ * Copyright (C) 2012 Xamarin Inc
  *
- * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED
- * OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
- *
- * Permission is hereby granted to use or copy this program
- * for any purpose,  provided the above notices are retained on all copies.
- * Permission to modify the code and to distribute modified code is granted,
- * provided the above notices are retained, and a notice that the code was
- * modified is included with the above copyright notice.
+ * 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.
  *
- * Copyright 2001-2003 Ximian, Inc
- * Copyright 2003-2010 Novell, Inc.
- * 
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sublicense, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- * 
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
- * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
- * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
- * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ * 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.
  */
 
+#include "config.h"
+
 #ifdef HAVE_SGEN_GC
 
 #include "utils/mono-counters.h"
 #include "metadata/sgen-gc.h"
+#include "metadata/sgen-memory-governor.h"
 
 /* Pinned objects are allocated in the LOS space if bigger than half a page
  * or from freelists otherwise. We assume that pinned objects are relatively few
@@ -108,6 +96,8 @@ static const int freelist_sizes [] = {
 
 #define LARGE_PINNED_MEM_HEADER_MAGIC  0x7d289f3a
 
+/* FIXME: Do we even need these anymore?  Large objects are always
+   allocated in the LOS. */
 typedef struct _LargePinnedMemHeader LargePinnedMemHeader;
 struct _LargePinnedMemHeader {
        guint32 magic;
@@ -155,7 +145,7 @@ report_pinned_chunk (SgenPinnedChunk *chunk, int seq) {
  * Debug reporting.
  */
 void
-mono_sgen_report_pinned_mem_usage (SgenPinnedAllocator *alc)
+sgen_report_pinned_mem_usage (SgenPinnedAllocator *alc)
 {
        SgenPinnedChunk *chunk;
        int i = 0;
@@ -214,10 +204,10 @@ alloc_pinned_chunk (SgenPinnedAllocator *alc)
        int offset;
        int size = SGEN_PINNED_CHUNK_SIZE;
 
-       chunk = mono_sgen_alloc_os_memory_aligned (size, size, TRUE);
+       chunk = sgen_alloc_os_memory_aligned (size, size, SGEN_ALLOC_HEAP | SGEN_ALLOC_ACTIVATE, "pinned chunk");
        chunk->block.role = MEMORY_ROLE_PINNED;
 
-       mono_sgen_update_heap_boundaries ((mword)chunk, ((mword)chunk + size));
+       sgen_update_heap_boundaries ((mword)chunk, ((mword)chunk + size));
 
        pinned_chunk_bytes_alloced += size;
 
@@ -236,7 +226,7 @@ alloc_pinned_chunk (SgenPinnedAllocator *alc)
        chunk->page_sizes [0] = PINNED_FIRST_SLOT_SIZE;
        build_freelist (alc, chunk, slot_for_size (PINNED_FIRST_SLOT_SIZE), PINNED_FIRST_SLOT_SIZE,
                        chunk->start_data, ((char*)chunk + FREELIST_PAGESIZE));
-       mono_sgen_debug_printf (4, "Allocated pinned chunk %p, size: %d\n", chunk, size);
+       SGEN_LOG (4, "Allocated pinned chunk %p, size: %d", chunk, size);
 
        chunk->block.next = alc->chunk_list;
        alc->chunk_list = chunk;
@@ -315,7 +305,7 @@ alloc_from_slot (SgenPinnedAllocator *alc, int slot)
 
 /* used for the GC-internal data structures */
 void*
-mono_sgen_alloc_pinned (SgenPinnedAllocator *alc, size_t size)
+sgen_alloc_pinned (SgenPinnedAllocator *alc, size_t size)
 {
        int slot;
        void *res = NULL;
@@ -326,7 +316,7 @@ mono_sgen_alloc_pinned (SgenPinnedAllocator *alc, size_t size)
                LargePinnedMemHeader *mh;
 
                size += sizeof (LargePinnedMemHeader);
-               mh = mono_sgen_alloc_os_memory (size, TRUE);
+               mh = sgen_alloc_os_memory (size, SGEN_ALLOC_HEAP | SGEN_ALLOC_ACTIVATE, "large pinned object");
                mh->magic = LARGE_PINNED_MEM_HEADER_MAGIC;
                mh->size = size;
                /* FIXME: do a CAS here */
@@ -362,7 +352,7 @@ free_from_slot (SgenPinnedAllocator *alc, void *addr, int slot)
 }
 
 void
-mono_sgen_free_pinned (SgenPinnedAllocator *alc, void *addr, size_t size)
+sgen_free_pinned (SgenPinnedAllocator *alc, void *addr, size_t size)
 {
        LargePinnedMemHeader *mh;
 
@@ -380,11 +370,11 @@ mono_sgen_free_pinned (SgenPinnedAllocator *alc, void *addr, size_t size)
        g_assert (mh->size == size + sizeof (LargePinnedMemHeader));
        /* FIXME: do a CAS */
        large_pinned_bytes_alloced -= mh->size;
-       mono_sgen_free_os_memory (mh, mh->size);
+       sgen_free_os_memory (mh, mh->size, SGEN_ALLOC_HEAP);
 }
 
 void
-mono_sgen_init_pinned_allocator (void)
+sgen_init_pinned_allocator (void)
 {
        g_assert (SGEN_PINNED_FREELIST_NUM_SLOTS == sizeof (freelist_sizes) / sizeof (freelist_sizes [0]));
 
@@ -394,7 +384,7 @@ mono_sgen_init_pinned_allocator (void)
 }
 
 void
-mono_sgen_pinned_scan_objects (SgenPinnedAllocator *alc, IterateObjectCallbackFunc callback, void *callback_data)
+sgen_pinned_scan_objects (SgenPinnedAllocator *alc, IterateObjectCallbackFunc callback, void *callback_data)
 {
        SgenPinnedChunk *chunk;
        int i, obj_size;
@@ -403,14 +393,14 @@ mono_sgen_pinned_scan_objects (SgenPinnedAllocator *alc, IterateObjectCallbackFu
        void *end_chunk;
        for (chunk = alc->chunk_list; chunk; chunk = chunk->block.next) {
                end_chunk = (char*)chunk + chunk->num_pages * FREELIST_PAGESIZE;
-               mono_sgen_debug_printf (6, "Scanning pinned chunk %p (range: %p-%p)\n", chunk, chunk->start_data, end_chunk);
+               SGEN_LOG (6, "Scanning pinned chunk %p (range: %p-%p)", chunk, chunk->start_data, end_chunk);
                for (i = 0; i < chunk->num_pages; ++i) {
                        obj_size = chunk->page_sizes [i];
                        if (!obj_size)
                                continue;
                        p = i? (char*)chunk + i * FREELIST_PAGESIZE: chunk->start_data;
                        endp = i? p + FREELIST_PAGESIZE: (char*)chunk + FREELIST_PAGESIZE;
-                       mono_sgen_debug_printf (6, "Page %d (size: %d, range: %p-%p)\n", i, obj_size, p, endp);
+                       SGEN_LOG (6, "Page %d (size: %d, range: %p-%p)", i, obj_size, p, endp);
                        while (p + obj_size <= endp) {
                                ptr = (void**)p;
                                /* if the first word (the vtable) is outside the chunk we have an object */
@@ -423,12 +413,12 @@ mono_sgen_pinned_scan_objects (SgenPinnedAllocator *alc, IterateObjectCallbackFu
 }
 
 void
-mono_sgen_pinned_update_heap_boundaries (SgenPinnedAllocator *alc)
+sgen_pinned_update_heap_boundaries (SgenPinnedAllocator *alc)
 {
        SgenPinnedChunk *chunk;
        for (chunk = alc->chunk_list; chunk; chunk = chunk->block.next) {
                char *end_chunk = (char*)chunk + chunk->num_pages * FREELIST_PAGESIZE;
-               mono_sgen_update_heap_boundaries ((mword)chunk, (mword)end_chunk);
+               sgen_update_heap_boundaries ((mword)chunk, (mword)end_chunk);
        }
 }
 
@@ -475,15 +465,15 @@ mark_pinned_from_addresses (SgenPinnedChunk *chunk, void **start, void **end, It
 }
 
 void
-mono_sgen_pinned_scan_pinned_objects (SgenPinnedAllocator *alc, IterateObjectCallbackFunc callback, void *callback_data)
+sgen_pinned_scan_pinned_objects (SgenPinnedAllocator *alc, IterateObjectCallbackFunc callback, void *callback_data)
 {
        SgenPinnedChunk *chunk;
 
        /* look for pinned addresses for pinned-alloc objects */
-       mono_sgen_debug_printf (6, "Pinning from pinned-alloc objects\n");
+       SGEN_LOG (6, "Pinning from pinned-alloc objects");
        for (chunk = alc->chunk_list; chunk; chunk = chunk->block.next) {
                int num_pinned;
-               void **pinned = mono_sgen_find_optimized_pin_queue_area (chunk->start_data,
+               void **pinned = sgen_find_optimized_pin_queue_area (chunk->start_data,
                                (char*)chunk + chunk->num_pages * FREELIST_PAGESIZE, &num_pinned);
                if (num_pinned)
                        mark_pinned_from_addresses (chunk, pinned, pinned + num_pinned, callback, callback_data);