Imported Upstream version 4.3.2.467

Former-commit-id: 9c2cb47f45fa221e661ab616387c9cda183f283d
This commit is contained in:
Xamarin Public Jenkins
2016-02-22 11:00:01 -05:00
parent f302175246
commit f3e3aab35a
4097 changed files with 122406 additions and 82300 deletions

View File

@@ -32,6 +32,7 @@ monosgen_sources = \
sgen-fin-weak-hash.c \
sgen-gc.c \
sgen-gc.h \
sgen-gchandles.c \
sgen-gray.c \
sgen-gray.h \
sgen-hash-table.c \

View File

@@ -105,6 +105,7 @@ am__objects_1 = libmonosgen_static_la-sgen-alloc.lo \
libmonosgen_static_la-sgen-descriptor.lo \
libmonosgen_static_la-sgen-fin-weak-hash.lo \
libmonosgen_static_la-sgen-gc.lo \
libmonosgen_static_la-sgen-gchandles.lo \
libmonosgen_static_la-sgen-gray.lo \
libmonosgen_static_la-sgen-hash-table.lo \
libmonosgen_static_la-sgen-internal.lo \
@@ -139,7 +140,8 @@ am__objects_3 = libmonosgen_la-sgen-alloc.lo \
libmonosgen_la-sgen-cardtable.lo libmonosgen_la-sgen-debug.lo \
libmonosgen_la-sgen-descriptor.lo \
libmonosgen_la-sgen-fin-weak-hash.lo libmonosgen_la-sgen-gc.lo \
libmonosgen_la-sgen-gray.lo libmonosgen_la-sgen-hash-table.lo \
libmonosgen_la-sgen-gchandles.lo libmonosgen_la-sgen-gray.lo \
libmonosgen_la-sgen-hash-table.lo \
libmonosgen_la-sgen-internal.lo \
libmonosgen_la-sgen-layout-stats.lo libmonosgen_la-sgen-los.lo \
libmonosgen_la-sgen-marksweep.lo \
@@ -231,8 +233,6 @@ AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
BOEHM_DEFINES = @BOEHM_DEFINES@
BUILD_EXEEXT = @BUILD_EXEEXT@
BUILD_GLIB_CFLAGS = @BUILD_GLIB_CFLAGS@
BUILD_GLIB_LIBS = @BUILD_GLIB_LIBS@
CC = @CC@
CCAS = @CCAS@
CCASDEPMODE = @CCASDEPMODE@
@@ -248,9 +248,9 @@ CXXCPP = @CXXCPP@
CXXDEPMODE = @CXXDEPMODE@
CXXFLAGS = @CXXFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFAULT_PROFILE = @DEFAULT_PROFILE@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
DISABLE_SHARED_HANDLES = @DISABLE_SHARED_HANDLES@
DLLTOOL = @DLLTOOL@
DOLT_BASH = @DOLT_BASH@
DSYMUTIL = @DSYMUTIL@
@@ -268,8 +268,6 @@ GDKX11 = @GDKX11@
GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@
GLIB_CFLAGS = @GLIB_CFLAGS@
GLIB_LIBS = @GLIB_LIBS@
GMODULE_CFLAGS = @GMODULE_CFLAGS@
GMODULE_LIBS = @GMODULE_LIBS@
GMSGFMT = @GMSGFMT@
GMSGFMT_015 = @GMSGFMT_015@
GREP = @GREP@
@@ -448,6 +446,7 @@ monosgen_sources = \
sgen-fin-weak-hash.c \
sgen-gc.c \
sgen-gc.h \
sgen-gchandles.c \
sgen-gray.c \
sgen-gray.h \
sgen-hash-table.c \
@@ -553,6 +552,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libmonosgen_la-sgen-descriptor.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libmonosgen_la-sgen-fin-weak-hash.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libmonosgen_la-sgen-gc.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libmonosgen_la-sgen-gchandles.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libmonosgen_la-sgen-gray.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libmonosgen_la-sgen-hash-table.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libmonosgen_la-sgen-internal.Plo@am__quote@
@@ -576,6 +576,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libmonosgen_static_la-sgen-descriptor.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libmonosgen_static_la-sgen-fin-weak-hash.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libmonosgen_static_la-sgen-gc.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libmonosgen_static_la-sgen-gchandles.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libmonosgen_static_la-sgen-gray.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libmonosgen_static_la-sgen-hash-table.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libmonosgen_static_la-sgen-internal.Plo@am__quote@
@@ -660,6 +661,13 @@ libmonosgen_static_la-sgen-gc.lo: sgen-gc.c
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libmonosgen_static_la_CFLAGS) $(CFLAGS) -c -o libmonosgen_static_la-sgen-gc.lo `test -f 'sgen-gc.c' || echo '$(srcdir)/'`sgen-gc.c
libmonosgen_static_la-sgen-gchandles.lo: sgen-gchandles.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libmonosgen_static_la_CFLAGS) $(CFLAGS) -MT libmonosgen_static_la-sgen-gchandles.lo -MD -MP -MF $(DEPDIR)/libmonosgen_static_la-sgen-gchandles.Tpo -c -o libmonosgen_static_la-sgen-gchandles.lo `test -f 'sgen-gchandles.c' || echo '$(srcdir)/'`sgen-gchandles.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libmonosgen_static_la-sgen-gchandles.Tpo $(DEPDIR)/libmonosgen_static_la-sgen-gchandles.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='sgen-gchandles.c' object='libmonosgen_static_la-sgen-gchandles.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libmonosgen_static_la_CFLAGS) $(CFLAGS) -c -o libmonosgen_static_la-sgen-gchandles.lo `test -f 'sgen-gchandles.c' || echo '$(srcdir)/'`sgen-gchandles.c
libmonosgen_static_la-sgen-gray.lo: sgen-gray.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libmonosgen_static_la_CFLAGS) $(CFLAGS) -MT libmonosgen_static_la-sgen-gray.lo -MD -MP -MF $(DEPDIR)/libmonosgen_static_la-sgen-gray.Tpo -c -o libmonosgen_static_la-sgen-gray.lo `test -f 'sgen-gray.c' || echo '$(srcdir)/'`sgen-gray.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libmonosgen_static_la-sgen-gray.Tpo $(DEPDIR)/libmonosgen_static_la-sgen-gray.Plo
@@ -821,6 +829,13 @@ libmonosgen_la-sgen-gc.lo: sgen-gc.c
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libmonosgen_la_CFLAGS) $(CFLAGS) -c -o libmonosgen_la-sgen-gc.lo `test -f 'sgen-gc.c' || echo '$(srcdir)/'`sgen-gc.c
libmonosgen_la-sgen-gchandles.lo: sgen-gchandles.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libmonosgen_la_CFLAGS) $(CFLAGS) -MT libmonosgen_la-sgen-gchandles.lo -MD -MP -MF $(DEPDIR)/libmonosgen_la-sgen-gchandles.Tpo -c -o libmonosgen_la-sgen-gchandles.lo `test -f 'sgen-gchandles.c' || echo '$(srcdir)/'`sgen-gchandles.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libmonosgen_la-sgen-gchandles.Tpo $(DEPDIR)/libmonosgen_la-sgen-gchandles.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='sgen-gchandles.c' object='libmonosgen_la-sgen-gchandles.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libmonosgen_la_CFLAGS) $(CFLAGS) -c -o libmonosgen_la-sgen-gchandles.lo `test -f 'sgen-gchandles.c' || echo '$(srcdir)/'`sgen-gchandles.c
libmonosgen_la-sgen-gray.lo: sgen-gray.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libmonosgen_la_CFLAGS) $(CFLAGS) -MT libmonosgen_la-sgen-gray.lo -MD -MP -MF $(DEPDIR)/libmonosgen_la-sgen-gray.Tpo -c -o libmonosgen_la-sgen-gray.lo `test -f 'sgen-gray.c' || echo '$(srcdir)/'`sgen-gray.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libmonosgen_la-sgen-gray.Tpo $(DEPDIR)/libmonosgen_la-sgen-gray.Plo

View File

@@ -31,6 +31,47 @@
#include "mono/sgen/sgen-conf.h"
#endif
/* h indicates whether to hide or just tag.
* (-!!h ^ p) is used instead of (h ? ~p : p) to avoid multiple mentions of p.
*/
#define MONO_GC_HIDE_POINTER(p,t,h) ((gpointer)(((-(size_t)!!(h) ^ (size_t)(p)) & ~(size_t)3) | ((t) & (size_t)3)))
#define MONO_GC_REVEAL_POINTER(p,h) ((gpointer)((-(size_t)!!(h) ^ (size_t)(p)) & ~(size_t)3))
#define MONO_GC_POINTER_TAG(p) ((size_t)(p) & (size_t)3)
#define MONO_GC_HANDLE_OCCUPIED_MASK (1)
#define MONO_GC_HANDLE_VALID_MASK (2)
#define MONO_GC_HANDLE_TAG_MASK (MONO_GC_HANDLE_OCCUPIED_MASK | MONO_GC_HANDLE_VALID_MASK)
#define MONO_GC_HANDLE_METADATA_POINTER(p,h) (MONO_GC_HIDE_POINTER ((p), MONO_GC_HANDLE_OCCUPIED_MASK, (h)))
#define MONO_GC_HANDLE_OBJECT_POINTER(p,h) (MONO_GC_HIDE_POINTER ((p), MONO_GC_HANDLE_OCCUPIED_MASK | MONO_GC_HANDLE_VALID_MASK, (h)))
#define MONO_GC_HANDLE_OCCUPIED(slot) ((size_t)(slot) & MONO_GC_HANDLE_OCCUPIED_MASK)
#define MONO_GC_HANDLE_VALID(slot) ((size_t)(slot) & MONO_GC_HANDLE_VALID_MASK)
#define MONO_GC_HANDLE_TAG(slot) ((size_t)(slot) & MONO_GC_HANDLE_TAG_MASK)
#define MONO_GC_HANDLE_IS_OBJECT_POINTER(slot) (MONO_GC_HANDLE_TAG (slot) == (MONO_GC_HANDLE_OCCUPIED_MASK | MONO_GC_HANDLE_VALID_MASK))
#define MONO_GC_HANDLE_IS_METADATA_POINTER(slot) (MONO_GC_HANDLE_TAG (slot) == MONO_GC_HANDLE_OCCUPIED_MASK)
typedef enum {
HANDLE_TYPE_MIN = 0,
HANDLE_WEAK = HANDLE_TYPE_MIN,
HANDLE_WEAK_TRACK,
HANDLE_NORMAL,
HANDLE_PINNED,
HANDLE_TYPE_MAX
} GCHandleType;
#define GC_HANDLE_TYPE_IS_WEAK(x) ((x) <= HANDLE_WEAK_TRACK)
#define MONO_GC_HANDLE_TYPE_SHIFT (3)
#define MONO_GC_HANDLE_TYPE_MASK ((1 << MONO_GC_HANDLE_TYPE_SHIFT) - 1)
#define MONO_GC_HANDLE_TYPE(x) ((GCHandleType)(((x) & MONO_GC_HANDLE_TYPE_MASK) - 1))
#define MONO_GC_HANDLE_SLOT(x) ((x) >> MONO_GC_HANDLE_TYPE_SHIFT)
#define MONO_GC_HANDLE_TYPE_IS_WEAK(x) ((x) <= HANDLE_WEAK_TRACK)
#define MONO_GC_HANDLE(slot, type) (((slot) << MONO_GC_HANDLE_TYPE_SHIFT) | (((type) & MONO_GC_HANDLE_TYPE_MASK) + 1))
typedef struct {
guint minor_gc_count;
guint major_gc_count;

View File

@@ -196,7 +196,7 @@ sgen_alloc_obj_nolock (GCVTable vtable, size_t size)
*/
if (real_size > SGEN_MAX_SMALL_OBJ_SIZE) {
p = sgen_los_alloc_large_inner (vtable, ALIGN_UP (real_size));
p = (void **)sgen_los_alloc_large_inner (vtable, ALIGN_UP (real_size));
} else {
/* tlab_next and tlab_temp_end are TLS vars so accessing them might be expensive */
@@ -252,7 +252,7 @@ sgen_alloc_obj_nolock (GCVTable vtable, size_t size)
available_in_tlab = (int)(TLAB_REAL_END - TLAB_NEXT);//We'll never have tlabs > 2Gb
if (size > tlab_size || available_in_tlab > SGEN_MAX_NURSERY_WASTE) {
/* Allocate directly from the nursery */
p = sgen_nursery_alloc (size);
p = (void **)sgen_nursery_alloc (size);
if (!p) {
/*
* We couldn't allocate from the nursery, so we try
@@ -273,7 +273,7 @@ sgen_alloc_obj_nolock (GCVTable vtable, size_t size)
*/
sgen_ensure_free_space (real_size);
if (!degraded_mode)
p = sgen_nursery_alloc (size);
p = (void **)sgen_nursery_alloc (size);
}
if (!p)
return alloc_degraded (vtable, size, FALSE);
@@ -285,12 +285,12 @@ sgen_alloc_obj_nolock (GCVTable vtable, size_t size)
SGEN_LOG (3, "Retire TLAB: %p-%p [%ld]", TLAB_START, TLAB_REAL_END, (long)(TLAB_REAL_END - TLAB_NEXT - size));
sgen_nursery_retire_region (p, available_in_tlab);
p = sgen_nursery_alloc_range (tlab_size, size, &alloc_size);
p = (void **)sgen_nursery_alloc_range (tlab_size, size, &alloc_size);
if (!p) {
/* See comment above in similar case. */
sgen_ensure_free_space (tlab_size);
if (!degraded_mode)
p = sgen_nursery_alloc_range (tlab_size, size, &alloc_size);
p = (void **)sgen_nursery_alloc_range (tlab_size, size, &alloc_size);
}
if (!p)
return alloc_degraded (vtable, size, FALSE);
@@ -304,7 +304,7 @@ sgen_alloc_obj_nolock (GCVTable vtable, size_t size)
zero_tlab_if_necessary (TLAB_START, alloc_size);
/* Allocate from the TLAB */
p = (void*)TLAB_NEXT;
p = (void **)TLAB_NEXT;
TLAB_NEXT += size;
sgen_set_nursery_scan_start ((char*)p);
}
@@ -349,7 +349,7 @@ sgen_try_alloc_obj_nolock (GCVTable vtable, size_t size)
if (G_UNLIKELY (size > tlab_size)) {
/* Allocate directly from the nursery */
p = sgen_nursery_alloc (size);
p = (void **)sgen_nursery_alloc (size);
if (!p)
return NULL;
sgen_set_nursery_scan_start ((char*)p);
@@ -380,7 +380,7 @@ sgen_try_alloc_obj_nolock (GCVTable vtable, size_t size)
}
} else if (available_in_tlab > SGEN_MAX_NURSERY_WASTE) {
/* Allocate directly from the nursery */
p = sgen_nursery_alloc (size);
p = (void **)sgen_nursery_alloc (size);
if (!p)
return NULL;
@@ -389,7 +389,7 @@ sgen_try_alloc_obj_nolock (GCVTable vtable, size_t size)
size_t alloc_size = 0;
sgen_nursery_retire_region (p, available_in_tlab);
new_next = sgen_nursery_alloc_range (tlab_size, size, &alloc_size);
new_next = (char *)sgen_nursery_alloc_range (tlab_size, size, &alloc_size);
p = (void**)new_next;
if (!p)
return NULL;
@@ -478,7 +478,7 @@ sgen_alloc_obj_pinned (GCVTable vtable, size_t size)
if (size > SGEN_MAX_SMALL_OBJ_SIZE) {
/* large objects are always pinned anyway */
p = sgen_los_alloc_large_inner (vtable, size);
p = (GCObject *)sgen_los_alloc_large_inner (vtable, size);
} else {
SGEN_ASSERT (9, sgen_client_vtable_is_inited (vtable), "class %s:%s is not initialized", sgen_client_vtable_get_namespace (vtable), sgen_client_vtable_get_name (vtable));
p = major_collector.alloc_small_pinned_obj (vtable, size, SGEN_VTABLE_HAS_REFERENCES (vtable));
@@ -554,9 +554,6 @@ sgen_init_allocator (void)
mono_tls_key_set_offset (TLS_KEY_SGEN_TLAB_NEXT_ADDR, tlab_next_addr_offset);
mono_tls_key_set_offset (TLS_KEY_SGEN_TLAB_TEMP_END, tlab_temp_end_offset);
g_assert (tlab_next_addr_offset != -1);
g_assert (tlab_temp_end_offset != -1);
#endif
#ifdef HEAVY_STATISTICS

View File

@@ -88,8 +88,8 @@
} while (0)
/* MS_BLOCK_SIZE must be a multiple of the system pagesize, which for some
archs is 64k. */
#if defined(TARGET_POWERPC64) && _CALL_ELF == 2
architectures is 64k. */
#if defined(TARGET_POWERPC64)
#define ARCH_MIN_MS_BLOCK_SIZE (64*1024)
#define ARCH_MIN_MS_BLOCK_SIZE_SHIFT 16
#endif

View File

@@ -86,8 +86,8 @@ sgen_card_table_wbarrier_set_field (GCObject *obj, gpointer field_ptr, GCObject*
static void
sgen_card_table_wbarrier_arrayref_copy (gpointer dest_ptr, gpointer src_ptr, int count)
{
gpointer *dest = dest_ptr;
gpointer *src = src_ptr;
gpointer *dest = (gpointer *)dest_ptr;
gpointer *src = (gpointer *)src_ptr;
/*overlapping that required backward copying*/
if (src < dest && (src + count) > dest) {
@@ -284,7 +284,7 @@ sgen_card_table_find_address (char *addr)
static gboolean
sgen_card_table_find_address_with_cards (char *cards_start, guint8 *cards, char *addr)
{
cards_start = sgen_card_table_align_pointer (cards_start);
cards_start = (char *)sgen_card_table_align_pointer (cards_start);
return cards [(addr - cards_start) >> CARD_BITS];
}
@@ -292,15 +292,18 @@ static void
update_mod_union (guint8 *dest, guint8 *start_card, size_t num_cards)
{
int i;
for (i = 0; i < num_cards; ++i)
dest [i] |= start_card [i];
/* Marking from another thread can happen while we mark here */
for (i = 0; i < num_cards; ++i) {
if (start_card [i])
dest [i] = 1;
}
}
guint8*
sgen_card_table_alloc_mod_union (char *obj, mword obj_size)
{
size_t num_cards = sgen_card_table_number_of_cards_in_range ((mword) obj, obj_size);
guint8 *mod_union = sgen_alloc_internal_dynamic (num_cards, INTERNAL_MEM_CARDTABLE_MOD_UNION, TRUE);
guint8 *mod_union = (guint8 *)sgen_alloc_internal_dynamic (num_cards, INTERNAL_MEM_CARDTABLE_MOD_UNION, TRUE);
memset (mod_union, 0, num_cards);
return mod_union;
}
@@ -570,10 +573,10 @@ sgen_card_tables_collect_stats (gboolean begin)
void
sgen_card_table_init (SgenRememberedSet *remset)
{
sgen_cardtable = sgen_alloc_os_memory (CARD_COUNT_IN_BYTES, SGEN_ALLOC_INTERNAL | SGEN_ALLOC_ACTIVATE, "card table");
sgen_cardtable = (guint8 *)sgen_alloc_os_memory (CARD_COUNT_IN_BYTES, (SgenAllocFlags)(SGEN_ALLOC_INTERNAL | SGEN_ALLOC_ACTIVATE), "card table");
#ifdef SGEN_HAVE_OVERLAPPING_CARDS
sgen_shadow_cardtable = sgen_alloc_os_memory (CARD_COUNT_IN_BYTES, SGEN_ALLOC_INTERNAL | SGEN_ALLOC_ACTIVATE, "shadow card table");
sgen_shadow_cardtable = (guint8 *)sgen_alloc_os_memory (CARD_COUNT_IN_BYTES, (SgenAllocFlags)(SGEN_ALLOC_INTERNAL | SGEN_ALLOC_ACTIVATE), "shadow card table");
#endif
#ifdef HEAVY_STATISTICS

View File

@@ -87,6 +87,19 @@ gboolean sgen_client_mark_ephemerons (ScanCopyContext ctx);
*/
void sgen_client_clear_unreachable_ephemerons (ScanCopyContext ctx);
/*
* May return NULL. Must be an aligned pointer.
*/
gpointer sgen_client_default_metadata (void);
gpointer sgen_client_metadata_for_object (GCObject *obj);
/*
* No action required.
*/
void sgen_client_gchandle_created (int handle_type, GCObject *obj, guint32 handle);
void sgen_client_gchandle_destroyed (int handle_type, guint32 handle);
void sgen_client_ensure_weak_gchandles_accessible (void);
/*
* This is called for objects that are larger than one card. If it's possible to scan only
* parts of the object based on which cards are marked, do so and return TRUE. Otherwise,
@@ -272,8 +285,6 @@ void sgen_client_describe_invalid_pointer (GCObject *ptr);
#define BEGIN_PROTOCOL_ENTRY_HEAVY6(method,t1,f1,t2,f2,t3,f3,t4,f4,t5,f5,t6,f6) \
void sgen_client_ ## method (t1 f1, t2 f2, t3 f3, t4 f4, t5 f5, t6 f6);
#define FLUSH()
#define DEFAULT_PRINT()
#define CUSTOM_PRINT(_)
@@ -282,6 +293,7 @@ void sgen_client_describe_invalid_pointer (GCObject *ptr);
#define IS_VTABLE_MATCH(_)
#define END_PROTOCOL_ENTRY
#define END_PROTOCOL_ENTRY_FLUSH
#define END_PROTOCOL_ENTRY_HEAVY
#include "sgen-protocol-def.h"

View File

@@ -185,6 +185,17 @@ typedef mword SgenDescriptor;
#define SGEN_MIN_ALLOWANCE_NURSERY_SIZE_RATIO 1.0
#define SGEN_MAX_ALLOWANCE_NURSERY_SIZE_RATIO 10.0
/*
* How much more we allow the heap to grow before triggering another major collection
*/
#define SGEN_DEFAULT_ALLOWANCE_HEAP_SIZE_RATIO 0.33
/*
* How much more we allow the heap to grow, relative to the allowance, while doing
* a concurrent collection, before forcing its finish.
*/
#define SGEN_DEFAULT_CONCURRENT_HEAP_ALLOWANCE_RATIO 0.25
/*
* Default ratio of memory we want to release in a major collection in relation to the the current heap size.
*

View File

@@ -50,15 +50,15 @@ par_copy_object_no_checks (char *destination, GCVTable vt, void *obj, mword objs
obj = destination;
if (queue) {
SGEN_LOG (9, "Enqueuing gray object %p (%s)", obj, sgen_client_vtable_get_name (vt));
GRAY_OBJECT_ENQUEUE (queue, obj, sgen_vtable_get_descriptor (vt));
GRAY_OBJECT_ENQUEUE (queue, (GCObject *)obj, sgen_vtable_get_descriptor (vt));
}
}
/*
* This can return OBJ itself on OOM.
*/
static MONO_NEVER_INLINE void*
copy_object_no_checks (void *obj, SgenGrayQueue *queue)
static MONO_NEVER_INLINE GCObject *
copy_object_no_checks (GCObject *obj, SgenGrayQueue *queue)
{
GCVTable vt = SGEN_LOAD_VTABLE_UNCHECKED (obj);
gboolean has_references = SGEN_VTABLE_HAS_REFERENCES (vt);
@@ -76,11 +76,11 @@ copy_object_no_checks (void *obj, SgenGrayQueue *queue)
if (!has_references)
queue = NULL;
par_copy_object_no_checks (destination, vt, obj, objsize, queue);
par_copy_object_no_checks ((char *)destination, vt, obj, objsize, queue);
/* FIXME: mark mod union cards if necessary */
/* set the forwarding pointer */
SGEN_FORWARD_OBJECT (obj, destination);
return destination;
return (GCObject *)destination;
}

View File

@@ -113,7 +113,7 @@ describe_pointer (char *ptr, gboolean need_setup)
if (object_is_pinned (ptr))
printf ("Object is pinned.\n");
if ((forwarded = object_is_forwarded (ptr))) {
if ((forwarded = (char *)object_is_forwarded (ptr))) {
printf ("Object is forwarded to %p:\n", forwarded);
ptr = forwarded;
goto restart;
@@ -334,9 +334,9 @@ static void
setup_valid_nursery_objects (void)
{
if (!valid_nursery_objects)
valid_nursery_objects = sgen_alloc_os_memory (DEFAULT_NURSERY_SIZE, SGEN_ALLOC_INTERNAL | SGEN_ALLOC_ACTIVATE, "debugging data");
valid_nursery_objects = (GCObject **)sgen_alloc_os_memory (DEFAULT_NURSERY_SIZE, (SgenAllocFlags)(SGEN_ALLOC_INTERNAL | SGEN_ALLOC_ACTIVATE), "debugging data");
valid_nursery_object_count = 0;
sgen_scan_area_with_callback (nursery_section->data, nursery_section->end_data, setup_mono_sgen_scan_area_with_callback, NULL, FALSE);
sgen_scan_area_with_callback (nursery_section->data, nursery_section->end_data, setup_mono_sgen_scan_area_with_callback, NULL, FALSE, FALSE);
}
static gboolean
@@ -469,7 +469,7 @@ sgen_check_whole_heap (gboolean allow_missing_pinned)
setup_valid_nursery_objects ();
broken_heap = FALSE;
sgen_scan_area_with_callback (nursery_section->data, nursery_section->end_data, verify_object_pointers_callback, (void*) (size_t) allow_missing_pinned, FALSE);
sgen_scan_area_with_callback (nursery_section->data, nursery_section->end_data, verify_object_pointers_callback, (void*) (size_t) allow_missing_pinned, FALSE, TRUE);
major_collector.iterate_objects (ITERATE_OBJECTS_SWEEP_ALL, verify_object_pointers_callback, (void*) (size_t) allow_missing_pinned);
sgen_los_iterate_objects (verify_object_pointers_callback, (void*) (size_t) allow_missing_pinned);
@@ -542,7 +542,7 @@ find_pinning_reference (char *obj, size_t size)
RootRecord *root;
char *endobj = obj + size;
SGEN_HASH_TABLE_FOREACH (&roots_hash [ROOT_TYPE_NORMAL], start, root) {
SGEN_HASH_TABLE_FOREACH (&roots_hash [ROOT_TYPE_NORMAL], char **, start, RootRecord *, root) {
/* if desc is non-null it has precise info */
if (!root->root_desc) {
while (start < (char**)root->end_root) {
@@ -623,7 +623,7 @@ sgen_check_nursery_objects_pinned (gboolean pinned)
{
sgen_clear_nursery_fragments ();
sgen_scan_area_with_callback (nursery_section->data, nursery_section->end_data,
(IterateObjectCallbackFunc)check_nursery_objects_pinned_callback, (void*) (size_t) pinned /* (void*)&ctx */, FALSE);
(IterateObjectCallbackFunc)check_nursery_objects_pinned_callback, (void*) (size_t) pinned /* (void*)&ctx */, FALSE, TRUE);
}
static void
@@ -679,7 +679,7 @@ sgen_debug_verify_nursery (gboolean do_dump_nursery_content)
is_array_fill);
}
if (nursery_canaries_enabled () && !is_array_fill) {
CHECK_CANARY_FOR_OBJECT ((GCObject*)cur);
CHECK_CANARY_FOR_OBJECT ((GCObject*)cur, TRUE);
CANARIFY_SIZE (size);
}
cur += size;
@@ -786,7 +786,7 @@ scan_roots_for_specific_ref (GCObject *key, int root_type)
RootRecord *root;
check_key = key;
SGEN_HASH_TABLE_FOREACH (&roots_hash [root_type], start_root, root) {
SGEN_HASH_TABLE_FOREACH (&roots_hash [root_type], void **, start_root, RootRecord *, root) {
SgenDescriptor desc = root->root_desc;
check_root = root;
@@ -796,13 +796,13 @@ scan_roots_for_specific_ref (GCObject *key, int root_type)
desc >>= ROOT_DESC_TYPE_SHIFT;
while (desc) {
if (desc & 1)
check_root_obj_specific_ref (root, key, *start_root);
check_root_obj_specific_ref (root, key, (GCObject *)*start_root);
desc >>= 1;
start_root++;
}
return;
case ROOT_DESC_COMPLEX: {
gsize *bitmap_data = sgen_get_complex_descriptor_bitmap (desc);
gsize *bitmap_data = (gsize *)sgen_get_complex_descriptor_bitmap (desc);
int bwords = (int) ((*bitmap_data) - 1);
void **start_run = start_root;
bitmap_data++;
@@ -811,7 +811,7 @@ scan_roots_for_specific_ref (GCObject *key, int root_type)
void **objptr = start_run;
while (bmap) {
if (bmap & 1)
check_root_obj_specific_ref (root, key, *objptr);
check_root_obj_specific_ref (root, key, (GCObject *)*objptr);
bmap >>= 1;
++objptr;
}
@@ -844,7 +844,7 @@ mono_gc_scan_for_specific_ref (GCObject *key, gboolean precise)
scan_object_for_specific_ref_precise = precise;
sgen_scan_area_with_callback (nursery_section->data, nursery_section->end_data,
(IterateObjectCallbackFunc)scan_object_for_specific_ref_callback, key, TRUE);
(IterateObjectCallbackFunc)scan_object_for_specific_ref_callback, key, TRUE, FALSE);
major_collector.iterate_objects (ITERATE_OBJECTS_SWEEP_ALL, (IterateObjectCallbackFunc)scan_object_for_specific_ref_callback, key);
@@ -853,9 +853,9 @@ mono_gc_scan_for_specific_ref (GCObject *key, gboolean precise)
scan_roots_for_specific_ref (key, ROOT_TYPE_NORMAL);
scan_roots_for_specific_ref (key, ROOT_TYPE_WBARRIER);
SGEN_HASH_TABLE_FOREACH (&roots_hash [ROOT_TYPE_PINNED], ptr, root) {
SGEN_HASH_TABLE_FOREACH (&roots_hash [ROOT_TYPE_PINNED], void **, ptr, RootRecord *, root) {
while (ptr < (void**)root->end_root) {
check_root_obj_specific_ref (root, *ptr, key);
check_root_obj_specific_ref (root, (GCObject *)*ptr, key);
++ptr;
}
} SGEN_HASH_TABLE_FOREACH_END;
@@ -887,7 +887,7 @@ sgen_scan_for_registered_roots_in_domain (MonoDomain *domain, int root_type)
void **start_root;
RootRecord *root;
check_domain = domain;
SGEN_HASH_TABLE_FOREACH (&roots_hash [root_type], start_root, root) {
SGEN_HASH_TABLE_FOREACH (&roots_hash [root_type], void **, start_root, RootRecord *, root) {
SgenDescriptor desc = root->root_desc;
/* The MonoDomain struct is allowed to hold
@@ -900,13 +900,13 @@ sgen_scan_for_registered_roots_in_domain (MonoDomain *domain, int root_type)
desc >>= ROOT_DESC_TYPE_SHIFT;
while (desc) {
if ((desc & 1) && *start_root)
check_obj_not_in_domain (*start_root);
check_obj_not_in_domain ((MonoObject **)*start_root);
desc >>= 1;
start_root++;
}
break;
case ROOT_DESC_COMPLEX: {
gsize *bitmap_data = sgen_get_complex_descriptor_bitmap (desc);
gsize *bitmap_data = (gsize *)sgen_get_complex_descriptor_bitmap (desc);
int bwords = (int)((*bitmap_data) - 1);
void **start_run = start_root;
bitmap_data++;
@@ -915,7 +915,7 @@ sgen_scan_for_registered_roots_in_domain (MonoDomain *domain, int root_type)
void **objptr = start_run;
while (bmap) {
if ((bmap & 1) && *objptr)
check_obj_not_in_domain (*objptr);
check_obj_not_in_domain ((MonoObject **)*objptr);
bmap >>= 1;
++objptr;
}
@@ -985,7 +985,7 @@ check_reference_for_xdomain (GCObject **ptr, GCObject *obj, MonoDomain *domain)
{
MonoObject *ref = *ptr;
size_t offset = (char*)(ptr) - (char*)obj;
MonoClass *class;
MonoClass *klass;
MonoClassField *field;
char *str;
@@ -995,12 +995,12 @@ check_reference_for_xdomain (GCObject **ptr, GCObject *obj, MonoDomain *domain)
return;
field = NULL;
for (class = obj->vtable->klass; class; class = class->parent) {
for (klass = obj->vtable->klass; klass; klass = klass->parent) {
int i;
for (i = 0; i < class->field.count; ++i) {
if (class->fields[i].offset == offset) {
field = &class->fields[i];
for (i = 0; i < klass->field.count; ++i) {
if (klass->fields[i].offset == offset) {
field = &klass->fields[i];
break;
}
}
@@ -1041,7 +1041,7 @@ sgen_check_for_xdomain_refs (void)
LOSObject *bigobj;
sgen_scan_area_with_callback (nursery_section->data, nursery_section->end_data,
(IterateObjectCallbackFunc)scan_object_for_xdomain_refs, NULL, FALSE);
(IterateObjectCallbackFunc)scan_object_for_xdomain_refs, NULL, FALSE, TRUE);
major_collector.iterate_objects (ITERATE_OBJECTS_SWEEP_ALL, (IterateObjectCallbackFunc)scan_object_for_xdomain_refs, NULL);
@@ -1113,7 +1113,7 @@ dump_object (GCObject *obj, gboolean dump_location)
#ifndef SGEN_WITHOUT_MONO
static char class_name [1024];
MonoClass *class = mono_object_class (obj);
MonoClass *klass = mono_object_class (obj);
int i, j;
/*
@@ -1121,16 +1121,16 @@ dump_object (GCObject *obj, gboolean dump_location)
* in strings, so we just ignore them;
*/
i = j = 0;
while (class->name [i] && j < sizeof (class_name) - 1) {
if (!strchr ("<>\"", class->name [i]))
class_name [j++] = class->name [i];
while (klass->name [i] && j < sizeof (class_name) - 1) {
if (!strchr ("<>\"", klass->name [i]))
class_name [j++] = klass->name [i];
++i;
}
g_assert (j < sizeof (class_name));
class_name [j] = 0;
fprintf (heap_dump_file, "<object class=\"%s.%s\" size=\"%zd\"",
class->name_space, class_name,
klass->name_space, class_name,
safe_object_get_size (obj));
if (dump_location) {
const char *location;
@@ -1181,7 +1181,7 @@ sgen_debug_dump_heap (const char *type, int num, const char *reason)
fprintf (heap_dump_file, "<pinned-objects>\n");
pinned_objects = sgen_pin_stats_get_object_list ();
for (i = 0; i < pinned_objects->next_slot; ++i)
dump_object (pinned_objects->data [i], TRUE);
dump_object ((GCObject *)pinned_objects->data [i], TRUE);
fprintf (heap_dump_file, "</pinned-objects>\n");
sgen_dump_section (nursery_section, "nursery");
@@ -1201,7 +1201,7 @@ static GCObject *found_obj;
static void
find_object_for_ptr_callback (GCObject *obj, size_t size, void *user_data)
{
char *ptr = user_data;
char *ptr = (char *)user_data;
if (ptr >= (char*)obj && ptr < (char*)obj + size) {
g_assert (!found_obj);
@@ -1216,7 +1216,7 @@ sgen_find_object_for_ptr (char *ptr)
if (ptr >= nursery_section->data && ptr < nursery_section->end_data) {
found_obj = NULL;
sgen_scan_area_with_callback (nursery_section->data, nursery_section->end_data,
find_object_for_ptr_callback, ptr, TRUE);
find_object_for_ptr_callback, ptr, TRUE, FALSE);
if (found_obj)
return found_obj;
}

View File

@@ -95,7 +95,7 @@ alloc_complex_descriptor (gsize *bitmap, int numbits)
}
if (complex_descriptors_next + nwords > complex_descriptors_size) {
int new_size = complex_descriptors_size * 2 + nwords;
complex_descriptors = g_realloc (complex_descriptors, new_size * sizeof (gsize));
complex_descriptors = (gsize *)g_realloc (complex_descriptors, new_size * sizeof (gsize));
complex_descriptors_size = new_size;
}
SGEN_LOG (6, "Complex descriptor %d, size: %d (total desc memory: %d)", res, nwords, complex_descriptors_size);
@@ -293,7 +293,7 @@ mono_gc_make_root_descr_all_refs (int numbits)
if (numbits < 32 && all_ref_root_descrs [numbits])
return all_ref_root_descrs [numbits];
gc_bitmap = g_malloc0 (ALIGN_TO (ALIGN_TO (numbits, 8) + 1, sizeof (gsize)));
gc_bitmap = (gsize *)g_malloc0 (ALIGN_TO (ALIGN_TO (numbits, 8) + 1, sizeof (gsize)));
memset (gc_bitmap, 0xff, num_bytes);
if (numbits < ((sizeof (*gc_bitmap) * 8) - ROOT_DESC_TYPE_SHIFT))
gc_bitmap[0] = GUINT64_TO_LE(gc_bitmap[0]);

View File

@@ -32,6 +32,7 @@
#include "mono/sgen/sgen-protocol.h"
#include "mono/sgen/sgen-pointer-queue.h"
#include "mono/sgen/sgen-client.h"
#include "mono/sgen/gc-internal-agnostic.h"
#include "mono/utils/mono-membar.h"
#define ptr_in_nursery sgen_ptr_in_nursery
@@ -40,9 +41,6 @@ typedef SgenGrayQueue GrayQueue;
static int no_finalize = 0;
#define DISLINK_OBJECT(l) (REVEAL_POINTER (*(void**)(l)))
#define DISLINK_TRACK(l) ((~(size_t)(*(void**)(l))) & 1)
/*
* The finalizable hash has the object as the key, the
* disappearing_link hash, has the link address as key.
@@ -123,7 +121,7 @@ sgen_collect_bridge_objects (int generation, ScanCopyContext ctx)
if (no_finalize)
return;
SGEN_HASH_TABLE_FOREACH (hash_table, object, dummy) {
SGEN_HASH_TABLE_FOREACH (hash_table, GCObject *, object, gpointer, dummy) {
int tag = tagged_object_get_tag (object);
object = tagged_object_get_object (object);
@@ -193,7 +191,7 @@ sgen_finalize_in_range (int generation, ScanCopyContext ctx)
if (no_finalize)
return;
SGEN_HASH_TABLE_FOREACH (hash_table, object, dummy) {
SGEN_HASH_TABLE_FOREACH (hash_table, GCObject *, object, gpointer, dummy) {
int tag = tagged_object_get_tag (object);
object = tagged_object_get_object (object);
if (!major_collector.is_object_live (object)) {
@@ -580,7 +578,7 @@ finalizers_with_predicate (SgenObjectPredicateFunc predicate, void *user_data, G
if (no_finalize || !out_size || !out_array)
return 0;
count = 0;
SGEN_HASH_TABLE_FOREACH (hash_table, object, dummy) {
SGEN_HASH_TABLE_FOREACH (hash_table, GCObject *, object, gpointer, dummy) {
object = tagged_object_get_object (object);
if (predicate (object, user_data)) {
@@ -629,149 +627,6 @@ sgen_gather_finalizers_if (SgenObjectPredicateFunc predicate, void *user_data, G
return result;
}
static SgenHashTable minor_disappearing_link_hash = SGEN_HASH_TABLE_INIT (INTERNAL_MEM_DISLINK_TABLE, INTERNAL_MEM_DISLINK, 0, sgen_aligned_addr_hash, NULL);
static SgenHashTable major_disappearing_link_hash = SGEN_HASH_TABLE_INIT (INTERNAL_MEM_DISLINK_TABLE, INTERNAL_MEM_DISLINK, 0, sgen_aligned_addr_hash, NULL);
static SgenHashTable*
get_dislink_hash_table (int generation)
{
switch (generation) {
case GENERATION_NURSERY: return &minor_disappearing_link_hash;
case GENERATION_OLD: return &major_disappearing_link_hash;
default: g_assert_not_reached ();
}
}
/* LOCKING: assumes the GC lock is held */
static void
add_or_remove_disappearing_link (GCObject *obj, void **link, int generation)
{
SgenHashTable *hash_table = get_dislink_hash_table (generation);
if (!obj) {
if (sgen_hash_table_remove (hash_table, link, NULL)) {
SGEN_LOG (5, "Removed dislink %p (%d) from %s table",
link, hash_table->num_entries, sgen_generation_name (generation));
}
return;
}
sgen_hash_table_replace (hash_table, link, NULL, NULL);
SGEN_LOG (5, "Added dislink for object: %p (%s) at %p to %s table",
obj, sgen_client_vtable_get_name (SGEN_LOAD_VTABLE_UNCHECKED (obj)), link, sgen_generation_name (generation));
}
/* LOCKING: requires that the GC lock is held */
void
sgen_null_link_in_range (int generation, gboolean before_finalization, ScanCopyContext ctx)
{
CopyOrMarkObjectFunc copy_func = ctx.ops->copy_or_mark_object;
GrayQueue *queue = ctx.queue;
void **link;
gpointer dummy G_GNUC_UNUSED;
SgenHashTable *hash = get_dislink_hash_table (generation);
SGEN_HASH_TABLE_FOREACH (hash, link, dummy) {
GCObject *object;
gboolean track;
/*
We null a weak link before unregistering it, so it's possible that a thread is
suspended right in between setting the content to null and staging the unregister.
The rest of this code cannot handle null links as DISLINK_OBJECT (NULL) produces an invalid address.
We should simply skip the entry as the staged removal will take place during the next GC.
*/
if (!*link) {
SGEN_LOG (5, "Dislink %p was externally nullified", link);
continue;
}
track = DISLINK_TRACK (link);
/*
* Tracked references are processed after
* finalization handling whereas standard weak
* references are processed before. If an
* object is still not marked after finalization
* handling it means that it either doesn't have
* a finalizer or the finalizer has already run,
* so we must null a tracking reference.
*/
if (track != before_finalization) {
object = DISLINK_OBJECT (link);
/*
We should guard against a null object been hidden. This can sometimes happen.
*/
if (!object) {
SGEN_LOG (5, "Dislink %p with a hidden null object", link);
continue;
}
if (!major_collector.is_object_live (object)) {
if (sgen_gc_is_object_ready_for_finalization (object)) {
*link = NULL;
binary_protocol_dislink_update (link, NULL, 0, 0);
SGEN_LOG (5, "Dislink nullified at %p to GCed object %p", link, object);
SGEN_HASH_TABLE_FOREACH_REMOVE (TRUE);
continue;
} else {
GCObject *copy = object;
copy_func (&copy, queue);
/* Update pointer if it's moved. If the object
* has been moved out of the nursery, we need to
* remove the link from the minor hash table to
* the major one.
*
* FIXME: what if an object is moved earlier?
*/
if (hash == &minor_disappearing_link_hash && !ptr_in_nursery (copy)) {
SGEN_HASH_TABLE_FOREACH_REMOVE (TRUE);
g_assert (copy);
*link = HIDE_POINTER (copy, track);
add_or_remove_disappearing_link (copy, link, GENERATION_OLD);
binary_protocol_dislink_update (link, copy, track, 0);
SGEN_LOG (5, "Upgraded dislink at %p to major because object %p moved to %p", link, object, copy);
continue;
} else {
*link = HIDE_POINTER (copy, track);
binary_protocol_dislink_update (link, copy, track, 0);
SGEN_LOG (5, "Updated dislink at %p to %p", link, DISLINK_OBJECT (link));
}
}
}
}
} SGEN_HASH_TABLE_FOREACH_END;
}
/* LOCKING: requires that the GC lock is held */
void
sgen_null_links_if (SgenObjectPredicateFunc predicate, void *data, int generation)
{
void **link;
gpointer dummy G_GNUC_UNUSED;
SgenHashTable *hash = get_dislink_hash_table (generation);
SGEN_HASH_TABLE_FOREACH (hash, link, dummy) {
char *object = DISLINK_OBJECT (link);
if (!*link)
continue;
if (predicate ((GCObject*)object, data)) {
*link = NULL;
binary_protocol_dislink_update (link, NULL, 0, 0);
SGEN_LOG (5, "Dislink nullified by predicate at %p to GCed object %p", link, object);
SGEN_HASH_TABLE_FOREACH_REMOVE (FALSE /* TRUE */);
continue;
}
} SGEN_HASH_TABLE_FOREACH_END;
}
void
sgen_remove_finalizers_if (SgenObjectPredicateFunc predicate, void *user_data, int generation)
{
@@ -779,7 +634,7 @@ sgen_remove_finalizers_if (SgenObjectPredicateFunc predicate, void *user_data, i
GCObject *object;
gpointer dummy G_GNUC_UNUSED;
SGEN_HASH_TABLE_FOREACH (hash_table, object, dummy) {
SGEN_HASH_TABLE_FOREACH (hash_table, GCObject *, object, gpointer, dummy) {
object = tagged_object_get_object (object);
if (predicate (object, user_data)) {
@@ -789,72 +644,6 @@ sgen_remove_finalizers_if (SgenObjectPredicateFunc predicate, void *user_data, i
} SGEN_HASH_TABLE_FOREACH_END;
}
/* LOCKING: requires that the GC lock is held */
static void
process_dislink_stage_entry (GCObject *obj, void *_link, int index)
{
void **link = _link;
if (index >= 0)
binary_protocol_dislink_process_staged (link, obj, index);
add_or_remove_disappearing_link (NULL, link, GENERATION_NURSERY);
add_or_remove_disappearing_link (NULL, link, GENERATION_OLD);
if (obj) {
if (ptr_in_nursery (obj))
add_or_remove_disappearing_link (obj, link, GENERATION_NURSERY);
else
add_or_remove_disappearing_link (obj, link, GENERATION_OLD);
}
}
#define NUM_DISLINK_STAGE_ENTRIES 1024
static volatile gint32 next_dislink_stage_entry = 0;
static StageEntry dislink_stage_entries [NUM_DISLINK_STAGE_ENTRIES];
/* LOCKING: requires that the GC lock is held */
void
sgen_process_dislink_stage_entries (void)
{
lock_stage_for_processing (&next_dislink_stage_entry);
process_stage_entries (NUM_DISLINK_STAGE_ENTRIES, &next_dislink_stage_entry, dislink_stage_entries, process_dislink_stage_entry);
}
void
sgen_register_disappearing_link (GCObject *obj, void **link, gboolean track, gboolean in_gc)
{
if (obj)
*link = HIDE_POINTER (obj, track);
else
*link = NULL;
#if 1
if (in_gc) {
binary_protocol_dislink_update (link, obj, track, 0);
process_dislink_stage_entry (obj, link, -1);
} else {
int index;
binary_protocol_dislink_update (link, obj, track, 1);
while ((index = add_stage_entry (NUM_DISLINK_STAGE_ENTRIES, &next_dislink_stage_entry, dislink_stage_entries, obj, link)) == -1) {
if (try_lock_stage_for_processing (NUM_DISLINK_STAGE_ENTRIES, &next_dislink_stage_entry)) {
LOCK_GC;
process_stage_entries (NUM_DISLINK_STAGE_ENTRIES, &next_dislink_stage_entry, dislink_stage_entries, process_dislink_stage_entry);
UNLOCK_GC;
}
}
binary_protocol_dislink_update_staged (link, obj, track, index);
}
#else
if (!in_gc)
LOCK_GC;
binary_protocol_dislink_update (link, obj, track, 0);
process_dislink_stage_entry (obj, link, -1);
if (!in_gc)
UNLOCK_GC;
#endif
}
void
sgen_init_fin_weak_hash (void)
{

View File

@@ -1 +1 @@
2fc21552caddc04ff91dd8a266149ea98d4f0dc0
b73c1d88ff1d2d1330fccfa95dd7c106ee86724c

View File

@@ -39,10 +39,12 @@ typedef struct _SgenThreadInfo SgenThreadInfo;
#include <stdint.h>
#include "mono/utils/mono-compiler.h"
#include "mono/utils/atomic.h"
#include "mono/utils/mono-mutex.h"
#include "mono/utils/mono-os-mutex.h"
#include "mono/utils/mono-coop-mutex.h"
#include "mono/sgen/sgen-conf.h"
#include "mono/sgen/sgen-hash-table.h"
#include "mono/sgen/sgen-protocol.h"
#include "mono/sgen/gc-internal-agnostic.h"
/* The method used to clear the nursery */
/* Clearing at nursery collections is the safest, but has bad interactions with caches.
@@ -88,18 +90,14 @@ struct _GCMemSection {
#define LOCK_DECLARE(name) mono_mutex_t name
/* if changing LOCK_INIT to something that isn't idempotent, look at
its use in mono_gc_base_init in sgen-gc.c */
#define LOCK_INIT(name) mono_mutex_init (&(name))
#define LOCK_GC do { \
MONO_TRY_BLOCKING \
mono_mutex_lock (&gc_mutex); \
MONO_FINISH_TRY_BLOCKING \
} while (0)
#define LOCK_INIT(name) mono_os_mutex_init (&(name))
#define LOCK_GC do { sgen_gc_lock (); } while (0)
#define UNLOCK_GC do { sgen_gc_unlock (); } while (0)
extern LOCK_DECLARE (sgen_interruption_mutex);
extern MonoCoopMutex sgen_interruption_mutex;
#define LOCK_INTERRUPTION mono_mutex_lock (&sgen_interruption_mutex)
#define UNLOCK_INTERRUPTION mono_mutex_unlock (&sgen_interruption_mutex)
#define LOCK_INTERRUPTION mono_coop_mutex_lock (&sgen_interruption_mutex)
#define UNLOCK_INTERRUPTION mono_coop_mutex_unlock (&sgen_interruption_mutex)
/* FIXME: Use InterlockedAdd & InterlockedAdd64 to reduce the CAS cost. */
#define SGEN_CAS InterlockedCompareExchange
@@ -167,14 +165,6 @@ sgen_aligned_addr_hash (gconstpointer ptr)
return GPOINTER_TO_UINT (ptr) >> 3;
}
/*
* The link pointer is hidden by negating each bit. We use the lowest
* bit of the link (before negation) to store whether it needs
* resurrection tracking.
*/
#define HIDE_POINTER(p,t) ((gpointer)(~((size_t)(p)|((t)?1:0))))
#define REVEAL_POINTER(p) ((gpointer)((~(size_t)(p))&~3L))
#define SGEN_PTR_IN_NURSERY(p,bits,start,end) (((mword)(p) & ~((1 << (bits)) - 1)) == (mword)(start))
#ifdef USER_CONFIG
@@ -247,8 +237,8 @@ sgen_get_nursery_end (void)
#define SGEN_POINTER_UNTAG_VTABLE(p) SGEN_POINTER_UNTAG_ALL((p))
/* returns NULL if not forwarded, or the forwarded address */
#define SGEN_VTABLE_IS_FORWARDED(vtable) (SGEN_POINTER_IS_TAGGED_FORWARDED ((vtable)) ? SGEN_POINTER_UNTAG_VTABLE ((vtable)) : NULL)
#define SGEN_OBJECT_IS_FORWARDED(obj) (SGEN_VTABLE_IS_FORWARDED (((mword*)(obj))[0]))
#define SGEN_VTABLE_IS_FORWARDED(vtable) ((GCVTable *)(SGEN_POINTER_IS_TAGGED_FORWARDED ((vtable)) ? SGEN_POINTER_UNTAG_VTABLE ((vtable)) : NULL))
#define SGEN_OBJECT_IS_FORWARDED(obj) ((GCObject *)SGEN_VTABLE_IS_FORWARDED (((mword*)(obj))[0]))
#define SGEN_VTABLE_IS_PINNED(vtable) SGEN_POINTER_IS_TAGGED_PINNED ((vtable))
#define SGEN_OBJECT_IS_PINNED(obj) (SGEN_VTABLE_IS_PINNED (((mword*)(obj))[0]))
@@ -274,7 +264,7 @@ sgen_get_nursery_end (void)
* Since we set bits in the vtable, use the macro to load it from the pointer to
* an object that is potentially pinned.
*/
#define SGEN_LOAD_VTABLE(obj) ((GCVTable)(SGEN_POINTER_UNTAG_ALL (SGEN_LOAD_VTABLE_UNCHECKED ((obj)))))
#define SGEN_LOAD_VTABLE(obj) ((GCVTable)(SGEN_POINTER_UNTAG_ALL (SGEN_LOAD_VTABLE_UNCHECKED ((GCObject *)(obj)))))
/*
List of what each bit on of the vtable gc bits means.
@@ -368,6 +358,8 @@ typedef struct _RootRecord RootRecord;
struct _RootRecord {
char *end_root;
SgenDescriptor root_desc;
int source;
const char *msg;
};
enum {
@@ -379,12 +371,12 @@ enum {
extern SgenHashTable roots_hash [ROOT_TYPE_NUM];
int sgen_register_root (char *start, size_t size, SgenDescriptor descr, int root_type);
int sgen_register_root (char *start, size_t size, SgenDescriptor descr, int root_type, int source, const char *msg);
void sgen_deregister_root (char* addr);
typedef void (*IterateObjectCallbackFunc) (GCObject*, size_t, void*);
void sgen_scan_area_with_callback (char *start, char *end, IterateObjectCallbackFunc callback, void *data, gboolean allow_flags);
void sgen_scan_area_with_callback (char *start, char *end, IterateObjectCallbackFunc callback, void *data, gboolean allow_flags, gboolean fail_on_canaries);
/* eventually share with MonoThread? */
/*
@@ -411,11 +403,14 @@ gboolean sgen_is_worker_thread (MonoNativeThreadId thread);
typedef void (*CopyOrMarkObjectFunc) (GCObject**, SgenGrayQueue*);
typedef void (*ScanObjectFunc) (GCObject *obj, SgenDescriptor desc, SgenGrayQueue*);
typedef void (*ScanVTypeFunc) (GCObject *full_object, char *start, SgenDescriptor desc, SgenGrayQueue* BINARY_PROTOCOL_ARG (size_t size));
typedef gboolean (*DrainGrayStackFunc) (SgenGrayQueue *queue);
typedef struct {
CopyOrMarkObjectFunc copy_or_mark_object;
ScanObjectFunc scan_object;
ScanVTypeFunc scan_vtype;
/* Drain stack optimized for the above functions */
DrainGrayStackFunc drain_gray_stack;
/*FIXME add allocation function? */
} SgenObjectOperations;
@@ -446,7 +441,7 @@ void sgen_pin_stats_register_global_remset (GCObject *obj);
void sgen_pin_stats_print_class_stats (void);
void sgen_sort_addresses (void **array, size_t size);
void sgen_add_to_global_remset (gpointer ptr, gpointer obj);
void sgen_add_to_global_remset (gpointer ptr, GCObject *obj);
int sgen_get_current_collection_generation (void);
gboolean sgen_collection_is_concurrent (void);
@@ -604,13 +599,6 @@ struct _SgenMajorCollector {
gboolean supports_cardtable;
gboolean sweeps_lazily;
/*
* This is set to TRUE by the sweep if the next major
* collection should be synchronous (for evacuation). For
* non-concurrent collectors, this should be NULL.
*/
gboolean *want_synchronous_collection;
void* (*alloc_heap) (mword nursery_size, mword nursery_align, int nursery_bits);
gboolean (*is_object_live) (GCObject *obj);
GCObject* (*alloc_small_pinned_obj) (GCVTable vtable, size_t size, gboolean has_references);
@@ -618,7 +606,6 @@ struct _SgenMajorCollector {
SgenObjectOperations major_ops_serial;
SgenObjectOperations major_ops_concurrent_start;
SgenObjectOperations major_ops_concurrent;
SgenObjectOperations major_ops_concurrent_finish;
GCObject* (*alloc_object) (GCVTable vtable, size_t size, gboolean has_references);
@@ -648,7 +635,6 @@ struct _SgenMajorCollector {
void (*finish_nursery_collection) (void);
void (*start_major_collection) (void);
void (*finish_major_collection) (ScannedObjectCounts *counts);
gboolean (*drain_gray_stack) (ScanCopyContext ctx);
gboolean (*ptr_is_in_non_pinned_space) (char *ptr, char **start);
gboolean (*ptr_is_from_pinned_alloc) (char *ptr);
void (*report_pinned_memory_usage) (void);
@@ -779,7 +765,7 @@ void sgen_collect_bridge_objects (int generation, ScanCopyContext ctx);
typedef gboolean (*SgenObjectPredicateFunc) (GCObject *obj, void *user_data);
void sgen_null_links_if (SgenObjectPredicateFunc predicate, void *data, int generation);
void sgen_null_links_if (SgenObjectPredicateFunc predicate, void *data, int generation, gboolean track);
gboolean sgen_gc_is_object_ready_for_finalization (GCObject *object);
void sgen_gc_lock (void);
@@ -789,7 +775,7 @@ void sgen_queue_finalization_entry (GCObject *obj);
const char* sgen_generation_name (int generation);
void sgen_finalize_in_range (int generation, ScanCopyContext ctx);
void sgen_null_link_in_range (int generation, gboolean before_finalization, ScanCopyContext ctx);
void sgen_null_link_in_range (int generation, ScanCopyContext ctx, gboolean track);
void sgen_process_fin_stage_entries (void);
gboolean sgen_have_pending_finalizers (void);
void sgen_object_register_for_finalization (GCObject *obj, void *user_data);
@@ -797,12 +783,11 @@ void sgen_object_register_for_finalization (GCObject *obj, void *user_data);
int sgen_gather_finalizers_if (SgenObjectPredicateFunc predicate, void *user_data, GCObject **out_array, int out_size);
void sgen_remove_finalizers_if (SgenObjectPredicateFunc predicate, void *user_data, int generation);
void sgen_process_dislink_stage_entries (void);
void sgen_register_disappearing_link (GCObject *obj, void **link, gboolean track, gboolean in_gc);
GCObject* sgen_weak_link_get (void **link_addr);
gboolean sgen_drain_gray_stack (int max_objs, ScanCopyContext ctx);
gboolean sgen_drain_gray_stack (ScanCopyContext ctx);
enum {
SPACE_NURSERY,
@@ -941,6 +926,19 @@ sgen_is_object_alive_for_current_gen (GCObject *object)
int sgen_gc_invoke_finalizers (void);
/* GC handles */
void sgen_init_gchandles (void);
void sgen_null_links_if (SgenObjectPredicateFunc predicate, void *data, int generation, gboolean track);
typedef gpointer (*SgenGCHandleIterateCallback) (gpointer hidden, GCHandleType handle_type, int max_generation, gpointer user);
void sgen_gchandle_iterate (GCHandleType handle_type, int max_generation, SgenGCHandleIterateCallback callback, gpointer user);
void sgen_gchandle_set_target (guint32 gchandle, GCObject *obj);
void sgen_mark_normal_gc_handles (void *addr, SgenUserMarkFunc mark_func, void *gc_data);
gpointer sgen_gchandle_get_metadata (guint32 gchandle);
/* Other globals */
extern GCMemSection *nursery_section;
@@ -953,7 +951,7 @@ extern guint32 tlab_size;
extern NurseryClearPolicy nursery_clear_policy;
extern gboolean sgen_try_free_some_memory;
extern LOCK_DECLARE (gc_mutex);
extern MonoCoopMutex gc_mutex;
/* Nursery helpers. */
@@ -1005,23 +1003,6 @@ void sgen_debug_dump_heap (const char *type, int num, const char *reason);
void sgen_debug_verify_nursery (gboolean do_dump_nursery_content);
void sgen_debug_check_nursery_is_clean (void);
/* Write barrier support */
/*
* This causes the compile to extend the liveness of 'v' till the call to dummy_use
*/
static inline void
sgen_dummy_use (gpointer v) {
#if defined(__GNUC__)
__asm__ volatile ("" : "=r"(v) : "r"(v));
#elif defined(_MSC_VER)
static volatile gpointer ptr;
ptr = v;
#else
#error "Implement sgen_dummy_use for your compiler"
#endif
}
/* Environment variable parsing */
#define MONO_GC_PARAMS_NAME "MONO_GC_PARAMS"
@@ -1056,15 +1037,34 @@ gboolean nursery_canaries_enabled (void);
#define CANARY_VALID(addr) (strncmp ((char*) (addr), CANARY_STRING, CANARY_SIZE) == 0)
#define CHECK_CANARY_FOR_OBJECT(addr) if (nursery_canaries_enabled ()) { \
#define CHECK_CANARY_FOR_OBJECT(addr,fail) if (nursery_canaries_enabled ()) { \
char* canary_ptr = (char*) (addr) + sgen_safe_object_get_size_unaligned ((GCObject *) (addr)); \
if (!CANARY_VALID(canary_ptr)) { \
char canary_copy[CANARY_SIZE +1]; \
strncpy (canary_copy, canary_ptr, CANARY_SIZE); \
canary_copy[CANARY_SIZE] = 0; \
g_error ("CORRUPT CANARY:\naddr->%p\ntype->%s\nexcepted->'%s'\nfound->'%s'\n", (char*) addr, sgen_client_vtable_get_name (SGEN_LOAD_VTABLE ((addr))), CANARY_STRING, canary_copy); \
if ((fail)) \
g_error ("CORRUPT CANARY:\naddr->%p\ntype->%s\nexcepted->'%s'\nfound->'%s'\n", (char*) addr, sgen_client_vtable_get_name (SGEN_LOAD_VTABLE ((addr))), CANARY_STRING, canary_copy); \
else \
g_warning ("CORRUPT CANARY:\naddr->%p\ntype->%s\nexcepted->'%s'\nfound->'%s'\n", (char*) addr, sgen_client_vtable_get_name (SGEN_LOAD_VTABLE ((addr))), CANARY_STRING, canary_copy); \
} }
/*
* This causes the compile to extend the liveness of 'v' till the call to dummy_use
*/
static inline void
sgen_dummy_use (gpointer v)
{
#if defined(__GNUC__)
__asm__ volatile ("" : "=r"(v) : "r"(v));
#elif defined(_MSC_VER)
static volatile gpointer ptr;
ptr = v;
#else
#error "Implement sgen_dummy_use for your compiler"
#endif
}
#endif /* HAVE_SGEN_GC */
#endif /* __MONO_SGENGC_H__ */

639
mono/sgen/sgen-gchandles.c Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -66,7 +66,7 @@ sgen_gray_object_alloc_queue_section (SgenGrayQueue *queue)
STATE_TRANSITION (section, GRAY_QUEUE_SECTION_STATE_FREE_LIST, GRAY_QUEUE_SECTION_STATE_FLOATING);
} else {
/* Allocate a new section */
section = sgen_alloc_internal (INTERNAL_MEM_GRAY_QUEUE);
section = (GrayQueueSection *)sgen_alloc_internal (INTERNAL_MEM_GRAY_QUEUE);
STATE_SET (section, GRAY_QUEUE_SECTION_STATE_FLOATING);
}
@@ -292,7 +292,7 @@ lock_section_queue (SgenSectionGrayQueue *queue)
if (!queue->locked)
return;
mono_mutex_lock (&queue->lock);
mono_os_mutex_lock (&queue->lock);
}
static void
@@ -301,7 +301,7 @@ unlock_section_queue (SgenSectionGrayQueue *queue)
if (!queue->locked)
return;
mono_mutex_unlock (&queue->lock);
mono_os_mutex_unlock (&queue->lock);
}
void
@@ -311,7 +311,7 @@ sgen_section_gray_queue_init (SgenSectionGrayQueue *queue, gboolean locked, Gray
queue->locked = locked;
if (locked) {
mono_mutex_init_recursive (&queue->lock);
mono_os_mutex_init_recursive (&queue->lock);
}
#ifdef SGEN_CHECK_GRAY_OBJECT_ENQUEUE

View File

@@ -53,7 +53,7 @@ rehash (SgenHashTable *hash_table)
new_size = g_spaced_primes_closest (hash_table->num_entries);
}
new_hash = sgen_alloc_internal_dynamic (new_size * sizeof (SgenHashTableEntry*), hash_table->table_mem_type, TRUE);
new_hash = (SgenHashTableEntry **)sgen_alloc_internal_dynamic (new_size * sizeof (SgenHashTableEntry*), hash_table->table_mem_type, TRUE);
for (i = 0; i < old_hash_size; ++i) {
for (entry = old_hash [i]; entry; entry = next) {
hash = hash_table->hash_func (entry->key) % new_size;
@@ -132,7 +132,7 @@ sgen_hash_table_replace (SgenHashTable *hash_table, gpointer key, gpointer new_v
return FALSE;
}
entry = sgen_alloc_internal (hash_table->entry_mem_type);
entry = (SgenHashTableEntry *)sgen_alloc_internal (hash_table->entry_mem_type);
entry->key = key;
memcpy (entry->data, new_value, hash_table->data_size);

View File

@@ -42,9 +42,9 @@ void sgen_init_hash_table (void);
#define sgen_hash_table_num_entries(h) ((h)->num_entries)
#define sgen_hash_table_key_for_value_pointer(v) (((SgenHashTableEntry*)((char*)(v) - G_STRUCT_OFFSET (SgenHashTableEntry, data)))->key)
#define sgen_hash_table_key_for_value_pointer(v) ((GCObject *)(((SgenHashTableEntry*)((char*)(v) - G_STRUCT_OFFSET (SgenHashTableEntry, data)))->key))
#define SGEN_HASH_TABLE_FOREACH(h,k,v) do { \
#define SGEN_HASH_TABLE_FOREACH(h,tk,k,tv,v) do { \
SgenHashTable *__hash_table = (h); \
SgenHashTableEntry **__table = __hash_table->table; \
guint __i; \
@@ -53,8 +53,8 @@ void sgen_init_hash_table (void);
for (__iter = &__table [__i]; *__iter; __iter = __next) { \
SgenHashTableEntry *__entry = *__iter; \
__next = &__entry->next; \
(k) = __entry->key; \
(v) = (gpointer)__entry->data;
(k) = (tk)__entry->key; \
(v) = (tv)__entry->data;
/* The loop must be continue'd after using this! */
#define SGEN_HASH_TABLE_FOREACH_REMOVE(free) do { \

View File

@@ -165,7 +165,7 @@ sgen_alloc_internal_dynamic (size_t size, int type, gboolean assert_on_failure)
void *p;
if (size > allocator_sizes [NUM_ALLOCATORS - 1]) {
p = sgen_alloc_os_memory (size, SGEN_ALLOC_INTERNAL | SGEN_ALLOC_ACTIVATE, NULL);
p = sgen_alloc_os_memory (size, (SgenAllocFlags)(SGEN_ALLOC_INTERNAL | SGEN_ALLOC_ACTIVATE), NULL);
if (!p)
sgen_assert_memory_alloc (NULL, size, description_for_type (type));
} else {

View File

@@ -92,6 +92,12 @@ static char *los_segment = NULL;
static int los_segment_index = 0;
#endif
mword
sgen_los_object_size (LOSObject *obj)
{
return obj->size & ~1L;
}
#ifdef LOS_CONSISTENCY_CHECK
static void
los_consistency_check (void)
@@ -102,12 +108,13 @@ los_consistency_check (void)
mword memory_usage = 0;
for (obj = los_object_list; obj; obj = obj->next) {
char *end = obj->data + obj->size;
mword obj_size = sgen_los_object_size (obj);
char *end = obj->data + obj_size;
int start_index, num_chunks;
memory_usage += obj->size;
memory_usage += obj_size;
if (obj->size > LOS_SECTION_OBJECT_LIMIT)
if (obj_size > LOS_SECTION_OBJECT_LIMIT)
continue;
section = LOS_SECTION_FOR_OBJ (obj);
@@ -115,7 +122,7 @@ los_consistency_check (void)
g_assert (end <= (char*)section + LOS_SECTION_SIZE);
start_index = LOS_CHUNK_INDEX (obj, section);
num_chunks = (obj->size + sizeof (LOSObject) + LOS_CHUNK_SIZE - 1) >> LOS_CHUNK_BITS;
num_chunks = (obj_size + sizeof (LOSObject) + LOS_CHUNK_SIZE - 1) >> LOS_CHUNK_BITS;
for (i = start_index; i < start_index + num_chunks; ++i)
g_assert (!section->free_chunk_map [i]);
}
@@ -231,7 +238,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, SGEN_ALLOC_HEAP | SGEN_ALLOC_ACTIVATE, NULL);
section = (LOSSection *)sgen_alloc_os_memory_aligned (LOS_SECTION_SIZE, LOS_SECTION_SIZE, (SgenAllocFlags)(SGEN_ALLOC_HEAP | SGEN_ALLOC_ACTIVATE), NULL);
if (!section)
return NULL;
@@ -296,9 +303,9 @@ sgen_los_free_object (LOSObject *obj)
SGEN_ASSERT (0, !obj->cardtable_mod_union, "We should never free a LOS object with a mod-union table.");
#ifndef LOS_DUMMY
size_t size = obj->size;
SGEN_LOG (4, "Freed large object %p, size %lu", obj->data, (unsigned long)obj->size);
binary_protocol_empty (obj->data, obj->size);
mword size = sgen_los_object_size (obj);
SGEN_LOG (4, "Freed large object %p, size %lu", obj->data, (unsigned long)size);
binary_protocol_empty (obj->data, size);
los_memory_usage -= size;
los_num_objects--;
@@ -372,7 +379,7 @@ sgen_los_alloc_large_inner (GCVTable 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, SGEN_ALLOC_HEAP | SGEN_ALLOC_ACTIVATE, NULL);
obj = (LOSObject *)sgen_alloc_os_memory (alloc_size, (SgenAllocFlags)(SGEN_ALLOC_HEAP | SGEN_ALLOC_ACTIVATE), NULL);
}
} else {
obj = get_los_section_memory (size + sizeof (LOSObject));
@@ -418,7 +425,7 @@ sgen_los_sweep (void)
SGEN_ASSERT (0, !SGEN_OBJECT_IS_PINNED (bigobj->data), "Who pinned a LOS object?");
if (bigobj->cardtable_mod_union) {
sgen_card_table_free_mod_union (bigobj->cardtable_mod_union, (char*)bigobj->data, bigobj->size);
sgen_card_table_free_mod_union (bigobj->cardtable_mod_union, (char*)bigobj->data, sgen_los_object_size (bigobj));
bigobj->cardtable_mod_union = NULL;
}
@@ -502,7 +509,7 @@ sgen_ptr_is_in_los (char *ptr, char **start)
*start = NULL;
for (obj = los_object_list; obj; obj = obj->next) {
char *end = (char*)obj->data + obj->size;
char *end = (char*)obj->data + sgen_los_object_size (obj);
if (ptr >= (char*)obj->data && ptr < end) {
*start = (char*)obj->data;
@@ -518,7 +525,7 @@ sgen_los_iterate_objects (IterateObjectCallbackFunc cb, void *user_data)
LOSObject *obj;
for (obj = los_object_list; obj; obj = obj->next)
cb (obj->data, obj->size, user_data);
cb (obj->data, sgen_los_object_size (obj), user_data);
}
gboolean
@@ -543,7 +550,7 @@ mono_sgen_los_describe_pointer (char *ptr)
mword size;
gboolean pinned;
if ((char*)obj->data > ptr || (char*)obj->data + obj->size <= ptr)
if ((char*)obj->data > ptr || (char*)obj->data + sgen_los_object_size (obj) <= ptr)
continue;
size = sgen_los_object_size (obj);
@@ -573,24 +580,25 @@ sgen_los_iterate_live_block_ranges (sgen_cardtable_block_callback callback)
for (obj = los_object_list; obj; obj = obj->next) {
GCVTable vt = SGEN_LOAD_VTABLE (obj->data);
if (SGEN_VTABLE_HAS_REFERENCES (vt))
callback ((mword)obj->data, (mword)obj->size);
callback ((mword)obj->data, sgen_los_object_size (obj));
}
}
static guint8*
get_cardtable_mod_union_for_object (LOSObject *obj)
{
mword size = sgen_los_object_size (obj);
guint8 *mod_union = obj->cardtable_mod_union;
guint8 *other;
if (mod_union)
return mod_union;
mod_union = sgen_card_table_alloc_mod_union ((char*)obj->data, obj->size);
other = SGEN_CAS_PTR ((gpointer*)&obj->cardtable_mod_union, mod_union, NULL);
mod_union = sgen_card_table_alloc_mod_union ((char*)obj->data, size);
other = (guint8 *)SGEN_CAS_PTR ((gpointer*)&obj->cardtable_mod_union, mod_union, NULL);
if (!other) {
SGEN_ASSERT (0, obj->cardtable_mod_union == mod_union, "Why did CAS not replace?");
return mod_union;
}
sgen_card_table_free_mod_union (mod_union, (char*)obj->data, obj->size);
sgen_card_table_free_mod_union (mod_union, (char*)obj->data, size);
return other;
}
@@ -615,7 +623,7 @@ sgen_los_scan_card_table (gboolean mod_union, ScanCopyContext ctx)
cards = NULL;
}
sgen_cardtable_scan_object (obj->data, obj->size, cards, mod_union, ctx);
sgen_cardtable_scan_object (obj->data, sgen_los_object_size (obj), cards, mod_union, ctx);
}
}
@@ -629,7 +637,7 @@ sgen_los_count_cards (long long *num_total_cards, long long *num_marked_cards)
for (obj = los_object_list; obj; obj = obj->next) {
int i;
guint8 *cards = sgen_card_table_get_card_scan_address ((mword) obj->data);
guint8 *cards_end = sgen_card_table_get_card_scan_address ((mword) obj->data + obj->size - 1);
guint8 *cards_end = sgen_card_table_get_card_scan_address ((mword) obj->data + sgen_los_object_size (obj) - 1);
mword num_cards = (cards_end - cards) + 1;
if (!SGEN_OBJECT_HAS_REFERENCES (obj->data))
@@ -655,16 +663,10 @@ sgen_los_update_cardtable_mod_union (void)
if (!SGEN_OBJECT_HAS_REFERENCES (obj->data))
continue;
sgen_card_table_update_mod_union (get_cardtable_mod_union_for_object (obj),
(char*)obj->data, obj->size, NULL);
(char*)obj->data, sgen_los_object_size (obj), NULL);
}
}
mword
sgen_los_object_size (LOSObject *obj)
{
return obj->size & ~1L;
}
LOSObject*
sgen_los_header_for_object (GCObject *data)
{

Some files were not shown because too many files have changed in this diff Show More