Welcome to mirror list, hosted at ThFree Co, Russian Federation.

allocheap.h « Runtime « Native « src - github.com/mono/corert.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 7a71c08506ef6795c16f5007f5754200e56ed2df (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
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
// 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.
#include "forward_declarations.h"

#ifdef FEATURE_RWX_MEMORY
#define WRITE_ACCESS_HOLDER_ARG                 , rh::util::WriteAccessHolder *pRWAccessHolder
#define WRITE_ACCESS_HOLDER_ARG_NULL_DEFAULT    , rh::util::WriteAccessHolder *pRWAccessHolder = NULL
#define PASS_WRITE_ACCESS_HOLDER_ARG            , pRWAccessHolder
#else // FEATURE_RWX_MEMORY
#define WRITE_ACCESS_HOLDER_ARG
#define WRITE_ACCESS_HOLDER_ARG_NULL_DEFAULT
#define PASS_WRITE_ACCESS_HOLDER_ARG
#endif // FEATURE_RWX_MEMORY

class AllocHeap
{
  public:
    AllocHeap();

#ifdef FEATURE_RWX_MEMORY
    // If pAccessMgr is non-NULL, it will be used to manage R/W access to the memory allocated.
    AllocHeap(UInt32 rwProtectType = PAGE_READWRITE,
              UInt32 roProtectType = 0, // 0 indicates "same as rwProtectType"
              rh::util::MemAccessMgr* pAccessMgr = NULL);
#endif // FEATURE_RWX_MEMORY

    bool Init();

    bool Init(UInt8 *    pbInitialMem,
              UIntNative cbInitialMemCommit,
              UIntNative cbInitialMemReserve,
              bool       fShouldFreeInitialMem);

    ~AllocHeap();

    // If AllocHeap was created with a MemAccessMgr, pRWAccessHolder must be non-NULL.
    // On return, the holder will permit R/W access to the allocated memory until it
    // is destructed.
    UInt8 * Alloc(UIntNative cbMem WRITE_ACCESS_HOLDER_ARG_NULL_DEFAULT);

    // If AllocHeap was created with a MemAccessMgr, pRWAccessHolder must be non-NULL.
    // On return, the holder will permit R/W access to the allocated memory until it
    // is destructed.
    UInt8 * AllocAligned(UIntNative cbMem,
                         UIntNative alignment
                         WRITE_ACCESS_HOLDER_ARG_NULL_DEFAULT);

    // Returns true if this AllocHeap owns the memory range [pvMem, pvMem+cbMem)
    bool Contains(void * pvMem,
                  UIntNative cbMem);

#ifdef FEATURE_RWX_MEMORY
    // Used with previously-allocated memory for which RW access is needed again.
    // Returns true on success. R/W access will be granted until the holder is
    // destructed.
    bool AcquireWriteAccess(void* pvMem,
                            UIntNative cbMem,
                            rh::util::WriteAccessHolder* pHolder);
#endif // FEATURE_RWX_MEMORY

  private:
    // Allocation Helpers
    UInt8* _Alloc(UIntNative cbMem, UIntNative alignment WRITE_ACCESS_HOLDER_ARG);
    bool _AllocNewBlock(UIntNative cbMem);
    UInt8* _AllocFromCurBlock(UIntNative cbMem, UIntNative alignment WRITE_ACCESS_HOLDER_ARG);
    bool _CommitFromCurBlock(UIntNative cbMem);

    // Access protection helpers
#ifdef FEATURE_RWX_MEMORY
    bool _AcquireWriteAccess(UInt8* pvMem, UIntNative cbMem, rh::util::WriteAccessHolder* pHolder);
#endif // FEATURE_RWX_MEMORY
    bool _UpdateMemPtrs(UInt8* pNextFree, UInt8* pFreeCommitEnd, UInt8* pFreeReserveEnd);
    bool _UpdateMemPtrs(UInt8* pNextFree, UInt8* pFreeCommitEnd);
    bool _UpdateMemPtrs(UInt8* pNextFree);
    bool _UseAccessManager() { return m_rwProtectType != m_roProtectType; }

    static const UIntNative s_minBlockSize = OS_PAGE_SIZE;

    typedef rh::util::MemRange Block;
    typedef DPTR(Block) PTR_Block;
    struct BlockListElem : public Block
    {
        BlockListElem(Block const & block)
            : Block(block)
            {}

        BlockListElem(UInt8 * pbMem, UIntNative  cbMem)
            : Block(pbMem, cbMem)
            {}

        Block       m_block;
        PTR_Block   m_pNext;
    };

    typedef SList<BlockListElem>    BlockList;
    BlockList                       m_blockList;

    UInt32                          m_rwProtectType; // READ/WRITE/EXECUTE/etc
    UInt32                          m_roProtectType; // What to do with fully allocated and initialized pages.

#ifdef FEATURE_RWX_MEMORY
    rh::util::MemAccessMgr*         m_pAccessMgr;
    rh::util::WriteAccessHolder     m_hCurPageRW;   // Used to hold RW access to the current allocation page
                                                    // Passed as pHint to MemAccessMgr::AcquireWriteAccess.
#endif // FEATURE_RWX_MEMORY
    UInt8 *                         m_pNextFree;
    UInt8 *                         m_pFreeCommitEnd;
    UInt8 *                         m_pFreeReserveEnd;

    UInt8 *                         m_pbInitialMem;
    bool                            m_fShouldFreeInitialMem;

    Crst                            m_lock;

    INDEBUG(bool                    m_fIsInit;)
};
typedef DPTR(AllocHeap) PTR_AllocHeap;

//-------------------------------------------------------------------------------------------------
void * __cdecl operator new(size_t n, AllocHeap * alloc);
void * __cdecl operator new[](size_t n, AllocHeap * alloc);