40
40
41
41
#if HAVE_BOEHM_GC
42
42
43
+ #if !HAVE_BDWGC_GC
44
+ #define GC_dirty (x )
45
+ #endif
46
+
43
47
#undef TRUE
44
48
#undef FALSE
45
49
#define THREAD_LOCAL_ALLOC 1
@@ -230,6 +234,19 @@ mono_gc_base_init (void)
230
234
} else if (g_str_has_prefix (opt , "toggleref-test" )) {
231
235
register_test_toggleref_callback ();
232
236
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 ;
233
250
} else {
234
251
/* Could be a parameter for sgen */
235
252
/*
@@ -250,11 +267,7 @@ mono_gc_base_init (void)
250
267
251
268
mono_thread_info_attach ();
252
269
253
- #ifdef HAVE_BDWGC_GC
254
- GC_set_on_event (on_gc_notification );
255
- #else
256
270
GC_set_on_collection_event (on_gc_notification );
257
- #endif
258
271
GC_on_heap_resize = on_gc_heap_resize ;
259
272
260
273
gc_initialized = TRUE;
@@ -634,6 +647,7 @@ mono_gc_weak_link_add (void **link_addr, MonoObject *obj, gboolean track)
634
647
{
635
648
/* libgc requires that we use HIDE_POINTER... */
636
649
* link_addr = (void * )HIDE_POINTER (obj );
650
+ GC_dirty (link_addr );
637
651
if (track )
638
652
GC_REGISTER_LONG_LINK (link_addr , obj );
639
653
else
@@ -878,41 +892,48 @@ void
878
892
mono_gc_wbarrier_set_field (MonoObject * obj , gpointer field_ptr , MonoObject * value )
879
893
{
880
894
* (void * * )field_ptr = value ;
895
+ GC_dirty (field_ptr );
881
896
}
882
897
883
898
void
884
899
mono_gc_wbarrier_set_arrayref (MonoArray * arr , gpointer slot_ptr , MonoObject * value )
885
900
{
886
901
* (void * * )slot_ptr = value ;
902
+ GC_dirty (slot_ptr );
887
903
}
888
904
889
905
void
890
906
mono_gc_wbarrier_arrayref_copy (gpointer dest_ptr , gpointer src_ptr , int count )
891
907
{
892
908
mono_gc_memmove_aligned (dest_ptr , src_ptr , count * sizeof (gpointer ));
909
+ GC_dirty (dest_ptr );
893
910
}
894
911
895
912
void
896
913
mono_gc_wbarrier_generic_store (gpointer ptr , MonoObject * value )
897
914
{
898
915
* (void * * )ptr = value ;
916
+ GC_dirty (ptr );
899
917
}
900
918
901
919
void
902
920
mono_gc_wbarrier_generic_store_atomic (gpointer ptr , MonoObject * value )
903
921
{
904
922
mono_atomic_store_ptr ((volatile gpointer * )ptr , value );
923
+ GC_dirty (ptr );
905
924
}
906
925
907
926
void
908
927
mono_gc_wbarrier_generic_nostore (gpointer ptr )
909
928
{
929
+ GC_dirty (ptr );
910
930
}
911
931
912
932
void
913
933
mono_gc_wbarrier_value_copy (gpointer dest , gpointer src , int count , MonoClass * klass )
914
934
{
915
935
mono_gc_memmove_atomic (dest , src , count * mono_class_value_size (klass , NULL ));
936
+ GC_dirty (dest );
916
937
}
917
938
918
939
void
@@ -921,6 +942,7 @@ mono_gc_wbarrier_object_copy (MonoObject* obj, MonoObject *src)
921
942
/* do not copy the sync state */
922
943
mono_gc_memmove_aligned ((char * )obj + sizeof (MonoObject ), (char * )src + sizeof (MonoObject ),
923
944
mono_object_class (obj )-> instance_size - sizeof (MonoObject ));
945
+ GC_dirty (obj );
924
946
}
925
947
926
948
void
@@ -1310,11 +1332,48 @@ mono_gc_get_managed_allocator_types (void)
1310
1332
return 0 ;
1311
1333
}
1312
1334
1335
+ static MonoMethod * write_barrier_conc_method ;
1313
1336
MonoMethod *
1314
1337
mono_gc_get_write_barrier (void )
1315
1338
{
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
+
1318
1377
}
1319
1378
1320
1379
#else
@@ -1349,11 +1408,48 @@ mono_gc_get_managed_allocator_types (void)
1349
1408
return 0 ;
1350
1409
}
1351
1410
1411
+ static MonoMethod * write_barrier_conc_method ;
1352
1412
MonoMethod *
1353
1413
mono_gc_get_write_barrier (void )
1354
1414
{
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
+
1357
1453
}
1358
1454
1359
1455
#endif
@@ -1398,7 +1494,11 @@ mono_gc_set_desktop_mode (void)
1398
1494
gboolean
1399
1495
mono_gc_is_moving (void )
1400
1496
{
1497
+ #if HAVE_BDWGC_GC
1498
+ return GC_is_incremental_mode ();
1499
+ #else
1401
1500
return FALSE;
1501
+ #endif
1402
1502
}
1403
1503
1404
1504
gboolean
@@ -1413,7 +1513,8 @@ mono_gc_is_disabled (void)
1413
1513
void
1414
1514
mono_gc_wbarrier_range_copy (gpointer _dest , gpointer _src , int size )
1415
1515
{
1416
- g_assert_not_reached ();
1516
+ memcpy (_dest , _src , size );
1517
+ GC_dirty (_dest );
1417
1518
}
1418
1519
1419
1520
void *
@@ -1425,7 +1526,6 @@ mono_gc_get_range_copy_func (void)
1425
1526
guint8 *
1426
1527
mono_gc_get_card_table (int * shift_bits , gpointer * card_mask )
1427
1528
{
1428
- g_assert_not_reached ();
1429
1529
return NULL ;
1430
1530
}
1431
1531
@@ -1775,6 +1875,7 @@ handle_data_grow (HandleData *handles, gboolean track)
1775
1875
gpointer * entries ;
1776
1876
entries = (void * * )mono_gc_alloc_fixed (sizeof (* handles -> entries ) * new_size , NULL , MONO_ROOT_SOURCE_GC_HANDLE , NULL , "GC Handle Table (Boehm)" );
1777
1877
mono_gc_memmove_aligned (entries , handles -> entries , sizeof (* handles -> entries ) * handles -> size );
1878
+ GC_dirty (entries );
1778
1879
mono_gc_free_fixed (handles -> entries );
1779
1880
handles -> entries = entries ;
1780
1881
}
@@ -1807,6 +1908,7 @@ alloc_handle (HandleData *handles, MonoObject *obj, gboolean track)
1807
1908
mono_gc_weak_link_add (& (handles -> entries [slot ]), obj , track );
1808
1909
} else {
1809
1910
handles -> entries [slot ] = obj ;
1911
+ GC_dirty (handles -> entries + slot );
1810
1912
}
1811
1913
1812
1914
#ifndef DISABLE_PERFCOUNTERS
@@ -1924,6 +2026,7 @@ mono_gchandle_set_target (guint32 gchandle, MonoObject *obj)
1924
2026
handles -> domain_ids [slot ] = (obj ? mono_object_get_domain (obj ) : mono_domain_get ())-> domain_id ;
1925
2027
} else {
1926
2028
handles -> entries [slot ] = obj ;
2029
+ GC_dirty (handles -> entries + slot );
1927
2030
}
1928
2031
} else {
1929
2032
/* print a warning? */
@@ -2002,6 +2105,7 @@ mono_gchandle_free (guint32 gchandle)
2002
2105
mono_gc_weak_link_remove (& handles -> entries [slot ], handles -> type == HANDLE_WEAK_TRACK );
2003
2106
} else {
2004
2107
handles -> entries [slot ] = NULL ;
2108
+ GC_dirty (handles -> entries + slot );
2005
2109
}
2006
2110
vacate_slot (handles , slot );
2007
2111
} else {
@@ -2044,6 +2148,7 @@ mono_gchandle_free_domain (MonoDomain *domain)
2044
2148
if (handles -> entries [slot ] && mono_object_domain (handles -> entries [slot ]) == domain ) {
2045
2149
vacate_slot (handles , slot );
2046
2150
handles -> entries [slot ] = NULL ;
2151
+ GC_dirty (handles -> entries + slot );
2047
2152
}
2048
2153
}
2049
2154
}
0 commit comments