Skip to content

Commit

Permalink
Merge pull request #958 from Unity-Technologies/incremental-boehm-sup…
Browse files Browse the repository at this point in the history
…port

Incremental boehm support
  • Loading branch information
jechter authored Jun 14, 2018
2 parents 855f47c + d574108 commit 7950418
Show file tree
Hide file tree
Showing 8 changed files with 143 additions and 19 deletions.
2 changes: 1 addition & 1 deletion external/bdwgc
Submodule bdwgc updated 198 files
125 changes: 115 additions & 10 deletions mono/metadata/boehm-gc.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,10 @@

#if HAVE_BOEHM_GC

#if !HAVE_BDWGC_GC
#define GC_dirty(x)
#endif

#undef TRUE
#undef FALSE
#define THREAD_LOCAL_ALLOC 1
Expand Down Expand Up @@ -230,6 +234,19 @@ mono_gc_base_init (void)
} else if (g_str_has_prefix (opt, "toggleref-test")) {
register_test_toggleref_callback ();
continue;
} else if (g_str_has_prefix (opt, "incremental=")) {
size_t time_limit;

opt = strchr (opt, '=') + 1;
if (*opt && mono_gc_parse_environment_string_extract_number (opt, &time_limit)) {
GC_enable_incremental ();
#if HAVE_BDWGC_GC
if (time_limit != 0)
// value is in milliseconds
GC_set_time_limit (time_limit);
#endif
}
continue;
} else {
/* Could be a parameter for sgen */
/*
Expand All @@ -250,11 +267,7 @@ mono_gc_base_init (void)

mono_thread_info_attach ();

#ifdef HAVE_BDWGC_GC
GC_set_on_event (on_gc_notification);
#else
GC_set_on_collection_event (on_gc_notification);
#endif
GC_on_heap_resize = on_gc_heap_resize;

gc_initialized = TRUE;
Expand Down Expand Up @@ -634,6 +647,7 @@ mono_gc_weak_link_add (void **link_addr, MonoObject *obj, gboolean track)
{
/* libgc requires that we use HIDE_POINTER... */
*link_addr = (void*)HIDE_POINTER (obj);
GC_dirty (link_addr);
if (track)
GC_REGISTER_LONG_LINK (link_addr, obj);
else
Expand Down Expand Up @@ -878,41 +892,48 @@ void
mono_gc_wbarrier_set_field (MonoObject *obj, gpointer field_ptr, MonoObject* value)
{
*(void**)field_ptr = value;
GC_dirty (field_ptr);
}

void
mono_gc_wbarrier_set_arrayref (MonoArray *arr, gpointer slot_ptr, MonoObject* value)
{
*(void**)slot_ptr = value;
GC_dirty (slot_ptr);
}

void
mono_gc_wbarrier_arrayref_copy (gpointer dest_ptr, gpointer src_ptr, int count)
{
mono_gc_memmove_aligned (dest_ptr, src_ptr, count * sizeof (gpointer));
GC_dirty (dest_ptr);
}

void
mono_gc_wbarrier_generic_store (gpointer ptr, MonoObject* value)
{
*(void**)ptr = value;
GC_dirty (ptr);
}

void
mono_gc_wbarrier_generic_store_atomic (gpointer ptr, MonoObject *value)
{
mono_atomic_store_ptr ((volatile gpointer *)ptr, value);
GC_dirty (ptr);
}

void
mono_gc_wbarrier_generic_nostore (gpointer ptr)
{
GC_dirty (ptr);
}

void
mono_gc_wbarrier_value_copy (gpointer dest, gpointer src, int count, MonoClass *klass)
{
mono_gc_memmove_atomic (dest, src, count * mono_class_value_size (klass, NULL));
GC_dirty (dest);
}

void
Expand All @@ -921,6 +942,7 @@ mono_gc_wbarrier_object_copy (MonoObject* obj, MonoObject *src)
/* do not copy the sync state */
mono_gc_memmove_aligned ((char*)obj + sizeof (MonoObject), (char*)src + sizeof (MonoObject),
mono_object_class (obj)->instance_size - sizeof (MonoObject));
GC_dirty (obj);
}

void
Expand Down Expand Up @@ -1310,11 +1332,48 @@ mono_gc_get_managed_allocator_types (void)
return 0;
}

static MonoMethod *write_barrier_conc_method;
MonoMethod*
mono_gc_get_write_barrier (void)
{
g_assert_not_reached ();
return NULL;
MonoMethod *res;
MonoMethodBuilder *mb;
MonoMethodSignature *sig;
MonoMethod **write_barrier_method_addr;
WrapperInfo *info;

write_barrier_method_addr = &write_barrier_conc_method;

if (*write_barrier_method_addr)
return *write_barrier_method_addr;

/* Create the IL version of mono_gc_barrier_generic_store () */
sig = mono_metadata_signature_alloc (mono_defaults.corlib, 1);
sig->ret = &mono_defaults.void_class->byval_arg;
sig->params [0] = &mono_defaults.int_class->byval_arg;

mb = mono_mb_new (mono_defaults.object_class, "wbarrier_conc", MONO_WRAPPER_WRITE_BARRIER);

mono_mb_emit_ldarg (mb, 0);
mono_mb_emit_icall (mb, mono_gc_wbarrier_generic_nostore);
mono_mb_emit_byte (mb, MONO_CEE_RET);

res = mono_mb_create_method (mb, sig, 16);
info = mono_wrapper_info_create (mb, WRAPPER_SUBTYPE_NONE);
mono_marshal_set_wrapper_info (res, info);
mono_mb_free (mb);

if (*write_barrier_method_addr) {
/* Already created */
mono_free_method (res);
} else {
/* double-checked locking */
mono_memory_barrier ();
*write_barrier_method_addr = res;
}

return *write_barrier_method_addr;

}

#else
Expand Down Expand Up @@ -1349,11 +1408,48 @@ mono_gc_get_managed_allocator_types (void)
return 0;
}

static MonoMethod *write_barrier_conc_method;
MonoMethod*
mono_gc_get_write_barrier (void)
{
g_assert_not_reached ();
return NULL;
MonoMethod *res;
MonoMethodBuilder *mb;
MonoMethodSignature *sig;
MonoMethod **write_barrier_method_addr;
WrapperInfo *info;

write_barrier_method_addr = &write_barrier_conc_method;

if (*write_barrier_method_addr)
return *write_barrier_method_addr;

/* Create the IL version of mono_gc_barrier_generic_store () */
sig = mono_metadata_signature_alloc (mono_defaults.corlib, 1);
sig->ret = &mono_defaults.void_class->byval_arg;
sig->params [0] = &mono_defaults.int_class->byval_arg;

mb = mono_mb_new (mono_defaults.object_class, "wbarrier_conc", MONO_WRAPPER_WRITE_BARRIER);

mono_mb_emit_ldarg (mb, 0);
mono_mb_emit_icall (mb, mono_gc_wbarrier_generic_nostore);
mono_mb_emit_byte (mb, MONO_CEE_RET);

res = mono_mb_create_method (mb, sig, 16);
info = mono_wrapper_info_create (mb, WRAPPER_SUBTYPE_NONE);
mono_marshal_set_wrapper_info (res, info);
mono_mb_free (mb);

if (*write_barrier_method_addr) {
/* Already created */
mono_free_method (res);
} else {
/* double-checked locking */
mono_memory_barrier ();
*write_barrier_method_addr = res;
}

return *write_barrier_method_addr;

}

#endif
Expand Down Expand Up @@ -1398,7 +1494,11 @@ mono_gc_set_desktop_mode (void)
gboolean
mono_gc_is_moving (void)
{
#if HAVE_BDWGC_GC
return GC_is_incremental_mode ();
#else
return FALSE;
#endif
}

gboolean
Expand All @@ -1413,7 +1513,8 @@ mono_gc_is_disabled (void)
void
mono_gc_wbarrier_range_copy (gpointer _dest, gpointer _src, int size)
{
g_assert_not_reached ();
memcpy (_dest, _src, size);
GC_dirty (_dest);
}

void*
Expand All @@ -1425,7 +1526,6 @@ mono_gc_get_range_copy_func (void)
guint8*
mono_gc_get_card_table (int *shift_bits, gpointer *card_mask)
{
g_assert_not_reached ();
return NULL;
}

Expand Down Expand Up @@ -1775,6 +1875,7 @@ handle_data_grow (HandleData *handles, gboolean track)
gpointer *entries;
entries = (void **)mono_gc_alloc_fixed (sizeof (*handles->entries) * new_size, NULL, MONO_ROOT_SOURCE_GC_HANDLE, NULL, "GC Handle Table (Boehm)");
mono_gc_memmove_aligned (entries, handles->entries, sizeof (*handles->entries) * handles->size);
GC_dirty (entries);
mono_gc_free_fixed (handles->entries);
handles->entries = entries;
}
Expand Down Expand Up @@ -1807,6 +1908,7 @@ alloc_handle (HandleData *handles, MonoObject *obj, gboolean track)
mono_gc_weak_link_add (&(handles->entries [slot]), obj, track);
} else {
handles->entries [slot] = obj;
GC_dirty (handles->entries + slot);
}

#ifndef DISABLE_PERFCOUNTERS
Expand Down Expand Up @@ -1924,6 +2026,7 @@ mono_gchandle_set_target (guint32 gchandle, MonoObject *obj)
handles->domain_ids [slot] = (obj ? mono_object_get_domain (obj) : mono_domain_get ())->domain_id;
} else {
handles->entries [slot] = obj;
GC_dirty (handles->entries + slot);
}
} else {
/* print a warning? */
Expand Down Expand Up @@ -2002,6 +2105,7 @@ mono_gchandle_free (guint32 gchandle)
mono_gc_weak_link_remove (&handles->entries [slot], handles->type == HANDLE_WEAK_TRACK);
} else {
handles->entries [slot] = NULL;
GC_dirty (handles->entries + slot);
}
vacate_slot (handles, slot);
} else {
Expand Down Expand Up @@ -2044,6 +2148,7 @@ mono_gchandle_free_domain (MonoDomain *domain)
if (handles->entries [slot] && mono_object_domain (handles->entries [slot]) == domain) {
vacate_slot (handles, slot);
handles->entries [slot] = NULL;
GC_dirty (handles->entries + slot);
}
}
}
Expand Down
4 changes: 4 additions & 0 deletions mono/metadata/domain.c
Original file line number Diff line number Diff line change
Expand Up @@ -1248,8 +1248,12 @@ mono_domain_free (MonoDomain *domain, gboolean force)

domain->setup = NULL;

#if !HAVE_BDWGC_GC
// This crashes in bdwgc because we never register such a root.
// Not sure why/how it works in sgen, or if it is needed?
if (mono_gc_is_moving ())
mono_gc_deregister_root ((char*)&(domain->MONO_DOMAIN_FIRST_GC_TRACKED));
#endif

mono_appdomains_lock ();
appdomains_list [domain->domain_id] = NULL;
Expand Down
9 changes: 9 additions & 0 deletions mono/metadata/object.c
Original file line number Diff line number Diff line change
Expand Up @@ -2084,6 +2084,10 @@ mono_class_create_runtime_vtable (MonoDomain *domain, MonoClass *klass, MonoErro
/* it's a pointer type: add check */
g_assert ((fklass->byval_arg.type == MONO_TYPE_PTR) || (fklass->byval_arg.type == MONO_TYPE_FNPTR));
*t = *(char *)data;
/* This is not needed by sgen, as it does not seem
+ to need write barriers for uncollectable objects (like the vtables storing static
+ fields), but it is needed for incremental boehm. */
mono_gc_wbarrier_generic_nostore (t);
}
continue;
}
Expand Down Expand Up @@ -3294,6 +3298,11 @@ mono_field_static_set_value (MonoVTable *vt, MonoClassField *field, void *value)
dest = (char*)mono_vtable_get_static_field_data (vt) + field->offset;
}
mono_copy_value (field->type, dest, value, FALSE);
/* This is not needed by sgen, as it does not seem
to need write barriers for uncollectable objects (like the vtables storing static
+ fields), but it is needed for incremental boehm. */
if (field->offset == -1)
mono_gc_wbarrier_generic_nostore (dest);
}

/**
Expand Down
5 changes: 2 additions & 3 deletions mono/mini/Makefile.am.in
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,7 @@ libgc_libs=$(monodir)/libgc/libmonogc.la
libgc_static_libs=$(monodir)/libgc/libmonogc-static.la
endif

libbdwgc_libs=$(monodir)/external/bdwgc/libgc.la
libbdwgc_static_libs=$(monodir)/external/bdwgc/libgc-static.la
libbdwgc_libs=$(monodir)/external/bdwgc/libgc-static.la

boehm_libs= \
$(monodir)/mono/metadata/libmonoruntime.la \
Expand Down Expand Up @@ -49,7 +48,7 @@ bdwgc_static_libs= \
$(monodir)/mono/metadata/libmonoruntimebdwgc-static.la \
$(monodir)/mono/utils/libmonoutils.la \
$(GLIB_LIBS) $(LIBICONV) \
$(libbdwgc_static_libs)
$(libbdwgc_libs)

sgen_static_libs = \
$(monodir)/mono/metadata/libmonoruntimesgen-static.la \
Expand Down
7 changes: 7 additions & 0 deletions mono/mini/method-to-ir.c
Original file line number Diff line number Diff line change
Expand Up @@ -10740,6 +10740,13 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b

EMIT_NEW_STORE_MEMBASE_TYPE (cfg, store, ftype, ins->dreg, 0, store_val->dreg);
store->flags |= ins_flag;
if (cfg->gen_write_barriers && cfg->method->wrapper_type != MONO_WRAPPER_WRITE_BARRIER &&
mini_type_is_reference (ftype)) {
/* insert call to write barrier. This is not needed by sgen, as it does not seem
to need write barriers for uncollectable objects (like the vtables storing static
fields), but it is needed for incremental boehm. */
mini_emit_write_barrier (cfg, store, ins);
}
} else {
gboolean is_const = FALSE;
MonoVTable *vtable = NULL;
Expand Down
2 changes: 1 addition & 1 deletion mono/utils/gc_wrapper.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
#define IGNORE_DYNAMIC_LOADING 1
#define GC_DONT_REGISTER_MAIN_STATIC_DATA 1
#define GC_VERSION_MAJOR 7
#define GC_VERSION_MINOR 4
#define GC_VERSION_MINOR 7
#define GC_VERSION_MICRO 0
#define GC_THREADS 1
#define USE_MMAP 1
Expand Down
8 changes: 4 additions & 4 deletions msvc/libgcbdwgc.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>$(MONO_LIBBDWGC_INCLUDE_DIR);$(MONO_LIBATOMICS_INCLUDE_DIR);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32_THREADS;ALL_INTERIOR_POINTERS=1;GC_GCJ_SUPPORT=1;JAVA_FINALIZATION=1;NO_EXECUTE_PERMISSION=1;GC_NO_THREADS_DISCOVERY=1;IGNORE_DYNAMIC_LOADING=1;GC_DONT_REGISTER_MAIN_STATIC_DATA=1;GC_VERSION_MAJOR=7;GC_VERSION_MINOR=4;GC_VERSION_MICRO=0;GC_THREADS=1;USE_MMAP=1;USE_MUNMAP=1;GC_INSIDE_DLL=1</PreprocessorDefinitions>
<PreprocessorDefinitions>WIN32_THREADS;ALL_INTERIOR_POINTERS=1;GC_GCJ_SUPPORT=1;JAVA_FINALIZATION=1;NO_EXECUTE_PERMISSION=1;GC_NO_THREADS_DISCOVERY=1;IGNORE_DYNAMIC_LOADING=1;GC_DONT_REGISTER_MAIN_STATIC_DATA=1;GC_VERSION_MAJOR=7;GC_VERSION_MINOR=7;GC_VERSION_MICRO=0;GC_THREADS=1;USE_MMAP=1;USE_MUNMAP=1;GC_INSIDE_DLL=1</PreprocessorDefinitions>
<MinimalRebuild>true</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<PrecompiledHeader>
Expand All @@ -105,7 +105,7 @@
<ClCompile>
<Optimization>MinSpace</Optimization>
<AdditionalIncludeDirectories>$(MONO_LIBBDWGC_INCLUDE_DIR);$(MONO_LIBATOMICS_INCLUDE_DIR);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32_THREADS;ALL_INTERIOR_POINTERS=1;GC_GCJ_SUPPORT=1;JAVA_FINALIZATION=1;NO_EXECUTE_PERMISSION=1;GC_NO_THREADS_DISCOVERY=1;IGNORE_DYNAMIC_LOADING=1;GC_DONT_REGISTER_MAIN_STATIC_DATA=1;GC_VERSION_MAJOR=7;GC_VERSION_MINOR=4;GC_VERSION_MICRO=0;GC_THREADS=1;USE_MMAP=1;USE_MUNMAP=1;</PreprocessorDefinitions>
<PreprocessorDefinitions>WIN32_THREADS;ALL_INTERIOR_POINTERS=1;GC_GCJ_SUPPORT=1;JAVA_FINALIZATION=1;NO_EXECUTE_PERMISSION=1;GC_NO_THREADS_DISCOVERY=1;IGNORE_DYNAMIC_LOADING=1;GC_DONT_REGISTER_MAIN_STATIC_DATA=1;GC_VERSION_MAJOR=7;GC_VERSION_MINOR=7;GC_VERSION_MICRO=0;GC_THREADS=1;USE_MMAP=1;USE_MUNMAP=1;</PreprocessorDefinitions>
<PrecompiledHeader>
</PrecompiledHeader>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
Expand All @@ -125,7 +125,7 @@
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>$(MONO_LIBBDWGC_INCLUDE_DIR);$(MONO_LIBATOMICS_INCLUDE_DIR);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32_THREADS;ALL_INTERIOR_POINTERS=1;GC_GCJ_SUPPORT=1;JAVA_FINALIZATION=1;NO_EXECUTE_PERMISSION=1;GC_NO_THREADS_DISCOVERY=1;IGNORE_DYNAMIC_LOADING=1;GC_DONT_REGISTER_MAIN_STATIC_DATA=1;GC_VERSION_MAJOR=7;GC_VERSION_MINOR=4;GC_VERSION_MICRO=0;GC_THREADS=1;USE_MMAP=1;USE_MUNMAP=1;</PreprocessorDefinitions>
<PreprocessorDefinitions>WIN32_THREADS;ALL_INTERIOR_POINTERS=1;GC_GCJ_SUPPORT=1;JAVA_FINALIZATION=1;NO_EXECUTE_PERMISSION=1;GC_NO_THREADS_DISCOVERY=1;IGNORE_DYNAMIC_LOADING=1;GC_DONT_REGISTER_MAIN_STATIC_DATA=1;GC_VERSION_MAJOR=7;GC_VERSION_MINOR=7;GC_VERSION_MICRO=0;GC_THREADS=1;USE_MMAP=1;USE_MUNMAP=1;</PreprocessorDefinitions>
<MinimalRebuild>true</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<PrecompiledHeader>
Expand All @@ -148,7 +148,7 @@
<ClCompile>
<Optimization>MinSpace</Optimization>
<AdditionalIncludeDirectories>$(MONO_LIBBDWGC_INCLUDE_DIR);$(MONO_LIBATOMICS_INCLUDE_DIR);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32_THREADS;ALL_INTERIOR_POINTERS=1;GC_GCJ_SUPPORT=1;JAVA_FINALIZATION=1;NO_EXECUTE_PERMISSION=1;GC_NO_THREADS_DISCOVERY=1;IGNORE_DYNAMIC_LOADING=1;GC_DONT_REGISTER_MAIN_STATIC_DATA=1;GC_VERSION_MAJOR=7;GC_VERSION_MINOR=4;GC_VERSION_MICRO=0;GC_THREADS=1;USE_MMAP=1;USE_MUNMAP=1;</PreprocessorDefinitions>
<PreprocessorDefinitions>WIN32_THREADS;ALL_INTERIOR_POINTERS=1;GC_GCJ_SUPPORT=1;JAVA_FINALIZATION=1;NO_EXECUTE_PERMISSION=1;GC_NO_THREADS_DISCOVERY=1;IGNORE_DYNAMIC_LOADING=1;GC_DONT_REGISTER_MAIN_STATIC_DATA=1;GC_VERSION_MAJOR=7;GC_VERSION_MINOR=7;GC_VERSION_MICRO=0;GC_THREADS=1;USE_MMAP=1;USE_MUNMAP=1;</PreprocessorDefinitions>
<PrecompiledHeader>
</PrecompiledHeader>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
Expand Down

0 comments on commit 7950418

Please sign in to comment.