/*
- * 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
#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;
* Debug reporting.
*/
void
-mono_sgen_report_pinned_mem_usage (SgenPinnedAllocator *alc)
+sgen_report_pinned_mem_usage (SgenPinnedAllocator *alc)
{
SgenPinnedChunk *chunk;
int i = 0;
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;
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;
/* 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;
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 */
}
void
-mono_sgen_free_pinned (SgenPinnedAllocator *alc, void *addr, size_t size)
+sgen_free_pinned (SgenPinnedAllocator *alc, void *addr, size_t size)
{
LargePinnedMemHeader *mh;
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]));
}
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;
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 */
}
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);
}
}
}
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);