Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openj9
Path: blob/master/runtime/gc_structs/PointerArrayletIterator.hpp
5990 views
1
/*******************************************************************************
2
* Copyright (c) 1991, 2021 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
/**
24
* @file
25
* @ingroup GC_Structs
26
*/
27
28
#if !defined(POINTERARRAYLETITERATOR_HPP_)
29
#define POINTERARRAYLETITERATOR_HPP_
30
31
#include "j9.h"
32
#include "j9cfg.h"
33
#include "ModronAssertions.h"
34
35
#include "ArrayObjectModel.hpp"
36
#include "Bits.hpp"
37
#include "GCExtensionsBase.hpp"
38
#include "ObjectIteratorState.hpp"
39
#include "SlotObject.hpp"
40
#include "ArrayletObjectModel.hpp"
41
42
/**
43
* Iterate over all slots in a pointer array which contain an object reference
44
* @ingroup GC_Structs
45
*/
46
class GC_PointerArrayletIterator
47
{
48
private:
49
J9IndexableObject *_arrayPtr; /**< pointer to the array object being iterated */
50
GC_SlotObject _slotObject; /**< Create own SlotObject class to provide output */
51
52
UDATA const _arrayletLeafSize; /* The size of an arraylet leaf */
53
UDATA const _fobjectsPerLeaf; /* The number of fj9object_t's per leaf */
54
UDATA _index; /* The current index of the array */
55
fj9object_t * _currentArrayletBaseAddress; /* The base address of the current arraylet */
56
UDATA _currentArrayletIndex; /* The index of the current arraylet */
57
UDATA _currentArrayletOffset; /* The offset to the _index'ed item from the currentArrayletBaseAddress */
58
59
MMINLINE void recalculateArrayletOffsets()
60
{
61
if ( _index > 0 ) {
62
MM_GCExtensionsBase *extensions = MM_GCExtensionsBase::getExtensions(_javaVM->omrVM);
63
_currentArrayletIndex = ((U_32)_index-1) / _fobjectsPerLeaf; /* The index of the arraylet containing _index */
64
_currentArrayletOffset = ((U_32)_index-1) % _fobjectsPerLeaf; /* The offset of _index in the current arraylet */
65
66
fj9object_t *arrayoidPointer = extensions->indexableObjectModel.getArrayoidPointer(_arrayPtr);
67
GC_SlotObject arrayletBaseSlotObject(_javaVM->omrVM, GC_SlotObject::addToSlotAddress(arrayoidPointer, _currentArrayletIndex, compressObjectReferences()));
68
_currentArrayletBaseAddress = (fj9object_t *)arrayletBaseSlotObject.readReferenceFromSlot();
69
70
/* note that we need to check the arraylet base address before reading it since we might be walking
71
* a partially allocated arraylet which still has some NULL leaf pointers. We return NULL, in those
72
* cases, which will cause the caller to stop iterating. This is correct behaviour if we can assume
73
* that arraylet leaves are always allocated in-order. This is currently true.
74
* Moreover, we can safely assume that an incomplete arraylet contains no non-null object references
75
* since it hasn't yet been returned from its allocation routine so it isn't yet visible to the mutator.
76
*/
77
if (NULL == _currentArrayletBaseAddress) {
78
_index = 0;
79
}
80
}
81
}
82
83
protected:
84
#if defined(OMR_GC_COMPRESSED_POINTERS) && defined(OMR_GC_FULL_POINTERS)
85
bool const _compressObjectReferences;
86
#endif /* defined(OMR_GC_COMPRESSED_POINTERS) && defined(OMR_GC_FULL_POINTERS) */
87
J9JavaVM *const _javaVM; /**< A cached pointer to the shared JavaVM instance */
88
89
public:
90
/**
91
* Return back true if object references are compressed
92
* @return true, if object references are compressed
93
*/
94
MMINLINE bool compressObjectReferences() {
95
return OMR_COMPRESS_OBJECT_REFERENCES(_compressObjectReferences);
96
}
97
98
MMINLINE void initialize(J9Object *objectPtr) {
99
MM_GCExtensionsBase *extensions = MM_GCExtensionsBase::getExtensions(_javaVM->omrVM);
100
101
/* if we are using hybrid arraylets, we need to ensure that we don't initialize the discontiguous iterator since it will try to read off the end of the header
102
* when reading the non-existent arrayoid. In the case of small arrays near the end of a region, this could cause us to read an uncommitted page.
103
*/
104
if (extensions->indexableObjectModel.isInlineContiguousArraylet((J9IndexableObject *)objectPtr)) {
105
_arrayPtr = NULL;
106
_index = 0;
107
} else {
108
_arrayPtr = (J9IndexableObject *)objectPtr;
109
110
/* Set current and end scan pointers */
111
_index = extensions->indexableObjectModel.getSizeInElements(_arrayPtr);
112
recalculateArrayletOffsets();
113
}
114
}
115
116
MMINLINE GC_SlotObject *nextSlot()
117
{
118
if (_index > 0) {
119
_slotObject.writeAddressToSlot(GC_SlotObject::addToSlotAddress(_currentArrayletBaseAddress, _currentArrayletOffset, compressObjectReferences()));
120
121
_index -= 1;
122
/* If we reach the end of the arraylet leaf, we need to recalculate our arrayletBaseAddress for the next _index */
123
if ( 0 == _currentArrayletOffset) {
124
recalculateArrayletOffsets();
125
} else {
126
_currentArrayletOffset -= 1;
127
}
128
129
return &_slotObject;
130
}
131
132
/* No more object slots to scan */
133
return NULL;
134
}
135
136
GC_PointerArrayletIterator(J9JavaVM *javaVM)
137
: _arrayPtr(NULL)
138
, _slotObject(GC_SlotObject(javaVM->omrVM, NULL))
139
, _arrayletLeafSize(javaVM->arrayletLeafSize)
140
, _fobjectsPerLeaf(_arrayletLeafSize / J9JAVAVM_REFERENCE_SIZE(javaVM))
141
, _index(0)
142
, _currentArrayletBaseAddress(NULL)
143
, _currentArrayletIndex(0)
144
, _currentArrayletOffset(0)
145
#if defined(OMR_GC_COMPRESSED_POINTERS) && defined(OMR_GC_FULL_POINTERS)
146
, _compressObjectReferences(J9JAVAVM_COMPRESS_OBJECT_REFERENCES(javaVM))
147
#endif /* defined(OMR_GC_COMPRESSED_POINTERS) && defined(OMR_GC_FULL_POINTERS) */
148
, _javaVM(javaVM)
149
{
150
}
151
152
/**
153
* @param objectPtr the array object to be processed
154
*/
155
GC_PointerArrayletIterator(J9JavaVM *javaVM, J9Object *objectPtr)
156
: _arrayPtr(NULL)
157
, _slotObject(GC_SlotObject(javaVM->omrVM, NULL))
158
, _arrayletLeafSize(javaVM->arrayletLeafSize)
159
, _fobjectsPerLeaf(_arrayletLeafSize / J9JAVAVM_REFERENCE_SIZE(javaVM))
160
, _index(0)
161
, _currentArrayletBaseAddress(NULL)
162
, _currentArrayletIndex(0)
163
, _currentArrayletOffset(0)
164
#if defined(OMR_GC_COMPRESSED_POINTERS) && defined(OMR_GC_FULL_POINTERS)
165
, _compressObjectReferences(J9JAVAVM_COMPRESS_OBJECT_REFERENCES(javaVM))
166
#endif /* defined(OMR_GC_COMPRESSED_POINTERS) && defined(OMR_GC_FULL_POINTERS) */
167
, _javaVM(javaVM)
168
{
169
initialize(objectPtr);
170
}
171
172
MMINLINE J9Object *getObject()
173
{
174
return (J9Object *)_arrayPtr;
175
}
176
177
/**
178
* Gets the current slot's array index.
179
* @return slot number (or zero based array index) of the last call to nextSlot.
180
* @return undefined if nextSlot has yet to be called.
181
*/
182
MMINLINE UDATA getIndex() {
183
return _index;
184
}
185
186
187
MMINLINE void setIndex(UDATA index) {
188
_index = index;
189
recalculateArrayletOffsets();
190
}
191
192
/**
193
* Restores the iterator state into this class
194
* @param[in] objectIteratorState partially scanned object iterator state
195
*/
196
MMINLINE void restore(GC_ObjectIteratorState *objectIteratorState) {
197
_arrayPtr = (J9IndexableObject *)objectIteratorState->_objectPtr;
198
setIndex(objectIteratorState->_index);
199
}
200
201
202
/**
203
* Saves the partially scanned state of this class
204
* @param[in] objectIteratorState where to store the state
205
*/
206
MMINLINE void save(GC_ObjectIteratorState *objectIteratorState) {
207
objectIteratorState->_objectPtr = (J9Object *)_arrayPtr;
208
objectIteratorState->_index = _index;
209
}
210
};
211
212
#endif /* POINTERARRAYLETITERATOR_HPP_ */
213
214