diff options
Diffstat (limited to 'src/md/hotdata/hotheapsdirectoryiterator.cpp')
-rw-r--r-- | src/md/hotdata/hotheapsdirectoryiterator.cpp | 110 |
1 files changed, 110 insertions, 0 deletions
diff --git a/src/md/hotdata/hotheapsdirectoryiterator.cpp b/src/md/hotdata/hotheapsdirectoryiterator.cpp new file mode 100644 index 0000000000..e0cdb1ca8e --- /dev/null +++ b/src/md/hotdata/hotheapsdirectoryiterator.cpp @@ -0,0 +1,110 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. +// +// File: HotHeapsDirectoryIterator.h +// + +// +// Class code:MetaData::HotHeapsDirectoryIterator represents an iterator through hot heaps directory +// (code:HotHeapsDirectory). +// +// ====================================================================================== + +#include "external.h" + +#include "hotheapsdirectoryiterator.h" +#include "hotdataformat.h" + +namespace MetaData +{ + +// -------------------------------------------------------------------------------------- +// +// Creates empty iterator. +// +HotHeapsDirectoryIterator::HotHeapsDirectoryIterator() +{ + m_RemainingHeapsDirectoryData.Clear(); + m_HotHeapsData.Clear(); +} // HotHeapsDirectoryIterator::HotHeapsDirectoryIterator + +// -------------------------------------------------------------------------------------- +// +// Initialize iteration on heaps directory (hotHeapsDirectoryData) with heap hot data (hotHeapsData). +// The caller guarantees that the heap hot data end where heaps directory beggins. +// +void +HotHeapsDirectoryIterator::Initialize( + DataBuffer hotHeapsDirectoryData, + DataBuffer hotHeapsData) +{ + _ASSERTE(hotHeapsData.GetDataPointerBehind() == hotHeapsDirectoryData.GetDataPointer()); + m_RemainingHeapsDirectoryData = hotHeapsDirectoryData; + m_HotHeapsData = hotHeapsData; +} // HotHeapsDirectoryIterator::Initialize + +// -------------------------------------------------------------------------------------- +// +// Gets next hot heap (*pHotHeap, of index *pHotHeapIndex) from the heaps directory. +// Returns S_OK and fills *pHotHeap and *pHotHeapIndex with the next code:HotHeap information. +// Returns S_FALSE, if the last hot heap was already returned. Clears *pHotHeap and *pHotHeapIndex in this +// case. +// Returns error code if the format is invalid. Clears *pHotHeap and *pHotHeapIndex in this case. +// +__checkReturn +HRESULT +HotHeapsDirectoryIterator::GetNext( + HotHeap *pHotHeap, + HeapIndex *pHotHeapIndex) +{ + HRESULT hr; + DataBuffer hotHeapHeaderData; + DataBuffer hotHeapData; + + struct HotHeapsDirectoryEntry *pEntry; + if (!m_RemainingHeapsDirectoryData.GetData<struct HotHeapsDirectoryEntry>( + &pEntry)) + { + hr = S_FALSE; + goto ErrExit; + } + + if (!HeapIndex::IsValid(pEntry->m_nHeapIndex)) + { + Debug_ReportError("Invalid hot heaps directory format - invalid heap index."); + IfFailGo(METADATA_E_INVALID_FORMAT); + } + pHotHeapIndex->Set(pEntry->m_nHeapIndex); + + hotHeapHeaderData = m_HotHeapsData; + if (!hotHeapHeaderData.SkipToExactSize(pEntry->m_nHeapHeaderStart_NegativeOffset)) + { + Debug_ReportError("Invalid hot heaps directory format - heap header offset reaches in front of of hot heaps data."); + IfFailGo(METADATA_E_INVALID_FORMAT); + } + + struct HotHeapHeader *pHeader; + if (!hotHeapHeaderData.PeekData<struct HotHeapHeader>(&pHeader)) + { + Debug_ReportError("Invalid hot heaps directory format - heap header reaches behind hot heaps data."); + IfFailGo(METADATA_E_INVALID_FORMAT); + } + + hotHeapData = m_HotHeapsData; + if (!hotHeapData.TruncateBySize(pEntry->m_nHeapHeaderStart_NegativeOffset)) + { + Debug_ReportInternalError("There's a bug because previous call to SkipToExactSize succeeded."); + IfFailGo(METADATA_E_INVALID_FORMAT); + } + + IfFailGo(pHotHeap->Initialize(pHeader, hotHeapData)); + _ASSERTE(hr == S_OK); + return hr; +ErrExit: + pHotHeap->Clear(); + pHotHeapIndex->SetInvalid(); + return hr; +} // HotHeapsDirectoryIterator::GetNext + +}; // namespace MetaData |