struct object_slab_cache_t {
#if USE_SPINLOCK
spinlock_t m_lock;
#else
mutex_t m_lock;
#endif
int m_object_size;
int m_object_size_shift;
int m_bitmap_size;
int m_cache_limit;
int m_cache_count;
object_slab_traits_t* m_vacant;
"vacant"は、「空(から)」という意味 (
http://eow.alc.co.jp/vacant/UTF-8/?ref=gg )。
object_slab_traits_t* m_occupied;
object_heap_t* m_heap;
object_slab_cache_t();
~object_slab_cache_t();
bool init(object_heap_t* object_heap, int object_size, bool gc);
void destroy();
void* new_collectible_object();
void* new_object();
void delete_object(void* obj);
void attach(void* slab);
void detach(void* slab);
void sweep(void *slab);
void iterate(void* slab, object_iter_proc_t proc, void* desc);
void init_freelist(uint8_t* top, uint8_t* bottom, object_slab_traits_t* traits);
void unload_filled(object_slab_traits_t* traits);
void* lookup(void* ref)
{
assert((uint8_t*)ref < (uint8_t*)OBJECT_SLAB_TRAITS_OF(ref) - m_bitmap_size);
assert((uint8_t*)ref >= (uint8_t*)OBJECT_SLAB_TOP_OF(ref));
return (void*)((intptr_t)ref & ~(m_object_size - 1));
}
bool state(void* obj)
{
assert(m_bitmap_size);
uint8_t* bitmap = (uint8_t*)OBJECT_SLAB_TRAITS_OF(obj) - m_bitmap_size;
int bit_n = ((intptr_t)obj & (OBJECT_SLAB_SIZE - 1)) >> m_object_size_shift;
assert(bit_n < m_bitmap_size * 8);
return (bitmap[bit_n >> 3] & (1 << (bit_n & 7))) != 0;
}
void mark(void* obj)
{
assert(m_bitmap_size);
uint8_t* bitmap = (uint8_t*)OBJECT_SLAB_TRAITS_OF(obj) - m_bitmap_size;
int bit_n = ((intptr_t)obj & (OBJECT_SLAB_SIZE - 1)) >> m_object_size_shift;
assert(bit_n < m_bitmap_size * 8);
#if PARALLEL_COLLECT
interlocked_or_uint8(bitmap + (bit_n >> 3), 1 << (bit_n & 7));
#else
bitmap[bit_n >> 3] |= (1 << (bit_n & 7));
#endif
}
bool test_and_mark(void* obj)
{
assert(m_bitmap_size);
uint8_t* bitmap = (uint8_t*)OBJECT_SLAB_TRAITS_OF(obj) - m_bitmap_size;
int bit_n = ((intptr_t)obj & (OBJECT_SLAB_SIZE - 1)) >> m_object_size_shift;
assert(bit_n < m_bitmap_size * 8);
uint8_t bit = (1 << (bit_n & 7));
uint8_t* p = bitmap + (bit_n >> 3);
if (*p & bit) return true;
#if PARALLEL_COLLECT
interlocked_or_uint8(p, bit);
#else
*p |= bit;
#endif
return false;
}
};