/******************************************************************************* * Copyright IBM Corp. and others 1991 * * This program and the accompanying materials are made available under * the terms of the Eclipse Public License 2.0 which accompanies this * distribution and is available at https://www.eclipse.org/legal/epl-2.0/ * or the Apache License, Version 2.0 which accompanies this distribution and * is available at https://www.apache.org/licenses/LICENSE-2.0. * * This Source Code may also be made available under the following * Secondary Licenses when the conditions for such availability set * forth in the Eclipse Public License, v. 2.0 are satisfied: GNU * General Public License, version 2 with the GNU Classpath * Exception [1] and GNU General Public License, version 2 with the * OpenJDK Assembly Exception [2]. * * [1] https://www.gnu.org/software/classpath/license.html * [2] https://openjdk.org/legal/assembly-exception.html * * SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0 OR GPL-2.0-only WITH OpenJDK-assembly-exception-1.0 *******************************************************************************/ #ifndef OBJECTFIELDINFO_HPP_ #define OBJECTFIELDINFO_HPP_ #include "j9comp.h" #include "j9port.h" #include "ut_j9vm.h" /** * represent information about number of various field types, including * single and double word primitives, object references, and hidden fields. * Hidden fields are held in a linked list, instance fields are a contiguous array of J9ROMFieldShape */ #define SINGLES_PRIORITY_FOR_BACKFILL class ObjectFieldInfo { private: U_32 _objectHeaderSize; U_32 _referenceSize; U_32 _cacheLineSize; bool _useContendedClassLayout; /* check this in constructor. Forced to false if we can't get the line size */ J9ROMClass *_romClass; U_32 _superclassFieldsSize; bool _objectCanUseBackfill; /* true if an object reference is the same size as a backfill slot */ /* These count uncontended instance and hidden fields */ U_32 _instanceObjectCount; U_32 _instanceSingleCount; U_32 _instanceDoubleCount; U_32 _totalObjectCount; U_32 _totalSingleCount; U_32 _totalDoubleCount; /* the following count fields annotated with @Contended, including regular fields in classes annotated with @Contended. */ U_32 _contendedObjectCount; U_32 _contendedSingleCount; U_32 _contendedDoubleCount; #if defined(J9VM_OPT_VALHALLA_FLATTENABLE_VALUE_TYPES) bool _isValue; J9FlattenedClassCache *_flattenedClassCache; U_32 _totalFlatFieldDoubleBytes; U_32 _totalFlatFieldRefBytes; U_32 _totalFlatFieldSingleBytes; U_32 _flatAlignedObjectInstanceBackfill; U_32 _flatAlignedSingleInstanceBackfill; U_32 _flatUnAlignedObjectInstanceBackfill; U_32 _flatUnAlignedSingleInstanceBackfill; bool _classRequiresPrePadding; bool _isBackFillPostPadded; #endif /* J9VM_OPT_VALHALLA_FLATTENABLE_VALUE_TYPES */ bool _hiddenFieldOffsetResolutionRequired; bool _instanceFieldBackfillEligible; /* use this to give instance fields priority over the hidden fields for backfill slots */ U_32 _hiddenFieldCount; IDATA _superclassBackfillOffset; /* inherited backfill */ IDATA _myBackfillOffset; /* backfill available for this class's fields */ IDATA _subclassBackfillOffset; /* backfill available to subclasses */ /** * Calculate a position guaranteed to be on a different cache line from the header, superclass fields, and hidden fields. * @return offset from the start of the header */ VMINLINE U_32 getPaddedTrueNonContendedSize(void) const { U_32 accumulator = _superclassFieldsSize + _objectHeaderSize; /* get the true size with header */ accumulator += (_totalObjectCount * _objectHeaderSize) + (_totalSingleCount * sizeof(U_32)) + (_totalDoubleCount * sizeof(U_64)); /* add the non-contended and hidden fields */ accumulator = ROUND_DOWN_TO_POWEROF2(accumulator, OBJECT_SIZE_INCREMENT_IN_BYTES) + _cacheLineSize; /* get the worst-case cache line boundary and add a cache size */ return accumulator; } public: enum { NO_BACKFILL_AVAILABLE = -1, BACKFILL_SIZE = sizeof(U_32), OBJECT_SIZE_INCREMENT_IN_BYTES = 8 }; #if defined(J9VM_OPT_VALHALLA_FLATTENABLE_VALUE_TYPES) ObjectFieldInfo(J9JavaVM *vm, J9ROMClass *romClass, J9FlattenedClassCache *flattenedClassCache): #else ObjectFieldInfo(J9JavaVM *vm, J9ROMClass *romClass): #endif /* J9VM_OPT_VALHALLA_FLATTENABLE_VALUE_TYPES */ _objectHeaderSize(J9JAVAVM_OBJECT_HEADER_SIZE(vm)), _referenceSize(J9JAVAVM_REFERENCE_SIZE(vm)), _cacheLineSize(0), _useContendedClassLayout(false), _romClass(romClass), _superclassFieldsSize((U_32) -1), _objectCanUseBackfill(J9JAVAVM_REFERENCE_SIZE(vm) == BACKFILL_SIZE), _instanceObjectCount(0), _instanceSingleCount(0), _instanceDoubleCount(0), _totalObjectCount(0), _totalSingleCount(0), _totalDoubleCount(0), _contendedObjectCount(0), _contendedSingleCount(0), _contendedDoubleCount(0), #if defined(J9VM_OPT_VALHALLA_FLATTENABLE_VALUE_TYPES) _isValue(J9ROMCLASS_IS_VALUE(romClass)), _flattenedClassCache(flattenedClassCache), _totalFlatFieldDoubleBytes(0), _totalFlatFieldRefBytes(0), _totalFlatFieldSingleBytes(0), _flatAlignedObjectInstanceBackfill(0), _flatAlignedSingleInstanceBackfill(0), _flatUnAlignedObjectInstanceBackfill(0), _flatUnAlignedSingleInstanceBackfill(0), _classRequiresPrePadding(false), _isBackFillPostPadded(false), #endif /* J9VM_OPT_VALHALLA_FLATTENABLE_VALUE_TYPES */ _hiddenFieldOffsetResolutionRequired(false), _instanceFieldBackfillEligible(false), _hiddenFieldCount(0), _superclassBackfillOffset(NO_BACKFILL_AVAILABLE), _myBackfillOffset(NO_BACKFILL_AVAILABLE), _subclassBackfillOffset(NO_BACKFILL_AVAILABLE) { if (J9ROMCLASS_IS_CONTENDED(romClass)) { UDATA dCacheLineSize = vm->dCacheLineSize; if (dCacheLineSize > 0) { _cacheLineSize = (U_32) dCacheLineSize; _useContendedClassLayout = true; } } } /** * Count the various types of instance fields from the ROM class. * Instance fields are represented as a contiguous array of variable size structures. */ void countInstanceFields(void); /** * Count the various types of hidden fields, filtering out those not applicable to this ROM class, * and copy them to a list. * @param hiddenFieldList linked list of hidden fields * @param hiddenFieldArray buffer into which to copy the applicable fields * @return number of hidden fields */ U_32 countAndCopyHiddenFields(J9HiddenInstanceField *hiddenFieldList, J9HiddenInstanceField *hiddenFieldArray[]); VMINLINE U_32 getTotalDoubleCount(void) const { return _totalDoubleCount; } VMINLINE U_32 getTotalObjectCount(void) const { return _totalObjectCount; } VMINLINE U_32 getTotalSingleCount(void) const { return _totalSingleCount; } /** * Priorities for slots are: * 1. instance singles * 2. instance objects * 3. flat end-aligned singles * 4. flat end-aligned objects * 5. flat end-unaligned singles * 6. flat end-unaligned objects * 7. hidden singles * 8. hidden objects * * @return number of object fields (instance and hidden) which do not go in a backfill slot. */ VMINLINE U_32 getNonBackfilledObjectCount(void) const { U_32 nonBackfilledObjects = _totalObjectCount; if (isBackfillSuitableObjectAvailable() && !isBackfillSuitableInstanceSingleAvailable() && isMyBackfillSlotAvailable() #if defined(J9VM_OPT_VALHALLA_FLATTENABLE_VALUE_TYPES) && (0 != nonBackfilledObjects) #endif /* defined(J9VM_OPT_VALHALLA_FLATTENABLE_VALUE_TYPES) */ ) { nonBackfilledObjects -= 1; } return nonBackfilledObjects; } VMINLINE U_32 getNonBackfilledSingleCount(void) const { U_32 nonBackfilledSingle = _totalSingleCount; if (isBackfillSuitableSingleAvailable() && isMyBackfillSlotAvailable() #if defined(J9VM_OPT_VALHALLA_FLATTENABLE_VALUE_TYPES) && (0 != nonBackfilledSingle) #endif /* defined(J9VM_OPT_VALHALLA_FLATTENABLE_VALUE_TYPES) */ ) { nonBackfilledSingle -= 1; } return nonBackfilledSingle; } VMINLINE U_32 getNonBackfilledInstanceObjectCount(void) const { U_32 nonBackfilledObjects = _instanceObjectCount; if (isBackfillSuitableInstanceObjectAvailable() && !isBackfillSuitableInstanceSingleAvailable() && isMyBackfillSlotAvailable() #if defined(J9VM_OPT_VALHALLA_FLATTENABLE_VALUE_TYPES) && (0 != nonBackfilledObjects) #endif /* defined(J9VM_OPT_VALHALLA_FLATTENABLE_VALUE_TYPES) */ ) { nonBackfilledObjects -= 1; } return nonBackfilledObjects; } VMINLINE U_32 getNonBackfilledInstanceSingleCount(void) const { U_32 nonBackfilledSingle = _instanceSingleCount; if (isBackfillSuitableInstanceSingleAvailable() && isMyBackfillSlotAvailable() #if defined(J9VM_OPT_VALHALLA_FLATTENABLE_VALUE_TYPES) && (0 != nonBackfilledSingle) #endif /* defined(J9VM_OPT_VALHALLA_FLATTENABLE_VALUE_TYPES) */ ) { nonBackfilledSingle -= 1; } return nonBackfilledSingle; } VMINLINE U_32 getInstanceDoubleCount(void) const { return _instanceDoubleCount; } VMINLINE U_32 getInstanceObjectCount(void) const { return _instanceObjectCount; } VMINLINE U_32 getInstanceSingleCount(void) const { return _instanceSingleCount; } VMINLINE U_32 getHiddenFieldCount(void) const { return _hiddenFieldCount; } VMINLINE bool isBackfillSuitableSingleAvailable(void) const { return ((0 != getTotalSingleCount()) #if defined(J9VM_OPT_VALHALLA_FLATTENABLE_VALUE_TYPES) || (0 != getFlatAlignedSingleInstanceBackfillSize()) || (0 != getFlatUnAlignedSingleInstanceBackfillSize()) #endif /* defined(J9VM_OPT_VALHALLA_FLATTENABLE_VALUE_TYPES) */ ); } VMINLINE bool isBackfillSuitableObjectAvailable(void) const { return ((_objectCanUseBackfill && (0 != getTotalObjectCount())) #if defined(J9VM_OPT_VALHALLA_FLATTENABLE_VALUE_TYPES) || (0 != getFlatAlignedObjectInstanceBackfillSize()) || (0 != getFlatUnAlignedObjectInstanceBackfillSize()) #endif /* defined(J9VM_OPT_VALHALLA_FLATTENABLE_VALUE_TYPES) */ ); } VMINLINE bool isBackfillSuitableInstanceSingleAvailable(void) const { return (0 != getInstanceSingleCount()); } VMINLINE bool isBackfillSuitableFlatInstanceSingleAvailable(void) const { #if defined(J9VM_OPT_VALHALLA_FLATTENABLE_VALUE_TYPES) return ((0 != getFlatAlignedSingleInstanceBackfillSize()) || (0 != getFlatUnAlignedSingleInstanceBackfillSize())); #else /* defined(J9VM_OPT_VALHALLA_FLATTENABLE_VALUE_TYPES) */ return false; #endif /* defined(J9VM_OPT_VALHALLA_FLATTENABLE_VALUE_TYPES) */ } VMINLINE bool isBackfillSuitableInstanceObjectAvailable(void) const { return ((_objectCanUseBackfill && (0 != getInstanceObjectCount())) #if defined(J9VM_OPT_VALHALLA_FLATTENABLE_VALUE_TYPES) || (0 != getFlatAlignedObjectInstanceBackfillSize()) || (0 != getFlatUnAlignedObjectInstanceBackfillSize()) #endif /* defined(J9VM_OPT_VALHALLA_FLATTENABLE_VALUE_TYPES) */ ); } VMINLINE bool isBackfillSuitableFieldAvailable(void) const { return isBackfillSuitableSingleAvailable() || isBackfillSuitableObjectAvailable(); } /** * * Returns the size of backfill. The order or precedence is: * 1. Singles * 2. Objects * 3. Flat end-aligned singles * 4. Flat end-aligned objects * 5. Flat end-unaligned singles * 6. Flat end un-aligned objects * * @return size of backfill */ VMINLINE U_32 getBackfillSize() { U_32 backFillSize = BACKFILL_SIZE; #if defined(J9VM_OPT_VALHALLA_FLATTENABLE_VALUE_TYPES) if ((0 != getInstanceSingleCount()) || (_objectCanUseBackfill && (0 != getInstanceObjectCount()))) { /* BACKFILL_SIZE */ } else if (0 != getFlatAlignedSingleInstanceBackfillSize()) { backFillSize = getFlatAlignedSingleInstanceBackfillSize(); } else if (_objectCanUseBackfill && (0 != getFlatAlignedObjectInstanceBackfillSize())) { backFillSize = getFlatAlignedObjectInstanceBackfillSize(); } else if (0 != getFlatUnAlignedSingleInstanceBackfillSize()) { backFillSize = getFlatUnAlignedSingleInstanceBackfillSize(); } else if (_objectCanUseBackfill && (0 != getFlatUnAlignedObjectInstanceBackfillSize())) { backFillSize = getFlatUnAlignedObjectInstanceBackfillSize(); } return backFillSize; #else /* if defined(J9VM_OPT_VALHALLA_FLATTENABLE_VALUE_TYPES) */ return backFillSize; #endif /* if defined(J9VM_OPT_VALHALLA_FLATTENABLE_VALUE_TYPES) */ } /** * @note This is used for hidden fields which use an offset from the header * @return offset of backfill slot from the start of the object */ VMINLINE IDATA getMyBackfillOffsetForHiddenField(void) const { return _myBackfillOffset + _objectHeaderSize; } VMINLINE U_32 getSuperclassFieldsSize(void) const { return _superclassFieldsSize; } VMINLINE U_32 getSuperclassObjectSize(void) const { return _superclassFieldsSize + _objectHeaderSize; } VMINLINE void setSuperclassFieldsSize(U_32 superTotalSize) { this->_superclassFieldsSize = superTotalSize; } VMINLINE bool const isMyBackfillSlotAvailable(void) const { return (_myBackfillOffset >= 0); } VMINLINE bool const isSuperclassBackfillSlotAvailable(void) const { return (_superclassBackfillOffset >= 0); } /** * Compute the total size of the object including padding to end on 8-byte boundary. * Update the backfill values to use for this class's fields and those of subclasses * @return size of the object in bytes, not including the header */ U_32 calculateTotalFieldsSizeAndBackfill(void); /** * Fields can start on the first 8-byte boundary after the end of the superclass. * If the superclass is not end-aligned, the padding bytes become the new backfill. * Since the superclass is not end-aligned it must have no embedded backfill. * @return offset to the first (non-backfilled) field. */ VMINLINE U_32 calculateFieldDataStart(void) { U_32 fieldDataStart = 0; if (!isContendedClassLayout()) { bool doubleAlignment = (_totalDoubleCount > 0); bool hasObjects = _totalObjectCount > 0; #if defined(J9VM_OPT_VALHALLA_FLATTENABLE_VALUE_TYPES) /* If the type has double field the doubles need to start on an 8-byte boundary. In the case of valuetypes * there is no lockword so the super class field size will be zero. This means that valueTypes in compressedrefs * mode with double alignment fields need to be pre-padded. */ doubleAlignment = (doubleAlignment || (_totalFlatFieldDoubleBytes > 0)); #endif /* defined(J9VM_OPT_VALHALLA_FLATTENABLE_VALUE_TYPES) */ fieldDataStart = getSuperclassFieldsSize(); if (((getSuperclassObjectSize() % OBJECT_SIZE_INCREMENT_IN_BYTES) != 0) /* superclass is not end-aligned */ && (doubleAlignment || (!_objectCanUseBackfill && hasObjects)) ) { #if defined(J9VM_OPT_VALHALLA_FLATTENABLE_VALUE_TYPES) fieldDataStart += getBackfillSize(); /* If a flat type is used up as backfill and its size is not 4, 12, 20, ... this * means that the starting point for doubles will not be on an 8byte boundary. To * fix this the field start position will be incremented by 4bytes so doubles start * at the correct position. */ if (!isBackfillTypeEndAligned(fieldDataStart)) { fieldDataStart += BACKFILL_SIZE; _isBackFillPostPadded = true; } #else /* defined(J9VM_OPT_VALHALLA_FLATTENABLE_VALUE_TYPES) */ fieldDataStart += BACKFILL_SIZE; #endif /* defined(J9VM_OPT_VALHALLA_FLATTENABLE_VALUE_TYPES) */ } } else { if (TrcEnabled_Trc_VM_contendedClass) { J9UTF8 *className = J9ROMCLASS_CLASSNAME(_romClass); U_32 utfLength = J9UTF8_LENGTH(className); U_8 *utfData = J9UTF8_DATA(className); Trc_VM_contendedClass(utfLength, utfData); } fieldDataStart = getPaddedTrueNonContendedSize() - _objectHeaderSize; } return fieldDataStart; } /** * @note Always uses the number of doubles * @param start end of previous field area * @return offset to end of the doubles area */ VMINLINE UDATA addDoublesArea(UDATA start) const { return start + ((isContendedClassLayout() ? _contendedDoubleCount: _totalDoubleCount) * sizeof(U_64)); } /** * @param start end of previous field area * @return offset to end of the objects area * @note takes into account objects which will go in the backfill */ VMINLINE UDATA addObjectsArea(UDATA start) const { return start + (isContendedClassLayout() ? _contendedObjectCount: getNonBackfilledObjectCount()) * _referenceSize; } #if defined(J9VM_OPT_VALHALLA_FLATTENABLE_VALUE_TYPES) /** * @param start end of previous field area, which should be the first field area * @return offset to end of the flat doubles area */ VMINLINE UDATA addFlatDoublesArea(UDATA start) const { return start + _totalFlatFieldDoubleBytes; } /** * @param start end of previous field area, which should be after doubles * @return offset to end of the flat doubles area */ VMINLINE UDATA addFlatObjectsArea(UDATA start) const { return start + getNonBackfilledFlatInstanceObjectSize(); } /** * @param start end of previous field area, which should be after objects * @return offset to end of the flat doubles area */ VMINLINE UDATA addFlatSinglesArea(UDATA start) const { return start + getNonBackfilledFlatInstanceSingleSize(); } /** * Determines if a double field can be placed contiguously after the * backfill. If this is the case then the back fill is considered * "end-aligned" * * @param fieldDataStart the address immediately following the backfill if any, * otherwise the address following the object header * * @return true if double field can be placed immediately after, false otherwise */ VMINLINE bool isBackfillTypeEndAligned(UDATA fieldDataStart) { return BACKFILL_SIZE == (fieldDataStart % sizeof(U_64)); } /** * Returns if type is a valuetype * * @return true if valuetype, false otherwise */ VMINLINE bool isValue() const { return _isValue; } /** * Returns the size of the end-aligned single backfill. * See 'isBackfillTypeEndAligned' * * @return size of flat single slot end-aligned backfill */ VMINLINE U_32 getFlatAlignedSingleInstanceBackfillSize() const { return _flatAlignedSingleInstanceBackfill; } /** * Returns the size of the non end-aligned single backfill. * See 'isBackfillTypeEndAligned' * * @return size of flat single slot non end-aligned backfill */ VMINLINE U_32 getFlatUnAlignedSingleInstanceBackfillSize() const { return _flatUnAlignedSingleInstanceBackfill; } /** * Returns the size of the end-aligned object backfill. * See 'isBackfillTypeEndAligned' * * @return size of flat object slot end-aligned backfill */ VMINLINE U_32 getFlatAlignedObjectInstanceBackfillSize() const { return _flatAlignedObjectInstanceBackfill; } /** * Returns the size of the non end-aligned single backfill. * See 'isBackfillTypeEndAligned' * * @return size of flat object slot end-aligned backfill */ VMINLINE U_32 getFlatUnAlignedObjectInstanceBackfillSize() const { return _flatUnAlignedObjectInstanceBackfill; } /** * Sets the size of the end-aligned single backfill. * See 'isBackfillTypeEndAligned' * * @param size of flat single slot end-aligned backfill */ VMINLINE void setFlatAlignedSingleInstanceBackfill(U_32 size) { _flatAlignedSingleInstanceBackfill = size; } /** * Sets the size of the non end-aligned single backfill. * See 'isBackfillTypeEndAligned' * * @param size of flat single slot non end-aligned backfill */ VMINLINE void setFlatUnAlignedSingleInstanceBackfill(U_32 size) { _flatUnAlignedSingleInstanceBackfill = size; } /** * Sets the size of the end-aligned object backfill. * See 'isBackfillTypeEndAligned' * * @param size of flat object slot end-aligned backfill */ VMINLINE void setFlatAlignedObjectInstanceBackfill(U_32 size) { _flatAlignedObjectInstanceBackfill = size; } /** * Sets the size of the non end-aligned object backfill. * See 'isBackfillTypeEndAligned' * * @param size of flat object slot non end-aligned backfill */ VMINLINE void setFlatUnAlignedObjectInstanceBackfill(U_32 size) { _flatUnAlignedObjectInstanceBackfill = size; } /** * Sets the size of the object backfill. Determines if the backfill * is end-aligned or not. End-aligned backfill gets precedence, once * the first end-aligned backfill is set not other object backfill * can be set. If not non end-aligned backfill will be set (which can * only be set once). * * See 'isBackfillTypeEndAligned' * * @param size of flat object slot end-aligned backfill */ VMINLINE void setPotentialFlatObjectInstanceBackfill(U_32 size) { if (_isValue) { if (isBackfillTypeEndAligned(size)) { if (0 == getFlatAlignedObjectInstanceBackfillSize()) { setFlatAlignedObjectInstanceBackfill(size); } } else { if (0 == getFlatUnAlignedObjectInstanceBackfillSize()) { setFlatUnAlignedObjectInstanceBackfill(size); } } } } /** * Sets the size of the single backfill. Determines if the backfill * is end-aligned or not. End-aligned backfill gets precedence, once * the first end-aligned backfill is set not other single backfill * can be set. If not non end-aligned backfill will be set (which can * only be set once). * * See 'isBackfillTypeEndAligned' * * @param size of flat single slot end-aligned backfill */ VMINLINE void setPotentialFlatSingleInstanceBackfill(U_32 size) { if (_isValue) { if (isBackfillTypeEndAligned(size)) { if (0 == getFlatAlignedSingleInstanceBackfillSize()) { setFlatAlignedSingleInstanceBackfill(size); } } else { if (0 == getFlatUnAlignedSingleInstanceBackfillSize()) { setFlatUnAlignedSingleInstanceBackfill(size); } } } } /** * Returns the size of the flat object instance bytes minus backfill * * @return size of flat object instance bytes */ VMINLINE U_32 getNonBackfilledFlatInstanceObjectSize(void) const { U_32 nonBackfilledFlatObjectsSize = _totalFlatFieldRefBytes; if (isBackfillSuitableInstanceObjectAvailable() && isMyBackfillSlotAvailable() && (0 == getInstanceSingleCount()) && (_objectCanUseBackfill && (0 == getInstanceObjectCount())) && (0 == getFlatAlignedSingleInstanceBackfillSize()) ) { U_32 backfillSize = getFlatAlignedObjectInstanceBackfillSize(); if (0 == backfillSize) { if (0 == getFlatUnAlignedSingleInstanceBackfillSize()) { backfillSize = getFlatUnAlignedObjectInstanceBackfillSize(); } } nonBackfilledFlatObjectsSize -= backfillSize; } return nonBackfilledFlatObjectsSize; } /** * Returns the size of the flat single instance bytes minus backfill * * @return size of flat single instance bytes */ VMINLINE U_32 getNonBackfilledFlatInstanceSingleSize(void) const { U_32 nonBackfilledFlatSinglesSize = _totalFlatFieldSingleBytes; if (isBackfillSuitableFlatInstanceSingleAvailable() && isMyBackfillSlotAvailable() && (0 == getInstanceSingleCount()) && (_objectCanUseBackfill && (0 == getInstanceObjectCount())) ) { U_32 backfillSize = getFlatAlignedSingleInstanceBackfillSize(); if (0 == backfillSize) { if (0 == getFlatAlignedObjectInstanceBackfillSize()) { backfillSize = getFlatUnAlignedSingleInstanceBackfillSize(); } } nonBackfilledFlatSinglesSize -= backfillSize; } return nonBackfilledFlatSinglesSize; } /** * Returns true if the type requires pre-padding. Pre-padding is * added on -XcompressedRefs and 32bit modes on valuetypes where there * is a field with double (64bit) alignment. These types need pre-padding as * valuetypes do not have lockwords and the double cannot be placed immediately * after a 32bit header. When a type is flattened the pre-padding is ommitted. * * @return true, if the type requires pre-padding */ VMINLINE bool doesClassRequiresPrePadding() const { return _classRequiresPrePadding; } /** * Sets the flag indicating that the type requires pre-padding */ VMINLINE void setClassRequiresPrePadding() { _classRequiresPrePadding = true; } /** * In cases where the backfill is not end-aligned (see isBackfillTypeEndAligned) * padding bytes need to be added after the backfill so a double can be placed immediately after. * * @return if type contains backfill that requires post-padding */ VMINLINE bool isBackFillPostPadded() { return _isBackFillPostPadded; } #endif /* J9VM_OPT_VALHALLA_FLATTENABLE_VALUE_TYPES */ VMINLINE bool isHiddenFieldOffsetResolutionRequired(void) const { return _hiddenFieldOffsetResolutionRequired; } /** * @note This is used for instance fields. * The backfill slot can either be embedded within the superclass, * or it can be the result of padding the superclass. * If there is no embedded backfile (i.e. backfillOffset == -1, then see if there is space available * at the end of the superclass. * @return backfill offset from the first field */ VMINLINE IDATA getMyBackfillOffset(void) const { return _myBackfillOffset; } VMINLINE IDATA getSubclassBackfillOffset(void) const { return _subclassBackfillOffset; } VMINLINE void setSuperclassBackfillOffset(IDATA _superclassBackfillOffset) { this->_superclassBackfillOffset = _superclassBackfillOffset; } VMINLINE IDATA getSuperclassBackfillOffset(void) const { return _superclassBackfillOffset; } VMINLINE bool isInstanceFieldBackfillEligible(void) const { return _instanceFieldBackfillEligible; } VMINLINE bool isContendedClassLayout(void) const { return _useContendedClassLayout; } }; #endif /* OBJECTFIELDINFO_HPP_ */