1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
|
// 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.
#ifndef _METHODDESCITER_H_
#define _METHODDESCITER_H_
#include "instmethhash.h"
#include "method.hpp"
#include "appdomain.hpp"
#include "domainfile.h"
#include "typehash.h"
// Iterate all the currently loaded instantiations of a mdMethodDef
// in a given AppDomain. Can be used for both generic + nongeneric methods.
// This may give back duplicate entries; and it may give back some extra
// MethodDescs for which HasNativeCode() returns false.
// Regarding EnC: MethodDescs only match the latest version in an EnC case.
// Thus this iterator does not go through all previous EnC versions.
// This iterator is almost a nop for the non-generic case.
// This is currently not an efficient implementation for the generic case
// as we search every entry in every item in the ParamTypes and/or InstMeth tables.
// It is possible we may have
// to make this more efficient, but it should not be used very often (only
// when debugging prejitted generic code, and then only when updating
// methodInfos after the load of a new module, and also when fetching
// the native code ranges for generic code).
class LoadedMethodDescIterator
{
Module * m_module;
mdMethodDef m_md;
MethodDesc * m_mainMD;
AppDomain * m_pAppDomain;
// The following hold the state of the iteration....
// Yes we iterate everything for the moment - we need
// to get every single module. Ideally when finding debugging information
// we should only iterate freshly added modules. We would also like to only
// iterate the relevant entries of the hash tables but that means changing the
// hash functions.
// These are used when iterating over an AppDomain
AppDomain::AssemblyIterator m_assemIterator;
DomainModuleIterator m_moduleIterator;
AssemblyIterationFlags m_assemIterationFlags;
ModuleIterationOption m_moduleIterationFlags;
// These are used when iterating over the SharedDomain
SharedDomain::SharedAssemblyIterator m_sharedAssemblyIterator;
Assembly::ModuleIterator m_sharedModuleIterator;
EETypeHashTable::Iterator m_typeIterator;
EETypeHashEntry * m_typeIteratorEntry;
BOOL m_startedNonGenericType;
InstMethodHashTable::Iterator m_methodIterator;
InstMethodHashEntry * m_methodIteratorEntry;
BOOL m_startedNonGenericMethod;
BOOL m_fFirstTime;
#ifdef _DEBUG
DomainAssembly * dbg_m_pDomainAssembly;
#endif //_DEBUG
public:
// Defines the set of assemblies that LoadedMethodDescIterator should consider.
// Typical usages:
// * Debugger controller (for setting breakpoint) just uses kModeAllADAssemblies.
// * RejitManager uses the iterator once with kModeSharedDomainAssemblies, and
// then a bunch of times (once per AD) with kModeUnsharedADAssemblies to
// ensure all assemblies in all ADs are considered, and to avoid unnecessary
// dupes for domain-neutral assemblies.
enum AssemblyIterationMode
{
// Default, used by debugger's breakpoint controller. Iterates through all
// Assemblies associated with the specified AppDomain
kModeAllADAssemblies,
// Iterate through only the *unshared* assemblies associated with the specified
// AppDomain.
kModeUnsharedADAssemblies,
// Rather than iterating through Assemblies associated with an AppDomain, just
// iterate over all Assemblies associated with the SharedDomain
kModeSharedDomainAssemblies,
};
// Iterates next MethodDesc. Updates the holder only if the assembly differs from the previous one.
// Caller should not release (i.e. change) the holder explicitly between calls, otherwise collectible
// assembly might be without a reference and get deallocated (even the native part).
BOOL Next(CollectibleAssemblyHolder<DomainAssembly *> * pDomainAssemblyHolder);
MethodDesc *Current();
void Start(AppDomain * pAppDomain,
Module *pModule,
mdMethodDef md,
AssemblyIterationMode assemblyIterationMode,
AssemblyIterationFlags assemIterationFlags = (AssemblyIterationFlags)(kIncludeLoaded | kIncludeExecution),
ModuleIterationOption moduleIterationFlags = kModIterIncludeLoaded);
void Start(AppDomain * pAppDomain, Module *pModule, mdMethodDef md, MethodDesc *pDesc);
LoadedMethodDescIterator(
AppDomain * pAppDomain,
Module *pModule,
mdMethodDef md,
AssemblyIterationMode assemblyIterationMode = kModeAllADAssemblies,
AssemblyIterationFlags assemblyIterationFlags = (AssemblyIterationFlags)(kIncludeLoaded | kIncludeExecution),
ModuleIterationOption moduleIterationFlags = kModIterIncludeLoaded)
{
LIMITED_METHOD_CONTRACT;
Start(pAppDomain, pModule, md, assemblyIterationMode, assemblyIterationFlags, moduleIterationFlags);
}
LoadedMethodDescIterator(void);
protected:
AssemblyIterationMode m_assemblyIterationMode;
BOOL m_fSharedDomain;
Module * GetCurrentModule();
BOOL NextSharedModule();
}; // class LoadedMethodDescIterator
#endif // _METHODDESCITER_H_
|