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
6
7#ifndef _METHODDESCITER_H_
8#define _METHODDESCITER_H_
9
10#include "instmethhash.h"
11#include "method.hpp"
12#include "appdomain.hpp"
13#include "domainfile.h"
14#include "typehash.h"
15
16
17// Iterate all the currently loaded instantiations of a mdMethodDef
18// in a given AppDomain. Can be used for both generic + nongeneric methods.
19// This may give back duplicate entries; and it may give back some extra
20// MethodDescs for which HasNativeCode() returns false.
21// Regarding EnC: MethodDescs only match the latest version in an EnC case.
22// Thus this iterator does not go through all previous EnC versions.
23
24// This iterator is almost a nop for the non-generic case.
25// This is currently not an efficient implementation for the generic case
26// as we search every entry in every item in the ParamTypes and/or InstMeth tables.
27// It is possible we may have
28// to make this more efficient, but it should not be used very often (only
29// when debugging prejitted generic code, and then only when updating
30// methodInfos after the load of a new module, and also when fetching
31// the native code ranges for generic code).
32class LoadedMethodDescIterator
33{
34 Module * m_module;
35 mdMethodDef m_md;
36 MethodDesc * m_mainMD;
37 AppDomain * m_pAppDomain;
38
39 // The following hold the state of the iteration....
40 // Yes we iterate everything for the moment - we need
41 // to get every single module. Ideally when finding debugging information
42 // we should only iterate freshly added modules. We would also like to only
43 // iterate the relevant entries of the hash tables but that means changing the
44 // hash functions.
45
46 // These are used when iterating over an AppDomain
47 AppDomain::AssemblyIterator m_assemIterator;
48 DomainModuleIterator m_moduleIterator;
49 AssemblyIterationFlags m_assemIterationFlags;
50 ModuleIterationOption m_moduleIterationFlags;
51
52 EETypeHashTable::Iterator m_typeIterator;
53 EETypeHashEntry * m_typeIteratorEntry;
54 BOOL m_startedNonGenericType;
55 InstMethodHashTable::Iterator m_methodIterator;
56 InstMethodHashEntry * m_methodIteratorEntry;
57 BOOL m_startedNonGenericMethod;
58 BOOL m_fFirstTime;
59
60#ifdef _DEBUG
61 DomainAssembly * dbg_m_pDomainAssembly;
62#endif //_DEBUG
63
64public:
65 // Iterates next MethodDesc. Updates the holder only if the assembly differs from the previous one.
66 // Caller should not release (i.e. change) the holder explicitly between calls, otherwise collectible
67 // assembly might be without a reference and get deallocated (even the native part).
68 BOOL Next(CollectibleAssemblyHolder<DomainAssembly *> * pDomainAssemblyHolder);
69 MethodDesc *Current();
70 void Start(AppDomain * pAppDomain,
71 Module *pModule,
72 mdMethodDef md,
73 AssemblyIterationFlags assemIterationFlags = (AssemblyIterationFlags)(kIncludeLoaded | kIncludeExecution),
74 ModuleIterationOption moduleIterationFlags = kModIterIncludeLoaded);
75 void Start(AppDomain * pAppDomain, Module *pModule, mdMethodDef md, MethodDesc *pDesc);
76
77 LoadedMethodDescIterator(
78 AppDomain * pAppDomain,
79 Module *pModule,
80 mdMethodDef md,
81 AssemblyIterationFlags assemblyIterationFlags = (AssemblyIterationFlags)(kIncludeLoaded | kIncludeExecution),
82 ModuleIterationOption moduleIterationFlags = kModIterIncludeLoaded)
83 {
84 LIMITED_METHOD_CONTRACT;
85 Start(pAppDomain, pModule, md, assemblyIterationFlags, moduleIterationFlags);
86 }
87 LoadedMethodDescIterator(void);
88
89protected:
90 Module * GetCurrentModule();
91
92}; // class LoadedMethodDescIterator
93
94
95#endif // _METHODDESCITER_H_
96