Path: blob/master/runtime/gc_glue_java/PointerArrayObjectScanner.hpp
5985 views
/*******************************************************************************1* Copyright (c) 2016, 2020 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#if !defined(POINTERARRAYOBJECTSCANNER_HPP_)23#define POINTERARRAYOBJECTSCANNER_HPP_2425#include "j9.h"26#include "j9cfg.h"27#include "modron.h"2829#include "ArrayObjectModel.hpp"30#include "GCExtensionsBase.hpp"31#include "IndexableObjectScanner.hpp"3233/**34* This class is used to iterate over the slots of a Java pointer array.35*/36class GC_PointerArrayObjectScanner : public GC_IndexableObjectScanner37{38/* Data Members */39private:40fomrobject_t *_mapPtr; /**< pointer to first array element in current scan segment */4142protected:4344public:4546/* Methods */47private:4849protected:50/**51* @param env The scanning thread environment52* @param[in] arrayPtr pointer to the array to be processed53* @param[in] basePtr pointer to the first contiguous array cell54* @param[in] limitPtr pointer to end of last contiguous array cell55* @param[in] scanPtr pointer to the array cell where scanning will start56* @param[in] endPtr pointer to the array cell where scanning will stop57* @param[in] flags Scanning context flags58*/59MMINLINE GC_PointerArrayObjectScanner(MM_EnvironmentBase *env, omrobjectptr_t arrayPtr, fomrobject_t *basePtr, fomrobject_t *limitPtr, fomrobject_t *scanPtr, fomrobject_t *endPtr, uintptr_t flags)60: GC_IndexableObjectScanner(env, arrayPtr, basePtr, limitPtr, scanPtr, endPtr61, (GC_SlotObject::subtractSlotAddresses(endPtr, scanPtr, env->compressObjectReferences()) < _bitsPerScanMap)62? ((uintptr_t)1 << GC_SlotObject::subtractSlotAddresses(endPtr, scanPtr, env->compressObjectReferences())) - 163: UDATA_MAX64, env->compressObjectReferences() ? sizeof(uint32_t) : sizeof(uintptr_t)65, flags)66, _mapPtr(_scanPtr)67{68_typeId = __FUNCTION__;69}7071/**72* Set up the scanner.73* @param[in] env Current environment74*/75MMINLINE void76initialize(MM_EnvironmentBase *env)77{78GC_IndexableObjectScanner::initialize(env);79}8081public:82/**83* @param[in] env The scanning thread environment84* @param[in] objectPtr pointer to the array to be processed85* @param[in] allocSpace pointer to space within which the scanner should be instantiated (in-place)86* @param[in] flags Scanning context flags87* @param[in] splitAmount If >0, the number of elements to include for this scanner instance; if 0, include all elements88* @param[in] startIndex The index of the first element to scan89*/90MMINLINE static GC_PointerArrayObjectScanner *91newInstance(MM_EnvironmentBase *env, omrobjectptr_t objectPtr, void *allocSpace, uintptr_t flags, uintptr_t splitAmount, uintptr_t startIndex = 0)92{93GC_PointerArrayObjectScanner *objectScanner = (GC_PointerArrayObjectScanner *)allocSpace;94if (NULL != objectScanner) {95bool const compressed = env->compressObjectReferences();96GC_ArrayObjectModel *arrayObjectModel = &(env->getExtensions()->indexableObjectModel);97omrarrayptr_t arrayPtr = (omrarrayptr_t)objectPtr;98uintptr_t sizeInElements = arrayObjectModel->getSizeInElements(arrayPtr);99fomrobject_t *basePtr = (fomrobject_t *)arrayObjectModel->getDataPointerForContiguous(arrayPtr);100fomrobject_t *scanPtr = GC_SlotObject::addToSlotAddress(basePtr, startIndex, compressed);101fomrobject_t *limitPtr = GC_SlotObject::addToSlotAddress(basePtr, sizeInElements, compressed);102fomrobject_t *endPtr = limitPtr;103104if (!GC_ObjectScanner::isIndexableObjectNoSplit(flags)) {105fomrobject_t *splitPtr = GC_SlotObject::addToSlotAddress(scanPtr, splitAmount, compressed);106if ((splitPtr > scanPtr) && (splitPtr < endPtr)) {107endPtr = splitPtr;108}109}110111new(objectScanner) GC_PointerArrayObjectScanner(env, objectPtr, basePtr, limitPtr, scanPtr, endPtr, flags);112objectScanner->initialize(env);113if (0 != startIndex) {114objectScanner->clearHeadObjectScanner();115}116}117return objectScanner;118}119120MMINLINE uintptr_t getBytesRemaining() { return (uintptr_t)_endPtr - (uintptr_t)_scanPtr; }121122/**123* @param env The scanning thread environment124* @param[in] allocSpace pointer to space within which the scanner should be instantiated (in-place)125* @param splitAmount The maximum number of array elements to include126* @return Pointer to split scanner in allocSpace127*/128virtual GC_IndexableObjectScanner *129splitTo(MM_EnvironmentBase *env, void *allocSpace, uintptr_t splitAmount)130{131GC_PointerArrayObjectScanner *splitScanner = NULL;132133Assert_MM_true(_limitPtr >= _endPtr);134/* Downsize splitAmount if larger than the tail of this scanner */135uintptr_t remainder = GC_SlotObject::subtractSlotAddresses(_limitPtr, _endPtr, compressObjectReferences());136if (splitAmount > remainder) {137splitAmount = remainder;138}139140Assert_MM_true(NULL != allocSpace);141/* If splitAmount is 0 the new scanner will return NULL on the first call to getNextSlot(). */142splitScanner = (GC_PointerArrayObjectScanner *)allocSpace;143/* Create new scanner for next chunk of array starting at the end of current chunk size splitAmount elements */144new(splitScanner) GC_PointerArrayObjectScanner(env, getArrayObject(), _basePtr, _limitPtr, _endPtr, GC_SlotObject::addToSlotAddress(_endPtr, splitAmount, compressObjectReferences()), _flags);145splitScanner->initialize(env);146147return splitScanner;148}149150/**151* Return base pointer and slot bit map for next block of contiguous slots to be scanned. The152* base pointer must be fomrobject_t-aligned. Bits in the bit map are scanned in order of153* increasing significance, and the least significant bit maps to the slot at the returned154* base pointer.155*156* @param[out] scanMap the bit map for the slots contiguous with the returned base pointer157* @param[out] hasNextSlotMap set this to true if this method should be called again, false if this map is known to be last158* @return a pointer to the first slot mapped by the least significant bit of the map, or NULL if no more slots159*/160virtual fomrobject_t *161getNextSlotMap(uintptr_t *slotMap, bool *hasNextSlotMap)162{163bool const compressed = compressObjectReferences();164fomrobject_t *result = NULL;165_mapPtr = GC_SlotObject::addToSlotAddress(_mapPtr, _bitsPerScanMap, compressed);166if (_endPtr > _mapPtr) {167intptr_t remainder = GC_SlotObject::subtractSlotAddresses(_endPtr, _mapPtr, compressed);168if (remainder >= _bitsPerScanMap) {169*slotMap = UDATA_MAX;170} else {171*slotMap = ((uintptr_t)1 << remainder) - 1;172}173*hasNextSlotMap = remainder > _bitsPerScanMap;174result = _mapPtr;175} else {176*slotMap = 0;177*hasNextSlotMap = false;178}179return result;180}181182#if defined(OMR_GC_LEAF_BITS)183/**184* Return base pointer and slot bit map for next block of contiguous slots to be scanned. The185* base pointer must be fomrobject_t-aligned. Bits in the bit map are scanned in order of186* increasing significance, and the least significant bit maps to the slot at the returned187* base pointer.188*189* @param[out] scanMap the bit map for the slots contiguous with the returned base pointer190* @param[out] leafMap the leaf bit map for the slots contiguous with the returned base pointer191* @param[out] hasNextSlotMap set this to true if this method should be called again, false if this map is known to be last192* @return a pointer to the first slot mapped by the least significant bit of the map, or NULL if no more slots193*/194virtual fomrobject_t *195getNextSlotMap(uintptr_t *scanMap, uintptr_t *leafMap, bool *hasNextSlotMap)196{197*leafMap = 0;198return getNextSlotMap(scanMap, hasNextSlotMap);199}200#endif /* defined(OMR_GC_LEAF_BITS) */201};202203#endif /* POINTERARRAYOBJECTSCANNER_HPP_ */204205206