Move the mono_thread_create () function into utils/mono-threads.h/c, change/simplify...
[mono.git] / mono / metadata / sgen-pinning.c
index 865951e51a3b1521f21c8ada2f2b952adee55db5..9ada778bc7460520a599b808cd156eaaa734d48e 100644 (file)
@@ -180,17 +180,14 @@ sgen_dump_pin_queue (void)
        }       
 }
 
-#define CEMENT_THRESHOLD       1000
-#define CEMENT_HASH_SIZE       61
-
 typedef struct _CementHashEntry CementHashEntry;
 struct _CementHashEntry {
        char *obj;
        unsigned int count;
 };
 
-static CementHashEntry cement_hash [CEMENT_HASH_SIZE];
-static CementHashEntry cement_hash_concurrent [CEMENT_HASH_SIZE];
+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;
@@ -249,7 +246,7 @@ sgen_cement_concurrent_finish (void)
 gboolean
 sgen_cement_lookup (char *obj)
 {
-       int i = mono_aligned_addr_hash (obj) % CEMENT_HASH_SIZE;
+       int i = mono_aligned_addr_hash (obj) % SGEN_CEMENT_HASH_SIZE;
 
        SGEN_ASSERT (5, sgen_ptr_in_nursery (obj), "Looking up cementing for non-nursery objects makes no sense");
 
@@ -261,14 +258,15 @@ sgen_cement_lookup (char *obj)
        if (cement_hash [i].obj != obj)
                return FALSE;
 
-       return cement_hash [i].count >= CEMENT_THRESHOLD;
+       return cement_hash [i].count >= SGEN_CEMENT_THRESHOLD;
 }
 
 gboolean
-sgen_cement_lookup_or_register (char *obj, gboolean concurrent_cementing)
+sgen_cement_lookup_or_register (char *obj)
 {
        int i;
        CementHashEntry *hash;
+       gboolean concurrent_cementing = sgen_concurrent_collection_in_progress ();
 
        if (!cement_enabled)
                return FALSE;
@@ -291,7 +289,7 @@ sgen_cement_lookup_or_register (char *obj, gboolean concurrent_cementing)
         * so if we make the hash size user-adjustable we should
         * figure out something not involving division.
         */
-       i = mono_aligned_addr_hash (obj) % CEMENT_HASH_SIZE;
+       i = mono_aligned_addr_hash (obj) % SGEN_CEMENT_HASH_SIZE;
 
        SGEN_ASSERT (5, sgen_ptr_in_nursery (obj), "Can only cement pointers to nursery objects");
 
@@ -302,16 +300,21 @@ sgen_cement_lookup_or_register (char *obj, gboolean concurrent_cementing)
                return FALSE;
        }
 
-       if (hash [i].count >= CEMENT_THRESHOLD)
+       if (hash [i].count >= SGEN_CEMENT_THRESHOLD)
                return TRUE;
 
        ++hash [i].count;
+       if (hash [i].count == SGEN_CEMENT_THRESHOLD) {
+               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),
+                                       vt->klass->name_space, vt->klass->name);
+               }
 #ifdef SGEN_BINARY_PROTOCOL
-       if (hash [i].count == CEMENT_THRESHOLD) {
                binary_protocol_cement (obj, (gpointer)SGEN_LOAD_VTABLE (obj),
                                sgen_safe_object_get_size ((MonoObject*)obj));
-       }
 #endif
+       }
 
        return FALSE;
 }
@@ -320,11 +323,11 @@ void
 sgen_cement_iterate (IterateObjectCallbackFunc callback, void *callback_data)
 {
        int i;
-       for (i = 0; i < CEMENT_HASH_SIZE; ++i) {
+       for (i = 0; i < SGEN_CEMENT_HASH_SIZE; ++i) {
                if (!cement_hash [i].count)
                        continue;
 
-               SGEN_ASSERT (5, cement_hash [i].count >= CEMENT_THRESHOLD, "Cementing hash inconsistent");
+               SGEN_ASSERT (5, cement_hash [i].count >= SGEN_CEMENT_THRESHOLD, "Cementing hash inconsistent");
 
                callback (cement_hash [i].obj, 0, callback_data);
        }
@@ -334,8 +337,8 @@ void
 sgen_cement_clear_below_threshold (void)
 {
        int i;
-       for (i = 0; i < CEMENT_HASH_SIZE; ++i) {
-               if (cement_hash [i].count < CEMENT_THRESHOLD) {
+       for (i = 0; i < SGEN_CEMENT_HASH_SIZE; ++i) {
+               if (cement_hash [i].count < SGEN_CEMENT_THRESHOLD) {
                        cement_hash [i].obj = NULL;
                        cement_hash [i].count = 0;
                }