-
Notifications
You must be signed in to change notification settings - Fork 748
/
Copy pathArrayletObjectModelBase.hpp
338 lines (312 loc) · 11.6 KB
/
ArrayletObjectModelBase.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
/*******************************************************************************
* Copyright IBM Corp. and others 1991
*
* 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] https://openjdk.org/legal/assembly-exception.html
*
* SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0 OR GPL-2.0-only WITH OpenJDK-assembly-exception-1.0
*******************************************************************************/
#if !defined(ARRAYLETOBJECTMODELBASE_)
#define ARRAYLETOBJECTMODELBASE_
#include "j9.h"
#include "j9cfg.h"
#include "j9consts.h"
#include "modron.h"
#include "modronopt.h"
#include "Bits.hpp"
#include "Math.hpp"
class MM_GCExtensionsBase;
class MM_MemorySubSpace;
class GC_ArrayletObjectModelBase
{
/*
* Data members
*/
private:
#if defined(J9VM_GC_ENABLE_DOUBLE_MAP)
bool _enableDoubleMapping; /** Allows arraylets to be double mapped */
#endif /* J9VM_GC_ENABLE_DOUBLE_MAP */
protected:
#if defined(OMR_GC_COMPRESSED_POINTERS) && defined(OMR_GC_FULL_POINTERS)
bool _compressObjectReferences;
#endif /* defined(OMR_GC_COMPRESSED_POINTERS) && defined(OMR_GC_FULL_POINTERS) */
OMR_VM *_omrVM; /**< used so that we can pull the arrayletLeafSize and arrayletLeafLogSize for arraylet sizing calculations */
void * _arrayletRangeBase; /**< The base heap range of where discontiguous arraylets are allowed. */
void * _arrayletRangeTop; /**< The top heap range of where discontiguous arraylets are allowed. */
MM_MemorySubSpace * _arrayletSubSpace; /**< The only subspace that is allowed to have discontiguous arraylets. */
uintptr_t _largestDesirableArraySpineSize; /**< A cached copy of the subspace's _largestDesirableArraySpineSize to be used when we don't have access to a subspace. */
#if defined(J9VM_GC_SPARSE_HEAP_ALLOCATION)
bool _enableVirtualLargeObjectHeap;
#endif /* defined(J9VM_GC_SPARSE_HEAP_ALLOCATION) */
#if defined(J9VM_ENV_DATA64)
bool _isIndexableDataAddrPresent;
#endif /* defined(J9VM_ENV_DATA64) */
uintptr_t _contiguousIndexableHeaderSize;
uintptr_t _discontiguousIndexableHeaderSize;
public:
typedef enum ArrayLayout {
Illegal = 0,
InlineContiguous,
Discontiguous,
Hybrid
} ArrayLayout;
/*
* Function members
*/
private:
protected:
virtual bool initialize(MM_GCExtensionsBase *extensions);
virtual void tearDown(MM_GCExtensionsBase *extensions);
/**
* Get the spine size without header for an arraylet with these properties
* @param layout The layout of the indexable object
* @param numberArraylets Number of arraylets for this indexable object
* @param dataSize How many elements are in the indexable object
* @param alignData Should the data section be aligned
* @return spineSize The actual size in byte of the spine
*/
uintptr_t
getSpineSizeWithoutHeader(ArrayLayout layout, uintptr_t numberArraylets, uintptr_t dataSize, bool alignData);
public:
/**
* Return back true if object references are compressed
* @return true, if object references are compressed
*/
MMINLINE bool
compressObjectReferences()
{
return OMR_COMPRESS_OBJECT_REFERENCES(_compressObjectReferences);
}
/**
* Returns the size of an indexable object in elements.
* @param arrayPtr Pointer to the indexable object whose size is required
* @return Size of object in elements
*/
MMINLINE uintptr_t
getSizeInElements(J9IndexableObject *arrayPtr)
{
uintptr_t size = 0;
if (compressObjectReferences()) {
size = ((J9IndexableObjectContiguousCompressed *)arrayPtr)->size;
if (0 == size) {
/* Discontiguous */
size = ((J9IndexableObjectDiscontiguousCompressed *)arrayPtr)->size;
}
} else {
size = ((J9IndexableObjectContiguousFull *)arrayPtr)->size;
if (0 == size) {
/* Discontiguous */
size = ((J9IndexableObjectDiscontiguousFull *)arrayPtr)->size;
}
}
return size;
}
/**
* Sets size in elements of a contiguous indexable object .
* @param arrayPtr Pointer to the indexable object whose size is required
* @param size Size in elements to set.
*/
MMINLINE void
setSizeInElementsForContiguous(J9IndexableObject *arrayPtr, uintptr_t size)
{
if (compressObjectReferences()) {
((J9IndexableObjectContiguousCompressed *)arrayPtr)->size = (uint32_t)size;
} else {
((J9IndexableObjectContiguousFull *)arrayPtr)->size = (uint32_t)size;
}
}
/**
* Sets the contiguous and discontiguous header size values
* @param vm Java VM
*/
MMINLINE void
setHeaderSizes(J9JavaVM *vm)
{
_contiguousIndexableHeaderSize = vm->contiguousIndexableHeaderSize;
_discontiguousIndexableHeaderSize = vm->discontiguousIndexableHeaderSize;
}
#if defined(J9VM_ENV_DATA64)
/**
* Sets whether the dataAddr field is present in the indexable object header
* @param vm Java VM
*/
MMINLINE void
setIsIndexableDataAddrPresent(J9JavaVM *vm)
{
_isIndexableDataAddrPresent = vm->isIndexableDataAddrPresent;
}
#endif /* defined(J9VM_ENV_DATA64) */
#if defined(J9VM_GC_ENABLE_DOUBLE_MAP)
/**
* Sets enable double mapping status. Note that the double map
* status value may differ from the requested one in certain
* circuntances.
*
* @param enableDoubleMapping
*/
MMINLINE void
setEnableDoubleMapping(bool enableDoubleMapping)
{
_enableDoubleMapping = enableDoubleMapping;
}
/**
* Returns enable double mapping status
*
* @return true if double mapping status is set to true, false otherwise.
*/
MMINLINE bool
isDoubleMappingEnabled()
{
return _enableDoubleMapping;
}
#endif /* J9VM_GC_ENABLE_DOUBLE_MAP */
/**
* Sets size in elements of a discontiguous indexable object .
* @param arrayPtr Pointer to the indexable object whose size is required
* @param size Size in elements to set.
*/
MMINLINE void
setSizeInElementsForDiscontiguous(J9IndexableObject *arrayPtr, uintptr_t size)
{
if (compressObjectReferences()) {
((J9IndexableObjectDiscontiguousCompressed *)arrayPtr)->mustBeZero = 0;
((J9IndexableObjectDiscontiguousCompressed *)arrayPtr)->size = (uint32_t)size;
} else {
((J9IndexableObjectDiscontiguousFull *)arrayPtr)->mustBeZero = 0;
((J9IndexableObjectDiscontiguousFull *)arrayPtr)->size = (uint32_t)size;
}
}
#if defined(J9VM_GC_SPARSE_HEAP_ALLOCATION)
/**
* Set whether the virtual large object heap (off-heap) allocation for large objects is enabled.
*
* @param enableVirtualLargeObjectHeap[in] if true, off-heap is enabled.
*/
MMINLINE void
setEnableVirtualLargeObjectHeap(bool enableVirtualLargeObjectHeap)
{
_enableVirtualLargeObjectHeap = enableVirtualLargeObjectHeap;
}
#endif /* defined(J9VM_GC_SPARSE_HEAP_ALLOCATION) */
#if defined(J9VM_ENV_DATA64)
/**
* Set whether the indexable header field dataAddr is present in the header of the indexable object.
*
* @param isDataAddressPresent[in] if true, dataAddr is present.
*/
MMINLINE void
setIsDataAddressPresent(bool isDataAddressPresent)
{
_isIndexableDataAddrPresent = isDataAddressPresent;
}
#endif /* defined(J9VM_ENV_DATA64) */
/**
* Query if virtual large object heap (off-heap) allocation for large objects is enabled.
*
* @return true if virtual large object heap (off-heap) allocation for large objects is enabled, 0 otherwise
*/
MMINLINE bool
isVirtualLargeObjectHeapEnabled()
{
#if defined(J9VM_GC_SPARSE_HEAP_ALLOCATION)
return _enableVirtualLargeObjectHeap;
#else /* defined(J9VM_GC_SPARSE_HEAP_ALLOCATION) */
return false;
#endif /* defined(J9VM_GC_SPARSE_HEAP_ALLOCATION) */
}
/**
* Determines whether or not a spine that represents an object of this
* class should have its data section aligned.
* @param clazz The class to check alignment for
* @return needAlignment Should the data section be aligned
*/
MMINLINE bool
shouldAlignSpineDataSection(J9Class *clazz)
{
bool needAlignment = false;
if (compressObjectReferences()) {
/* Compressed pointers require that each leaf starts at an appropriately-aligned address
* (based on the compressed shift value). If this is not done, compressed leaf pointers
* would be unable to reach all of the heap.
*/
needAlignment = true;
#if !defined(J9VM_ENV_DATA64)
} else {
/* The alignment padding is only required when the size of the spine pointers are
* not 8 byte aligned. For example, on a 64-bit non-compressed platform, a single
* spine pointer would be 8 byte aligned, whereas on a 32-bit platform, a single
* spine pointer would not be 8 byte aligned, and would require additional padding.
*/
if (OBJECT_HEADER_SHAPE_DOUBLES == J9GC_CLASS_SHAPE(clazz)) {
needAlignment = true;
}
#endif /* !J9VM_ENV_DATA64 */
}
return needAlignment;
}
/**
* Get the size in bytes for the arraylet at index in indexable object objPtr
* @param objPtr Pointer to an array object
* @param index the index in question. 0<=index<numArraylets(objPtr)
* @param dataSizeInBytes size of data in an indexable object, in bytes, including leaves, excluding the header.
* @param numArraylets total number of arraylets for the given indexable object
* @return the size of the indexth arraylet
*/
MMINLINE uintptr_t
arrayletSize(J9IndexableObject *objPtr, uintptr_t index, uintptr_t dataSizeInBytes, uintptr_t numArraylets)
{
uintptr_t arrayletLeafSize = _omrVM->_arrayletLeafSize;
if (index < numArraylets - 1) {
return arrayletLeafSize;
} else {
return MM_Math::saturatingSubtract(dataSizeInBytes, index * arrayletLeafSize);
}
}
/**
* Return the total number of arraylets for an indexable object with a size of dataInSizeByte
* @param dataSizeInBytes size of an array in bytes (not elements)
* @return the number of arraylets used for an array of dataSizeInBytes bytes
*/
MMINLINE uintptr_t
numArraylets(uintptr_t dataSizeInBytes)
{
uintptr_t leafSize = _omrVM->_arrayletLeafSize;
uintptr_t numberOfArraylets = 1;
if (UDATA_MAX != leafSize) {
uintptr_t leafSizeMask = leafSize - 1;
uintptr_t leafLogSize = _omrVM->_arrayletLeafLogSize;
/* CMVC 135307 : following logic for calculating the leaf count would not overflow dataSizeInBytes.
* the assumption is leaf size is order of 2. It's identical to:
* if (dataSizeInBytes % leafSize) is 0
* leaf count = dataSizeInBytes >> leafLogSize
* else
* leaf count = (dataSizeInBytes >> leafLogSize) + 1
*/
numberOfArraylets = ((dataSizeInBytes >> leafLogSize) + (((dataSizeInBytes & leafSizeMask) + leafSizeMask) >> leafLogSize));
}
return numberOfArraylets;
}
/**
* Expands the heap range in which discontiguous arraylets are allowed.
* @param subSpace The subspace of the range in which discontiguous arraylets are allowed.
* @param rangeBase The base heap range of where discontiguous arraylets are allowed.
* @param rangeTop The top heap range of where discontiguous arraylets are allowed.
* @param largestDesirableArraySpineSize The subspace's _largestDesirableArraySpineSize to be used when we don't have access to a subspace.
*/
void
expandArrayletSubSpaceRange(MM_MemorySubSpace* subSpace, void* rangeBase, void* rangeTop, uintptr_t largestDesirableArraySpineSize);
};
#endif /* ARRAYLETOBJECTMODELBASE_ */