void ObjectCache::ReturnObjectToSlab(slab* source, void* object, uint32 flags) { if (source == NULL) { panic("object_cache: free'd object has no slab"); return; } ParanoiaChecker _(source); uint8* data = (uint8*) object; if (data < source->pages || data >= (uint8*) source->pages + source->size * object_size) { panic("object_cache: free'd object does not belong to slab"); } intptr_t objectOffset = data - source->offset - (uint8*) source->pages; if (objectOffset % object_size != 0) { panic("object_cache: returning a wrong pointer to a slab object"); } object_link* link = object_to_link(object, object_size); TRACE_CACHE(this, "returning %p (%p) to %p, %lu used (%lu empty slabs).", object, link, source, source->size - source->count, empty_count); _push(source->free, link); source->count++; used_count--; ADD_PARANOIA_CHECK(PARANOIA_SUSPICIOUS, source, &link->next, sizeof(void*)); if (source->count == source->size) { partial.Remove(source); if (empty_count < pressure && total_objects - used_count - source->size >= min_object_reserve) { empty_count++; empty.Add(source); } else { ReturnSlab(source, flags); } } else if (source->count == 1) { full.Remove(source); partial.Add(source); } }
void ObjectCache::ReturnObjectToSlab(slab* source, void* object, uint32 flags) { if (source == NULL) { panic("object_cache: free'd object has no slab"); return; } ParanoiaChecker _(source); object_link* link = object_to_link(object, object_size); TRACE_CACHE(this, "returning %p (%p) to %p, %lu used (%lu empty slabs).", object, link, source, source->size - source->count, empty_count); _push(source->free, link); source->count++; used_count--; ADD_PARANOIA_CHECK(PARANOIA_SUSPICIOUS, source, &link->next, sizeof(void*)); if (source->count == source->size) { partial.Remove(source); if (empty_count < pressure && total_objects - used_count - source->size >= min_object_reserve) { empty_count++; empty.Add(source); } else { ReturnSlab(source, flags); } } else if (source->count == 1) { full.Remove(source); partial.Add(source); } }