int CentralFreeList::RemoveRange(void **start, void **end, int N) { ASSERT(N > 0); lock_.Lock(); if (N == Static::sizemap()->num_objects_to_move(size_class_) && used_slots_ > 0) { int slot = --used_slots_; ASSERT(slot >= 0); TCEntry *entry = &tc_slots_[slot]; *start = entry->head; *end = entry->tail; lock_.Unlock(); return N; } int result = 0; void* head = NULL; void* tail = NULL; // TODO: Prefetch multiple TCEntries? tail = FetchFromSpansSafe(); if (tail != NULL) { SLL_SetNext(tail, NULL); head = tail; result = 1; while (result < N) { void *t = FetchFromSpans(); if (!t) break; SLL_Push(&head, t); result++; } } lock_.Unlock(); *start = head; *end = tail; return result; }
void CCentralCacheMgr::ReleaseToSpan(int iclz, void * object) { size_t clz = iclz; PRINT("clz:%zd, objaddr:%p", clz, object); struct SSpanInfo & spanInfo = m_sSpanList[clz]; PRINT("%s", spanInfo.c_string()); struct SSpanNode * spanNode = m_pSpanNodeCache; if (spanNode == NULL || m_iLastClazz != clz || SpanTreeSearch(clz, spanNode, object)) { //cache invalid. PRINT("span info cache invalid, spanInfo:%p, lastclz:%zd, clz:%zd, %s, search from rbtree", &spanInfo, m_iLastClazz, clz, spanNode == NULL ? "NULL" : spanNode->c_string()); spanNode = RbSearch(clz, &spanInfo.span_tree, object, &CCentralCacheMgr::SpanTreeGetObject, &CCentralCacheMgr::SpanTreeSearch); m_pSpanNodeCache = spanNode; m_iLastClazz = clz; } PRINT("spannode:%p", spanNode); if (spanNode == NULL) { PRINT("Error, can't find spanInfo for obj:%p", object); return; } PRINT("%s", spanNode->c_string()); bool needInsert2AllocTree = (spanNode->free_size == 0); SLL_Push(&(spanNode->object_list), object); spanNode->free_size++; spanInfo.free_object++; PRINT("insert2allocTree:%d, %s", needInsert2AllocTree, spanNode->c_string()); if (needInsert2AllocTree) { RbInsert(&spanInfo.alloc_tree, spanNode, &CCentralCacheMgr::AllocTreeGetObject, &CCentralCacheMgr::AllocTreeNode, &CCentralCacheMgr::AllocTreeInsert); } ReleaseSpan(clz, spanNode); }