1// Licensed to the .NET Foundation under one or more agreements.
2// The .NET Foundation licenses this file to you under the MIT license.
3// See the LICENSE file in the project root for more information.
4//
5// File: HotHeapsDirectoryIterator.h
6//
7
8//
9// Class code:MetaData::HotHeapsDirectoryIterator represents an iterator through hot heaps directory
10// (code:HotHeapsDirectory).
11//
12// ======================================================================================
13
14#include "external.h"
15
16#include "hotheapsdirectoryiterator.h"
17#include "hotdataformat.h"
18
19namespace MetaData
20{
21
22// --------------------------------------------------------------------------------------
23//
24// Creates empty iterator.
25//
26HotHeapsDirectoryIterator::HotHeapsDirectoryIterator()
27{
28 m_RemainingHeapsDirectoryData.Clear();
29 m_HotHeapsData.Clear();
30} // HotHeapsDirectoryIterator::HotHeapsDirectoryIterator
31
32// --------------------------------------------------------------------------------------
33//
34// Initialize iteration on heaps directory (hotHeapsDirectoryData) with heap hot data (hotHeapsData).
35// The caller guarantees that the heap hot data end where heaps directory beggins.
36//
37void
38HotHeapsDirectoryIterator::Initialize(
39 DataBuffer hotHeapsDirectoryData,
40 DataBuffer hotHeapsData)
41{
42 _ASSERTE(hotHeapsData.GetDataPointerBehind() == hotHeapsDirectoryData.GetDataPointer());
43 m_RemainingHeapsDirectoryData = hotHeapsDirectoryData;
44 m_HotHeapsData = hotHeapsData;
45} // HotHeapsDirectoryIterator::Initialize
46
47// --------------------------------------------------------------------------------------
48//
49// Gets next hot heap (*pHotHeap, of index *pHotHeapIndex) from the heaps directory.
50// Returns S_OK and fills *pHotHeap and *pHotHeapIndex with the next code:HotHeap information.
51// Returns S_FALSE, if the last hot heap was already returned. Clears *pHotHeap and *pHotHeapIndex in this
52// case.
53// Returns error code if the format is invalid. Clears *pHotHeap and *pHotHeapIndex in this case.
54//
55__checkReturn
56HRESULT
57HotHeapsDirectoryIterator::GetNext(
58 HotHeap *pHotHeap,
59 HeapIndex *pHotHeapIndex)
60{
61 HRESULT hr;
62 DataBuffer hotHeapHeaderData;
63 DataBuffer hotHeapData;
64
65 struct HotHeapsDirectoryEntry *pEntry;
66 if (!m_RemainingHeapsDirectoryData.GetData<struct HotHeapsDirectoryEntry>(
67 &pEntry))
68 {
69 hr = S_FALSE;
70 goto ErrExit;
71 }
72
73 if (!HeapIndex::IsValid(pEntry->m_nHeapIndex))
74 {
75 Debug_ReportError("Invalid hot heaps directory format - invalid heap index.");
76 IfFailGo(METADATA_E_INVALID_FORMAT);
77 }
78 pHotHeapIndex->Set(pEntry->m_nHeapIndex);
79
80 hotHeapHeaderData = m_HotHeapsData;
81 if (!hotHeapHeaderData.SkipToExactSize(pEntry->m_nHeapHeaderStart_NegativeOffset))
82 {
83 Debug_ReportError("Invalid hot heaps directory format - heap header offset reaches in front of of hot heaps data.");
84 IfFailGo(METADATA_E_INVALID_FORMAT);
85 }
86
87 struct HotHeapHeader *pHeader;
88 if (!hotHeapHeaderData.PeekData<struct HotHeapHeader>(&pHeader))
89 {
90 Debug_ReportError("Invalid hot heaps directory format - heap header reaches behind hot heaps data.");
91 IfFailGo(METADATA_E_INVALID_FORMAT);
92 }
93
94 hotHeapData = m_HotHeapsData;
95 if (!hotHeapData.TruncateBySize(pEntry->m_nHeapHeaderStart_NegativeOffset))
96 {
97 Debug_ReportInternalError("There's a bug because previous call to SkipToExactSize succeeded.");
98 IfFailGo(METADATA_E_INVALID_FORMAT);
99 }
100
101 IfFailGo(pHotHeap->Initialize(pHeader, hotHeapData));
102 _ASSERTE(hr == S_OK);
103 return hr;
104ErrExit:
105 pHotHeap->Clear();
106 pHotHeapIndex->SetInvalid();
107 return hr;
108} // HotHeapsDirectoryIterator::GetNext
109
110}; // namespace MetaData
111