-
Notifications
You must be signed in to change notification settings - Fork 393
/
HeapRegionDescriptor.hpp
373 lines (328 loc) · 11.8 KB
/
HeapRegionDescriptor.hpp
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
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
/*******************************************************************************
* Copyright (c) 1991, 2021 IBM Corp. and others
*
* This program and the accompanying materials are made available under
* the terms of the Eclipse Public License 2.0 which accompanies this
* distribution and is available at https://www.eclipse.org/legal/epl-2.0/
* or the Apache License, Version 2.0 which accompanies this distribution and
* is available at https://www.apache.org/licenses/LICENSE-2.0.
*
* This Source Code may also be made available under the following
* Secondary Licenses when the conditions for such availability set
* forth in the Eclipse Public License, v. 2.0 are satisfied: GNU
* General Public License, version 2 with the GNU Classpath
* Exception [1] and GNU General Public License, version 2 with the
* OpenJDK Assembly Exception [2].
*
* [1] https://www.gnu.org/software/classpath/license.html
* [2] http://openjdk.java.net/legal/assembly-exception.html
*
* SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 OR LicenseRef-GPL-2.0 WITH Assembly-exception
*******************************************************************************/
#if !defined(HEAPREGIONDESCRIPTOR_HPP)
#define HEAPREGIONDESCRIPTOR_HPP
#include "omrcfg.h"
#include "omrcomp.h"
#include "ModronAssertions.h"
#include "j9nongenerated.h"
#include "BaseVirtual.hpp"
#include "MemorySubSpace.hpp"
class MM_MemoryPool;
class MM_MemorySubSpace;
class MM_HeapRegionManager;
class MM_HeapRegionManagerTarok;
class MM_EnvironmentBase;
/**
* Base abstract class for heap region descriptors.
* For Tarok, the heap is divided into a number of regions, each with potentially many different properties
* (e.g., object size class, node affinity, etc). The heap region descriptor is found in the heap region table
* which describes a single region.
*/
class MM_HeapRegionDescriptor : public MM_BaseVirtual
{
friend class MM_HeapRegionManager;
friend class MM_HeapRegionManagerTarok;
friend class MM_MemorySubSpace;
public:
enum RegionType {
RESERVED = 0, /**< Represents regions that are currently uncommited */
FREE = 1, /**< Represents regions that are completely free */
SEGREGATED_SMALL = 2, /**< Represents regions that contain objects */
SEGREGATED_LARGE = 3, /**< Represents spanning regions that contain objects */
ARRAYLET_LEAF = 4, /**< Represents regions that contain arraylet leaf's */
ADDRESS_ORDERED = 5, /**< Represents regions that have an AOL MemoryPool */
ADDRESS_ORDERED_IDLE = 6, /**< Represents regions that have an AOL MemoryPool but are not actively being used (that is, they can be made into other kinds of regions without penalty) */
ADDRESS_ORDERED_MARKED = 7, /**< Represents regions that have an AOL MemoryPool and an accurate mark set in extensions->previousMarkMap */
/* TODO: remove BUMP_ALLOCATED, BUMP_ALLOCATED_IDLE, BUMP_ALLOCATED_MARKED with BumpPointer MemoryPool */
BUMP_ALLOCATED = 8, /**< Represents regions that have a BumpPointer MemoryPool */
BUMP_ALLOCATED_IDLE = 9, /**< Represents regions that have a BumpPointer MemoryPool but are not actively being used (that is, they can be made into other kinds of regions without penalty) */
BUMP_ALLOCATED_MARKED = 10, /**< Represents regions that have a BumpPointer MemoryPool and an accurate mark set in extensions->previousMarkMap */
LAST_REGION_TYPE /**< This dummy type is sed later as a size of an array for stats of region counts */
};
uintptr_t _regionsInSpan; /**< most likely a temporary piece of data which, along with _nextInSet, builds a freelist (public for assertions) */
MM_HeapRegionDescriptor *_headOfSpan; /**< in a spanning region, points to the HEAD of the span. In non-spanning, points at this */
void *_heapRegionDescriptorExtension; /**< Language-specific extension of per region descriptor can be attached by configuration delegate (MM_ConfigurationDelegate) */
/**
* The values of the members in this enum will be ORed into @ref _regionProperties
* as flags they should therefore be powers of 2 which don't exceed the range
* of @ref _regionProperties
*/
enum RegionProperties {
ALL = 0xFFFFFFFF
,MANAGED = 1
};
protected:
private:
void *_lowAddress; /**< low address of the region (inclusive) */
void *_highAddress; /**< high address of the region (exclusive) */
MM_HeapRegionDescriptor *_previousRegion; /**< previous region descriptor in the list (used by HeapRegionManager) */
MM_HeapRegionDescriptor *_nextRegion; /**< next region descriptor in the list (used by HeapRegionManager) */
MM_HeapRegionDescriptor *_previousRegionInSubSpace; /**< previous region descriptor in the list (used by MM_MemorySubSpaceGeneric) */
MM_HeapRegionDescriptor *_nextRegionInSubSpace; /**< next region descriptor in the list (used by MM_MemorySubSpaceGeneric) */
MM_HeapRegionDescriptor *_nextInSet; /**< most likely a temporary link which is used for passing around ad-hoc "collections" of regions */
bool _isAllocated; /**< This will become an enumeration of more interesting region states once we have them */
MM_MemorySubSpace *_memorySubSpace; /**< the memory subspace associated with this region */
RegionType _regionType; /**< This regions current type */
MM_MemoryPool *_memoryPool; /**< The memory pool associated with this region. This may be NULL */
uintptr_t _numaNode; /**< The NUMA node this region is associated with */
uint32_t _regionProperties; /**< A bitmap of the RegionProperties this region possesses */
public:
MM_HeapRegionDescriptor(MM_EnvironmentBase *env, void *lowAddress, void *highAddress);
virtual void associateWithSubSpace(MM_MemorySubSpace *subSpace);
virtual void disassociateWithSubSpace();
/**
* Set the specified property in the @ref _regionProperties bitmap
* @param[in] property The RegionProperties property to set
*/
MMINLINE void setRegionProperty(RegionProperties property) { _regionProperties |= property; }
/**
* Clear the specified property from the @ref _regionProperties bitmap
* @param[in] property The RegionProperties property to clear
*/
MMINLINE void clearRegionProperty(RegionProperties property) { _regionProperties &= ~property; }
/**
* Get this region's @ref _regionProperties
*
* @return This region's @ref _regionProperties
*/
MMINLINE uint32_t getRegionProperties() { return _regionProperties; }
/**
* Test whether or not a certain property is set in the @ref _regionProperties bitmap
* @param[in] property The RegionProperties property to test
*
* @return True if the property is set, false otherwise
*/
MMINLINE bool regionPropertyIsSet(RegionProperties property) { return (0 != (getRegionProperties() & property)); }
/**
* Get the low address of this region
*
* @return the lowest address in the region
*/
void*
getLowAddress() const
{
void *low = _lowAddress;
return low;
}
/**
* Get the high address of this region
*
* @return the first address beyond the end of the region
*/
void*
getHighAddress() const
{
void *result = NULL;
if (0 == _regionsInSpan) {
result = _highAddress;
} else {
void *low = _lowAddress;
void *high = _highAddress;
uintptr_t delta = (uintptr_t)high - (uintptr_t)low;
result = (void *)((uintptr_t)low + _regionsInSpan * delta);
}
/* Note that we can't assert that this is the same high address as our root backing since, when a spanning
* region is being released, a root backing becomes temporarily out of sync with a descriptor built on it
*/
return result;
}
/**
* Determine if the specified address is in the region
* @parm address - the address to test
* @return true if address is within the receiver, false otherwise
*/
bool
isAddressInRegion(const void* address)
{
return (address >= getLowAddress()) && (address < getHighAddress());
}
/**
* Returns the MM_MemorySubSpace associated with the receiver.
*
* @return The MM_MemorySubSpace associated with the receiver
*/
MM_MemorySubSpace *
getSubSpace()
{
return _memorySubSpace;
}
/**
* A helper to request the type flags from the Subspace associated with the receiving region.
*
* @return The type flags of the Subspace associated with this region
*/
uintptr_t
getTypeFlags()
{
return MEMORY_TYPE_RAM | getSubSpace()->getTypeFlags();
}
/**
* @return The number of contiguous bytes represented by the receiver
*/
uintptr_t
getSize() const
{
return (uintptr_t)getHighAddress() - (uintptr_t)getLowAddress();
}
void
setRegionType(RegionType type)
{
_regionType = type;
}
RegionType
getRegionType()
{
return _regionType;
}
void
setMemoryPool(MM_MemoryPool *memoryPool)
{
_memoryPool = memoryPool;
}
MM_MemoryPool*
getMemoryPool()
{
return _memoryPool;
}
/**
* @return True if the memory backing this region is committed
*/
bool
isCommitted()
{
/* currently, we only check to see if we have set a subspace but this will eventually be a meta-data flag */
return (NULL != getSubSpace());
}
/**
* Set the NUMA node the memory in the region is associated with
*/
void
setNumaNode(uintptr_t numaNode) {
_numaNode = numaNode;
}
/**
* @return the NUMA node the memory in the region is associated with
*/
uintptr_t
getNumaNode() {
return _numaNode;
}
/**
* @return true if the region is a type which can contain objects
*/
bool
containsObjects()
{
bool result = false;
switch (getRegionType()) {
case SEGREGATED_SMALL:
case SEGREGATED_LARGE:
case ADDRESS_ORDERED:
case ADDRESS_ORDERED_MARKED:
case BUMP_ALLOCATED:
case BUMP_ALLOCATED_MARKED:
result = true;
break;
default:
/* all other types do not contain objects */
result = false;
break;
}
return result;
}
/**
* @return true if the region has an up-to-date mark map
*/
bool
hasValidMarkMap()
{
bool result = false;
switch (getRegionType()) {
case ADDRESS_ORDERED_MARKED:
case BUMP_ALLOCATED_MARKED:
result = true;
break;
default:
/* all other types do not have valid mark maps */
result = false;
break;
}
return result;
}
/**
* @return true if the region is free or idle
*/
bool
isFreeOrIdle()
{
bool result = false;
switch (getRegionType()) {
case ADDRESS_ORDERED_IDLE:
case BUMP_ALLOCATED_IDLE:
case FREE:
result = true;
break;
default:
/* all other types are not free */
result = false;
break;
}
return result;
}
/**
* Sets a ADDRESS_ORDERED region to ADDRESS_ORDERED_MARKED. Asserts if called on any other region type.
* This can be extended to other region types which have a "marked" variant as they are needed.
*/
/*
void setMarkMapValid()
{
Assert_MM_true(ADDRESS_ORDERED == getRegionType());
setRegionType(ADDRESS_ORDERED_MARKED);
}
*/
/* temporary change for breaking cross dependency */
void setMarkMapValid()
{
Assert_MM_true((ADDRESS_ORDERED == getRegionType()) || (BUMP_ALLOCATED == getRegionType()));
if (ADDRESS_ORDERED == getRegionType()) {
setRegionType(ADDRESS_ORDERED_MARKED);
} else {
setRegionType(BUMP_ALLOCATED_MARKED);
}
}
/**
* Allocate supporting resources (large enough to justify not to preallocate them for all regions at the startup) when region is being committed.
* @param env[in] of a GC thread
* @return true if allocation is successful
*/
virtual bool allocateSupportingResources(MM_EnvironmentBase *env) { return true; }
virtual bool check(MM_EnvironmentBase *env) { return true; }
bool initialize(MM_EnvironmentBase *env, MM_HeapRegionManager *regionManager);
void tearDown(MM_EnvironmentBase *env);
static bool initializer(MM_EnvironmentBase *env, MM_HeapRegionManager *regionManager, MM_HeapRegionDescriptor *descriptor, void *lowAddress, void *highAddress);
static void destructor(MM_EnvironmentBase *env, MM_HeapRegionManager *regionManager, MM_HeapRegionDescriptor *descriptor);
protected:
void reinitialize(MM_EnvironmentBase *env, void *lowAddress, void *highAddress);
private:
};
#endif /* HEAPREGIONDESCRIPTOR_HPP */