You've already forked linux-packaging-mono
Imported Upstream version 4.3.2.467
Former-commit-id: 9c2cb47f45fa221e661ab616387c9cda183f283d
This commit is contained in:
@@ -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 \
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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.
|
||||
*
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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]);
|
||||
|
||||
@@ -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 (©, 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)
|
||||
{
|
||||
|
||||
@@ -1 +1 @@
|
||||
2fc21552caddc04ff91dd8a266149ea98d4f0dc0
|
||||
b73c1d88ff1d2d1330fccfa95dd7c106ee86724c
|
||||
@@ -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
639
mono/sgen/sgen-gchandles.c
Normal file
File diff suppressed because it is too large
Load Diff
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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 { \
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
Reference in New Issue
Block a user