Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openj9
Path: blob/master/runtime/gc_glue_java/PointerArrayObjectScanner.hpp
5985 views
1
/*******************************************************************************
2
* Copyright (c) 2016, 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(POINTERARRAYOBJECTSCANNER_HPP_)
24
#define POINTERARRAYOBJECTSCANNER_HPP_
25
26
#include "j9.h"
27
#include "j9cfg.h"
28
#include "modron.h"
29
30
#include "ArrayObjectModel.hpp"
31
#include "GCExtensionsBase.hpp"
32
#include "IndexableObjectScanner.hpp"
33
34
/**
35
* This class is used to iterate over the slots of a Java pointer array.
36
*/
37
class GC_PointerArrayObjectScanner : public GC_IndexableObjectScanner
38
{
39
/* Data Members */
40
private:
41
fomrobject_t *_mapPtr; /**< pointer to first array element in current scan segment */
42
43
protected:
44
45
public:
46
47
/* Methods */
48
private:
49
50
protected:
51
/**
52
* @param env The scanning thread environment
53
* @param[in] arrayPtr pointer to the array to be processed
54
* @param[in] basePtr pointer to the first contiguous array cell
55
* @param[in] limitPtr pointer to end of last contiguous array cell
56
* @param[in] scanPtr pointer to the array cell where scanning will start
57
* @param[in] endPtr pointer to the array cell where scanning will stop
58
* @param[in] flags Scanning context flags
59
*/
60
MMINLINE GC_PointerArrayObjectScanner(MM_EnvironmentBase *env, omrobjectptr_t arrayPtr, fomrobject_t *basePtr, fomrobject_t *limitPtr, fomrobject_t *scanPtr, fomrobject_t *endPtr, uintptr_t flags)
61
: GC_IndexableObjectScanner(env, arrayPtr, basePtr, limitPtr, scanPtr, endPtr
62
, (GC_SlotObject::subtractSlotAddresses(endPtr, scanPtr, env->compressObjectReferences()) < _bitsPerScanMap)
63
? ((uintptr_t)1 << GC_SlotObject::subtractSlotAddresses(endPtr, scanPtr, env->compressObjectReferences())) - 1
64
: UDATA_MAX
65
, env->compressObjectReferences() ? sizeof(uint32_t) : sizeof(uintptr_t)
66
, flags)
67
, _mapPtr(_scanPtr)
68
{
69
_typeId = __FUNCTION__;
70
}
71
72
/**
73
* Set up the scanner.
74
* @param[in] env Current environment
75
*/
76
MMINLINE void
77
initialize(MM_EnvironmentBase *env)
78
{
79
GC_IndexableObjectScanner::initialize(env);
80
}
81
82
public:
83
/**
84
* @param[in] env The scanning thread environment
85
* @param[in] objectPtr pointer to the array to be processed
86
* @param[in] allocSpace pointer to space within which the scanner should be instantiated (in-place)
87
* @param[in] flags Scanning context flags
88
* @param[in] splitAmount If >0, the number of elements to include for this scanner instance; if 0, include all elements
89
* @param[in] startIndex The index of the first element to scan
90
*/
91
MMINLINE static GC_PointerArrayObjectScanner *
92
newInstance(MM_EnvironmentBase *env, omrobjectptr_t objectPtr, void *allocSpace, uintptr_t flags, uintptr_t splitAmount, uintptr_t startIndex = 0)
93
{
94
GC_PointerArrayObjectScanner *objectScanner = (GC_PointerArrayObjectScanner *)allocSpace;
95
if (NULL != objectScanner) {
96
bool const compressed = env->compressObjectReferences();
97
GC_ArrayObjectModel *arrayObjectModel = &(env->getExtensions()->indexableObjectModel);
98
omrarrayptr_t arrayPtr = (omrarrayptr_t)objectPtr;
99
uintptr_t sizeInElements = arrayObjectModel->getSizeInElements(arrayPtr);
100
fomrobject_t *basePtr = (fomrobject_t *)arrayObjectModel->getDataPointerForContiguous(arrayPtr);
101
fomrobject_t *scanPtr = GC_SlotObject::addToSlotAddress(basePtr, startIndex, compressed);
102
fomrobject_t *limitPtr = GC_SlotObject::addToSlotAddress(basePtr, sizeInElements, compressed);
103
fomrobject_t *endPtr = limitPtr;
104
105
if (!GC_ObjectScanner::isIndexableObjectNoSplit(flags)) {
106
fomrobject_t *splitPtr = GC_SlotObject::addToSlotAddress(scanPtr, splitAmount, compressed);
107
if ((splitPtr > scanPtr) && (splitPtr < endPtr)) {
108
endPtr = splitPtr;
109
}
110
}
111
112
new(objectScanner) GC_PointerArrayObjectScanner(env, objectPtr, basePtr, limitPtr, scanPtr, endPtr, flags);
113
objectScanner->initialize(env);
114
if (0 != startIndex) {
115
objectScanner->clearHeadObjectScanner();
116
}
117
}
118
return objectScanner;
119
}
120
121
MMINLINE uintptr_t getBytesRemaining() { return (uintptr_t)_endPtr - (uintptr_t)_scanPtr; }
122
123
/**
124
* @param env The scanning thread environment
125
* @param[in] allocSpace pointer to space within which the scanner should be instantiated (in-place)
126
* @param splitAmount The maximum number of array elements to include
127
* @return Pointer to split scanner in allocSpace
128
*/
129
virtual GC_IndexableObjectScanner *
130
splitTo(MM_EnvironmentBase *env, void *allocSpace, uintptr_t splitAmount)
131
{
132
GC_PointerArrayObjectScanner *splitScanner = NULL;
133
134
Assert_MM_true(_limitPtr >= _endPtr);
135
/* Downsize splitAmount if larger than the tail of this scanner */
136
uintptr_t remainder = GC_SlotObject::subtractSlotAddresses(_limitPtr, _endPtr, compressObjectReferences());
137
if (splitAmount > remainder) {
138
splitAmount = remainder;
139
}
140
141
Assert_MM_true(NULL != allocSpace);
142
/* If splitAmount is 0 the new scanner will return NULL on the first call to getNextSlot(). */
143
splitScanner = (GC_PointerArrayObjectScanner *)allocSpace;
144
/* Create new scanner for next chunk of array starting at the end of current chunk size splitAmount elements */
145
new(splitScanner) GC_PointerArrayObjectScanner(env, getArrayObject(), _basePtr, _limitPtr, _endPtr, GC_SlotObject::addToSlotAddress(_endPtr, splitAmount, compressObjectReferences()), _flags);
146
splitScanner->initialize(env);
147
148
return splitScanner;
149
}
150
151
/**
152
* Return base pointer and slot bit map for next block of contiguous slots to be scanned. The
153
* base pointer must be fomrobject_t-aligned. Bits in the bit map are scanned in order of
154
* increasing significance, and the least significant bit maps to the slot at the returned
155
* base pointer.
156
*
157
* @param[out] scanMap the bit map for the slots contiguous with the returned base pointer
158
* @param[out] hasNextSlotMap set this to true if this method should be called again, false if this map is known to be last
159
* @return a pointer to the first slot mapped by the least significant bit of the map, or NULL if no more slots
160
*/
161
virtual fomrobject_t *
162
getNextSlotMap(uintptr_t *slotMap, bool *hasNextSlotMap)
163
{
164
bool const compressed = compressObjectReferences();
165
fomrobject_t *result = NULL;
166
_mapPtr = GC_SlotObject::addToSlotAddress(_mapPtr, _bitsPerScanMap, compressed);
167
if (_endPtr > _mapPtr) {
168
intptr_t remainder = GC_SlotObject::subtractSlotAddresses(_endPtr, _mapPtr, compressed);
169
if (remainder >= _bitsPerScanMap) {
170
*slotMap = UDATA_MAX;
171
} else {
172
*slotMap = ((uintptr_t)1 << remainder) - 1;
173
}
174
*hasNextSlotMap = remainder > _bitsPerScanMap;
175
result = _mapPtr;
176
} else {
177
*slotMap = 0;
178
*hasNextSlotMap = false;
179
}
180
return result;
181
}
182
183
#if defined(OMR_GC_LEAF_BITS)
184
/**
185
* Return base pointer and slot bit map for next block of contiguous slots to be scanned. The
186
* base pointer must be fomrobject_t-aligned. Bits in the bit map are scanned in order of
187
* increasing significance, and the least significant bit maps to the slot at the returned
188
* base pointer.
189
*
190
* @param[out] scanMap the bit map for the slots contiguous with the returned base pointer
191
* @param[out] leafMap the leaf bit map for the slots contiguous with the returned base pointer
192
* @param[out] hasNextSlotMap set this to true if this method should be called again, false if this map is known to be last
193
* @return a pointer to the first slot mapped by the least significant bit of the map, or NULL if no more slots
194
*/
195
virtual fomrobject_t *
196
getNextSlotMap(uintptr_t *scanMap, uintptr_t *leafMap, bool *hasNextSlotMap)
197
{
198
*leafMap = 0;
199
return getNextSlotMap(scanMap, hasNextSlotMap);
200
}
201
#endif /* defined(OMR_GC_LEAF_BITS) */
202
};
203
204
#endif /* POINTERARRAYOBJECTSCANNER_HPP_ */
205
206