Skip to content

Commit f7192b6

Browse files
authored
Merge pull request #1008 from Unity-Technologies/incremental-boehm-strict-mode
Add option for strict write barriers
2 parents 7e7a83f + a4994b5 commit f7192b6

File tree

6 files changed

+64
-19
lines changed

6 files changed

+64
-19
lines changed

mono/metadata/appdomain.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,13 +198,15 @@ create_domain_objects (MonoDomain *domain)
198198
mono_error_assert_ok (&error);
199199
mono_field_static_set_value (string_vt, string_empty_fld, empty_str);
200200
domain->empty_string = empty_str;
201+
mono_gc_wbarrier_generic_nostore (&domain->empty_string);
201202

202203
/*
203204
* Create an instance early since we can't do it when there is no memory.
204205
*/
205206
arg = mono_string_new_checked (domain, "Out of memory", &error);
206207
mono_error_assert_ok (&error);
207208
domain->out_of_memory_ex = mono_exception_from_name_two_strings_checked (mono_defaults.corlib, "System", "OutOfMemoryException", arg, NULL, &error);
209+
mono_gc_wbarrier_generic_nostore (&domain->out_of_memory_ex);
208210
mono_error_assert_ok (&error);
209211

210212
/*
@@ -214,14 +216,17 @@ create_domain_objects (MonoDomain *domain)
214216
arg = mono_string_new_checked (domain, "A null value was found where an object instance was required", &error);
215217
mono_error_assert_ok (&error);
216218
domain->null_reference_ex = mono_exception_from_name_two_strings_checked (mono_defaults.corlib, "System", "NullReferenceException", arg, NULL, &error);
219+
mono_gc_wbarrier_generic_nostore (&domain->null_reference_ex);
217220
mono_error_assert_ok (&error);
218221
arg = mono_string_new_checked (domain, "The requested operation caused a stack overflow.", &error);
219222
mono_error_assert_ok (&error);
220223
domain->stack_overflow_ex = mono_exception_from_name_two_strings_checked (mono_defaults.corlib, "System", "StackOverflowException", arg, NULL, &error);
224+
mono_gc_wbarrier_generic_nostore (&domain->stack_overflow_ex);
221225
mono_error_assert_ok (&error);
222226

223227
/*The ephemeron tombstone i*/
224228
domain->ephemeron_tombstone = mono_object_new_checked (domain, mono_defaults.object_class, &error);
229+
mono_gc_wbarrier_generic_nostore (&domain->ephemeron_tombstone);
225230
mono_error_assert_ok (&error);
226231

227232
if (domain != old_domain) {
@@ -292,7 +297,9 @@ mono_runtime_init_checked (MonoDomain *domain, MonoThreadStartCB start_cb, MonoT
292297

293298
ad->data = domain;
294299
domain->domain = ad;
300+
mono_gc_wbarrier_generic_nostore (&domain->domain);
295301
domain->setup = setup;
302+
mono_gc_wbarrier_generic_nostore (&domain->setup);
296303

297304
mono_thread_attach (domain);
298305

mono/metadata/boehm-gc.c

Lines changed: 44 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ void *pthread_get_stackaddr_np(pthread_t);
5959
#define MIN_BOEHM_MAX_HEAP_SIZE (MIN_BOEHM_MAX_HEAP_SIZE_IN_MB << 20)
6060

6161
static gboolean gc_initialized = FALSE;
62+
static gboolean gc_strict_wbarriers = FALSE;
6263
static mono_mutex_t mono_gc_lock;
6364

6465
typedef void (*GC_push_other_roots_proc)(void);
@@ -247,7 +248,10 @@ mono_gc_base_init (void)
247248
#endif
248249
}
249250
continue;
250-
} else {
251+
} else if (g_str_has_prefix (opt, "strict-wbarriers")) {
252+
gc_strict_wbarriers = TRUE;
253+
continue;
254+
}else {
251255
/* Could be a parameter for sgen */
252256
/*
253257
fprintf (stderr, "MONO_GC_PARAMS must be a comma-delimited list of one or more of the following:\n");
@@ -273,6 +277,24 @@ mono_gc_base_init (void)
273277
gc_initialized = TRUE;
274278
}
275279

280+
void
281+
mono_gc_dirty(void **ptr)
282+
{
283+
GC_dirty (ptr);
284+
}
285+
286+
void
287+
mono_gc_dirty_range(void **ptr, size_t size)
288+
{
289+
if (G_UNLIKELY(gc_strict_wbarriers))
290+
{
291+
for (int i = 0; i < size/sizeof(void*); i++)
292+
GC_dirty(ptr + i);
293+
}
294+
else
295+
GC_dirty (ptr);
296+
}
297+
276298
void
277299
mono_gc_base_cleanup (void)
278300
{
@@ -647,7 +669,7 @@ mono_gc_weak_link_add (void **link_addr, MonoObject *obj, gboolean track)
647669
{
648670
/* libgc requires that we use HIDE_POINTER... */
649671
*link_addr = (void*)HIDE_POINTER (obj);
650-
GC_dirty (link_addr);
672+
mono_gc_dirty (link_addr);
651673
if (track)
652674
GC_REGISTER_LONG_LINK (link_addr, obj);
653675
else
@@ -892,57 +914,60 @@ void
892914
mono_gc_wbarrier_set_field (MonoObject *obj, gpointer field_ptr, MonoObject* value)
893915
{
894916
*(void**)field_ptr = value;
895-
GC_dirty (field_ptr);
917+
mono_gc_dirty (field_ptr);
896918
}
897919

898920
void
899921
mono_gc_wbarrier_set_arrayref (MonoArray *arr, gpointer slot_ptr, MonoObject* value)
900922
{
901923
*(void**)slot_ptr = value;
902-
GC_dirty (slot_ptr);
924+
mono_gc_dirty (slot_ptr);
903925
}
904926

905927
void
906928
mono_gc_wbarrier_arrayref_copy (gpointer dest_ptr, gpointer src_ptr, int count)
907929
{
908930
mono_gc_memmove_aligned (dest_ptr, src_ptr, count * sizeof (gpointer));
909-
GC_dirty (dest_ptr);
931+
mono_gc_dirty_range (dest_ptr, count * sizeof(gpointer));
910932
}
911933

912934
void
913935
mono_gc_wbarrier_generic_store (gpointer ptr, MonoObject* value)
914936
{
915937
*(void**)ptr = value;
916-
GC_dirty (ptr);
938+
mono_gc_dirty (ptr);
917939
}
918940

919941
void
920942
mono_gc_wbarrier_generic_store_atomic (gpointer ptr, MonoObject *value)
921943
{
922944
mono_atomic_store_ptr ((volatile gpointer *)ptr, value);
923-
GC_dirty (ptr);
945+
mono_gc_dirty (ptr);
924946
}
925947

926948
void
927949
mono_gc_wbarrier_generic_nostore (gpointer ptr)
928950
{
929-
GC_dirty (ptr);
951+
mono_gc_dirty (ptr);
930952
}
931953

932954
void
933955
mono_gc_wbarrier_value_copy (gpointer dest, gpointer src, int count, MonoClass *klass)
934956
{
935-
mono_gc_memmove_atomic (dest, src, count * mono_class_value_size (klass, NULL));
936-
GC_dirty (dest);
957+
size_t size = count * mono_class_value_size (klass, NULL);
958+
mono_gc_memmove_atomic (dest, src, size);
959+
mono_gc_dirty_range (dest, size);
937960
}
938961

939962
void
940963
mono_gc_wbarrier_object_copy (MonoObject* obj, MonoObject *src)
941964
{
942965
/* do not copy the sync state */
943-
mono_gc_memmove_aligned ((char*)obj + sizeof (MonoObject), (char*)src + sizeof (MonoObject),
944-
mono_object_class (obj)->instance_size - sizeof (MonoObject));
945-
GC_dirty (obj);
966+
size_t size = mono_object_class (obj)->instance_size - sizeof (MonoObject);
967+
char * dstPtr = (char*)obj + sizeof (MonoObject);
968+
mono_gc_memmove_aligned (dstPtr, (char*)src + sizeof (MonoObject),
969+
size);
970+
mono_gc_dirty_range ((void**)dstPtr, size);
946971
}
947972

948973
void
@@ -1514,7 +1539,7 @@ void
15141539
mono_gc_wbarrier_range_copy (gpointer _dest, gpointer _src, int size)
15151540
{
15161541
memcpy (_dest, _src, size);
1517-
GC_dirty (_dest);
1542+
mono_gc_dirty_range (_dest, size);
15181543
}
15191544

15201545
void*
@@ -1875,7 +1900,7 @@ handle_data_grow (HandleData *handles, gboolean track)
18751900
gpointer *entries;
18761901
entries = (void **)mono_gc_alloc_fixed (sizeof (*handles->entries) * new_size, NULL, MONO_ROOT_SOURCE_GC_HANDLE, NULL, "GC Handle Table (Boehm)");
18771902
mono_gc_memmove_aligned (entries, handles->entries, sizeof (*handles->entries) * handles->size);
1878-
GC_dirty (entries);
1903+
mono_gc_dirty_range (entries, new_size * sizeof (*handles->entries));
18791904
mono_gc_free_fixed (handles->entries);
18801905
handles->entries = entries;
18811906
}
@@ -1908,7 +1933,7 @@ alloc_handle (HandleData *handles, MonoObject *obj, gboolean track)
19081933
mono_gc_weak_link_add (&(handles->entries [slot]), obj, track);
19091934
} else {
19101935
handles->entries [slot] = obj;
1911-
GC_dirty (handles->entries + slot);
1936+
mono_gc_dirty (handles->entries + slot);
19121937
}
19131938

19141939
#ifndef DISABLE_PERFCOUNTERS
@@ -2026,7 +2051,7 @@ mono_gchandle_set_target (guint32 gchandle, MonoObject *obj)
20262051
handles->domain_ids [slot] = (obj ? mono_object_get_domain (obj) : mono_domain_get ())->domain_id;
20272052
} else {
20282053
handles->entries [slot] = obj;
2029-
GC_dirty (handles->entries + slot);
2054+
mono_gc_dirty (handles->entries + slot);
20302055
}
20312056
} else {
20322057
/* print a warning? */
@@ -2105,7 +2130,7 @@ mono_gchandle_free (guint32 gchandle)
21052130
mono_gc_weak_link_remove (&handles->entries [slot], handles->type == HANDLE_WEAK_TRACK);
21062131
} else {
21072132
handles->entries [slot] = NULL;
2108-
GC_dirty (handles->entries + slot);
2133+
mono_gc_dirty (handles->entries + slot);
21092134
}
21102135
vacate_slot (handles, slot);
21112136
} else {
@@ -2148,7 +2173,7 @@ mono_gchandle_free_domain (MonoDomain *domain)
21482173
if (handles->entries [slot] && mono_object_domain (handles->entries [slot]) == domain) {
21492174
vacate_slot (handles, slot);
21502175
handles->entries [slot] = NULL;
2151-
GC_dirty (handles->entries + slot);
2176+
mono_gc_dirty (handles->entries + slot);
21522177
}
21532178
}
21542179
}

mono/metadata/domain.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -923,6 +923,7 @@ mono_domain_set_internal_with_options (MonoDomain *domain, gboolean migrate_exce
923923

924924
SET_APPDOMAIN (domain);
925925
SET_APPCONTEXT (domain->default_context);
926+
mono_gc_wbarrier_generic_nostore (&domain->default_context);
926927

927928
if (migrate_exception) {
928929
thread = mono_thread_internal_current ();

mono/metadata/icall.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2479,6 +2479,7 @@ ves_icall_RuntimeType_GetInterfaces (MonoReflectionTypeHandle ref_type, MonoErro
24792479
g_hash_table_destroy (iface_hash);
24802480
if (!domain->empty_types) {
24812481
domain->empty_types = mono_array_new_cached (domain, mono_defaults.runtimetype_class, 0, error);
2482+
mono_gc_wbarrier_generic_nostore (&domain->empty_types);
24822483
goto_if_nok (error, fail);
24832484
}
24842485
return MONO_HANDLE_NEW (MonoArray, domain->empty_types);

mono/metadata/reflection.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -534,7 +534,10 @@ mono_type_get_object_checked (MonoDomain *domain, MonoType *type, MonoError *err
534534
mono_g_hash_table_insert (domain->type_hash, type, res);
535535

536536
if (type->type == MONO_TYPE_VOID)
537+
{
537538
domain->typeof_void = (MonoObject*)res;
539+
mono_gc_wbarrier_generic_nostore (&domain->typeof_void);
540+
}
538541

539542
mono_domain_unlock (domain);
540543
mono_loader_unlock ();

mono/metadata/threads.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -523,6 +523,7 @@ set_current_thread_for_domain (MonoDomain *domain, MonoInternalThread *thread, M
523523

524524
g_assert (!*current_thread_ptr);
525525
*current_thread_ptr = current;
526+
mono_gc_wbarrier_generic_nostore (current_thread_ptr);
526527
}
527528

528529
static MonoThread*
@@ -1781,6 +1782,7 @@ mono_thread_current (void)
17811782
if (!*current_thread_ptr) {
17821783
g_assert (domain != mono_get_root_domain ());
17831784
*current_thread_ptr = create_thread_object (domain, internal);
1785+
mono_gc_wbarrier_generic_nostore (current_thread_ptr);
17841786
}
17851787
return *current_thread_ptr;
17861788
}
@@ -1798,6 +1800,7 @@ mono_thread_current_for_thread (MonoInternalThread *internal)
17981800
if (!*current_thread_ptr) {
17991801
g_assert (domain != mono_get_root_domain ());
18001802
*current_thread_ptr = create_thread_object (domain, internal);
1803+
mono_gc_wbarrier_generic_nostore (current_thread_ptr);
18011804
}
18021805
return *current_thread_ptr;
18031806
}
@@ -4139,10 +4142,13 @@ mono_alloc_static_data (gpointer **static_data_ptr, guint32 offset, void *alloc_
41394142
if (mono_gc_user_markers_supported ())
41404143
static_data [i] = g_malloc0 (static_data_size [i]);
41414144
else
4145+
{
41424146
static_data [i] = mono_gc_alloc_fixed (static_data_size [i], MONO_GC_DESCRIPTOR_NULL,
41434147
threadlocal ? MONO_ROOT_SOURCE_THREAD_STATIC : MONO_ROOT_SOURCE_CONTEXT_STATIC,
41444148
alloc_key,
41454149
threadlocal ? "ThreadStatic Fields" : "ContextStatic Fields");
4150+
mono_gc_wbarrier_generic_nostore (static_data + i);
4151+
}
41464152
}
41474153
}
41484154

@@ -4221,6 +4227,7 @@ context_adjust_static_data (MonoAppContext *ctx)
42214227
if (context_static_info.offset || context_static_info.idx > 0) {
42224228
guint32 offset = MAKE_SPECIAL_STATIC_OFFSET (context_static_info.idx, context_static_info.offset, 0);
42234229
mono_alloc_static_data (&ctx->static_data, offset, ctx, FALSE);
4230+
mono_gc_wbarrier_generic_nostore (&ctx->static_data);
42244231
ctx->data->static_data = ctx->static_data;
42254232
}
42264233
}
@@ -4250,6 +4257,7 @@ alloc_context_static_data_helper (gpointer key, gpointer value, gpointer user)
42504257

42514258
guint32 offset = GPOINTER_TO_UINT (user);
42524259
mono_alloc_static_data (&ctx->static_data, offset, ctx, FALSE);
4260+
mono_gc_wbarrier_generic_nostore (&ctx->static_data);
42534261
ctx->data->static_data = ctx->static_data;
42544262
}
42554263

0 commit comments

Comments
 (0)