/* static */ void GCAlloc::VerifyFreeBlockIntegrity(const void* item, uint32_t size) { // go through every item on the free list and make sure it wasn't written to // after being poisoned. while(item) { #ifdef MMGC_64BIT int n = (size >> 2) - 3; #else int n = (size >> 2) - 1; #endif int startIndex = (int)((uint32_t*)item - (uint32_t*)GetRealPointer(item)); for(int i=startIndex; i<n; i++) { uint32_t data = ((uint32_t*)item)[i]; if(data != 0xbabababa && data != 0xcacacaca) { ReportDeletedMemoryWrite(item); break; } } // next free item item = *((const void**)item); } }
/*static*/ int GCAlloc::ConservativeGetMark(const void *item, bool bogusPointerReturnValue) { GCBlock *block = GetBlock(item); #ifdef MMGC_MEMORY_INFO item = GetRealPointer(item); #endif // guard against bogus pointers to the block header if (item < block->items) return bogusPointerReturnValue; // floor value to start of item // FIXME: do this w/o division if we can int itemNum = GetIndex(block, item); // skip pointers into dead space at end of block if (itemNum > block->alloc->m_itemsPerBlock - 1) return bogusPointerReturnValue; // skip pointers into objects if(block->items + itemNum * block->size != item) return bogusPointerReturnValue; return GetMark(item); }
void FixedMalloc::LargeFree(void *item) { #if defined DEBUG && !defined AVMPLUS_SAMPLER RemoveFromLargeObjectTracker(item); #endif UpdateLargeFreeStats(item, GCHeap::SizeToBlocks(LargeSize(item))); #ifdef MMGC_HOOKS if(m_heap->HooksEnabled()) { m_heap->FinalizeHook(item, Size(item)); m_heap->FreeHook(item, Size(item), uint8_t(GCHeap::FXFreedPoison)); } #endif m_heap->FreeNoProfile(GetRealPointer(item)); }
/*static*/ void FixedAlloc::Free(void *item) { FixedBlock *b = (FixedBlock*) ((uintptr_t)item & ~0xFFF); GCAssertMsg(b->alloc->m_heap->IsAddressInHeap(item), "Bogus pointer passed to free"); #ifdef MMGC_HOOKS GCHeap *heap = b->alloc->m_heap; if(heap->HooksEnabled()) { #ifdef MMGC_MEMORY_PROFILER if(heap->GetProfiler()) b->alloc->m_totalAskSize -= heap->GetProfiler()->GetAskSize(item); #endif heap->FinalizeHook(item, b->size - DebugSize()); heap->FreeHook(item, b->size - DebugSize(), 0xed); } #endif item = GetRealPointer(item); // Add this item to the free list *((void**)item) = b->firstFree; b->firstFree = item; // We were full but now we have a free spot, add us to the free block list. if (b->numAlloc == b->alloc->m_itemsPerBlock) { GCAssert(!b->nextFree && !b->prevFree); b->nextFree = b->alloc->m_firstFree; if (b->alloc->m_firstFree) b->alloc->m_firstFree->prevFree = b; b->alloc->m_firstFree = b; } #ifdef _DEBUG else // we should already be on the free list { GCAssert ((b == b->alloc->m_firstFree) || b->prevFree); } #endif b->numAlloc--; if(b->numAlloc == 0) { b->alloc->FreeChunk(b); } }
/* static */ void FixedAlloc::VerifyFreeBlockIntegrity(void* item, uint32_t size) { while(item) { #ifdef MMGC_64BIT int n = (size >> 2) - 3; #else int n = (size >> 2) - 1; #endif int startIndex = (int)((uint32_t*)item - (uint32_t*)GetRealPointer(item)); for(int i=startIndex; i<n; i++) { uint32_t data = ((uint32_t*)item)[i]; if(data != uint32_t(GCHeap::FXFreedPoison)) { ReportDeletedMemoryWrite(item); break; } } // next free item item = FLNext(item); } }
void FixedMalloc::EnsureFixedMallocMemory(const void* item) { // For a discussion of this flag, see bugzilla 564878. if (!m_heap->config.checkFixedMemory()) return; for (int i=0; i<kNumSizeClasses; i++) if (m_allocs[i].QueryOwnsObject(item)) return; #ifdef AVMPLUS_SAMPLER if (m_heap->SafeSize(GetRealPointer(item)) != (size_t)-1) return; #else { MMGC_LOCK(m_largeObjectLock); for ( LargeObject* lo=largeObjects; lo != NULL ; lo=lo->next) if (lo->item == item) return; } #endif GCAssertMsg(false, "Trying to delete an object with FixedMalloc::Free that was not allocated with FixedMalloc::Alloc"); }
size_t FixedMalloc::LargeSize(const void *item) { return m_heap->Size(GetRealPointer(item)) * GCHeap::kBlockSize; }