void* nsPresArena::Allocate(uint32_t aCode, size_t aSize) { NS_ABORT_IF_FALSE(aSize > 0, "PresArena cannot allocate zero bytes"); // We only hand out aligned sizes aSize = PL_ARENA_ALIGN(&mPool, aSize); // If there is no free-list entry for this type already, we have // to create one now, to record its size. FreeList* list = mFreeLists.PutEntry(aCode); nsTArray<void*>::index_type len = list->mEntries.Length(); if (list->mEntrySize == 0) { NS_ABORT_IF_FALSE(len == 0, "list with entries but no recorded size"); list->mEntrySize = aSize; } else { NS_ABORT_IF_FALSE(list->mEntrySize == aSize, "different sizes for same object type code"); } void* result; if (len > 0) { // LIFO behavior for best cache utilization result = list->mEntries.ElementAt(len - 1); list->mEntries.RemoveElementAt(len - 1); #if defined(DEBUG) { MOZ_MAKE_MEM_DEFINED(result, list->mEntrySize); char* p = reinterpret_cast<char*>(result); char* limit = p + list->mEntrySize; for (; p < limit; p += sizeof(uintptr_t)) { uintptr_t val = *reinterpret_cast<uintptr_t*>(p); NS_ABORT_IF_FALSE(val == mozPoisonValue(), nsPrintfCString("PresArena: poison overwritten; " "wanted %.16llx " "found %.16llx " "errors in bits %.16llx", uint64_t(mozPoisonValue()), uint64_t(val), uint64_t(mozPoisonValue() ^ val) ).get()); } } #endif MOZ_MAKE_MEM_UNDEFINED(result, list->mEntrySize); return result; } // Allocate a new chunk from the arena list->mEntriesEverAllocated++; PL_ARENA_ALLOCATE(result, &mPool, aSize); if (!result) { NS_ABORT_OOM(aSize); } return result; }
/* static */ PLDHashOperator nsPresArena::UnpoisonFreeList(FreeList* aEntry, void*) { nsTArray<void*>::index_type len; while ((len = aEntry->mEntries.Length())) { void* result = aEntry->mEntries.ElementAt(len - 1); aEntry->mEntries.RemoveElementAt(len - 1); MOZ_MAKE_MEM_UNDEFINED(result, aEntry->mEntrySize); } return PL_DHASH_NEXT; }
void BumpChunk::delete_(BumpChunk *chunk) { #ifdef DEBUG // Part of the chunk may have been marked as poisoned/noaccess. Undo that // before writing the 0xcd bytes. size_t size = sizeof(*chunk) + chunk->bumpSpaceSize; MOZ_MAKE_MEM_UNDEFINED(chunk, size); memset(chunk, 0xcd, size); #endif js_free(chunk); }