Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openj9
Path: blob/master/runtime/gc_glue_java/FlattenedArrayObjectScanner.hpp
5990 views
1
/*******************************************************************************
2
* Copyright (c) 2020, 2020 IBM Corp. and others
3
*
4
* This program and the accompanying materials are made available under
5
* the terms of the Eclipse Public License 2.0 which accompanies this
6
* distribution and is available at https://www.eclipse.org/legal/epl-2.0/
7
* or the Apache License, Version 2.0 which accompanies this distribution and
8
* is available at https://www.apache.org/licenses/LICENSE-2.0.
9
*
10
* This Source Code may also be made available under the following
11
* Secondary Licenses when the conditions for such availability set
12
* forth in the Eclipse Public License, v. 2.0 are satisfied: GNU
13
* General Public License, version 2 with the GNU Classpath
14
* Exception [1] and GNU General Public License, version 2 with the
15
* OpenJDK Assembly Exception [2].
16
*
17
* [1] https://www.gnu.org/software/classpath/license.html
18
* [2] http://openjdk.java.net/legal/assembly-exception.html
19
*
20
* 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
21
*******************************************************************************/
22
23
#if !defined(FLATTENEDARRAYOBJECTSCANNER_HPP_)
24
#define FLATTENEDARRAYOBJECTSCANNER_HPP_
25
26
#include "j9.h"
27
#include "j9cfg.h"
28
#include "modron.h"
29
30
#include "objectdescription.h"
31
#include "ArrayObjectModel.hpp"
32
#include "GCExtensionsBase.hpp"
33
#include "HeadlessMixedObjectScanner.hpp"
34
#include "IndexableObjectScanner.hpp"
35
36
class GC_FlattenedArrayObjectScanner : public GC_HeadlessMixedObjectScanner
37
{
38
/* Data Members */
39
private:
40
41
MM_EnvironmentBase *_env;
42
uintptr_t _elementSizeWithoutPadding; /**< Size of the flattened element, without padding */
43
uintptr_t *_descriptionBasePtr; /**< Pointer to the description base */
44
#if defined(OMR_GC_LEAF_BITS)
45
uintptr_t *_leafBasePtr; /**< Pointer to the leaf description base */
46
#endif /* defined(OMR_GC_LEAF_BITS) */
47
GC_IndexableObjectScanner _indexableScanner; /**< Used to iterate the array by element */
48
49
protected:
50
51
public:
52
53
/* Methods */
54
private:
55
56
protected:
57
58
/**
59
* @param env The scanning thread environment
60
* @param arrayPtr pointer to the array to be processed
61
* @param basePtr pointer to the first contiguous array cell
62
* @param limitPtr pointer to end of last contiguous array cell
63
* @param scanPtr pointer to the array cell where scanning will start
64
* @param endPtr pointer to the array cell where scanning will stop
65
* @param scanMap The first scan map
66
* @param elementSize The size of each element, without padding
67
* @param elementStride The stride of each element, including element padding
68
* @param flags Scanning context flags
69
*/
70
MMINLINE GC_FlattenedArrayObjectScanner(
71
MM_EnvironmentBase *env
72
, omrobjectptr_t arrayPtr
73
, fomrobject_t *basePtr
74
, fomrobject_t *limitPtr
75
, fomrobject_t *scanPtr
76
, fomrobject_t *endPtr
77
, uintptr_t elementSize
78
, uintptr_t elementStride
79
, uintptr_t *descriptionBasePtr
80
#if defined(OMR_GC_LEAF_BITS)
81
, uintptr_t *leafBasePtr
82
#endif /* defined(OMR_GC_LEAF_BITS) */
83
, uintptr_t flags)
84
: GC_HeadlessMixedObjectScanner(env, scanPtr, elementSize, flags | GC_ObjectScanner::indexableObject)
85
, _env(env)
86
, _elementSizeWithoutPadding(elementSize)
87
, _descriptionBasePtr(descriptionBasePtr)
88
#if defined(OMR_GC_LEAF_BITS)
89
, _leafBasePtr(leafBasePtr)
90
#endif /* defined(OMR_GC_LEAF_BITS) */
91
/* Pass 0 for scanMap, as the indexable iterator does not use the scanMap */
92
, _indexableScanner(env, arrayPtr, basePtr, limitPtr, scanPtr, endPtr, 0, elementStride, flags)
93
{
94
_typeId = __FUNCTION__;
95
}
96
97
MMINLINE void
98
initialize(MM_EnvironmentBase *env)
99
{
100
#if defined(OMR_GC_LEAF_BITS)
101
GC_HeadlessMixedObjectScanner::initialize(env, _descriptionBasePtr, _leafBasePtr);
102
#else /* defined(OMR_GC_LEAF_BITS) */
103
GC_HeadlessMixedObjectScanner::initialize(env, _descriptionBasePtr);
104
#endif /* defined(OMR_GC_LEAF_BITS) */
105
106
_indexableScanner.initialize(env);
107
108
/* The HeadlessMixedObjectScanner will setNoMoreSlots() causing us
109
* to miss other elements of the array
110
*/
111
setMoreSlots();
112
}
113
114
public:
115
116
/**
117
* @param[in] env The scanning thread environment
118
* @param[in] objectPtr pointer to the array to be processed
119
* @param[in] allocSpace pointer to space within which the scanner should be instantiated (in-place)
120
* @param[in] flags Scanning context flags
121
* @param[in] splitAmount If >0, the number of elements to include for this scanner instance; if 0, include all elements
122
* @param[in] startIndex The index of the first element to scan
123
*/
124
MMINLINE static GC_FlattenedArrayObjectScanner *
125
newInstance(MM_EnvironmentBase *env, omrobjectptr_t objectPtr, void *allocSpace, uintptr_t flags, uintptr_t splitAmount, uintptr_t startIndex = 0)
126
{
127
GC_FlattenedArrayObjectScanner *objectScanner = (GC_FlattenedArrayObjectScanner *)allocSpace;
128
GC_ArrayObjectModel *arrayObjectModel = &(env->getExtensions()->indexableObjectModel);
129
J9Class *clazzPtr = J9GC_J9OBJECT_CLAZZ(objectPtr, env);
130
J9ArrayClass *j9ArrayClass = (J9ArrayClass *) clazzPtr;
131
132
/* TODO are these always the same? */
133
Assert_MM_true(j9ArrayClass->componentType == j9ArrayClass->leafComponentType);
134
135
J9Class *elementClass = j9ArrayClass->componentType;
136
omrarrayptr_t arrayPtr = (omrarrayptr_t)objectPtr;
137
138
uintptr_t sizeInElements = arrayObjectModel->getSizeInElements(arrayPtr);
139
uintptr_t elementSize = J9_VALUETYPE_FLATTENED_SIZE(elementClass);
140
uintptr_t elementStride = J9ARRAYCLASS_GET_STRIDE(clazzPtr);
141
fomrobject_t *basePtr = (fomrobject_t *)arrayObjectModel->getDataPointerForContiguous(arrayPtr);
142
fomrobject_t *limitPtr = (fomrobject_t *)((uintptr_t)basePtr + (sizeInElements * elementStride));
143
fomrobject_t *scanPtr = (fomrobject_t *)((uintptr_t)basePtr + (startIndex * elementStride));
144
fomrobject_t *endPtr = limitPtr;
145
if (!GC_ObjectScanner::isIndexableObjectNoSplit(flags) && (splitAmount != 0)) {
146
Assert_MM_unreachable();
147
endPtr = (fomrobject_t *)((uintptr_t)scanPtr + (splitAmount * elementStride));
148
if (endPtr > limitPtr) {
149
endPtr = limitPtr;
150
}
151
}
152
uintptr_t *instanceDescription = elementClass->instanceDescription;
153
#if defined(OMR_GC_LEAF_BITS)
154
uintptr_t *leafDescription = elementClass->instanceLeafDescription;
155
new(objectScanner) GC_FlattenedArrayObjectScanner(env, objectPtr, basePtr, limitPtr, scanPtr, endPtr, elementSize, elementStride, instanceDescription, leafDescription, flags);
156
#else /* defined(OMR_GC_LEAF_BITS) */
157
new(objectScanner) GC_FlattenedArrayObjectScanner(env, objectPtr, basePtr, limitPtr, scanPtr, endPtr, elementSize, elementStride, instanceDescription, flags);
158
#endif /* defined(OMR_GC_LEAF_BITS) */
159
160
objectScanner->initialize(env);
161
if (0 != startIndex) {
162
objectScanner->clearHeadObjectScanner();
163
}
164
return objectScanner;
165
}
166
167
MMINLINE uintptr_t getBytesRemaining() { return sizeof(fomrobject_t) * (_endPtr - _scanPtr); }
168
169
/**
170
* @param env The scanning thread environment
171
* @param allocSpace pointer to space within which the scanner should be instantiated (in-place)
172
* @param splitAmount The maximum number of array elements to include
173
* @return Pointer to split scanner in allocSpace
174
*/
175
GC_IndexableObjectScanner *
176
splitTo(MM_EnvironmentBase *env, void *allocSpace, uintptr_t splitAmount)
177
{
178
Assert_MM_unimplemented();
179
return NULL;
180
}
181
182
/**
183
* Return base pointer and slot bit map for next block of contiguous slots to be scanned. The
184
* base pointer must be fomrobject_t-aligned. Bits in the bit map are scanned in order of
185
* increasing significance, and the least significant bit maps to the slot at the returned
186
* base pointer.
187
*
188
* @param[out] scanMap the bit map for the slots contiguous with the returned base pointer
189
* @param[out] hasNextSlotMap set this to true if this method should be called again, false if this map is known to be last
190
* @return a pointer to the first slot mapped by the least significant bit of the map, or NULL if no more slots
191
*/
192
virtual fomrobject_t *
193
getNextSlotMap(uintptr_t *slotMap, bool *hasNextSlotMap)
194
{
195
fomrobject_t *result = GC_HeadlessMixedObjectScanner::getNextSlotMap(slotMap, hasNextSlotMap);
196
/* Ignore hasNextSlotMap from HeadLess, we want to always report that there is another element */
197
*hasNextSlotMap = true;
198
if (result == NULL) {
199
/* No more slots in the current element, get the next element of the array */
200
result = _indexableScanner.nextIndexableElement();
201
if (result == NULL) {
202
/* There are no elements in the array */
203
*hasNextSlotMap = false;
204
} else {
205
_mapPtr = result;
206
_endPtr = (fomrobject_t *)((uintptr_t)_mapPtr + _elementSizeWithoutPadding);
207
GC_HeadlessMixedObjectScanner::initialize(_env, _descriptionBasePtr, _leafBasePtr);
208
/* GC_HeadlessMixedObjectScanner::initialize() may setNoMoreSlots(), so set it back to true.
209
* We must also return (hasNextSlotMap = true) on top of this
210
*/
211
setMoreSlots();
212
}
213
}
214
return result;
215
}
216
217
#if defined(OMR_GC_LEAF_BITS)
218
/**
219
* Return base pointer and slot bit map for next block of contiguous slots to be scanned. The
220
* base pointer must be fomrobject_t-aligned. Bits in the bit map are scanned in order of
221
* increasing significance, and the least significant bit maps to the slot at the returned
222
* base pointer.
223
*
224
* @param[out] scanMap the bit map for the slots contiguous with the returned base pointer
225
* @param[out] leafMap the leaf bit map for the slots contiguous with the returned base pointer
226
* @param[out] hasNextSlotMap set this to true if this method should be called again, false if this map is known to be last
227
* @return a pointer to the first slot mapped by the least significant bit of the map, or NULL if no more slots
228
*/
229
virtual fomrobject_t *
230
getNextSlotMap(uintptr_t *slotMap, uintptr_t *leafMap, bool *hasNextSlotMap)
231
{
232
fomrobject_t *result = GC_HeadlessMixedObjectScanner::getNextSlotMap(slotMap, leafMap, hasNextSlotMap);
233
/* Ignore hasNextSlotMap from HeadLess, we want to always report that there is another element */
234
*hasNextSlotMap = true;
235
if (result == NULL) {
236
/* No more slots in the current element, get the next element of the array */
237
result = _indexableScanner.nextIndexableElement();
238
if (result == NULL) {
239
/* There are no elements in the array */
240
*hasNextSlotMap = false;
241
} else {
242
_mapPtr = result;
243
_endPtr = (fomrobject_t *)((uintptr_t)_mapPtr + _elementSizeWithoutPadding);
244
GC_HeadlessMixedObjectScanner::initialize(_env, _descriptionBasePtr, _leafBasePtr);
245
/* GC_HeadlessMixedObjectScanner::initialize() may setNoMoreSlots(), so set it back to true.
246
* We must also return (hasNextSlotMap = true) on top of this
247
*/
248
setMoreSlots();
249
}
250
}
251
return result;
252
}
253
#endif /* defined(OMR_GC_LEAF_BITS) */
254
};
255
256
#endif /* FLATTENEDARRAYOBJECTSCANNER_HPP_ */
257
258