Path: blob/master/runtime/gc_structs/MixedObjectIterator.hpp
5990 views
/*******************************************************************************1* Copyright (c) 1991, 2021 IBM Corp. and others2*3* This program and the accompanying materials are made available under4* the terms of the Eclipse Public License 2.0 which accompanies this5* distribution and is available at https://www.eclipse.org/legal/epl-2.0/6* or the Apache License, Version 2.0 which accompanies this distribution and7* is available at https://www.apache.org/licenses/LICENSE-2.0.8*9* This Source Code may also be made available under the following10* Secondary Licenses when the conditions for such availability set11* forth in the Eclipse Public License, v. 2.0 are satisfied: GNU12* General Public License, version 2 with the GNU Classpath13* Exception [1] and GNU General Public License, version 2 with the14* OpenJDK Assembly Exception [2].15*16* [1] https://www.gnu.org/software/classpath/license.html17* [2] http://openjdk.java.net/legal/assembly-exception.html18*19* 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-exception20*******************************************************************************/2122/**23* @file24* @ingroup GC_Structs25*/2627#if !defined(MIXEDOBJECTITERATOR_HPP_)28#define MIXEDOBJECTITERATOR_HPP_2930#include "j9.h"31#include "j9cfg.h"32#include "modron.h"33#include "ModronAssertions.h"34#include "GCExtensionsBase.hpp"3536#include "Bits.hpp"37#include "ObjectModel.hpp"38#include "MixedObjectModel.hpp"39#include "ObjectIteratorState.hpp"40#include "SlotObject.hpp"4142class GC_MixedObjectIterator43{44/* Data Members */45private:46protected:47GC_SlotObject _slotObject; /**< Create own SlotObject class to provide output */48#if defined(OMR_GC_COMPRESSED_POINTERS) && defined(OMR_GC_FULL_POINTERS)49bool const _compressObjectReferences;50#endif /* defined(OMR_GC_COMPRESSED_POINTERS) && defined(OMR_GC_FULL_POINTERS) */5152J9Object *_objectPtr; /**< save address of object this class initiated with */53fj9object_t *_scanPtr; /**< current scan pointer */54fj9object_t *_endPtr; /**< end scan pointer */55UDATA *_descriptionPtr; /**< current description pointer */56UDATA _description; /**< current description word */57UDATA _descriptionIndex; /**< current bit number in description word */58public:5960/* Member Functions */61private:62protected:63/**64* Set up the description bits65* @param clazzPtr[in] Class that from which to load description bits66*/67MMINLINE void68initializeDescriptionBits(J9Class *clazzPtr)69{70UDATA tempDescription = (UDATA)clazzPtr->instanceDescription;71if (tempDescription & 1) {72_description = (tempDescription >> 1);73} else {74_descriptionPtr = (UDATA *)tempDescription;75_description = *_descriptionPtr;76_descriptionPtr += 1;77}78_descriptionIndex = J9BITS_BITS_IN_SLOT;79}8081public:82/**83* Return back true if object references are compressed84* @return true, if object references are compressed85*/86MMINLINE bool compressObjectReferences() {87return OMR_COMPRESS_OBJECT_REFERENCES(_compressObjectReferences);88}8990/**91* Initialize the internal walk description for the given object.92* @param objectPtr[in] Mixed object to be scanned93*/94MMINLINE void95initialize(OMR_VM *omrVM, J9Object *objectPtr)96{97MM_GCExtensionsBase *extensions = MM_GCExtensionsBase::getExtensions(omrVM);98_objectPtr = objectPtr;99J9Class *clazzPtr = J9GC_J9OBJECT_CLAZZ(objectPtr, extensions);100initializeDescriptionBits(clazzPtr);101102/* Set current and end scan pointers */103_scanPtr = extensions->mixedObjectModel.getHeadlessObject(objectPtr);104_endPtr = (fj9object_t *)((U_8*)_scanPtr + extensions->mixedObjectModel.getSizeInBytesWithoutHeader(objectPtr));105}106107/**108* Initialize the internal walk description for the given class and address.109* @param clazzPtr[in] Class of object need to be scanned110* @param fj9object_t*[in] Address within an object to scan111*/112MMINLINE void113initialize(OMR_VM *omrVM, J9Class *clazzPtr, fj9object_t *addr)114{115MM_GCExtensionsBase *extensions = MM_GCExtensionsBase::getExtensions(omrVM);116_objectPtr = NULL;117initializeDescriptionBits(clazzPtr);118119/* Set current and end scan pointers */120_scanPtr = addr;121_endPtr = (fj9object_t *)((U_8*)_scanPtr + extensions->mixedObjectModel.getSizeInBytesWithoutHeader(clazzPtr));122}123124125/**126* Return back SlotObject for next reference127* @return SlotObject128*/129MMINLINE GC_SlotObject *nextSlot()130{131bool const compressed = compressObjectReferences();132while (_scanPtr < _endPtr) {133/* Record the slot information */134if (_description & 1) {135_slotObject.writeAddressToSlot(_scanPtr);136_scanPtr = GC_SlotObject::addToSlotAddress(_scanPtr, 1, compressed);137138/* Advance the description pointer information */139if (--_descriptionIndex) {140_description >>= 1;141} else {142_description = *_descriptionPtr;143_descriptionPtr += 1;144_descriptionIndex = J9BITS_BITS_IN_SLOT;145}146return &_slotObject;147} else {148_scanPtr = GC_SlotObject::addToSlotAddress(_scanPtr, 1, compressed);149150/* Advance the description pointer information */151if (--_descriptionIndex) {152_description >>= 1;153} else {154_description = *_descriptionPtr;155_descriptionPtr += 1;156_descriptionIndex = J9BITS_BITS_IN_SLOT;157}158}159}160/* No more object slots to scan */161return NULL;162}163164/**165* Restores the iterator state into this class166* @param[in] objectIteratorState partially scanned object iterator state167*/168MMINLINE void restore(GC_ObjectIteratorState *objectIteratorState)169{170_objectPtr = objectIteratorState->_objectPtr;171_scanPtr = objectIteratorState->_scanPtr;172_endPtr = objectIteratorState->_endPtr;173_descriptionPtr = objectIteratorState->_descriptionPtr;174_description = objectIteratorState->_description;175_descriptionIndex = objectIteratorState->_descriptionIndex;176}177178/**179* Saves the partially scanned state of this class180* @param[in] objectIteratorState where to store the state181*/182MMINLINE void save(GC_ObjectIteratorState *objectIteratorState)183{184objectIteratorState->_objectPtr = _objectPtr;185objectIteratorState->_scanPtr = _scanPtr;186objectIteratorState->_endPtr = _endPtr;187objectIteratorState->_descriptionPtr = _descriptionPtr;188objectIteratorState->_description = _description;189objectIteratorState->_descriptionIndex = _descriptionIndex;190}191192MMINLINE J9Object *getObject()193{194return _objectPtr;195}196197/**198* A much lighter-weight way to restore iterator state: pass in the slot pointer and the iterator will align itself199* to return that as its next slot.200* @param slotPtr[in] The iterator slot which should be next returned by the iterator201*/202MMINLINE void advanceToSlot(fj9object_t *slotPtr)203{204Assert_MM_true(slotPtr >= _scanPtr);205UDATA bitsToTravel = GC_SlotObject::subtractSlotAddresses(slotPtr, _scanPtr, compressObjectReferences());206if (NULL != _descriptionPtr) {207Assert_MM_true(J9BITS_BITS_IN_SLOT >= _descriptionIndex);208/* _descriptionIndex uses backward math so put it in forward-facing bit counts */209UDATA currentBitIndexInCurrentSlot = J9BITS_BITS_IN_SLOT - _descriptionIndex;210UDATA newBitIndexRelativeToCurrentSlot = currentBitIndexInCurrentSlot + bitsToTravel;211UDATA slotsToMove = newBitIndexRelativeToCurrentSlot / J9BITS_BITS_IN_SLOT;212UDATA newBitIndexAfterSlotMove = newBitIndexRelativeToCurrentSlot % J9BITS_BITS_IN_SLOT;213/* bump the _descriptionPtr by the appropriate number of slots */214_descriptionPtr += slotsToMove;215/* _descriptionPtr ALWAYS points at the NEXT slot of index bits so read the CURRENT by subtracting 1 */216UDATA *currentDescriptionPointer = _descriptionPtr - 1;217_description = *currentDescriptionPointer;218/* use J9BITS_BITS_IN_SLOT as the "0" for _descriptionIndex since it uses backward math */219_descriptionIndex = J9BITS_BITS_IN_SLOT;220/* now, advance the number of bits required into this slot */221_descriptionIndex -= newBitIndexAfterSlotMove;222_description >>= newBitIndexAfterSlotMove;223} else {224Assert_MM_true(_descriptionIndex >= bitsToTravel);225_descriptionIndex -= bitsToTravel;226_description >>= bitsToTravel;227}228/* save back the new slot ptr */229_scanPtr = slotPtr;230Assert_MM_true (_description & 1);231}232233/**234* @param vm[in] pointer to the JVM235*/236GC_MixedObjectIterator(OMR_VM *omrVM)237: _slotObject(GC_SlotObject(omrVM, NULL))238#if defined(OMR_GC_COMPRESSED_POINTERS) && defined(OMR_GC_FULL_POINTERS)239, _compressObjectReferences(OMRVM_COMPRESS_OBJECT_REFERENCES(omrVM))240#endif /* defined(OMR_GC_COMPRESSED_POINTERS) && defined(OMR_GC_FULL_POINTERS) */241, _objectPtr(NULL)242, _scanPtr(NULL)243, _endPtr(NULL)244, _descriptionPtr(NULL)245, _description(0)246, _descriptionIndex(0)247{248}249250/**251* @param vm[in] pointer to the JVM252* @param objectPtr[in] the object to be processed253*/254GC_MixedObjectIterator(OMR_VM *omrVM, J9Object *objectPtr)255: _slotObject(GC_SlotObject(omrVM, NULL))256#if defined(OMR_GC_COMPRESSED_POINTERS) && defined(OMR_GC_FULL_POINTERS)257, _compressObjectReferences(OMRVM_COMPRESS_OBJECT_REFERENCES(omrVM))258#endif /* defined(OMR_GC_COMPRESSED_POINTERS) && defined(OMR_GC_FULL_POINTERS) */259, _objectPtr(NULL)260, _scanPtr(NULL)261, _endPtr(NULL)262, _descriptionPtr(NULL)263, _description(0)264, _descriptionIndex(0)265{266initialize(omrVM, objectPtr);267}268};269270#endif /* MIXEDOBJECTITERATOR_HPP_ */271272273