summaryrefslogtreecommitdiff
path: root/src/vm/methoditer.h
blob: 05fbb0a59b7187d87bb813547c2dab4ca77a9e78 (plain)
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
// 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;

    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:
    // 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,
               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,
        AssemblyIterationFlags assemblyIterationFlags = (AssemblyIterationFlags)(kIncludeLoaded | kIncludeExecution),
        ModuleIterationOption moduleIterationFlags = kModIterIncludeLoaded)
    {
        LIMITED_METHOD_CONTRACT;
        Start(pAppDomain, pModule, md, assemblyIterationFlags, moduleIterationFlags);
    }
    LoadedMethodDescIterator(void);

protected:
    Module * GetCurrentModule();

};  // class LoadedMethodDescIterator


#endif // _METHODDESCITER_H_