Skip to content

Commit 7950418

Browse files
authored
Merge pull request #958 from Unity-Technologies/incremental-boehm-support
Incremental boehm support
2 parents 855f47c + d574108 commit 7950418

File tree

8 files changed

+143
-19
lines changed

8 files changed

+143
-19
lines changed

external/bdwgc

Submodule bdwgc updated 198 files

mono/metadata/boehm-gc.c

Lines changed: 115 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,10 @@
4040

4141
#if HAVE_BOEHM_GC
4242

43+
#if !HAVE_BDWGC_GC
44+
#define GC_dirty(x)
45+
#endif
46+
4347
#undef TRUE
4448
#undef FALSE
4549
#define THREAD_LOCAL_ALLOC 1
@@ -230,6 +234,19 @@ mono_gc_base_init (void)
230234
} else if (g_str_has_prefix (opt, "toggleref-test")) {
231235
register_test_toggleref_callback ();
232236
continue;
237+
} else if (g_str_has_prefix (opt, "incremental=")) {
238+
size_t time_limit;
239+
240+
opt = strchr (opt, '=') + 1;
241+
if (*opt && mono_gc_parse_environment_string_extract_number (opt, &time_limit)) {
242+
GC_enable_incremental ();
243+
#if HAVE_BDWGC_GC
244+
if (time_limit != 0)
245+
// value is in milliseconds
246+
GC_set_time_limit (time_limit);
247+
#endif
248+
}
249+
continue;
233250
} else {
234251
/* Could be a parameter for sgen */
235252
/*
@@ -250,11 +267,7 @@ mono_gc_base_init (void)
250267

251268
mono_thread_info_attach ();
252269

253-
#ifdef HAVE_BDWGC_GC
254-
GC_set_on_event (on_gc_notification);
255-
#else
256270
GC_set_on_collection_event (on_gc_notification);
257-
#endif
258271
GC_on_heap_resize = on_gc_heap_resize;
259272

260273
gc_initialized = TRUE;
@@ -634,6 +647,7 @@ mono_gc_weak_link_add (void **link_addr, MonoObject *obj, gboolean track)
634647
{
635648
/* libgc requires that we use HIDE_POINTER... */
636649
*link_addr = (void*)HIDE_POINTER (obj);
650+
GC_dirty (link_addr);
637651
if (track)
638652
GC_REGISTER_LONG_LINK (link_addr, obj);
639653
else
@@ -878,41 +892,48 @@ void
878892
mono_gc_wbarrier_set_field (MonoObject *obj, gpointer field_ptr, MonoObject* value)
879893
{
880894
*(void**)field_ptr = value;
895+
GC_dirty (field_ptr);
881896
}
882897

883898
void
884899
mono_gc_wbarrier_set_arrayref (MonoArray *arr, gpointer slot_ptr, MonoObject* value)
885900
{
886901
*(void**)slot_ptr = value;
902+
GC_dirty (slot_ptr);
887903
}
888904

889905
void
890906
mono_gc_wbarrier_arrayref_copy (gpointer dest_ptr, gpointer src_ptr, int count)
891907
{
892908
mono_gc_memmove_aligned (dest_ptr, src_ptr, count * sizeof (gpointer));
909+
GC_dirty (dest_ptr);
893910
}
894911

895912
void
896913
mono_gc_wbarrier_generic_store (gpointer ptr, MonoObject* value)
897914
{
898915
*(void**)ptr = value;
916+
GC_dirty (ptr);
899917
}
900918

901919
void
902920
mono_gc_wbarrier_generic_store_atomic (gpointer ptr, MonoObject *value)
903921
{
904922
mono_atomic_store_ptr ((volatile gpointer *)ptr, value);
923+
GC_dirty (ptr);
905924
}
906925

907926
void
908927
mono_gc_wbarrier_generic_nostore (gpointer ptr)
909928
{
929+
GC_dirty (ptr);
910930
}
911931

912932
void
913933
mono_gc_wbarrier_value_copy (gpointer dest, gpointer src, int count, MonoClass *klass)
914934
{
915935
mono_gc_memmove_atomic (dest, src, count * mono_class_value_size (klass, NULL));
936+
GC_dirty (dest);
916937
}
917938

918939
void
@@ -921,6 +942,7 @@ mono_gc_wbarrier_object_copy (MonoObject* obj, MonoObject *src)
921942
/* do not copy the sync state */
922943
mono_gc_memmove_aligned ((char*)obj + sizeof (MonoObject), (char*)src + sizeof (MonoObject),
923944
mono_object_class (obj)->instance_size - sizeof (MonoObject));
945+
GC_dirty (obj);
924946
}
925947

926948
void
@@ -1310,11 +1332,48 @@ mono_gc_get_managed_allocator_types (void)
13101332
return 0;
13111333
}
13121334

1335+
static MonoMethod *write_barrier_conc_method;
13131336
MonoMethod*
13141337
mono_gc_get_write_barrier (void)
13151338
{
1316-
g_assert_not_reached ();
1317-
return NULL;
1339+
MonoMethod *res;
1340+
MonoMethodBuilder *mb;
1341+
MonoMethodSignature *sig;
1342+
MonoMethod **write_barrier_method_addr;
1343+
WrapperInfo *info;
1344+
1345+
write_barrier_method_addr = &write_barrier_conc_method;
1346+
1347+
if (*write_barrier_method_addr)
1348+
return *write_barrier_method_addr;
1349+
1350+
/* Create the IL version of mono_gc_barrier_generic_store () */
1351+
sig = mono_metadata_signature_alloc (mono_defaults.corlib, 1);
1352+
sig->ret = &mono_defaults.void_class->byval_arg;
1353+
sig->params [0] = &mono_defaults.int_class->byval_arg;
1354+
1355+
mb = mono_mb_new (mono_defaults.object_class, "wbarrier_conc", MONO_WRAPPER_WRITE_BARRIER);
1356+
1357+
mono_mb_emit_ldarg (mb, 0);
1358+
mono_mb_emit_icall (mb, mono_gc_wbarrier_generic_nostore);
1359+
mono_mb_emit_byte (mb, MONO_CEE_RET);
1360+
1361+
res = mono_mb_create_method (mb, sig, 16);
1362+
info = mono_wrapper_info_create (mb, WRAPPER_SUBTYPE_NONE);
1363+
mono_marshal_set_wrapper_info (res, info);
1364+
mono_mb_free (mb);
1365+
1366+
if (*write_barrier_method_addr) {
1367+
/* Already created */
1368+
mono_free_method (res);
1369+
} else {
1370+
/* double-checked locking */
1371+
mono_memory_barrier ();
1372+
*write_barrier_method_addr = res;
1373+
}
1374+
1375+
return *write_barrier_method_addr;
1376+
13181377
}
13191378

13201379
#else
@@ -1349,11 +1408,48 @@ mono_gc_get_managed_allocator_types (void)
13491408
return 0;
13501409
}
13511410

1411+
static MonoMethod *write_barrier_conc_method;
13521412
MonoMethod*
13531413
mono_gc_get_write_barrier (void)
13541414
{
1355-
g_assert_not_reached ();
1356-
return NULL;
1415+
MonoMethod *res;
1416+
MonoMethodBuilder *mb;
1417+
MonoMethodSignature *sig;
1418+
MonoMethod **write_barrier_method_addr;
1419+
WrapperInfo *info;
1420+
1421+
write_barrier_method_addr = &write_barrier_conc_method;
1422+
1423+
if (*write_barrier_method_addr)
1424+
return *write_barrier_method_addr;
1425+
1426+
/* Create the IL version of mono_gc_barrier_generic_store () */
1427+
sig = mono_metadata_signature_alloc (mono_defaults.corlib, 1);
1428+
sig->ret = &mono_defaults.void_class->byval_arg;
1429+
sig->params [0] = &mono_defaults.int_class->byval_arg;
1430+
1431+
mb = mono_mb_new (mono_defaults.object_class, "wbarrier_conc", MONO_WRAPPER_WRITE_BARRIER);
1432+
1433+
mono_mb_emit_ldarg (mb, 0);
1434+
mono_mb_emit_icall (mb, mono_gc_wbarrier_generic_nostore);
1435+
mono_mb_emit_byte (mb, MONO_CEE_RET);
1436+
1437+
res = mono_mb_create_method (mb, sig, 16);
1438+
info = mono_wrapper_info_create (mb, WRAPPER_SUBTYPE_NONE);
1439+
mono_marshal_set_wrapper_info (res, info);
1440+
mono_mb_free (mb);
1441+
1442+
if (*write_barrier_method_addr) {
1443+
/* Already created */
1444+
mono_free_method (res);
1445+
} else {
1446+
/* double-checked locking */
1447+
mono_memory_barrier ();
1448+
*write_barrier_method_addr = res;
1449+
}
1450+
1451+
return *write_barrier_method_addr;
1452+
13571453
}
13581454

13591455
#endif
@@ -1398,7 +1494,11 @@ mono_gc_set_desktop_mode (void)
13981494
gboolean
13991495
mono_gc_is_moving (void)
14001496
{
1497+
#if HAVE_BDWGC_GC
1498+
return GC_is_incremental_mode ();
1499+
#else
14011500
return FALSE;
1501+
#endif
14021502
}
14031503

14041504
gboolean
@@ -1413,7 +1513,8 @@ mono_gc_is_disabled (void)
14131513
void
14141514
mono_gc_wbarrier_range_copy (gpointer _dest, gpointer _src, int size)
14151515
{
1416-
g_assert_not_reached ();
1516+
memcpy (_dest, _src, size);
1517+
GC_dirty (_dest);
14171518
}
14181519

14191520
void*
@@ -1425,7 +1526,6 @@ mono_gc_get_range_copy_func (void)
14251526
guint8*
14261527
mono_gc_get_card_table (int *shift_bits, gpointer *card_mask)
14271528
{
1428-
g_assert_not_reached ();
14291529
return NULL;
14301530
}
14311531

@@ -1775,6 +1875,7 @@ handle_data_grow (HandleData *handles, gboolean track)
17751875
gpointer *entries;
17761876
entries = (void **)mono_gc_alloc_fixed (sizeof (*handles->entries) * new_size, NULL, MONO_ROOT_SOURCE_GC_HANDLE, NULL, "GC Handle Table (Boehm)");
17771877
mono_gc_memmove_aligned (entries, handles->entries, sizeof (*handles->entries) * handles->size);
1878+
GC_dirty (entries);
17781879
mono_gc_free_fixed (handles->entries);
17791880
handles->entries = entries;
17801881
}
@@ -1807,6 +1908,7 @@ alloc_handle (HandleData *handles, MonoObject *obj, gboolean track)
18071908
mono_gc_weak_link_add (&(handles->entries [slot]), obj, track);
18081909
} else {
18091910
handles->entries [slot] = obj;
1911+
GC_dirty (handles->entries + slot);
18101912
}
18111913

18121914
#ifndef DISABLE_PERFCOUNTERS
@@ -1924,6 +2026,7 @@ mono_gchandle_set_target (guint32 gchandle, MonoObject *obj)
19242026
handles->domain_ids [slot] = (obj ? mono_object_get_domain (obj) : mono_domain_get ())->domain_id;
19252027
} else {
19262028
handles->entries [slot] = obj;
2029+
GC_dirty (handles->entries + slot);
19272030
}
19282031
} else {
19292032
/* print a warning? */
@@ -2002,6 +2105,7 @@ mono_gchandle_free (guint32 gchandle)
20022105
mono_gc_weak_link_remove (&handles->entries [slot], handles->type == HANDLE_WEAK_TRACK);
20032106
} else {
20042107
handles->entries [slot] = NULL;
2108+
GC_dirty (handles->entries + slot);
20052109
}
20062110
vacate_slot (handles, slot);
20072111
} else {
@@ -2044,6 +2148,7 @@ mono_gchandle_free_domain (MonoDomain *domain)
20442148
if (handles->entries [slot] && mono_object_domain (handles->entries [slot]) == domain) {
20452149
vacate_slot (handles, slot);
20462150
handles->entries [slot] = NULL;
2151+
GC_dirty (handles->entries + slot);
20472152
}
20482153
}
20492154
}

mono/metadata/domain.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1248,8 +1248,12 @@ mono_domain_free (MonoDomain *domain, gboolean force)
12481248

12491249
domain->setup = NULL;
12501250

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

12541258
mono_appdomains_lock ();
12551259
appdomains_list [domain->domain_id] = NULL;

mono/metadata/object.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2084,6 +2084,10 @@ mono_class_create_runtime_vtable (MonoDomain *domain, MonoClass *klass, MonoErro
20842084
/* it's a pointer type: add check */
20852085
g_assert ((fklass->byval_arg.type == MONO_TYPE_PTR) || (fklass->byval_arg.type == MONO_TYPE_FNPTR));
20862086
*t = *(char *)data;
2087+
/* This is not needed by sgen, as it does not seem
2088+
+ to need write barriers for uncollectable objects (like the vtables storing static
2089+
+ fields), but it is needed for incremental boehm. */
2090+
mono_gc_wbarrier_generic_nostore (t);
20872091
}
20882092
continue;
20892093
}
@@ -3294,6 +3298,11 @@ mono_field_static_set_value (MonoVTable *vt, MonoClassField *field, void *value)
32943298
dest = (char*)mono_vtable_get_static_field_data (vt) + field->offset;
32953299
}
32963300
mono_copy_value (field->type, dest, value, FALSE);
3301+
/* This is not needed by sgen, as it does not seem
3302+
to need write barriers for uncollectable objects (like the vtables storing static
3303+
+ fields), but it is needed for incremental boehm. */
3304+
if (field->offset == -1)
3305+
mono_gc_wbarrier_generic_nostore (dest);
32973306
}
32983307

32993308
/**

mono/mini/Makefile.am.in

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,7 @@ libgc_libs=$(monodir)/libgc/libmonogc.la
1818
libgc_static_libs=$(monodir)/libgc/libmonogc-static.la
1919
endif
2020

21-
libbdwgc_libs=$(monodir)/external/bdwgc/libgc.la
22-
libbdwgc_static_libs=$(monodir)/external/bdwgc/libgc-static.la
21+
libbdwgc_libs=$(monodir)/external/bdwgc/libgc-static.la
2322

2423
boehm_libs= \
2524
$(monodir)/mono/metadata/libmonoruntime.la \
@@ -49,7 +48,7 @@ bdwgc_static_libs= \
4948
$(monodir)/mono/metadata/libmonoruntimebdwgc-static.la \
5049
$(monodir)/mono/utils/libmonoutils.la \
5150
$(GLIB_LIBS) $(LIBICONV) \
52-
$(libbdwgc_static_libs)
51+
$(libbdwgc_libs)
5352

5453
sgen_static_libs = \
5554
$(monodir)/mono/metadata/libmonoruntimesgen-static.la \

mono/mini/method-to-ir.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10740,6 +10740,13 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b
1074010740

1074110741
EMIT_NEW_STORE_MEMBASE_TYPE (cfg, store, ftype, ins->dreg, 0, store_val->dreg);
1074210742
store->flags |= ins_flag;
10743+
if (cfg->gen_write_barriers && cfg->method->wrapper_type != MONO_WRAPPER_WRITE_BARRIER &&
10744+
mini_type_is_reference (ftype)) {
10745+
/* insert call to write barrier. This is not needed by sgen, as it does not seem
10746+
to need write barriers for uncollectable objects (like the vtables storing static
10747+
fields), but it is needed for incremental boehm. */
10748+
mini_emit_write_barrier (cfg, store, ins);
10749+
}
1074310750
} else {
1074410751
gboolean is_const = FALSE;
1074510752
MonoVTable *vtable = NULL;

mono/utils/gc_wrapper.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
#define IGNORE_DYNAMIC_LOADING 1
2222
#define GC_DONT_REGISTER_MAIN_STATIC_DATA 1
2323
#define GC_VERSION_MAJOR 7
24-
#define GC_VERSION_MINOR 4
24+
#define GC_VERSION_MINOR 7
2525
#define GC_VERSION_MICRO 0
2626
#define GC_THREADS 1
2727
#define USE_MMAP 1

msvc/libgcbdwgc.vcxproj

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@
8484
<ClCompile>
8585
<Optimization>Disabled</Optimization>
8686
<AdditionalIncludeDirectories>$(MONO_LIBBDWGC_INCLUDE_DIR);$(MONO_LIBATOMICS_INCLUDE_DIR);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
87-
<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>
87+
<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>
8888
<MinimalRebuild>true</MinimalRebuild>
8989
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
9090
<PrecompiledHeader>
@@ -105,7 +105,7 @@
105105
<ClCompile>
106106
<Optimization>MinSpace</Optimization>
107107
<AdditionalIncludeDirectories>$(MONO_LIBBDWGC_INCLUDE_DIR);$(MONO_LIBATOMICS_INCLUDE_DIR);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
108-
<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>
108+
<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>
109109
<PrecompiledHeader>
110110
</PrecompiledHeader>
111111
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
@@ -125,7 +125,7 @@
125125
<ClCompile>
126126
<Optimization>Disabled</Optimization>
127127
<AdditionalIncludeDirectories>$(MONO_LIBBDWGC_INCLUDE_DIR);$(MONO_LIBATOMICS_INCLUDE_DIR);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
128-
<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>
128+
<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>
129129
<MinimalRebuild>true</MinimalRebuild>
130130
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
131131
<PrecompiledHeader>
@@ -148,7 +148,7 @@
148148
<ClCompile>
149149
<Optimization>MinSpace</Optimization>
150150
<AdditionalIncludeDirectories>$(MONO_LIBBDWGC_INCLUDE_DIR);$(MONO_LIBATOMICS_INCLUDE_DIR);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
151-
<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>
151+
<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>
152152
<PrecompiledHeader>
153153
</PrecompiledHeader>
154154
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>

0 commit comments

Comments
 (0)