Skip to content

Commit e65f2b0

Browse files
committed
Add option for strict write barriers
1 parent 7e7a83f commit e65f2b0

File tree

1 file changed

+44
-19
lines changed

1 file changed

+44
-19
lines changed

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
}

0 commit comments

Comments
 (0)