-
Notifications
You must be signed in to change notification settings - Fork 23
/
Copy pathObjMemPriv.inl
98 lines (79 loc) · 2.47 KB
/
ObjMemPriv.inl
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
///////////////////////////////////////////////////////////////////////////////
// ObjectMemory Private Inlines
#include "objmem.h"
#include "STBehavior.h"
#define _CRTBLD
#include "winheap.h"
#undef _CRTBLD
#ifdef MEMSTATS
extern unsigned m_nSmallAllocated;
extern unsigned m_nSmallFreed;
#endif
///////////////////////////////////////////////////////////////////////////////
// Low-level memory allocation
inline POBJECT ObjectMemory::allocChunk(MWORD chunkSize)
{
#if defined(PRIVATE_HEAP)
POBJECT pObj = static_cast<POBJECT>(::HeapAlloc(m_hHeap, HEAP_NO_SERIALIZE, chunkSize));
#ifdef _DEBUG
memset(pObj, 0xCD, chunkSize);
#endif
return pObj;
#else
return malloc(chunkSize);
#endif
}
extern "C" ST::Object emptyObj;
inline POBJECT ObjectMemory::allocSmallChunk(MWORD chunkSize)
{
#ifdef MEMSTATS
++m_nSmallAllocated;
#endif
ASSERT(chunkSize <= MaxSmallObjectSize);
return chunkSize > MaxSizeOfPoolObject
? static_cast<POBJECT>(__sbh_alloc_block(chunkSize))
: chunkSize == 0
? &emptyObj
: // Use chunk pools, which are fast but can cause memory fragmentation
spacePoolForSize(chunkSize).allocate();
}
inline void ObjectMemory::freeSmallChunk(POBJECT pBlock, MWORD size)
{
#ifdef MEMSTATS
++m_nSmallFreed;
#endif
ASSERT(size <= MaxSmallObjectSize);
if (size > MaxSizeOfPoolObject)
{
// Locate and dealloc SBH block
PHEADER pHeader = __sbh_find_block(pBlock);
ASSERT(pHeader != NULL);
__sbh_free_block(pHeader, pBlock);
}
else
{
if (pBlock != &emptyObj)
spacePoolForSize(size).deallocate(pBlock);
}
}
///////////////////////////////////////////////////////////////////////////////
// Oop allocation
inline OTE* __fastcall ObjectMemory::allocateOop(POBJECT pLocation)
{
// OT is globally shared, so access must be in crit section
// ASSERT(m_nInCritSection > 0);
ASSERT(m_pFreePointerList != NULL);
// N.B. By not ref. counting class here, we make a useful saving of a redundant
// ref. counting operation in primitiveNew and primitiveNewWithArg
OTE* ote = m_pFreePointerList;
m_pFreePointerList = reinterpret_cast<OTE*>(ote->m_location);
ASSERT(ote->isFree());
_ASSERTE(--m_nFreeOTEs >= 0);
// Set OTE fields of the Oop
ote->m_location = pLocation;
// Maintain the last used garbage collector mark to speed up collections
// Doing this will also reset the free bit and set the pointer bit
// so byte allocations will need to reset it
ote->m_dwFlags = *reinterpret_cast<BYTE*>(&m_spaceOTEBits[OTEFlags::PoolSpace]);
return ote;
}