Path: blob/master/runtime/gc_glue_java/ArrayletObjectModelBase.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#if !defined(ARRAYLETOBJECTMODELBASE_)23#define ARRAYLETOBJECTMODELBASE_2425#include "j9.h"26#include "j9cfg.h"27#include "j9consts.h"28#include "modron.h"29#include "modronopt.h"3031#include "Bits.hpp"32#include "Math.hpp"3334class MM_GCExtensionsBase;35class MM_MemorySubSpace;3637class GC_ArrayletObjectModelBase38{39/*40* Data members41*/42private:43#if defined(J9VM_GC_ENABLE_DOUBLE_MAP)44bool _enableDoubleMapping; /** Allows arraylets to be double mapped */45#endif /* J9VM_GC_ENABLE_DOUBLE_MAP */46protected:47#if defined(OMR_GC_COMPRESSED_POINTERS) && defined(OMR_GC_FULL_POINTERS)48bool _compressObjectReferences;49#endif /* defined(OMR_GC_COMPRESSED_POINTERS) && defined(OMR_GC_FULL_POINTERS) */50OMR_VM *_omrVM; /**< used so that we can pull the arrayletLeafSize and arrayletLeafLogSize for arraylet sizing calculations */51void * _arrayletRangeBase; /**< The base heap range of where discontiguous arraylets are allowed. */52void * _arrayletRangeTop; /**< The top heap range of where discontiguous arraylets are allowed. */53MM_MemorySubSpace * _arrayletSubSpace; /**< The only subspace that is allowed to have discontiguous arraylets. */54UDATA _largestDesirableArraySpineSize; /**< A cached copy of the subspace's _largestDesirableArraySpineSize to be used when we don't have access to a subspace. */55public:56typedef enum ArrayLayout {57Illegal = 0,58InlineContiguous,59Discontiguous,60Hybrid61} ArrayLayout;6263/*64* Function members65*/66private:67protected:68virtual bool initialize(MM_GCExtensionsBase *extensions);69virtual void tearDown(MM_GCExtensionsBase *extensions);7071/**72* Get the spine size without header for an arraylet with these properties73* @param layout The layout of the indexable object74* @param numberArraylets Number of arraylets for this indexable object75* @param dataSize How many elements are in the indexable object76* @param alignData Should the data section be aligned77* @return spineSize The actual size in byte of the spine78*/79UDATA80getSpineSizeWithoutHeader(ArrayLayout layout, UDATA numberArraylets, UDATA dataSize, bool alignData);8182public:83/**84* Return back true if object references are compressed85* @return true, if object references are compressed86*/87MMINLINE bool88compressObjectReferences()89{90return OMR_COMPRESS_OBJECT_REFERENCES(_compressObjectReferences);91}9293/**94* Returns the size of an indexable object in elements.95* @param arrayPtr Pointer to the indexable object whose size is required96* @return Size of object in elements97*/98MMINLINE UDATA99getSizeInElements(J9IndexableObject *arrayPtr)100{101UDATA size = 0;102if (compressObjectReferences()) {103size = ((J9IndexableObjectContiguousCompressed *)arrayPtr)->size;104if (0 == size) {105/* Discontiguous */106size = ((J9IndexableObjectDiscontiguousCompressed *)arrayPtr)->size;107}108} else {109size = ((J9IndexableObjectContiguousFull *)arrayPtr)->size;110if (0 == size) {111/* Discontiguous */112size = ((J9IndexableObjectDiscontiguousFull *)arrayPtr)->size;113}114}115return size;116}117118/**119* Sets size in elements of a contiguous indexable object .120* @param arrayPtr Pointer to the indexable object whose size is required121* @param size Size in elements to set.122*/123MMINLINE void124setSizeInElementsForContiguous(J9IndexableObject *arrayPtr, UDATA size)125{126if (compressObjectReferences()) {127((J9IndexableObjectContiguousCompressed *)arrayPtr)->size = (U_32)size;128} else {129((J9IndexableObjectContiguousFull *)arrayPtr)->size = (U_32)size;130}131}132133#if defined(J9VM_GC_ENABLE_DOUBLE_MAP)134/**135* Sets enable double mapping status. Note that the double map136* status value may differ from the requested one in certain137* circuntances.138*139* @param enableDoubleMapping140*/141MMINLINE void142setEnableDoubleMapping(bool enableDoubleMapping)143{144_enableDoubleMapping = enableDoubleMapping;145}146147/**148* Returns enable double mapping status149*150* @return true if double mapping status is set to true, false otherwise.151*/152MMINLINE bool153isDoubleMappingEnabled()154{155return _enableDoubleMapping;156}157#endif /* J9VM_GC_ENABLE_DOUBLE_MAP */158159/**160* Sets size in elements of a discontiguous indexable object .161* @param arrayPtr Pointer to the indexable object whose size is required162* @param size Size in elements to set.163*/164MMINLINE void165setSizeInElementsForDiscontiguous(J9IndexableObject *arrayPtr, UDATA size)166{167if (compressObjectReferences()) {168((J9IndexableObjectDiscontiguousCompressed *)arrayPtr)->mustBeZero = 0;169((J9IndexableObjectDiscontiguousCompressed *)arrayPtr)->size = (U_32)size;170} else {171((J9IndexableObjectDiscontiguousFull *)arrayPtr)->mustBeZero = 0;172((J9IndexableObjectDiscontiguousFull *)arrayPtr)->size = (U_32)size;173}174}175176/**177* Determines whether or not a spine that represents an object of this178* class should have its data section aligned.179* @param clazz The class to check alignment for180* @return needAlignment Should the data section be aligned181*/182MMINLINE bool183shouldAlignSpineDataSection(J9Class *clazz)184{185bool needAlignment = false;186187if (compressObjectReferences()) {188/* Compressed pointers require that each leaf starts at an appropriately-aligned address189* (based on the compressed shift value). If this is not done, compressed leaf pointers190* would be unable to reach all of the heap.191*/192needAlignment = true;193#if !defined(J9VM_ENV_DATA64)194} else {195/* The alignment padding is only required when the size of the spine pointers are196* not 8 byte aligned. For example, on a 64-bit non-compressed platform, a single197* spine pointer would be 8 byte aligned, whereas on a 32-bit platform, a single198* spine pointer would not be 8 byte aligned, and would require additional padding.199*/200if (OBJECT_HEADER_SHAPE_DOUBLES == J9GC_CLASS_SHAPE(clazz)) {201needAlignment = true;202}203#endif /* !J9VM_ENV_DATA64 */204}205206return needAlignment;207}208209/**210* Get the size in bytes for the arraylet at index in indexable object objPtr211* @param objPtr Pointer to an array object212* @param index the index in question. 0<=index<numArraylets(objPtr)213* @param dataSizeInBytes size of data in an indexable object, in bytes, including leaves, excluding the header.214* @param numArraylets total number of arraylets for the given indexable object215* @return the size of the indexth arraylet216*/217MMINLINE UDATA218arrayletSize(J9IndexableObject *objPtr, UDATA index, UDATA dataSizeInBytes, UDATA numArraylets)219{220UDATA arrayletLeafSize = _omrVM->_arrayletLeafSize;221if (index < numArraylets - 1) {222return arrayletLeafSize;223} else {224return MM_Math::saturatingSubtract(dataSizeInBytes, index * arrayletLeafSize);225}226}227228/**229* Return the total number of arraylets for an indexable object with a size of dataInSizeByte230* @param dataSizeInBytes size of an array in bytes (not elements)231* @return the number of arraylets used for an array of dataSizeInBytes bytes232*/233MMINLINE UDATA234numArraylets(UDATA dataSizeInBytes)235{236UDATA leafSize = _omrVM->_arrayletLeafSize;237UDATA numberOfArraylets = 1;238if (UDATA_MAX != leafSize) {239UDATA leafSizeMask = leafSize - 1;240UDATA leafLogSize = _omrVM->_arrayletLeafLogSize;241242/* CMVC 135307 : following logic for calculating the leaf count would not overflow dataSizeInBytes.243* the assumption is leaf size is order of 2. It's identical to:244* if (dataSizeInBytes % leafSize) is 0245* leaf count = dataSizeInBytes >> leafLogSize246* else247* leaf count = (dataSizeInBytes >> leafLogSize) + 1248*/249numberOfArraylets = ((dataSizeInBytes >> leafLogSize) + (((dataSizeInBytes & leafSizeMask) + leafSizeMask) >> leafLogSize));250}251return numberOfArraylets;252}253254/**255* Expands the heap range in which discontiguous arraylets are allowed.256* @param subSpace The subspace of the range in which discontiguous arraylets are allowed.257* @param rangeBase The base heap range of where discontiguous arraylets are allowed.258* @param rangeTop The top heap range of where discontiguous arraylets are allowed.259* @param largestDesirableArraySpineSize The subspace's _largestDesirableArraySpineSize to be used when we don't have access to a subspace.260*/261void262expandArrayletSubSpaceRange(MM_MemorySubSpace* subSpace, void* rangeBase, void* rangeTop, UDATA largestDesirableArraySpineSize);263};264265#endif /* ARRAYLETOBJECTMODELBASE_ */266267268