Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openj9
Path: blob/master/runtime/gc_structs/MixedObjectIterator.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(MIXEDOBJECTITERATOR_HPP_)
29
#define MIXEDOBJECTITERATOR_HPP_
30
31
#include "j9.h"
32
#include "j9cfg.h"
33
#include "modron.h"
34
#include "ModronAssertions.h"
35
#include "GCExtensionsBase.hpp"
36
37
#include "Bits.hpp"
38
#include "ObjectModel.hpp"
39
#include "MixedObjectModel.hpp"
40
#include "ObjectIteratorState.hpp"
41
#include "SlotObject.hpp"
42
43
class GC_MixedObjectIterator
44
{
45
/* Data Members */
46
private:
47
protected:
48
GC_SlotObject _slotObject; /**< Create own SlotObject class to provide output */
49
#if defined(OMR_GC_COMPRESSED_POINTERS) && defined(OMR_GC_FULL_POINTERS)
50
bool const _compressObjectReferences;
51
#endif /* defined(OMR_GC_COMPRESSED_POINTERS) && defined(OMR_GC_FULL_POINTERS) */
52
53
J9Object *_objectPtr; /**< save address of object this class initiated with */
54
fj9object_t *_scanPtr; /**< current scan pointer */
55
fj9object_t *_endPtr; /**< end scan pointer */
56
UDATA *_descriptionPtr; /**< current description pointer */
57
UDATA _description; /**< current description word */
58
UDATA _descriptionIndex; /**< current bit number in description word */
59
public:
60
61
/* Member Functions */
62
private:
63
protected:
64
/**
65
* Set up the description bits
66
* @param clazzPtr[in] Class that from which to load description bits
67
*/
68
MMINLINE void
69
initializeDescriptionBits(J9Class *clazzPtr)
70
{
71
UDATA tempDescription = (UDATA)clazzPtr->instanceDescription;
72
if (tempDescription & 1) {
73
_description = (tempDescription >> 1);
74
} else {
75
_descriptionPtr = (UDATA *)tempDescription;
76
_description = *_descriptionPtr;
77
_descriptionPtr += 1;
78
}
79
_descriptionIndex = J9BITS_BITS_IN_SLOT;
80
}
81
82
public:
83
/**
84
* Return back true if object references are compressed
85
* @return true, if object references are compressed
86
*/
87
MMINLINE bool compressObjectReferences() {
88
return OMR_COMPRESS_OBJECT_REFERENCES(_compressObjectReferences);
89
}
90
91
/**
92
* Initialize the internal walk description for the given object.
93
* @param objectPtr[in] Mixed object to be scanned
94
*/
95
MMINLINE void
96
initialize(OMR_VM *omrVM, J9Object *objectPtr)
97
{
98
MM_GCExtensionsBase *extensions = MM_GCExtensionsBase::getExtensions(omrVM);
99
_objectPtr = objectPtr;
100
J9Class *clazzPtr = J9GC_J9OBJECT_CLAZZ(objectPtr, extensions);
101
initializeDescriptionBits(clazzPtr);
102
103
/* Set current and end scan pointers */
104
_scanPtr = extensions->mixedObjectModel.getHeadlessObject(objectPtr);
105
_endPtr = (fj9object_t *)((U_8*)_scanPtr + extensions->mixedObjectModel.getSizeInBytesWithoutHeader(objectPtr));
106
}
107
108
/**
109
* Initialize the internal walk description for the given class and address.
110
* @param clazzPtr[in] Class of object need to be scanned
111
* @param fj9object_t*[in] Address within an object to scan
112
*/
113
MMINLINE void
114
initialize(OMR_VM *omrVM, J9Class *clazzPtr, fj9object_t *addr)
115
{
116
MM_GCExtensionsBase *extensions = MM_GCExtensionsBase::getExtensions(omrVM);
117
_objectPtr = NULL;
118
initializeDescriptionBits(clazzPtr);
119
120
/* Set current and end scan pointers */
121
_scanPtr = addr;
122
_endPtr = (fj9object_t *)((U_8*)_scanPtr + extensions->mixedObjectModel.getSizeInBytesWithoutHeader(clazzPtr));
123
}
124
125
126
/**
127
* Return back SlotObject for next reference
128
* @return SlotObject
129
*/
130
MMINLINE GC_SlotObject *nextSlot()
131
{
132
bool const compressed = compressObjectReferences();
133
while (_scanPtr < _endPtr) {
134
/* Record the slot information */
135
if (_description & 1) {
136
_slotObject.writeAddressToSlot(_scanPtr);
137
_scanPtr = GC_SlotObject::addToSlotAddress(_scanPtr, 1, compressed);
138
139
/* Advance the description pointer information */
140
if (--_descriptionIndex) {
141
_description >>= 1;
142
} else {
143
_description = *_descriptionPtr;
144
_descriptionPtr += 1;
145
_descriptionIndex = J9BITS_BITS_IN_SLOT;
146
}
147
return &_slotObject;
148
} else {
149
_scanPtr = GC_SlotObject::addToSlotAddress(_scanPtr, 1, compressed);
150
151
/* Advance the description pointer information */
152
if (--_descriptionIndex) {
153
_description >>= 1;
154
} else {
155
_description = *_descriptionPtr;
156
_descriptionPtr += 1;
157
_descriptionIndex = J9BITS_BITS_IN_SLOT;
158
}
159
}
160
}
161
/* No more object slots to scan */
162
return NULL;
163
}
164
165
/**
166
* Restores the iterator state into this class
167
* @param[in] objectIteratorState partially scanned object iterator state
168
*/
169
MMINLINE void restore(GC_ObjectIteratorState *objectIteratorState)
170
{
171
_objectPtr = objectIteratorState->_objectPtr;
172
_scanPtr = objectIteratorState->_scanPtr;
173
_endPtr = objectIteratorState->_endPtr;
174
_descriptionPtr = objectIteratorState->_descriptionPtr;
175
_description = objectIteratorState->_description;
176
_descriptionIndex = objectIteratorState->_descriptionIndex;
177
}
178
179
/**
180
* Saves the partially scanned state of this class
181
* @param[in] objectIteratorState where to store the state
182
*/
183
MMINLINE void save(GC_ObjectIteratorState *objectIteratorState)
184
{
185
objectIteratorState->_objectPtr = _objectPtr;
186
objectIteratorState->_scanPtr = _scanPtr;
187
objectIteratorState->_endPtr = _endPtr;
188
objectIteratorState->_descriptionPtr = _descriptionPtr;
189
objectIteratorState->_description = _description;
190
objectIteratorState->_descriptionIndex = _descriptionIndex;
191
}
192
193
MMINLINE J9Object *getObject()
194
{
195
return _objectPtr;
196
}
197
198
/**
199
* A much lighter-weight way to restore iterator state: pass in the slot pointer and the iterator will align itself
200
* to return that as its next slot.
201
* @param slotPtr[in] The iterator slot which should be next returned by the iterator
202
*/
203
MMINLINE void advanceToSlot(fj9object_t *slotPtr)
204
{
205
Assert_MM_true(slotPtr >= _scanPtr);
206
UDATA bitsToTravel = GC_SlotObject::subtractSlotAddresses(slotPtr, _scanPtr, compressObjectReferences());
207
if (NULL != _descriptionPtr) {
208
Assert_MM_true(J9BITS_BITS_IN_SLOT >= _descriptionIndex);
209
/* _descriptionIndex uses backward math so put it in forward-facing bit counts */
210
UDATA currentBitIndexInCurrentSlot = J9BITS_BITS_IN_SLOT - _descriptionIndex;
211
UDATA newBitIndexRelativeToCurrentSlot = currentBitIndexInCurrentSlot + bitsToTravel;
212
UDATA slotsToMove = newBitIndexRelativeToCurrentSlot / J9BITS_BITS_IN_SLOT;
213
UDATA newBitIndexAfterSlotMove = newBitIndexRelativeToCurrentSlot % J9BITS_BITS_IN_SLOT;
214
/* bump the _descriptionPtr by the appropriate number of slots */
215
_descriptionPtr += slotsToMove;
216
/* _descriptionPtr ALWAYS points at the NEXT slot of index bits so read the CURRENT by subtracting 1 */
217
UDATA *currentDescriptionPointer = _descriptionPtr - 1;
218
_description = *currentDescriptionPointer;
219
/* use J9BITS_BITS_IN_SLOT as the "0" for _descriptionIndex since it uses backward math */
220
_descriptionIndex = J9BITS_BITS_IN_SLOT;
221
/* now, advance the number of bits required into this slot */
222
_descriptionIndex -= newBitIndexAfterSlotMove;
223
_description >>= newBitIndexAfterSlotMove;
224
} else {
225
Assert_MM_true(_descriptionIndex >= bitsToTravel);
226
_descriptionIndex -= bitsToTravel;
227
_description >>= bitsToTravel;
228
}
229
/* save back the new slot ptr */
230
_scanPtr = slotPtr;
231
Assert_MM_true (_description & 1);
232
}
233
234
/**
235
* @param vm[in] pointer to the JVM
236
*/
237
GC_MixedObjectIterator(OMR_VM *omrVM)
238
: _slotObject(GC_SlotObject(omrVM, NULL))
239
#if defined(OMR_GC_COMPRESSED_POINTERS) && defined(OMR_GC_FULL_POINTERS)
240
, _compressObjectReferences(OMRVM_COMPRESS_OBJECT_REFERENCES(omrVM))
241
#endif /* defined(OMR_GC_COMPRESSED_POINTERS) && defined(OMR_GC_FULL_POINTERS) */
242
, _objectPtr(NULL)
243
, _scanPtr(NULL)
244
, _endPtr(NULL)
245
, _descriptionPtr(NULL)
246
, _description(0)
247
, _descriptionIndex(0)
248
{
249
}
250
251
/**
252
* @param vm[in] pointer to the JVM
253
* @param objectPtr[in] the object to be processed
254
*/
255
GC_MixedObjectIterator(OMR_VM *omrVM, J9Object *objectPtr)
256
: _slotObject(GC_SlotObject(omrVM, NULL))
257
#if defined(OMR_GC_COMPRESSED_POINTERS) && defined(OMR_GC_FULL_POINTERS)
258
, _compressObjectReferences(OMRVM_COMPRESS_OBJECT_REFERENCES(omrVM))
259
#endif /* defined(OMR_GC_COMPRESSED_POINTERS) && defined(OMR_GC_FULL_POINTERS) */
260
, _objectPtr(NULL)
261
, _scanPtr(NULL)
262
, _endPtr(NULL)
263
, _descriptionPtr(NULL)
264
, _description(0)
265
, _descriptionIndex(0)
266
{
267
initialize(omrVM, objectPtr);
268
}
269
};
270
271
#endif /* MIXEDOBJECTITERATOR_HPP_ */
272
273