gboolean sgen_cement_lookup (GCObject *obj) { guint hv = sgen_aligned_addr_hash (obj); int i = SGEN_CEMENT_HASH (hv); SGEN_ASSERT (5, sgen_ptr_in_nursery (obj), "Looking up cementing for non-nursery objects makes no sense"); if (!cement_enabled) return FALSE; if (!cement_hash [i].obj) return FALSE; if (cement_hash [i].obj != obj) return FALSE; return cement_hash [i].count >= SGEN_CEMENT_THRESHOLD; }
gboolean sgen_cement_lookup_or_register (GCObject *obj) { guint hv; int i; CementHashEntry *hash = cement_hash; if (!cement_enabled) return FALSE; hv = sgen_aligned_addr_hash (obj); i = SGEN_CEMENT_HASH (hv); SGEN_ASSERT (5, sgen_ptr_in_nursery (obj), "Can only cement pointers to nursery objects"); if (!hash [i].obj) { GCObject *old_obj; old_obj = InterlockedCompareExchangePointer ((gpointer*)&hash [i].obj, obj, NULL); /* Check if the slot was occupied by some other object */ if (old_obj != NULL && old_obj != obj) return FALSE; } else if (hash [i].obj != obj) { return FALSE; } if (hash [i].count >= SGEN_CEMENT_THRESHOLD) return TRUE; if (InterlockedIncrement ((gint32*)&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); binary_protocol_cement (obj, (gpointer)SGEN_LOAD_VTABLE (obj), (int)sgen_safe_object_get_size (obj)); } return FALSE; }
static int tagged_object_hash (GCObject *o) { return sgen_aligned_addr_hash (tagged_object_get_object (o)); }