X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Fmetadata%2Fsgen-los.c;h=b273a5ab822bd0cf5f35c3a3590f6c5836723fff;hb=157cb97206f627685c15410953d2767146f6e426;hp=c00611469abff28ce578593e461096a8947cfdbf;hpb=4d84028bd8d48b06a1858854715145e44378e6bd;p=mono.git diff --git a/mono/metadata/sgen-los.c b/mono/metadata/sgen-los.c index c00611469ab..b273a5ab822 100644 --- a/mono/metadata/sgen-los.c +++ b/mono/metadata/sgen-los.c @@ -1,5 +1,5 @@ /* - * sgen-los.c: Simple generational GC. + * sgen-los.c: Large objects space. * * Author: * Paolo Molaro (lupus@ximian.com) @@ -11,38 +11,22 @@ * 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. - * - * 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. - * - * * Copyright 2001-2003 Ximian, Inc * Copyright 2003-2010 Novell, Inc. + * Copyright (C) 2012 Xamarin 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: + * 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; * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. + * 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. * - * 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" @@ -94,7 +78,6 @@ static LOSSection *los_sections = NULL; static LOSFreeChunks *los_fast_free_lists [LOS_NUM_FAST_SIZES]; /* 0 is for larger sizes */ static mword los_num_objects = 0; static int los_num_sections = 0; -static mword next_los_collection = 2*1024*1024; /* 2 MB, need to tune */ //#define USE_MALLOC //#define LOS_CONSISTENCY_CHECK @@ -245,7 +228,7 @@ get_los_section_memory (size_t size) if (!sgen_memgov_try_alloc_space (LOS_SECTION_SIZE, SPACE_LOS)) return NULL; - section = sgen_alloc_os_memory_aligned (LOS_SECTION_SIZE, LOS_SECTION_SIZE, TRUE); + section = sgen_alloc_os_memory_aligned (LOS_SECTION_SIZE, LOS_SECTION_SIZE, SGEN_ALLOC_HEAP | SGEN_ALLOC_ACTIVATE, NULL); if (!section) return NULL; @@ -309,7 +292,7 @@ sgen_los_free_object (LOSObject *obj) { #ifndef LOS_DUMMY size_t size = obj->size; - DEBUG (4, fprintf (gc_debug_file, "Freed large object %p, size %lu\n", obj->data, (unsigned long)obj->size)); + SGEN_LOG (4, "Freed large object %p, size %lu", obj->data, (unsigned long)obj->size); binary_protocol_empty (obj->data, obj->size); los_memory_usage -= size; @@ -324,7 +307,7 @@ sgen_los_free_object (LOSObject *obj) size += sizeof (LOSObject); size += pagesize - 1; size &= ~(pagesize - 1); - sgen_free_os_memory (obj, size); + sgen_free_os_memory (obj, size, SGEN_ALLOC_HEAP); sgen_memgov_release_space (size, SPACE_LOS); } else { free_los_section_memory (obj, size + sizeof (LOSObject)); @@ -349,10 +332,11 @@ sgen_los_alloc_large_inner (MonoVTable *vtable, size_t size) void **vtslot; g_assert (size > SGEN_MAX_SMALL_OBJ_SIZE); + g_assert ((size & 1) == 0); #ifdef LOS_DUMMY if (!los_segment) - los_segment = sgen_alloc_os_memory (LOS_SEGMENT_SIZE, TRUE); + los_segment = sgen_alloc_os_memory (LOS_SEGMENT_SIZE, SGEN_ALLOC_HEAP | SGEN_ALLOC_ACTIVATE, NULL); los_segment_index = ALIGN_UP (los_segment_index); obj = (LOSObject*)(los_segment + los_segment_index); @@ -373,9 +357,7 @@ sgen_los_alloc_large_inner (MonoVTable *vtable, size_t size) alloc_size += pagesize - 1; alloc_size &= ~(pagesize - 1); if (sgen_memgov_try_alloc_space (alloc_size, SPACE_LOS)) { - obj = sgen_alloc_os_memory (alloc_size, TRUE); - if (obj) - obj->huge_object = TRUE; + obj = sgen_alloc_os_memory (alloc_size, SGEN_ALLOC_HEAP | SGEN_ALLOC_ACTIVATE, NULL); } } else { obj = get_los_section_memory (size + sizeof (LOSObject)); @@ -395,7 +377,7 @@ sgen_los_alloc_large_inner (MonoVTable *vtable, size_t size) los_object_list = obj; los_memory_usage += size; los_num_objects++; - DEBUG (4, fprintf (gc_debug_file, "Allocated large object %p, vtable: %p (%s), size: %zd\n", obj->data, vtable, vtable->klass->name, size)); + SGEN_LOG (4, "Allocated large object %p, vtable: %p (%s), size: %zd", obj->data, vtable, vtable->klass->name, size); binary_protocol_alloc (obj->data, vtable, size); #ifdef LOS_CONSISTENCY_CHECK @@ -424,7 +406,7 @@ sgen_los_sweep (void) prev->next = next; else los_sections = next; - sgen_free_os_memory (section, LOS_SECTION_SIZE); + sgen_free_os_memory (section, LOS_SECTION_SIZE, SGEN_ALLOC_HEAP); sgen_memgov_release_space (LOS_SECTION_SIZE, SPACE_LOS); section = next; --los_num_sections; @@ -510,23 +492,29 @@ mono_sgen_los_describe_pointer (char *ptr) for (obj = los_object_list; obj; obj = obj->next) { MonoVTable *vtable; + const char *los_kind; + mword size; + gboolean pinned; + if (obj->data > ptr || obj->data + obj->size <= ptr) continue; - if (obj->size > LOS_SECTION_OBJECT_LIMIT) - fprintf (gc_debug_file, "huge-los-ptr "); + size = sgen_los_object_size (obj); + pinned = sgen_los_object_is_pinned (obj->data); + + if (size > LOS_SECTION_OBJECT_LIMIT) + los_kind = "huge-los-ptr"; else - fprintf (gc_debug_file, "los-ptr "); + los_kind = "los-ptr"; vtable = (MonoVTable*)SGEN_LOAD_VTABLE (obj->data); - if (obj->data == ptr) - fprintf (gc_debug_file, "(object %s.%s size %d)", - vtable->klass->name_space, vtable->klass->name, (int)obj->size); - else - fprintf (gc_debug_file, "(interior-ptr offset %td of %p (%s.%s) size %d)", - ptr - obj->data, obj->data, - vtable->klass->name_space, vtable->klass->name, (int)obj->size); + if (obj->data == ptr) { + SGEN_LOG (0, "%s (size %td pin %d)\n", los_kind, size, pinned ? 1 : 0); + } else { + SGEN_LOG (0, "%s (interior-ptr offset %td size %td pin %d)", + los_kind, ptr - obj->data, size, pinned ? 1 : 0); + } return TRUE; } @@ -544,16 +532,65 @@ sgen_los_iterate_live_block_ranges (sgen_cardtable_block_callback callback) } } -#ifdef SGEN_HAVE_CARDTABLE void -sgen_los_scan_card_table (SgenGrayQueue *queue) +sgen_los_scan_card_table (gboolean mod_union, SgenGrayQueue *queue) { LOSObject *obj; for (obj = los_object_list; obj; obj = obj->next) { - sgen_cardtable_scan_object (obj->data, obj->size, NULL, queue); + guint8 *cards = NULL; + if (mod_union) { + cards = obj->cardtable_mod_union; + g_assert (cards); + } + + sgen_cardtable_scan_object (obj->data, obj->size, cards, mod_union, queue); } } -#endif + +void +sgen_los_update_cardtable_mod_union (void) +{ + LOSObject *obj; + + for (obj = los_object_list; obj; obj = obj->next) { + obj->cardtable_mod_union = sgen_card_table_update_mod_union (obj->cardtable_mod_union, + obj->data, obj->size, NULL); + } +} + +mword +sgen_los_object_size (LOSObject *obj) +{ + return obj->size & ~1L; +} + +LOSObject* +sgen_los_header_for_object (char *data) +{ + return (LOSObject*)(data - sizeof (LOSObject)); +} + +void +sgen_los_pin_object (char *data) +{ + LOSObject *obj = sgen_los_header_for_object (data); + obj->size = obj->size | 1; + binary_protocol_pin (data, (gpointer)SGEN_LOAD_VTABLE (data), sgen_safe_object_get_size ((MonoObject*)data)); +} + +void +sgen_los_unpin_object (char *data) +{ + LOSObject *obj = sgen_los_header_for_object (data); + obj->size = sgen_los_object_size (obj); +} + +gboolean +sgen_los_object_is_pinned (char *data) +{ + LOSObject *obj = sgen_los_header_for_object (data); + return obj->size & 1; +} #endif /* HAVE_SGEN_GC */