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 | |
19 | namespace MetaData |
20 | { |
21 | |
22 | // -------------------------------------------------------------------------------------- |
23 | // |
24 | // Creates empty iterator. |
25 | // |
26 | HotHeapsDirectoryIterator::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 | // |
37 | void |
38 | HotHeapsDirectoryIterator::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 |
56 | HRESULT |
57 | HotHeapsDirectoryIterator::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; |
104 | ErrExit: |
105 | pHotHeap->Clear(); |
106 | pHotHeapIndex->SetInvalid(); |
107 | return hr; |
108 | } // HotHeapsDirectoryIterator::GetNext |
109 | |
110 | }; // namespace MetaData |
111 |