X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Fmetadata%2Fsgen-pinning.c;h=2d7a8ca498c81f01374ad692d400d423fc24e07b;hb=f4e44e771fd180f6881e7e536212db89a3af310e;hp=9c8c819a0974a6d1c94f1943b381cb9ed40f8399;hpb=730d0ccd6fcf8d2a0ca9612fde07ecb42a4fadf4;p=mono.git diff --git a/mono/metadata/sgen-pinning.c b/mono/metadata/sgen-pinning.c index 9c8c819a097..2d7a8ca498c 100644 --- a/mono/metadata/sgen-pinning.c +++ b/mono/metadata/sgen-pinning.c @@ -182,10 +182,8 @@ struct _CementHashEntry { }; static CementHashEntry cement_hash [SGEN_CEMENT_HASH_SIZE]; -static CementHashEntry cement_hash_concurrent [SGEN_CEMENT_HASH_SIZE]; static gboolean cement_enabled = TRUE; -static gboolean cement_concurrent = FALSE; void sgen_cement_init (gboolean enabled) @@ -196,48 +194,10 @@ sgen_cement_init (gboolean enabled) void sgen_cement_reset (void) { - SGEN_ASSERT (1, !cement_concurrent, "Concurrent cementing cannot simply be reset"); - memset (cement_hash, 0, sizeof (cement_hash)); binary_protocol_cement_reset (); } -/* - * The reason we cannot simply reset cementing at the start of a - * concurrent collection is that the nursery collections running - * concurrently must keep pinning the cemented objects, because we - * don't have the global remsets that point to them anymore - if the - * nursery collector moved the cemented objects, we'd have invalid - * pointers in the major heap. - * - * What we do instead is to reset cementing at the start of concurrent - * collections in such a way that nursery collections happening during - * the major collection still pin the formerly cemented objects. We - * have a shadow cementing table for that purpose. The nursery - * collections still work with the old cementing table, while the - * major collector builds up a new cementing table, adding global - * remsets whenever needed like usual. When the major collector - * finishes, the old cementing table is replaced by the new one. - */ - -void -sgen_cement_concurrent_start (void) -{ - SGEN_ASSERT (1, !cement_concurrent, "Concurrent cementing has already been started"); - cement_concurrent = TRUE; - - memset (cement_hash_concurrent, 0, sizeof (cement_hash)); -} - -void -sgen_cement_concurrent_finish (void) -{ - SGEN_ASSERT (1, cement_concurrent, "Concurrent cementing hasn't been started"); - cement_concurrent = FALSE; - - memcpy (cement_hash, cement_hash_concurrent, sizeof (cement_hash)); -} - gboolean sgen_cement_lookup (char *obj) { @@ -262,20 +222,11 @@ sgen_cement_lookup_or_register (char *obj) { guint hv; int i; - CementHashEntry *hash; - gboolean concurrent_cementing = sgen_concurrent_collection_in_progress (); + CementHashEntry *hash = cement_hash; if (!cement_enabled) return FALSE; - if (concurrent_cementing) - SGEN_ASSERT (5, cement_concurrent, "Cementing wasn't inited with concurrent flag"); - - if (concurrent_cementing) - hash = cement_hash_concurrent; - else - hash = cement_hash; - hv = mono_aligned_addr_hash (obj); i = SGEN_CEMENT_HASH (hv); @@ -293,6 +244,10 @@ sgen_cement_lookup_or_register (char *obj) ++hash [i].count; if (hash [i].count == SGEN_CEMENT_THRESHOLD) { + SGEN_ASSERT (9, sgen_get_current_collection_generation () >= 0, "We can only cement objects when we're in a collection pause."); + SGEN_ASSERT (9, SGEN_OBJECT_IS_PINNED (obj), "Can only cement pinned objects"); + SGEN_CEMENT_OBJECT (obj); + if (G_UNLIKELY (MONO_GC_OBJ_CEMENTED_ENABLED())) { MonoVTable *vt G_GNUC_UNUSED = (MonoVTable*)SGEN_LOAD_VTABLE (obj); MONO_GC_OBJ_CEMENTED ((mword)obj, sgen_safe_object_get_size ((MonoObject*)obj), @@ -305,21 +260,31 @@ sgen_cement_lookup_or_register (char *obj) return FALSE; } -void -sgen_pin_cemented_objects (void) +static void +pin_from_hash (CementHashEntry *hash, gboolean has_been_reset) { int i; for (i = 0; i < SGEN_CEMENT_HASH_SIZE; ++i) { - if (!cement_hash [i].count) + if (!hash [i].count) continue; - SGEN_ASSERT (5, cement_hash [i].count >= SGEN_CEMENT_THRESHOLD, "Cementing hash inconsistent"); + if (has_been_reset) + SGEN_ASSERT (5, hash [i].count >= SGEN_CEMENT_THRESHOLD, "Cementing hash inconsistent"); - sgen_pin_stage_ptr (cement_hash [i].obj); + sgen_pin_stage_ptr (hash [i].obj); + binary_protocol_cement_stage (hash [i].obj); /* FIXME: do pin stats if enabled */ + + SGEN_CEMENT_OBJECT (hash [i].obj); } } +void +sgen_pin_cemented_objects (void) +{ + pin_from_hash (cement_hash, TRUE); +} + void sgen_cement_clear_below_threshold (void) {