Imported Upstream version 4.6.0.125

Former-commit-id: a2155e9bd80020e49e72e86c44da02a8ac0e57a4
This commit is contained in:
Xamarin Public Jenkins (auto-signing)
2016-08-03 10:59:49 +00:00
parent a569aebcfd
commit e79aa3c0ed
17047 changed files with 3137615 additions and 392334 deletions

View File

@@ -43,7 +43,6 @@ monosgen_sources = \
sgen-los.c \
sgen-major-copy-object.h \
sgen-marksweep-drain-gray-stack.h \
sgen-marksweep-scan-object-concurrent.h \
sgen-marksweep.c \
sgen-memory-governor.c \
sgen-memory-governor.h \
@@ -55,6 +54,8 @@ monosgen_sources = \
sgen-pinning.h \
sgen-pointer-queue.c \
sgen-pointer-queue.h \
sgen-array-list.h \
sgen-array-list.c \
sgen-protocol-def.h \
sgen-protocol.c \
sgen-protocol.h \

View File

@@ -117,6 +117,7 @@ am__objects_1 = libmonosgen_static_la-sgen-alloc.lo \
libmonosgen_static_la-sgen-pinning-stats.lo \
libmonosgen_static_la-sgen-pinning.lo \
libmonosgen_static_la-sgen-pointer-queue.lo \
libmonosgen_static_la-sgen-array-list.lo \
libmonosgen_static_la-sgen-protocol.lo \
libmonosgen_static_la-sgen-qsort.lo \
libmonosgen_static_la-sgen-simple-nursery.lo \
@@ -150,6 +151,7 @@ am__objects_3 = libmonosgen_la-sgen-alloc.lo \
libmonosgen_la-sgen-pinning-stats.lo \
libmonosgen_la-sgen-pinning.lo \
libmonosgen_la-sgen-pointer-queue.lo \
libmonosgen_la-sgen-array-list.lo \
libmonosgen_la-sgen-protocol.lo libmonosgen_la-sgen-qsort.lo \
libmonosgen_la-sgen-simple-nursery.lo \
libmonosgen_la-sgen-split-nursery.lo \
@@ -315,8 +317,6 @@ NM = @NM@
NMEDIT = @NMEDIT@
OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
OPROFILE_CFLAGS = @OPROFILE_CFLAGS@
OPROFILE_LIBS = @OPROFILE_LIBS@
OTOOL = @OTOOL@
OTOOL64 = @OTOOL64@
PACKAGE = @PACKAGE@
@@ -457,7 +457,6 @@ monosgen_sources = \
sgen-los.c \
sgen-major-copy-object.h \
sgen-marksweep-drain-gray-stack.h \
sgen-marksweep-scan-object-concurrent.h \
sgen-marksweep.c \
sgen-memory-governor.c \
sgen-memory-governor.h \
@@ -469,6 +468,8 @@ monosgen_sources = \
sgen-pinning.h \
sgen-pointer-queue.c \
sgen-pointer-queue.h \
sgen-array-list.h \
sgen-array-list.c \
sgen-protocol-def.h \
sgen-protocol.c \
sgen-protocol.h \
@@ -547,6 +548,7 @@ distclean-compile:
-rm -f *.tab.c
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libmonosgen_la-sgen-alloc.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libmonosgen_la-sgen-array-list.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libmonosgen_la-sgen-cardtable.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libmonosgen_la-sgen-debug.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libmonosgen_la-sgen-descriptor.Plo@am__quote@
@@ -571,6 +573,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libmonosgen_la-sgen-thread-pool.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libmonosgen_la-sgen-workers.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libmonosgen_static_la-sgen-alloc.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libmonosgen_static_la-sgen-array-list.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libmonosgen_static_la-sgen-cardtable.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libmonosgen_static_la-sgen-debug.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libmonosgen_static_la-sgen-descriptor.Plo@am__quote@
@@ -745,6 +748,13 @@ libmonosgen_static_la-sgen-pointer-queue.lo: sgen-pointer-queue.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-pointer-queue.lo `test -f 'sgen-pointer-queue.c' || echo '$(srcdir)/'`sgen-pointer-queue.c
libmonosgen_static_la-sgen-array-list.lo: sgen-array-list.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-array-list.lo -MD -MP -MF $(DEPDIR)/libmonosgen_static_la-sgen-array-list.Tpo -c -o libmonosgen_static_la-sgen-array-list.lo `test -f 'sgen-array-list.c' || echo '$(srcdir)/'`sgen-array-list.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libmonosgen_static_la-sgen-array-list.Tpo $(DEPDIR)/libmonosgen_static_la-sgen-array-list.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='sgen-array-list.c' object='libmonosgen_static_la-sgen-array-list.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-array-list.lo `test -f 'sgen-array-list.c' || echo '$(srcdir)/'`sgen-array-list.c
libmonosgen_static_la-sgen-protocol.lo: sgen-protocol.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-protocol.lo -MD -MP -MF $(DEPDIR)/libmonosgen_static_la-sgen-protocol.Tpo -c -o libmonosgen_static_la-sgen-protocol.lo `test -f 'sgen-protocol.c' || echo '$(srcdir)/'`sgen-protocol.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libmonosgen_static_la-sgen-protocol.Tpo $(DEPDIR)/libmonosgen_static_la-sgen-protocol.Plo
@@ -913,6 +923,13 @@ libmonosgen_la-sgen-pointer-queue.lo: sgen-pointer-queue.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-pointer-queue.lo `test -f 'sgen-pointer-queue.c' || echo '$(srcdir)/'`sgen-pointer-queue.c
libmonosgen_la-sgen-array-list.lo: sgen-array-list.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-array-list.lo -MD -MP -MF $(DEPDIR)/libmonosgen_la-sgen-array-list.Tpo -c -o libmonosgen_la-sgen-array-list.lo `test -f 'sgen-array-list.c' || echo '$(srcdir)/'`sgen-array-list.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libmonosgen_la-sgen-array-list.Tpo $(DEPDIR)/libmonosgen_la-sgen-array-list.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='sgen-array-list.c' object='libmonosgen_la-sgen-array-list.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-array-list.lo `test -f 'sgen-array-list.c' || echo '$(srcdir)/'`sgen-array-list.c
libmonosgen_la-sgen-protocol.lo: sgen-protocol.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-protocol.lo -MD -MP -MF $(DEPDIR)/libmonosgen_la-sgen-protocol.Tpo -c -o libmonosgen_la-sgen-protocol.lo `test -f 'sgen-protocol.c' || echo '$(srcdir)/'`sgen-protocol.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libmonosgen_la-sgen-protocol.Tpo $(DEPDIR)/libmonosgen_la-sgen-protocol.Plo

View File

@@ -3,18 +3,7 @@
*
* Copyright (C) 2015 Xamarin Inc
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License 2.0 as published by the Free Software Foundation;
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License 2.0 along with this library; if not, write to the Free
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
* Licensed under the MIT license. See LICENSE file in the project root for full license information.
*/
#ifndef __MONO_METADATA_GCINTERNALAGNOSTIC_H__

View File

@@ -10,18 +10,7 @@
* Copyright 2011 Xamarin, Inc.
* Copyright (C) 2012 Xamarin Inc
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License 2.0 as published by the Free Software Foundation;
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License 2.0 along with this library; if not, write to the Free
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
* Licensed under the MIT license. See LICENSE file in the project root for full license information.
*/
/*
@@ -79,6 +68,9 @@ static __thread char *tlab_temp_end;
static __thread char *tlab_real_end;
/* Used by the managed allocator/wbarrier */
static __thread char **tlab_next_addr MONO_ATTR_USED;
#ifndef SGEN_WITHOUT_MONO
static __thread volatile int *in_critical_region_addr MONO_ATTR_USED;
#endif
#endif
#ifdef HAVE_KW_THREAD
@@ -101,10 +93,10 @@ alloc_degraded (GCVTable vtable, size_t size, gboolean for_mature)
if (!for_mature) {
sgen_client_degraded_allocation (size);
SGEN_ATOMIC_ADD_P (degraded_mode, size);
sgen_ensure_free_space (size);
sgen_ensure_free_space (size, GENERATION_OLD);
} else {
if (sgen_need_major_collection (size))
sgen_perform_collection (size, GENERATION_OLD, "mature allocation failure", !for_mature);
sgen_perform_collection (size, GENERATION_OLD, "mature allocation failure", !for_mature, TRUE);
}
@@ -172,7 +164,7 @@ sgen_alloc_obj_nolock (GCVTable vtable, size_t size)
if (collect_before_allocs) {
if (((current_alloc % collect_before_allocs) == 0) && nursery_section) {
sgen_perform_collection (0, GENERATION_NURSERY, "collect-before-alloc-triggered", TRUE);
sgen_perform_collection (0, GENERATION_NURSERY, "collect-before-alloc-triggered", TRUE, TRUE);
if (!degraded_mode && sgen_can_alloc_size (size) && real_size <= SGEN_MAX_SMALL_OBJ_SIZE) {
// FIXME:
g_assert_not_reached ();
@@ -208,11 +200,6 @@ sgen_alloc_obj_nolock (GCVTable vtable, size_t size)
if (G_LIKELY (new_next < TLAB_TEMP_END)) {
/* Fast path */
/*
* FIXME: We might need a memory barrier here so the change to tlab_next is
* visible before the vtable store.
*/
CANARIFY_ALLOC(p,real_size);
SGEN_LOG (6, "Allocated object %p, vtable: %p (%s), size: %zd", p, vtable, sgen_client_vtable_get_name (vtable), size);
binary_protocol_alloc (p , vtable, size, sgen_client_get_provenance ());
@@ -271,7 +258,7 @@ sgen_alloc_obj_nolock (GCVTable vtable, size_t size)
* always loop we will loop endlessly in the case of
* OOM).
*/
sgen_ensure_free_space (real_size);
sgen_ensure_free_space (real_size, GENERATION_NURSERY);
if (!degraded_mode)
p = (void **)sgen_nursery_alloc (size);
}
@@ -288,7 +275,7 @@ sgen_alloc_obj_nolock (GCVTable vtable, size_t 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);
sgen_ensure_free_space (tlab_size, GENERATION_NURSERY);
if (!degraded_mode)
p = (void **)sgen_nursery_alloc_range (tlab_size, size, &alloc_size);
}
@@ -426,8 +413,6 @@ sgen_alloc_obj (GCVTable vtable, size_t size)
if (!SGEN_CAN_ALIGN_UP (size))
return NULL;
#ifndef DISABLE_CRITICAL_REGION
if (G_UNLIKELY (has_per_allocation_action)) {
static int alloc_count;
int current_alloc = InterlockedIncrement (&alloc_count);
@@ -439,7 +424,7 @@ sgen_alloc_obj (GCVTable vtable, size_t size)
if (collect_before_allocs) {
if (((current_alloc % collect_before_allocs) == 0) && nursery_section) {
LOCK_GC;
sgen_perform_collection (0, GENERATION_NURSERY, "collect-before-alloc-triggered", TRUE);
sgen_perform_collection (0, GENERATION_NURSERY, "collect-before-alloc-triggered", TRUE, TRUE);
UNLOCK_GC;
}
}
@@ -452,12 +437,10 @@ sgen_alloc_obj (GCVTable vtable, size_t size)
return res;
}
EXIT_CRITICAL_REGION;
#endif
LOCK_GC;
res = sgen_alloc_obj_nolock (vtable, size);
UNLOCK_GC;
if (G_UNLIKELY (!res))
sgen_client_out_of_memory (size);
return res;
}
@@ -521,6 +504,9 @@ sgen_init_tlab_info (SgenThreadInfo* info)
#ifdef HAVE_KW_THREAD
tlab_next_addr = &tlab_next;
#ifndef SGEN_WITHOUT_MONO
in_critical_region_addr = &info->client_info.in_critical_region;
#endif
#endif
}
@@ -545,13 +531,15 @@ sgen_init_allocator (void)
#if defined(HAVE_KW_THREAD) && !defined(SGEN_WITHOUT_MONO)
int tlab_next_addr_offset = -1;
int tlab_temp_end_offset = -1;
int in_critical_region_addr_offset = -1;
MONO_THREAD_VAR_OFFSET (tlab_next_addr, tlab_next_addr_offset);
MONO_THREAD_VAR_OFFSET (tlab_temp_end, tlab_temp_end_offset);
MONO_THREAD_VAR_OFFSET (in_critical_region_addr, in_critical_region_addr_offset);
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);
mono_tls_key_set_offset (TLS_KEY_SGEN_IN_CRITICAL_REGION_ADDR, in_critical_region_addr_offset);
#endif
#ifdef HEAVY_STATISTICS

View File

@@ -5,88 +5,33 @@
* Copyright 2003-2010 Novell, Inc.
* Copyright (C) 2012 Xamarin Inc
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License 2.0 as published by the Free Software Foundation;
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License 2.0 along with this library; if not, write to the Free
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
* Licensed under the MIT license. See LICENSE file in the project root for full license information.
*/
#ifndef __MONO_SGENARCHDEP_H__
#define __MONO_SGENARCHDEP_H__
#include <mono/utils/mono-context.h>
/*
* Define either USE_MONO_CTX, or
* ARCH_SIGCTX_SP/ARCH_SIGCTX_IP/ARCH_STORE_REGS/ARCH_COPY_SIGCTX_REGS.
* Define ARCH_NUM_REGS to be the number of general registers in MonoContext, or the
* number of registers stored by ARCH_STORE_REGS.
*/
#if defined(MONO_CROSS_COMPILE)
#define REDZONE_SIZE 0
#define ARCH_NUM_REGS 0
#define ARCH_STORE_REGS(ptr)
#define ARCH_SIGCTX_SP(ctx) NULL
#define ARCH_SIGCTX_IP(ctx) NULL
#define ARCH_COPY_SIGCTX_REGS(a,ctx)
#elif defined(TARGET_X86)
#define REDZONE_SIZE 0
#define ARCH_NUM_REGS 8
#ifndef MONO_ARCH_HAS_MONO_CONTEXT
#error 0
#endif
#define USE_MONO_CTX
#elif defined(TARGET_AMD64)
#define REDZONE_SIZE 128
#define ARCH_NUM_REGS 16
#define USE_MONO_CTX
#elif defined(TARGET_POWERPC)
#define REDZONE_SIZE 224
#define ARCH_NUM_REGS 32
#ifdef __APPLE__
#define ARCH_STORE_REGS(ptr) \
__asm__ __volatile__( \
"stmw r0, 0(%0)\n" \
: \
: "b" (ptr) \
)
#else
#define ARCH_STORE_REGS(ptr) \
__asm__ __volatile__( \
"stmw 0, 0(%0)\n" \
: \
: "b" (ptr) \
)
#endif
#define ARCH_SIGCTX_SP(ctx) (UCONTEXT_REG_Rn((ctx), 1))
#define ARCH_SIGCTX_IP(ctx) (UCONTEXT_REG_NIP((ctx)))
#define ARCH_COPY_SIGCTX_REGS(a,ctx) do { \
int __i; \
for (__i = 0; __i < 32; ++__i) \
((a)[__i]) = (gpointer) UCONTEXT_REG_Rn((ctx), __i); \
} while (0)
/* MS_BLOCK_SIZE must be a multiple of the system pagesize, which for some
architectures is 64k. */
#if defined(TARGET_POWERPC) || defined(TARGET_POWERPC64)
@@ -97,10 +42,6 @@
#elif defined(TARGET_ARM)
#define REDZONE_SIZE 0
#define USE_MONO_CTX
/* We dont store ip, sp */
#define ARCH_NUM_REGS 14
#elif defined(TARGET_ARM64)
@@ -111,99 +52,19 @@
#else
#error "Not implemented."
#endif
#define USE_MONO_CTX
#define ARCH_NUM_REGS 31
#elif defined(__mips__)
#define REDZONE_SIZE 0
#define USE_MONO_CTX
#define ARCH_NUM_REGS 32
#elif defined(__s390x__)
#define REDZONE_SIZE 0
#define USE_MONO_CTX
#define ARCH_NUM_REGS 16
#elif defined(__sparc__)
#define REDZONE_SIZE 0
/* Don't bother with %g0 (%r0), it's always hard-coded to zero */
#define ARCH_NUM_REGS 15
#ifdef __sparcv9
#define ARCH_STORE_REGS(ptr) \
__asm__ __volatile__( \
"st %%g1,[%0]\n\t" \
"st %%g2,[%0+0x08]\n\t" \
"st %%g3,[%0+0x10]\n\t" \
"st %%g4,[%0+0x18]\n\t" \
"st %%g5,[%0+0x20]\n\t" \
"st %%g6,[%0+0x28]\n\t" \
"st %%g7,[%0+0x30]\n\t" \
"st %%o0,[%0+0x38]\n\t" \
"st %%o1,[%0+0x40]\n\t" \
"st %%o2,[%0+0x48]\n\t" \
"st %%o3,[%0+0x50]\n\t" \
"st %%o4,[%0+0x58]\n\t" \
"st %%o5,[%0+0x60]\n\t" \
"st %%o6,[%0+0x68]\n\t" \
"st %%o7,[%0+0x70]\n\t" \
: \
: "r" (ptr) \
: "memory" \
)
#else
#define ARCH_STORE_REGS(ptr) \
__asm__ __volatile__( \
"st %%g1,[%0]\n\t" \
"st %%g2,[%0+0x04]\n\t" \
"st %%g3,[%0+0x08]\n\t" \
"st %%g4,[%0+0x0c]\n\t" \
"st %%g5,[%0+0x10]\n\t" \
"st %%g6,[%0+0x14]\n\t" \
"st %%g7,[%0+0x18]\n\t" \
"st %%o0,[%0+0x1c]\n\t" \
"st %%o1,[%0+0x20]\n\t" \
"st %%o2,[%0+0x24]\n\t" \
"st %%o3,[%0+0x28]\n\t" \
"st %%o4,[%0+0x2c]\n\t" \
"st %%o5,[%0+0x30]\n\t" \
"st %%o6,[%0+0x34]\n\t" \
"st %%o7,[%0+0x38]\n\t" \
: \
: "r" (ptr) \
: "memory" \
)
#endif
#ifndef REG_SP
#define REG_SP REG_O6
#endif
#define ARCH_SIGCTX_SP(ctx) (((ucontext_t *)(ctx))->uc_mcontext.gregs [REG_SP])
#define ARCH_SIGCTX_IP(ctx) (((ucontext_t *)(ctx))->uc_mcontext.gregs [REG_PC])
#define ARCH_COPY_SIGCTX_REGS(a,ctx) do { \
(a)[0] = (gpointer) (((ucontext_t *)(ctx))->uc_mcontext.gregs [REG_G1]); \
(a)[1] = (gpointer) (((ucontext_t *)(ctx))->uc_mcontext.gregs [REG_G2]); \
(a)[2] = (gpointer) (((ucontext_t *)(ctx))->uc_mcontext.gregs [REG_G3]); \
(a)[3] = (gpointer) (((ucontext_t *)(ctx))->uc_mcontext.gregs [REG_G4]); \
(a)[4] = (gpointer) (((ucontext_t *)(ctx))->uc_mcontext.gregs [REG_G5]); \
(a)[5] = (gpointer) (((ucontext_t *)(ctx))->uc_mcontext.gregs [REG_G6]); \
(a)[6] = (gpointer) (((ucontext_t *)(ctx))->uc_mcontext.gregs [REG_G7]); \
(a)[7] = (gpointer) (((ucontext_t *)(ctx))->uc_mcontext.gregs [REG_O0]); \
(a)[8] = (gpointer) (((ucontext_t *)(ctx))->uc_mcontext.gregs [REG_O1]); \
(a)[9] = (gpointer) (((ucontext_t *)(ctx))->uc_mcontext.gregs [REG_O2]); \
(a)[10] = (gpointer) (((ucontext_t *)(ctx))->uc_mcontext.gregs [REG_O3]); \
(a)[11] = (gpointer) (((ucontext_t *)(ctx))->uc_mcontext.gregs [REG_O4]); \
(a)[12] = (gpointer) (((ucontext_t *)(ctx))->uc_mcontext.gregs [REG_O5]); \
(a)[13] = (gpointer) (((ucontext_t *)(ctx))->uc_mcontext.gregs [REG_O6]); \
(a)[14] = (gpointer) (((ucontext_t *)(ctx))->uc_mcontext.gregs [REG_O7]); \
} while (0)
#endif
#endif /* __MONO_SGENARCHDEP_H__ */

213
mono/sgen/sgen-array-list.c Normal file
View File

@@ -0,0 +1,213 @@
/*
* sgen-array-list.c: A pointer array list that doesn't require reallocs
*
* Copyright (C) 2016 Xamarin Inc
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License 2.0 as published by the Free Software Foundation;
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License 2.0 along with this library; if not, write to the Free
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifdef HAVE_SGEN_GC
#include <string.h>
#include "mono/sgen/sgen-gc.h"
#include "mono/sgen/sgen-array-list.h"
static void
sgen_array_list_grow (SgenArrayList *array, guint32 old_capacity)
{
const guint32 new_bucket = sgen_array_list_index_bucket (old_capacity);
const guint32 growth = sgen_array_list_bucket_size (new_bucket);
const guint32 new_capacity = old_capacity + growth;
const guint32 new_bucket_size = sizeof (**array->entries) * growth;
gpointer *entries;
if (array->capacity >= new_capacity)
return;
if (array->mem_type != -1)
entries = (gpointer*) sgen_alloc_internal_dynamic (new_bucket_size, array->mem_type, TRUE);
else
entries = (gpointer*) g_malloc0 (new_bucket_size);
if (array->bucket_alloc_callback)
array->bucket_alloc_callback (entries, new_bucket_size, TRUE);
/*
* The zeroing of the newly allocated bucket must be complete before storing
* the new bucket pointer.
*/
mono_memory_write_barrier ();
if (InterlockedCompareExchangePointer ((volatile gpointer *)&array->entries [new_bucket], entries, NULL) == NULL) {
/*
* It must not be the case that we succeeded in setting the bucket
* pointer, while someone else succeeded in changing the capacity.
*/
if (InterlockedCompareExchange ((volatile gint32 *)&array->capacity, new_capacity, old_capacity) != old_capacity)
g_assert_not_reached ();
array->slot_hint = old_capacity;
return;
}
/* Someone beat us to the allocation. */
if (array->bucket_alloc_callback)
array->bucket_alloc_callback (entries, new_bucket_size, FALSE);
if (array->mem_type != -1)
sgen_free_internal_dynamic (entries, new_bucket_size, array->mem_type);
else
g_free (entries);
}
static guint32
sgen_array_list_find_unset (SgenArrayList *array, guint32 capacity)
{
if (!array->is_slot_set_func) {
guint32 next_slot = array->next_slot;
/* We can't lookup empty slots, use next_slot */
if (next_slot < capacity)
return next_slot;
} else {
guint32 slot_hint = array->slot_hint;
guint32 index;
volatile gpointer *slot;
SGEN_ARRAY_LIST_FOREACH_SLOT_RANGE(array, slot_hint, capacity, slot, index) {
if (!array->is_slot_set_func (slot))
return index;
} SGEN_ARRAY_LIST_END_FOREACH_SLOT_RANGE;
SGEN_ARRAY_LIST_FOREACH_SLOT_RANGE (array, 0, slot_hint, slot, index) {
if (!array->is_slot_set_func (slot))
return index;
} SGEN_ARRAY_LIST_END_FOREACH_SLOT_RANGE;
}
return -1;
}
static void
sgen_array_list_update_next_slot (SgenArrayList *array, guint32 new_index)
{
if (!array->set_slot_func) {
/*
* If we don't have a custom setter it means we don't have thread
* safety requirements.
*/
if (new_index >= array->next_slot)
array->next_slot = new_index + 1;
} else {
guint32 old_next_slot;
/* Thread safe update */
do {
old_next_slot = array->next_slot;
if (new_index < old_next_slot)
break;
} while (InterlockedCompareExchange ((volatile gint32 *)&array->next_slot, new_index + 1, old_next_slot) != old_next_slot);
}
}
/*
* Extension for the array list that allows fast allocation and index based fetching
* of long lived memory of various sizes, without the need of realloc. Not thread safe.
*/
guint32
sgen_array_list_alloc_block (SgenArrayList *array, guint32 slots_to_add)
{
guint32 new_index = array->next_slot;
guint32 old_capacity = array->capacity;
/* FIXME Don't allocate arrays that will be skipped */
/* There are no empty arrays between next_slot and capacity because we allocate incrementally */
while ((old_capacity - new_index) < slots_to_add) {
sgen_array_list_grow (array, old_capacity);
new_index = old_capacity;
old_capacity = array->capacity;
}
SGEN_ASSERT (0, sgen_array_list_index_bucket (new_index) == sgen_array_list_index_bucket (new_index + slots_to_add - 1),
"We failed to allocate a continuous block of slots");
array->next_slot = new_index + slots_to_add;
/* The slot address will point to the allocated memory */
return new_index;
}
guint32
sgen_array_list_add (SgenArrayList *array, gpointer ptr, int data, gboolean increase_size_before_set)
{
guint32 index, capacity;
volatile gpointer *slot;
if (!array->capacity)
sgen_array_list_grow (array, 0);
retry:
capacity = array->capacity;
index = sgen_array_list_find_unset (array, capacity);
if (index == -1) {
sgen_array_list_grow (array, capacity);
goto retry;
}
array->slot_hint = index;
if (increase_size_before_set) {
sgen_array_list_update_next_slot (array, index);
mono_memory_write_barrier ();
}
slot = sgen_array_list_get_slot (array, index);
if (array->set_slot_func) {
if (!array->set_slot_func (slot, ptr, data))
goto retry;
} else {
*slot = ptr;
}
if (!increase_size_before_set) {
mono_memory_write_barrier ();
sgen_array_list_update_next_slot (array, index);
}
return index;
}
/*
* Removes all NULL pointers from the array. Not thread safe
*/
void
sgen_array_list_remove_nulls (SgenArrayList *array)
{
guint32 start = 0;
volatile gpointer *slot;
SGEN_ARRAY_LIST_FOREACH_SLOT (array, slot) {
if (*slot)
*sgen_array_list_get_slot (array, start++) = *slot;
} SGEN_ARRAY_LIST_END_FOREACH_SLOT;
mono_memory_write_barrier ();
array->next_slot = start;
}
/*
* Does a linear search through the pointer array to find `ptr`. Returns the index if
* found, otherwise (guint32)-1.
*/
guint32
sgen_array_list_find (SgenArrayList *array, gpointer ptr)
{
volatile gpointer *slot;
SGEN_ARRAY_LIST_FOREACH_SLOT (array, slot) {
if (*slot == ptr)
return __index;
} SGEN_ARRAY_LIST_END_FOREACH_SLOT;
return (guint32)-1;
}
#endif

137
mono/sgen/sgen-array-list.h Normal file
View File

@@ -0,0 +1,137 @@
/*
* sgen-array-list.h: A pointer array that doesn't use reallocs.
*
* Copyright (C) 2016 Xamarin Inc
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License 2.0 as published by the Free Software Foundation;
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License 2.0 along with this library; if not, write to the Free
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef __MONO_SGEN_ARRAY_LIST_H__
#define __MONO_SGEN_ARRAY_LIST_H__
#include <glib.h>
#define SGEN_ARRAY_LIST_BUCKETS (32)
#define SGEN_ARRAY_LIST_MIN_BUCKET_BITS (5)
#define SGEN_ARRAY_LIST_MIN_BUCKET_SIZE (1 << SGEN_ARRAY_LIST_MIN_BUCKET_BITS)
typedef void (*SgenArrayListBucketAllocCallback) (gpointer *bucket, guint32 new_bucket_size, gboolean alloc);
typedef gboolean (*SgenArrayListIsSlotSetFunc) (volatile gpointer *slot);
typedef gboolean (*SgenArrayListSetSlotFunc) (volatile gpointer *slot, gpointer ptr, int data);
/*
* 'entries' is an array of pointers to buckets of increasing size. The first
* bucket has size 'MIN_BUCKET_SIZE', and each bucket is twice the size of the
* previous, i.e.:
*
* |-------|-- MIN_BUCKET_SIZE
* [0] -> xxxxxxxx
* [1] -> xxxxxxxxxxxxxxxx
* [2] -> xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
* ...
*
* 'slot_hint' denotes the position of the last allocation, so that the
* whole array needn't be searched on every allocation.
*
* The size of the spine, 'SGEN_ARRAY_LIST_BUCKETS', is chosen so
* that the maximum number of entries is no less than G_MAXUINT32.
*/
typedef struct {
volatile gpointer *volatile entries [SGEN_ARRAY_LIST_BUCKETS];
volatile guint32 capacity;
volatile guint32 slot_hint;
volatile guint32 next_slot;
SgenArrayListBucketAllocCallback bucket_alloc_callback;
SgenArrayListIsSlotSetFunc is_slot_set_func;
SgenArrayListSetSlotFunc set_slot_func;
int mem_type; /* sgen internal mem type or -1 for malloc allocation */
} SgenArrayList;
/*
* Computes floor(log2(index + MIN_BUCKET_SIZE)) - 1, giving the index
* of the bucket containing a slot.
*/
static inline guint32
sgen_array_list_index_bucket (guint32 index)
{
#ifdef __GNUC__
return CHAR_BIT * sizeof (index) - __builtin_clz (index + SGEN_ARRAY_LIST_MIN_BUCKET_SIZE) - 1 - SGEN_ARRAY_LIST_MIN_BUCKET_BITS;
#else
guint count = 0;
index += SGEN_ARRAY_LIST_MIN_BUCKET_SIZE;
while (index) {
++count;
index >>= 1;
}
return count - 1 - SGEN_ARRAY_LIST_MIN_BUCKET_BITS;
#endif
}
static inline guint32
sgen_array_list_bucket_size (guint32 index)
{
return 1 << (index + SGEN_ARRAY_LIST_MIN_BUCKET_BITS);
}
static inline void
sgen_array_list_bucketize (guint32 index, guint32 *bucket, guint32 *offset)
{
*bucket = sgen_array_list_index_bucket (index);
*offset = index - sgen_array_list_bucket_size (*bucket) + SGEN_ARRAY_LIST_MIN_BUCKET_SIZE;
}
static inline volatile gpointer *
sgen_array_list_get_slot (SgenArrayList *array, guint32 index)
{
guint32 bucket, offset;
SGEN_ASSERT (0, index < array->capacity, "Why are we accessing an entry that is not allocated");
sgen_array_list_bucketize (index, &bucket, &offset);
return &(array->entries [bucket] [offset]);
}
#define SGEN_ARRAY_LIST_INIT(bucket_alloc_callback, is_slot_set_func, set_slot_func, mem_type) { { NULL }, 0, 0, 0, (bucket_alloc_callback), (is_slot_set_func), (set_slot_func), (mem_type) }
#define SGEN_ARRAY_LIST_FOREACH_SLOT(array, slot) { \
guint32 __bucket, __offset; \
const guint32 __max_bucket = sgen_array_list_index_bucket ((array)->capacity); \
guint32 __index = 0; \
const guint32 __next_slot = (array)->next_slot; \
for (__bucket = 0; __bucket < __max_bucket; ++__bucket) { \
volatile gpointer *__entries = (array)->entries [__bucket]; \
for (__offset = 0; __offset < sgen_array_list_bucket_size (__bucket); ++__offset, ++__index) { \
if (__index >= __next_slot) \
break; \
slot = &__entries [__offset];
#define SGEN_ARRAY_LIST_END_FOREACH_SLOT } } }
#define SGEN_ARRAY_LIST_FOREACH_SLOT_RANGE(array, begin, end, slot, index) { \
for (index = (begin); index < (end); index++) { \
guint32 __bucket, __offset; \
volatile gpointer *__entries; \
sgen_array_list_bucketize (index, &__bucket, &__offset); \
__entries = (array)->entries [__bucket]; \
slot = &__entries [__offset];
#define SGEN_ARRAY_LIST_END_FOREACH_SLOT_RANGE } }
guint32 sgen_array_list_alloc_block (SgenArrayList *array, guint32 slots_to_add);
guint32 sgen_array_list_add (SgenArrayList *array, gpointer ptr, int data, gboolean increase_size_before_set);
guint32 sgen_array_list_find (SgenArrayList *array, gpointer ptr);
void sgen_array_list_remove_nulls (SgenArrayList *array);
#endif

View File

@@ -9,18 +9,7 @@
* Copyright 2011 Xamarin Inc (http://www.xamarin.com)
* Copyright (C) 2012 Xamarin Inc
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License 2.0 as published by the Free Software Foundation;
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License 2.0 along with this library; if not, write to the Free
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
* Licensed under the MIT license. See LICENSE file in the project root for full license information.
*/
#include "config.h"
@@ -119,19 +108,13 @@ sgen_card_table_wbarrier_value_copy (gpointer dest, gpointer src, int count, siz
{
size_t size = count * element_size;
#ifdef DISABLE_CRITICAL_REGION
LOCK_GC;
#else
TLAB_ACCESS_INIT;
ENTER_CRITICAL_REGION;
#endif
mono_gc_memmove_atomic (dest, src, size);
sgen_card_table_mark_range ((mword)dest, size);
#ifdef DISABLE_CRITICAL_REGION
UNLOCK_GC;
#else
EXIT_CRITICAL_REGION;
#endif
}
static void
@@ -139,20 +122,14 @@ sgen_card_table_wbarrier_object_copy (GCObject* obj, GCObject *src)
{
size_t size = sgen_client_par_object_get_size (SGEN_LOAD_VTABLE_UNCHECKED (obj), obj);
#ifdef DISABLE_CRITICAL_REGION
LOCK_GC;
#else
TLAB_ACCESS_INIT;
ENTER_CRITICAL_REGION;
#endif
mono_gc_memmove_aligned ((char*)obj + SGEN_CLIENT_OBJECT_HEADER_SIZE, (char*)src + SGEN_CLIENT_OBJECT_HEADER_SIZE,
size - SGEN_CLIENT_OBJECT_HEADER_SIZE);
sgen_card_table_mark_range ((mword)obj, size);
#ifdef DISABLE_CRITICAL_REGION
UNLOCK_GC;
#else
EXIT_CRITICAL_REGION;
#endif
}
static void
@@ -354,6 +331,29 @@ sgen_card_table_update_mod_union (guint8 *dest, char *obj, mword obj_size, size_
*out_num_cards = num_cards;
}
/* Preclean cards and saves the cards that need to be scanned afterwards in cards_preclean */
void
sgen_card_table_preclean_mod_union (guint8 *cards, guint8 *cards_preclean, size_t num_cards)
{
size_t i;
memcpy (cards_preclean, cards, num_cards);
for (i = 0; i < num_cards; i++) {
if (cards_preclean [i]) {
cards [i] = 0;
}
}
/*
* When precleaning we need to make sure the card cleaning
* takes place before the object is scanned. If we don't
* do this we could finish scanning the object and, before
* the cleaning of the card takes place, another thread
* could dirty the object, mark the mod_union card only for
* us to clean it back, without scanning the object again.
*/
mono_memory_barrier ();
}
#ifdef SGEN_HAVE_OVERLAPPING_CARDS
static void
@@ -438,11 +438,11 @@ sgen_card_table_scan_remsets (ScanCopyContext ctx)
sgen_card_table_clear_cards ();
#endif
SGEN_TV_GETTIME (atv);
sgen_get_major_collector ()->scan_card_table (FALSE, ctx);
sgen_get_major_collector ()->scan_card_table (CARDTABLE_SCAN_GLOBAL, ctx);
SGEN_TV_GETTIME (btv);
last_major_scan_time = SGEN_TV_ELAPSED (atv, btv);
major_card_scan_time += last_major_scan_time;
sgen_los_scan_card_table (FALSE, ctx);
sgen_los_scan_card_table (CARDTABLE_SCAN_GLOBAL, ctx);
SGEN_TV_GETTIME (atv);
last_los_scan_time = SGEN_TV_ELAPSED (btv, atv);
los_card_scan_time += last_los_scan_time;
@@ -489,11 +489,11 @@ sgen_card_table_dump_obj_card (GCObject *object, size_t size, void *dummy)
#endif
void
sgen_cardtable_scan_object (GCObject *obj, mword block_obj_size, guint8 *cards, gboolean mod_union, ScanCopyContext ctx)
sgen_cardtable_scan_object (GCObject *obj, mword block_obj_size, guint8 *cards, ScanCopyContext ctx)
{
HEAVY_STAT (++large_objects);
if (sgen_client_cardtable_scan_object (obj, block_obj_size, cards, mod_union, ctx))
if (sgen_client_cardtable_scan_object (obj, block_obj_size, cards, ctx))
return;
HEAVY_STAT (++bloby_objects);

View File

@@ -2,24 +2,7 @@
* Copyright 2001-2003 Ximian, Inc
* Copyright 2003-2010 Novell, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* Licensed under the MIT license. See LICENSE file in the project root for full license information.
*/
#ifndef __MONO_SGEN_CARD_TABLE_INLINES_H__
#define __MONO_SGEN_CARD_TABLE_INLINES_H__
@@ -31,7 +14,7 @@ void sgen_card_table_reset_region (mword start, mword end);
void* sgen_card_table_align_pointer (void *ptr);
void sgen_card_table_mark_range (mword address, mword size);
void sgen_cardtable_scan_object (GCObject *obj, mword obj_size, guint8 *cards,
gboolean mod_union, ScanCopyContext ctx);
ScanCopyContext ctx);
gboolean sgen_card_table_get_card_data (guint8 *dest, mword address, mword cards);
@@ -40,6 +23,7 @@ void sgen_card_table_free_mod_union (guint8 *mod_union, char *obj, mword obj_siz
void sgen_card_table_update_mod_union_from_cards (guint8 *dest, guint8 *start_card, size_t num_cards);
void sgen_card_table_update_mod_union (guint8 *dest, char *obj, mword obj_size, size_t *out_num_cards);
void sgen_card_table_preclean_mod_union (guint8 *cards, guint8 *cards_preclean, size_t num_cards);
guint8* sgen_get_card_table_configuration (int *shift_bits, gpointer *mask);

View File

@@ -3,18 +3,7 @@
*
* Copyright (C) 2014 Xamarin Inc
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License 2.0 as published by the Free Software Foundation;
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License 2.0 along with this library; if not, write to the Free
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
* Licensed under the MIT license. See LICENSE file in the project root for full license information.
*/
#include "mono/sgen/sgen-pointer-queue.h"
@@ -105,7 +94,7 @@ void sgen_client_ensure_weak_gchandles_accessible (void);
* parts of the object based on which cards are marked, do so and return TRUE. Otherwise,
* return FALSE.
*/
gboolean sgen_client_cardtable_scan_object (GCObject *obj, mword block_obj_size, guint8 *cards, gboolean mod_union, ScanCopyContext ctx);
gboolean sgen_client_cardtable_scan_object (GCObject *obj, mword block_obj_size, guint8 *cards, ScanCopyContext ctx);
/*
* Called after nursery objects have been pinned. No action is necessary.
@@ -140,14 +129,6 @@ void sgen_client_degraded_allocation (size_t size);
*/
void sgen_client_total_allocated_heap_changed (size_t allocated_heap_size);
/*
* Called when an object allocation fails. The suggested action is to abort the program.
*
* FIXME: Don't we want to return a BOOL here that indicates whether to retry the
* allocation?
*/
void sgen_client_out_of_memory (size_t size);
/*
* If the client has registered any internal memory types, this must return a string
* describing the given type. Only used for debugging.
@@ -193,7 +174,7 @@ void sgen_client_scan_thread_data (void *start_nursery, void *end_nursery, gbool
* single-threaded programs this is a nop.
*/
void sgen_client_stop_world (int generation);
void sgen_client_restart_world (int generation, GGTimingInfo *timing);
void sgen_client_restart_world (int generation, gint64 *stw_time);
/*
* Must return FALSE. The bridge is not supported outside of Mono.
@@ -216,12 +197,6 @@ void sgen_client_bridge_register_finalized_object (GCObject *object);
void sgen_client_mark_togglerefs (char *start, char *end, ScanCopyContext ctx);
void sgen_client_clear_togglerefs (char *start, char *end, ScanCopyContext ctx);
/*
* Called after collections, reporting the amount of time they took. No action is
* necessary.
*/
void sgen_client_log_timing (GGTimingInfo *info, mword last_major_num_sections, mword last_los_memory_usage);
/*
* Called to handle `MONO_GC_PARAMS` and `MONO_GC_DEBUG` options. The `handle` functions
* must return TRUE if they have recognized and processed the option, FALSE otherwise.

View File

@@ -6,18 +6,7 @@
* Copyright 2011 Xamarin Inc (http://www.xamarin.com)
* Copyright (C) 2012 Xamarin Inc
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License 2.0 as published by the Free Software Foundation;
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License 2.0 along with this library; if not, write to the Free
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
* Licensed under the MIT license. See LICENSE file in the project root for full license information.
*/
#ifndef __MONO_SGENCONF_H__
#define __MONO_SGENCONF_H__
@@ -190,12 +179,6 @@ typedef mword SgenDescriptor;
*/
#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

@@ -5,18 +5,7 @@
* Copyright 2003-2010 Novell, Inc.
* Copyright (C) 2012 Xamarin Inc
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License 2.0 as published by the Free Software Foundation;
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License 2.0 along with this library; if not, write to the Free
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
* Licensed under the MIT license. See LICENSE file in the project root for full license information.
*/
extern guint64 stat_copy_object_called_nursery;

View File

@@ -10,18 +10,7 @@
* Copyright 2011 Xamarin, Inc.
* Copyright (C) 2012 Xamarin Inc
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License 2.0 as published by the Free Software Foundation;
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License 2.0 along with this library; if not, write to the Free
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
* Licensed under the MIT license. See LICENSE file in the project root for full license information.
*/
#include "config.h"
@@ -504,10 +493,10 @@ static void
find_pinning_ref_from_thread (char *obj, size_t size)
{
#ifndef SGEN_WITHOUT_MONO
int j;
char *endobj = obj + size;
FOREACH_THREAD (info) {
mword *ctxstart, *ctxcurrent, *ctxend;
char **start = (char**)info->client_info.stack_start;
if (info->client_info.skip || info->client_info.gc_disabled)
continue;
@@ -517,15 +506,11 @@ find_pinning_ref_from_thread (char *obj, size_t size)
start++;
}
for (j = 0; j < ARCH_NUM_REGS; ++j) {
#ifdef USE_MONO_CTX
mword w = ((mword*)&info->client_info.ctx) [j];
#else
mword w = (mword)&info->client_info.regs [j];
#endif
for (ctxstart = ctxcurrent = (mword*) &info->client_info.ctx, ctxend = (mword*) (&info->client_info.ctx + 1); ctxcurrent < ctxend; ctxcurrent ++) {
mword w = *ctxcurrent;
if (w >= (mword)obj && w < (mword)obj + size)
SGEN_LOG (0, "Object %p referenced in saved reg %d of thread %p (id %p)", obj, j, info, (gpointer)mono_thread_info_get_tid (info));
SGEN_LOG (0, "Object %p referenced in saved reg %d of thread %p (id %p)", obj, (int) (ctxcurrent - ctxstart), info, (gpointer)mono_thread_info_get_tid (info));
}
} FOREACH_THREAD_END
#endif
@@ -1007,9 +992,11 @@ check_reference_for_xdomain (GCObject **ptr, GCObject *obj, MonoDomain *domain)
break;
}
if (ref->vtable->klass == mono_defaults.string_class)
str = mono_string_to_utf8 ((MonoString*)ref);
else
if (ref->vtable->klass == mono_defaults.string_class) {
MonoError error;
str = mono_string_to_utf8_checked ((MonoString*)ref, &error);
mono_error_cleanup (&error);
} else
str = NULL;
g_print ("xdomain reference in %p (%s.%s) at offset %d (%s) to %p (%s.%s) (%s) - pointed to by:\n",
obj, obj->vtable->klass->name_space, obj->vtable->klass->name,

View File

@@ -6,18 +6,7 @@
* Copyright 2011 Xamarin Inc (http://www.xamarin.com)
* Copyright (C) 2012 Xamarin Inc
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License 2.0 as published by the Free Software Foundation;
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License 2.0 along with this library; if not, write to the Free
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
* Licensed under the MIT license. See LICENSE file in the project root for full license information.
*/
#include "config.h"
#ifdef HAVE_SGEN_GC
@@ -44,6 +33,7 @@
#include "mono/sgen/sgen-gc.h"
#include "mono/sgen/gc-internal-agnostic.h"
#include "mono/sgen/sgen-array-list.h"
#define MAX_USER_DESCRIPTORS 16
@@ -51,9 +41,7 @@
#define ALIGN_TO(val,align) ((((guint64)val) + ((align) - 1)) & ~((align) - 1))
static gsize* complex_descriptors = NULL;
static int complex_descriptors_size = 0;
static int complex_descriptors_next = 0;
static SgenArrayList complex_descriptors = SGEN_ARRAY_LIST_INIT (NULL, NULL, NULL, INTERNAL_MEM_COMPLEX_DESCRIPTORS);
static SgenUserRootMarkFunc user_descriptors [MAX_USER_DESCRIPTORS];
static int user_descriptors_next = 0;
static SgenDescriptor all_ref_root_descrs [32];
@@ -67,43 +55,50 @@ static int
alloc_complex_descriptor (gsize *bitmap, int numbits)
{
int nwords, res, i;
volatile gpointer *slot;
gsize *descriptor;
SGEN_ASSERT (0, sizeof (gsize) == sizeof (mword), "We expect gsize and mword to have same size");
numbits = ALIGN_TO (numbits, GC_BITS_PER_WORD);
nwords = numbits / GC_BITS_PER_WORD + 1;
sgen_gc_lock ();
res = complex_descriptors_next;
/* linear search, so we don't have duplicates with domain load/unload
* this should not be performance critical or we'd have bigger issues
* (the number and size of complex descriptors should be small).
*/
for (i = 0; i < complex_descriptors_next; ) {
if (complex_descriptors [i] == nwords) {
SGEN_ARRAY_LIST_FOREACH_SLOT (&complex_descriptors, slot) {
gsize first_word = *(gsize*)slot;
if (first_word == 0) {
/* Unused slots should be 0 so we simply skip them */
continue;
} else if (first_word == nwords) {
int j, found = TRUE;
for (j = 0; j < nwords - 1; ++j) {
if (complex_descriptors [i + 1 + j] != bitmap [j]) {
if (((gsize*)slot) [j + 1] != bitmap [j]) {
found = FALSE;
break;
}
}
if (found) {
sgen_gc_unlock ();
return i;
return __index;
}
}
i += (int)complex_descriptors [i];
}
if (complex_descriptors_next + nwords > complex_descriptors_size) {
int new_size = complex_descriptors_size * 2 + nwords;
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);
complex_descriptors_next += nwords;
complex_descriptors [res] = nwords;
/* Skip the bitmap words */
__index += (guint32)(first_word - 1);
__offset += (guint32)(first_word - 1);
} SGEN_ARRAY_LIST_END_FOREACH_SLOT;
res = sgen_array_list_alloc_block (&complex_descriptors, nwords);
SGEN_LOG (6, "Complex descriptor %d, size: %d (total desc memory: %d)", res, nwords, complex_descriptors.capacity);
descriptor = (gsize*)sgen_array_list_get_slot (&complex_descriptors, res);
descriptor [0] = nwords;
for (i = 0; i < nwords - 1; ++i) {
complex_descriptors [res + 1 + i] = bitmap [i];
SGEN_LOG (6, "\tvalue: %p", (void*)complex_descriptors [res + 1 + i]);
descriptor [1 + i] = bitmap [i];
SGEN_LOG (6, "\tvalue: %p", (void*)descriptor [1 + i]);
}
sgen_gc_unlock ();
return res;
@@ -112,7 +107,7 @@ alloc_complex_descriptor (gsize *bitmap, int numbits)
gsize*
sgen_get_complex_descriptor (SgenDescriptor desc)
{
return complex_descriptors + (desc >> LOW_TYPE_BITS);
return (gsize*) sgen_array_list_get_slot (&complex_descriptors, desc >> LOW_TYPE_BITS);
}
/*
@@ -123,10 +118,7 @@ mono_gc_make_descr_for_object (gsize *bitmap, int numbits, size_t obj_size)
{
int first_set = -1, num_set = 0, last_set = -1, i;
SgenDescriptor desc = 0;
size_t stored_size = obj_size;
stored_size += SGEN_ALLOC_ALIGN - 1;
stored_size &= ~(SGEN_ALLOC_ALIGN - 1);
size_t stored_size = SGEN_ALIGN_UP (obj_size);
for (i = 0; i < numbits; ++i) {
if (bitmap [i / GC_BITS_PER_WORD] & ((gsize)1 << (i % GC_BITS_PER_WORD))) {
@@ -200,7 +192,7 @@ mono_gc_make_descr_for_array (int vector, gsize *elem_bitmap, int numbits, size_
}
/* Note: we also handle structs with just ref fields */
if (num_set * sizeof (gpointer) == elem_size) {
return desc | VECTOR_SUBTYPE_REFS | ((gssize)(-1) << 16);
return desc | VECTOR_SUBTYPE_REFS | ((gsize)(-1) << 16);
}
/* FIXME: try run-len first */
/* Note: we can't skip the object header here, because it's not present */
@@ -325,7 +317,7 @@ sgen_make_user_root_descriptor (SgenUserRootMarkFunc marker)
void*
sgen_get_complex_descriptor_bitmap (SgenDescriptor desc)
{
return complex_descriptors + (desc >> ROOT_DESC_TYPE_SHIFT);
return (void*) sgen_array_list_get_slot (&complex_descriptors, desc >> ROOT_DESC_TYPE_SHIFT);
}
SgenUserRootMarkFunc

View File

@@ -7,18 +7,7 @@
*
* Copyright (C) 2012 Xamarin Inc
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License 2.0 as published by the Free Software Foundation;
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License 2.0 along with this library; if not, write to the Free
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
* Licensed under the MIT license. See LICENSE file in the project root for full license information.
*/
#ifndef __MONO_SGEN_DESCRIPTOR_H__
#define __MONO_SGEN_DESCRIPTOR_H__
@@ -226,7 +215,7 @@ sgen_gc_descr_has_references (SgenDescriptor desc)
} while (0)
#endif
#define OBJ_COMPLEX_FOREACH_PTR(vt,obj) do { \
#define OBJ_COMPLEX_FOREACH_PTR(desc,obj) do { \
/* there are pointers */ \
void **_objptr = (void**)(obj); \
gsize *bitmap_data = sgen_get_complex_descriptor ((desc)); \

View File

@@ -10,18 +10,7 @@
* Copyright 2011 Xamarin, Inc.
* Copyright (C) 2012 Xamarin Inc
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License 2.0 as published by the Free Software Foundation;
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License 2.0 along with this library; if not, write to the Free
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
* Licensed under the MIT license. See LICENSE file in the project root for full license information.
*/
#include "config.h"
@@ -451,7 +440,7 @@ add_stage_entry (int num_entries, volatile gint32 *next_entry, StageEntry *entri
* This seems like a good value. Determined by timing
* sgen-weakref-stress.exe.
*/
g_usleep (200);
mono_thread_info_usleep (200);
HEAVY_STAT (++stat_wait_for_processing);
}
continue;
@@ -568,30 +557,27 @@ sgen_object_register_for_finalization (GCObject *obj, void *user_data)
}
/* LOCKING: requires that the GC lock is held */
static int
finalizers_with_predicate (SgenObjectPredicateFunc predicate, void *user_data, GCObject **out_array, int out_size, SgenHashTable *hash_table)
static void
finalize_with_predicate (SgenObjectPredicateFunc predicate, void *user_data, SgenHashTable *hash_table)
{
GCObject *object;
gpointer dummy G_GNUC_UNUSED;
int count;
if (no_finalize || !out_size || !out_array)
return 0;
count = 0;
if (no_finalize)
return;
SGEN_HASH_TABLE_FOREACH (hash_table, GCObject *, object, gpointer, dummy) {
object = tagged_object_get_object (object);
if (predicate (object, user_data)) {
/* remove and put in out_array */
SGEN_HASH_TABLE_FOREACH_REMOVE (TRUE);
out_array [count ++] = object;
SGEN_LOG (5, "Collecting object for finalization: %p (%s) (%d)", object, sgen_client_vtable_get_name (SGEN_LOAD_VTABLE (object)), sgen_hash_table_num_entries (hash_table));
if (count == out_size)
return count;
continue;
sgen_queue_finalization_entry (object);
SGEN_LOG (5, "Enqueuing object for finalization: %p (%s) (%d)", object, sgen_client_vtable_get_name (SGEN_LOAD_VTABLE (object)), sgen_hash_table_num_entries (hash_table));
}
if (sgen_suspend_finalizers)
break;
} SGEN_HASH_TABLE_FOREACH_END;
return count;
}
/**
@@ -610,21 +596,14 @@ finalizers_with_predicate (SgenObjectPredicateFunc predicate, void *user_data, G
* @out_array me be on the stack, or registered as a root, to allow the GC to know the
* objects are still alive.
*/
int
sgen_gather_finalizers_if (SgenObjectPredicateFunc predicate, void *user_data, GCObject **out_array, int out_size)
void
sgen_finalize_if (SgenObjectPredicateFunc predicate, void *user_data)
{
int result;
LOCK_GC;
sgen_process_fin_stage_entries ();
result = finalizers_with_predicate (predicate, user_data, (GCObject**)out_array, out_size, &minor_finalizable_hash);
if (result < out_size) {
result += finalizers_with_predicate (predicate, user_data, (GCObject**)out_array + result, out_size - result,
&major_finalizable_hash);
}
finalize_with_predicate (predicate, user_data, &minor_finalizable_hash);
finalize_with_predicate (predicate, user_data, &major_finalizable_hash);
UNLOCK_GC;
return result;
}
void

View File

@@ -1 +1 @@
14605014e14187566c4a9854c7dc2a1d6914fb34
2a1cd09094a18072d2cc366ab4c686942eee3913

View File

@@ -6,18 +6,7 @@
* Copyright 2011 Xamarin Inc (http://www.xamarin.com)
* Copyright (C) 2012 Xamarin Inc
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License 2.0 as published by the Free Software Foundation;
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License 2.0 along with this library; if not, write to the Free
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
* Licensed under the MIT license. See LICENSE file in the project root for full license information.
*/
#ifndef __MONO_SGENGC_H__
#define __MONO_SGENGC_H__
@@ -146,12 +135,16 @@ extern int current_collection_generation;
extern unsigned int sgen_global_stop_count;
#define SGEN_ALIGN_UP_TO(val,align) (((val) + (align - 1)) & ~(align - 1))
#define SGEN_ALIGN_DOWN_TO(val,align) ((val) & ~(align - 1))
#define SGEN_ALLOC_ALIGN 8
#define SGEN_ALLOC_ALIGN_BITS 3
/* s must be non-negative */
#define SGEN_CAN_ALIGN_UP(s) ((s) <= SIZE_MAX - (SGEN_ALLOC_ALIGN - 1))
#define SGEN_ALIGN_UP(s) (((s)+(SGEN_ALLOC_ALIGN-1)) & ~(SGEN_ALLOC_ALIGN-1))
#define SGEN_ALIGN_UP(s) SGEN_ALIGN_UP_TO(s, SGEN_ALLOC_ALIGN)
#define SGEN_ALIGN_DOWN(s) SGEN_ALIGN_DOWN_TO(s, SGEN_ALLOC_ALIGN)
#if SIZEOF_VOID_P == 4
#define ONE_P 1
@@ -285,6 +278,8 @@ void sgen_check_section_scan_starts (GCMemSection *section);
void sgen_conservatively_pin_objects_from (void **start, void **end, void *start_nursery, void *end_nursery, int pin_type);
gboolean sgen_gc_initialized (void);
/* Keep in sync with description_for_type() in sgen-internal.c! */
enum {
INTERNAL_MEM_PIN_QUEUE,
@@ -322,6 +317,8 @@ enum {
INTERNAL_MEM_CARDTABLE_MOD_UNION,
INTERNAL_MEM_BINARY_PROTOCOL,
INTERNAL_MEM_TEMPORARY,
INTERNAL_MEM_LOG_ENTRY,
INTERNAL_MEM_COMPLEX_DESCRIPTORS,
INTERNAL_MEM_FIRST_CLIENT
};
@@ -403,12 +400,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 void (*ScanPtrFieldFunc) (GCObject *obj, GCObject **ptr, SgenGrayQueue* queue);
typedef gboolean (*DrainGrayStackFunc) (SgenGrayQueue *queue);
typedef struct {
CopyOrMarkObjectFunc copy_or_mark_object;
ScanObjectFunc scan_object;
ScanVTypeFunc scan_vtype;
ScanPtrFieldFunc scan_ptr_field;
/* Drain stack optimized for the above functions */
DrainGrayStackFunc drain_gray_stack;
/*FIXME add allocation function? */
@@ -533,6 +532,7 @@ typedef struct {
GCObject* (*alloc_for_promotion) (GCVTable vtable, GCObject *obj, size_t objsize, gboolean has_references);
SgenObjectOperations serial_ops;
SgenObjectOperations serial_ops_with_concurrent_major;
void (*prepare_to_space) (char *to_space_bitmap, size_t space_bitmap_size);
void (*clear_fragments) (void);
@@ -553,7 +553,8 @@ void sgen_split_nursery_init (SgenMinorCollector *collector);
/* Updating references */
#ifdef SGEN_CHECK_UPDATE_REFERENCE
gboolean sgen_thread_pool_is_thread_pool_thread (MonoNativeThreadId some_thread) MONO_INTERNAL;
gboolean sgen_thread_pool_is_thread_pool_thread (MonoNativeThreadId some_thread);
static inline void
sgen_update_reference (GCObject **p, GCObject *o, gboolean allow_null)
{
@@ -591,6 +592,12 @@ typedef struct
size_t num_unique_scanned_objects;
} ScannedObjectCounts;
typedef enum {
CARDTABLE_SCAN_GLOBAL = 0,
CARDTABLE_SCAN_MOD_UNION = 1,
CARDTABLE_SCAN_MOD_UNION_PRECLEAN = CARDTABLE_SCAN_MOD_UNION | 2,
} CardTableScanType;
typedef struct _SgenMajorCollector SgenMajorCollector;
struct _SgenMajorCollector {
size_t section_size;
@@ -620,7 +627,7 @@ struct _SgenMajorCollector {
void (*free_non_pinned_object) (GCObject *obj, size_t size);
void (*pin_objects) (SgenGrayQueue *queue);
void (*pin_major_object) (GCObject *obj, SgenGrayQueue *queue);
void (*scan_card_table) (gboolean mod_union, ScanCopyContext ctx);
void (*scan_card_table) (CardTableScanType scan_type, ScanCopyContext ctx);
void (*iterate_live_block_ranges) (sgen_cardtable_block_callback callback);
void (*update_cardtable_mod_union) (void);
void (*init_to_space) (void);
@@ -780,8 +787,9 @@ void sgen_process_fin_stage_entries (void);
gboolean sgen_have_pending_finalizers (void);
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_finalize_if (SgenObjectPredicateFunc predicate, void *user_data);
void sgen_remove_finalizers_if (SgenObjectPredicateFunc predicate, void *user_data, int generation);
void sgen_set_suspend_finalizers (void);
void sgen_register_disappearing_link (GCObject *obj, void **link, gboolean track, gboolean in_gc);
@@ -798,9 +806,9 @@ enum {
void sgen_pin_object (GCObject *object, SgenGrayQueue *queue);
void sgen_set_pinned_from_failed_allocation (mword objsize);
void sgen_ensure_free_space (size_t size);
void sgen_ensure_free_space (size_t size, int generation);
void sgen_gc_collect (int generation);
void sgen_perform_collection (size_t requested_size, int generation_to_collect, const char *reason, gboolean wait_to_finish);
void sgen_perform_collection (size_t requested_size, int generation_to_collect, const char *reason, gboolean wait_to_finish, gboolean stw);
int sgen_gc_collection_count (int generation);
/* FIXME: what exactly does this return? */
@@ -809,17 +817,8 @@ size_t sgen_gc_get_total_heap_allocation (void);
/* STW */
typedef struct {
int generation;
const char *reason;
gboolean is_overflow;
gint64 total_time;
gint64 stw_time;
gint64 bridge_time;
} GGTimingInfo;
void sgen_stop_world (int generation);
void sgen_restart_world (int generation, GGTimingInfo *timing);
void sgen_restart_world (int generation);
gboolean sgen_is_world_stopped (void);
gboolean sgen_set_allow_synchronous_major (gboolean flag);
@@ -839,6 +838,7 @@ struct _LOSObject {
extern LOSObject *los_object_list;
extern mword los_memory_usage;
extern mword los_memory_usage_total;
void sgen_los_free_object (LOSObject *obj);
void* sgen_los_alloc_large_inner (GCVTable vtable, size_t size);
@@ -846,7 +846,7 @@ void sgen_los_sweep (void);
gboolean sgen_ptr_is_in_los (char *ptr, char **start);
void sgen_los_iterate_objects (IterateObjectCallbackFunc cb, void *user_data);
void sgen_los_iterate_live_block_ranges (sgen_cardtable_block_callback callback);
void sgen_los_scan_card_table (gboolean mod_union, ScanCopyContext ctx);
void sgen_los_scan_card_table (CardTableScanType scan_type, ScanCopyContext ctx);
void sgen_los_update_cardtable_mod_union (void);
void sgen_los_count_cards (long long *num_total_cards, long long *num_marked_cards);
gboolean sgen_los_is_valid_object (char *object);
@@ -950,7 +950,9 @@ extern int default_nursery_size;
extern guint32 tlab_size;
extern NurseryClearPolicy nursery_clear_policy;
extern gboolean sgen_try_free_some_memory;
extern mword total_promoted_size;
extern mword total_allocated_major;
extern volatile gboolean sgen_suspend_finalizers;
extern MonoCoopMutex gc_mutex;
/* Nursery helpers. */

File diff suppressed because it is too large Load Diff

View File

@@ -5,18 +5,7 @@
* Copyright 2003-2010 Novell, Inc.
* Copyright (C) 2012 Xamarin Inc
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License 2.0 as published by the Free Software Foundation;
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License 2.0 along with this library; if not, write to the Free
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
* Licensed under the MIT license. See LICENSE file in the project root for full license information.
*/
#include "config.h"
#ifdef HAVE_SGEN_GC

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