Path: blob/master/runtime/gc_base/ObjectAccessBarrier.hpp
5985 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_Base25*/2627#if !defined(OBJECTACCESSBARRIER_HPP_)28#define OBJECTACCESSBARRIER_HPP_2930#include "j9.h"31#include "j9cfg.h"32#include "modron.h"3334#include <string.h>3536#include "AtomicOperations.hpp"37#include "GCExtensions.hpp"38#include "Heap.hpp"39#include "ModronAssertions.h"40#include "ObjectModel.hpp"4142/* These macros are temporary during the migration to the new object/indexable43* access barrier. Once the 'real' versions can be included these will be removed44*/45#define J9OAB_MIXEDOBJECT_EA(object, offset, type) (type *)(((U_8 *)(object)) + offset)4647class MM_ObjectAccessBarrier : public MM_BaseVirtual48{49/* data members */50private:51protected:52MM_GCExtensions *_extensions;53MM_Heap *_heap;54#if defined(OMR_GC_COMPRESSED_POINTERS)55#if defined(OMR_GC_FULL_POINTERS)56bool _compressObjectReferences;57#endif /* defined(OMR_GC_FULL_POINTERS) */58UDATA _compressedPointersShift; /**< the number of bits to shift by when converting between the compressed pointers heap and real heap */59#endif /* defined(OMR_GC_COMPRESSED_POINTERS) */60UDATA _referenceLinkOffset; /** Offset within java/lang/ref/Reference of the reference link field */61UDATA _ownableSynchronizerLinkOffset; /** Offset within java/util/concurrent/locks/AbstractOwnableSynchronizer of the ownable synchronizer link field */62public:6364/* member function */65private:66/**67* Find the finalize link field in the specified object.68* @param object[in] the object69* @param clazz[in] the class to read the finalizeLinkOffset from70* @return a pointer to the finalize link field in the object71*/72MMINLINE fj9object_t* getFinalizeLinkAddress(j9object_t object, J9Class *clazz)73{74UDATA fieldOffset = clazz->finalizeLinkOffset;75if (0 == fieldOffset) {76return NULL;77}78return (fj9object_t*)((UDATA)object + fieldOffset);79}8081protected:82virtual bool initialize(MM_EnvironmentBase *env);83virtual void tearDown(MM_EnvironmentBase *env);8485/**86* Find the finalize link field in the specified object.87* @param object[in] the object88* @return a pointer to the finalize link field in the object89*/90MMINLINE fj9object_t* getFinalizeLinkAddress(j9object_t object)91{92J9Class *clazz = J9GC_J9OBJECT_CLAZZ(object, this);93return getFinalizeLinkAddress(object, clazz);94}9596/**97* Effective address of array slot with a given slot index and slot size98* @param array the array for which the calculation is performed99* @param index the index of the slot for which address is returned100* @param elementSize size of the slot in the array101* @return address of the slot with the given index102*/103MMINLINE void *104indexableEffectiveAddress(J9VMThread *vmThread, J9IndexableObject *array, I_32 index, UDATA elementSize)105{106MM_GCExtensions *extensions = MM_GCExtensions::getExtensions(vmThread);107108/* hybrid arraylet */109GC_ArrayletObjectModel::ArrayLayout layout = extensions->indexableObjectModel.getArrayLayout(array);110if (GC_ArrayletObjectModel::InlineContiguous == layout) {111UDATA data = (UDATA)extensions->indexableObjectModel.getDataPointerForContiguous(array);112return (void *)(data + (elementSize * (UDATA)index));113}114115/* discontiguous arraylet */116fj9object_t *arrayoidPointer = extensions->indexableObjectModel.getArrayoidPointer(array);117U_32 slotsPerArrayletLeaf = (U_32)(J9VMTHREAD_JAVAVM(vmThread)->arrayletLeafSize / elementSize);118U_32 arrayletIndex = (U_32)index / slotsPerArrayletLeaf;119U_32 arrayletOffset = (U_32)index % slotsPerArrayletLeaf;120UDATA arrayletLeafBase = 0;121fj9object_t *arrayletLeafSlot = GC_SlotObject::addToSlotAddress(arrayoidPointer, arrayletIndex, compressObjectReferences());122if (compressObjectReferences()) {123arrayletLeafBase = (UDATA)convertPointerFromToken(*(U_32*)arrayletLeafSlot);124} else {125arrayletLeafBase = *(UDATA*)arrayletLeafSlot;126}127return (void *)(arrayletLeafBase + (elementSize * (UDATA)arrayletOffset));128}129130virtual mm_j9object_t readObjectImpl(J9VMThread *vmThread, mm_j9object_t srcObject, fj9object_t *srcAddress, bool isVolatile=false);131virtual mm_j9object_t staticReadObjectImpl(J9VMThread *vmThread, J9Class *clazz, j9object_t *srcAddress, bool isVolatile=false);132virtual mm_j9object_t readObjectFromInternalVMSlotImpl(J9VMThread *vmThread, j9object_t *srcAddress, bool isVolatile=false);133134virtual void *readAddressImpl(J9VMThread *vmThread, mm_j9object_t srcObject, void **srcAddress, bool isVolatile=false);135virtual U_8 readU8Impl(J9VMThread *vmThread, mm_j9object_t srcObject, U_8 *srcAddress, bool isVolatile=false);136virtual I_8 readI8Impl(J9VMThread *vmThread, mm_j9object_t srcObject, I_8 *srcAddress, bool isVolatile=false);137virtual U_16 readU16Impl(J9VMThread *vmThread, mm_j9object_t srcObject, U_16 *srcAddress, bool isVolatile=false);138virtual I_16 readI16Impl(J9VMThread *vmThread, mm_j9object_t srcObject, I_16 *srcAddress, bool isVolatile=false);139virtual U_32 readU32Impl(J9VMThread *vmThread, mm_j9object_t srcObject, U_32 *srcAddress, bool isVolatile=false);140virtual I_32 readI32Impl(J9VMThread *vmThread, mm_j9object_t srcObject, I_32 *srcAddress, bool isVolatile=false);141virtual U_64 readU64Impl(J9VMThread *vmThread, mm_j9object_t srcObject, U_64 *srcAddress, bool isVolatile=false);142virtual I_64 readI64Impl(J9VMThread *vmThread, mm_j9object_t srcObject, I_64 *srcAddress, bool isVolatile=false);143144virtual void storeObjectImpl(J9VMThread *vmThread, mm_j9object_t destObject, fj9object_t *destAddress, mm_j9object_t value, bool isVolatile=false);145virtual void staticStoreObjectImpl(J9VMThread *vmThread, J9Class* clazz, j9object_t *destAddress, mm_j9object_t value, bool isVolatile=false);146virtual void storeObjectToInternalVMSlotImpl(J9VMThread *vmThread, j9object_t *destAddress, mm_j9object_t value, bool isVolatile=false);147148virtual void storeAddressImpl(J9VMThread *vmThread, mm_j9object_t destObject, void **destAddress, void *value, bool isVolatile=false);149virtual void storeU8Impl(J9VMThread *vmThread, mm_j9object_t destObject, U_8 *destAddress, U_8 value, bool isVolatile=false);150virtual void storeI8Impl(J9VMThread *vmThread, mm_j9object_t destObject, I_8 *destAddress, I_8 value, bool isVolatile=false);151virtual void storeU16Impl(J9VMThread *vmThread, mm_j9object_t destObject, U_16 *destAddress, U_16 value, bool isVolatile=false);152virtual void storeI16Impl(J9VMThread *vmThread, mm_j9object_t destObject, I_16 *destAddress, I_16 value, bool isVolatile=false);153virtual void storeU32Impl(J9VMThread *vmThread, mm_j9object_t destObject, U_32 *destAddress, U_32 value, bool isVolatile=false);154virtual void storeI32Impl(J9VMThread *vmThread, mm_j9object_t destObject, I_32 *destAddress, I_32 value, bool isVolatile=false);155virtual void storeU64Impl(J9VMThread *vmThread, mm_j9object_t destObject, U_64 *destAddress, U_64 value, bool isVolatile=false);156virtual void storeI64Impl(J9VMThread *vmThread, mm_j9object_t destObject, I_64 *destAddress, I_64 value, bool isVolatile=false);157158void protectIfVolatileBefore(J9VMThread *vmThread, bool isVolatile, bool isRead, bool isWide);159void protectIfVolatileAfter(J9VMThread *vmThread, bool isVolatile, bool isRead, bool isWide);160void printNativeMethod(J9VMThread* vmThread);161162public:163virtual void kill(MM_EnvironmentBase *env);164165virtual J9Object *mixedObjectReadObject(J9VMThread *vmThread, J9Object *srcObject, UDATA srcOffset, bool isVolatile=false);166virtual void *mixedObjectReadAddress(J9VMThread *vmThread, J9Object *srcObject, UDATA srcOffset, bool isVolatile=false);167virtual U_32 mixedObjectReadU32(J9VMThread *vmThread, J9Object *srcObject, UDATA srcOffset, bool isVolatile=false);168virtual I_32 mixedObjectReadI32(J9VMThread *vmThread, J9Object *srcObject, UDATA srcOffset, bool isVolatile=false);169virtual U_64 mixedObjectReadU64(J9VMThread *vmThread, J9Object *srcObject, UDATA srcOffset, bool isVolatile=false);170virtual I_64 mixedObjectReadI64(J9VMThread *vmThread, J9Object *srcObject, UDATA srcOffset, bool isVolatile=false);171172virtual void mixedObjectStoreObject(J9VMThread *vmThread, J9Object *destObject, UDATA destOffset, J9Object *value, bool isVolatile=false);173virtual void mixedObjectStoreAddress(J9VMThread *vmThread, J9Object *destObject, UDATA destOffset, void *value, bool isVolatile=false);174virtual void mixedObjectStoreU32(J9VMThread *vmThread, J9Object *destObject, UDATA destOffset, U_32 value, bool isVolatile=false);175virtual void mixedObjectStoreI32(J9VMThread *vmThread, J9Object *destObject, UDATA destOffset, I_32 value, bool isVolatile=false);176virtual void mixedObjectStoreU64(J9VMThread *vmThread, J9Object *destObject, UDATA destOffset, U_64 value, bool isVolatile=false);177virtual void mixedObjectStoreI64(J9VMThread *vmThread, J9Object *destObject, UDATA destOffset, I_64 value, bool isVolatile=false);178179virtual J9Object *indexableReadObject(J9VMThread *vmThread, J9IndexableObject *srcObject, I_32 srcIndex, bool isVolatile=false);180virtual void *indexableReadAddress(J9VMThread *vmThread, J9IndexableObject *srcObject, I_32 srcIndex, bool isVolatile=false);181virtual U_8 indexableReadU8(J9VMThread *vmThread, J9IndexableObject *srcObject, I_32 srcIndex, bool isVolatile=false);182virtual I_8 indexableReadI8(J9VMThread *vmThread, J9IndexableObject *srcObject, I_32 srcIndex, bool isVolatile=false);183virtual U_16 indexableReadU16(J9VMThread *vmThread, J9IndexableObject *srcObject, I_32 srcIndex, bool isVolatile=false);184virtual I_16 indexableReadI16(J9VMThread *vmThread, J9IndexableObject *srcObject, I_32 srcIndex, bool isVolatile=false);185virtual U_32 indexableReadU32(J9VMThread *vmThread, J9IndexableObject *srcObject, I_32 srcIndex, bool isVolatile=false);186virtual I_32 indexableReadI32(J9VMThread *vmThread, J9IndexableObject *srcObject, I_32 srcIndex, bool isVolatile=false);187virtual U_64 indexableReadU64(J9VMThread *vmThread, J9IndexableObject *srcObject, I_32 srcIndex, bool isVolatile=false);188virtual I_64 indexableReadI64(J9VMThread *vmThread, J9IndexableObject *srcObject, I_32 srcIndex, bool isVolatile=false);189190virtual void indexableStoreObject(J9VMThread *vmThread, J9IndexableObject *destObject, I_32 destIndex, J9Object *value, bool isVolatile=false);191virtual void indexableStoreAddress(J9VMThread *vmThread, J9IndexableObject *destObject, I_32 destIndex, void *value, bool isVolatile=false);192virtual void indexableStoreU8(J9VMThread *vmThread, J9IndexableObject *destObject, I_32 destIndex, U_8 value, bool isVolatile=false);193virtual void indexableStoreI8(J9VMThread *vmThread, J9IndexableObject *destObject, I_32 destIndex, I_8 value, bool isVolatile=false);194virtual void indexableStoreU16(J9VMThread *vmThread, J9IndexableObject *destObject, I_32 destIndex, U_16 value, bool isVolatile=false);195virtual void indexableStoreI16(J9VMThread *vmThread, J9IndexableObject *destObject, I_32 destIndex, I_16 value, bool isVolatile=false);196virtual void indexableStoreU32(J9VMThread *vmThread, J9IndexableObject *destObject, I_32 destIndex, U_32 value, bool isVolatile=false);197virtual void indexableStoreI32(J9VMThread *vmThread, J9IndexableObject *destObject, I_32 destIndex, I_32 value, bool isVolatile=false);198virtual void indexableStoreU64(J9VMThread *vmThread, J9IndexableObject *destObject, I_32 destIndex, U_64 value, bool isVolatile=false);199virtual void indexableStoreI64(J9VMThread *vmThread, J9IndexableObject *destObject, I_32 destIndex, I_64 value, bool isVolatile=false);200virtual void copyObjectFieldsToFlattenedArrayElement(J9VMThread *vmThread, J9ArrayClass *arrayClazz, j9object_t srcObject, J9IndexableObject *arrayRef, I_32 index);201virtual void copyObjectFieldsFromFlattenedArrayElement(J9VMThread *vmThread, J9ArrayClass *arrayClazz, j9object_t destObject, J9IndexableObject *arrayRef, I_32 index);202203enum {204ARRAY_COPY_SUCCESSFUL = -1,205ARRAY_COPY_NOT_DONE = -2206};207208virtual I_32 doCopyContiguousForward(J9VMThread *vmThread, J9IndexableObject *srcObject, J9IndexableObject *destObject, I_32 srcIndex, I_32 destIndex, I_32 lengthInSlots);209virtual I_32 doCopyContiguousBackward(J9VMThread *vmThread, J9IndexableObject *srcObject, J9IndexableObject *destObject, I_32 srcIndex, I_32 destIndex, I_32 lengthInSlots);210virtual I_32 backwardReferenceArrayCopyIndex(J9VMThread *vmThread, J9IndexableObject *srcObject, J9IndexableObject *destObject, I_32 srcIndex, I_32 destIndex, I_32 lengthInSlots) { return -2; }211virtual I_32 forwardReferenceArrayCopyIndex(J9VMThread *vmThread, J9IndexableObject *srcObject, J9IndexableObject *destObject, I_32 srcIndex, I_32 destIndex, I_32 lengthInSlots) { return -2; }212213virtual J9Object *staticReadObject(J9VMThread *vmThread, J9Class *clazz, J9Object **srcSlot, bool isVolatile=false);214virtual void *staticReadAddress(J9VMThread *vmThread, J9Class *clazz, void **srcSlot, bool isVolatile=false);215virtual U_32 staticReadU32(J9VMThread *vmThread, J9Class *clazz, U_32 *srcSlot, bool isVolatile=false);216virtual I_32 staticReadI32(J9VMThread *vmThread, J9Class *clazz, I_32 *srcSlot, bool isVolatile=false);217virtual U_64 staticReadU64(J9VMThread *vmThread, J9Class *clazz, U_64 *srcSlot, bool isVolatile=false);218virtual I_64 staticReadI64(J9VMThread *vmThread, J9Class *clazz, I_64 *srcSlot, bool isVolatile=false);219220virtual void staticStoreObject(J9VMThread *vmThread, J9Class *clazz, J9Object **destSlot, J9Object *value, bool isVolatile=false);221virtual void staticStoreAddress(J9VMThread *vmThread, J9Class *clazz, void **destSlot, void *value, bool isVolatile=false);222virtual void staticStoreU32(J9VMThread *vmThread, J9Class *clazz, U_32 *destSlot, U_32 value, bool isVolatile=false);223virtual void staticStoreI32(J9VMThread *vmThread, J9Class *clazz, I_32 *destSlot, I_32 value, bool isVolatile=false);224virtual void staticStoreU64(J9VMThread *vmThread, J9Class *clazz, U_64 *destSlot, U_64 value, bool isVolatile=false);225virtual void staticStoreI64(J9VMThread *vmThread, J9Class *clazz, I_64 *destSlot, I_64 value, bool isVolatile=false);226227virtual U_8 *getArrayObjectDataAddress(J9VMThread *vmThread, J9IndexableObject *arrayObject);228virtual j9objectmonitor_t *getLockwordAddress(J9VMThread *vmThread, J9Object *object);229virtual void cloneObject(J9VMThread *vmThread, J9Object *srcObject, J9Object *destObject);230virtual void copyObjectFields(J9VMThread *vmThread, J9Class *valueClass, J9Object *srcObject, UDATA srcOffset, J9Object *destObject, UDATA destOffset);231virtual BOOLEAN structuralCompareFlattenedObjects(J9VMThread *vmThread, J9Class *valueClass, j9object_t lhsObject, j9object_t rhsObject, UDATA startOffset);232virtual void cloneIndexableObject(J9VMThread *vmThread, J9IndexableObject *srcObject, J9IndexableObject *destObject);233virtual J9Object *asConstantPoolObject(J9VMThread *vmThread, J9Object* toConvert, UDATA allocationFlags);234virtual void storeObjectToInternalVMSlot(J9VMThread *vmThread, J9Object** destSlot, J9Object *value);235virtual J9Object *readObjectFromInternalVMSlot(J9VMThread *vmThread, J9Object **srcSlot);236virtual bool compareAndSwapObject(J9VMThread *vmThread, J9Object *destObject, fj9object_t *destAddress, J9Object *compareObject, J9Object *swapObject);237virtual bool staticCompareAndSwapObject(J9VMThread *vmThread, J9Class *destClass, j9object_t *destAddress, J9Object *compareObject, J9Object *swapObject);238virtual bool mixedObjectCompareAndSwapInt(J9VMThread *vmThread, J9Object *destObject, UDATA offset, U_32 compareValue, U_32 swapValue);239virtual bool staticCompareAndSwapInt(J9VMThread *vmThread, J9Class *destClass, U_32 *destAddress, U_32 compareValue, U_32 swapValue);240virtual bool mixedObjectCompareAndSwapLong(J9VMThread *vmThread, J9Object *destObject, UDATA offset, U_64 compareValue, U_64 swapValue);241virtual bool staticCompareAndSwapLong(J9VMThread *vmThread, J9Class *destClass, U_64 *destAddress, U_64 compareValue, U_64 swapValue);242virtual J9Object *compareAndExchangeObject(J9VMThread *vmThread, J9Object *destObject, fj9object_t *destAddress, J9Object *compareObject, J9Object *swapObject);243virtual J9Object *staticCompareAndExchangeObject(J9VMThread *vmThread, J9Class *destClass, j9object_t *destAddress, J9Object *compareObject, J9Object *swapObject);244virtual U_32 mixedObjectCompareAndExchangeInt(J9VMThread *vmThread, J9Object *destObject, UDATA offset, U_32 compareValue, U_32 swapValue);245virtual U_32 staticCompareAndExchangeInt(J9VMThread *vmThread, J9Class *destClass, U_32 *destAddress, U_32 compareValue, U_32 swapValue);246virtual U_64 mixedObjectCompareAndExchangeLong(J9VMThread *vmThread, J9Object *destObject, UDATA offset, U_64 compareValue, U_64 swapValue);247virtual U_64 staticCompareAndExchangeLong(J9VMThread *vmThread, J9Class *destClass, U_64 *destAddress, U_64 compareValue, U_64 swapValue);248249virtual void deleteHeapReference(MM_EnvironmentBase *env, J9Object *object) {}250251virtual bool preObjectStore(J9VMThread *vmThread, J9Object *destObject, fj9object_t *destAddress, J9Object *value, bool isVolatile=false);252virtual bool preObjectStore(J9VMThread *vmThread, J9Object *destClass, J9Object **destAddress, J9Object *value, bool isVolatile=false);253virtual bool preObjectStore(J9VMThread *vmThread, J9Object **destAddress, J9Object *value, bool isVolatile=false);254virtual void postObjectStore(J9VMThread *vmThread, J9Object *destObject, fj9object_t *destAddress, J9Object *value, bool isVolatile=false);255virtual void postObjectStore(J9VMThread *vmThread, J9Class *destClass, J9Object **destAddress, J9Object *value, bool isVolatile=false);256virtual void postObjectStore(J9VMThread *vmThread, J9Object **destAddress, J9Object *value, bool isVolatile=false);257258virtual bool postBatchObjectStore(J9VMThread *vmThread, J9Object *destObject, bool isVolatile=false);259virtual bool postBatchObjectStore(J9VMThread *vmThread, J9Class *destClass, bool isVolatile=false);260261virtual bool preObjectRead(J9VMThread *vmThread, J9Object *srcObject, fj9object_t *srcAddress);262virtual bool preObjectRead(J9VMThread *vmThread, J9Class *srcClass, j9object_t *srcAddress);263virtual bool preWeakRootSlotRead(J9VMThread *vmThread, j9object_t *srcAddress);264virtual bool preWeakRootSlotRead(J9JavaVM *vm, j9object_t *srcAddress);265virtual bool postObjectRead(J9VMThread *vmThread, J9Object *srcObject, fj9object_t *srcAddress);266virtual bool postObjectRead(J9VMThread *vmThread, J9Class *srcClass, J9Object **srcAddress);267268/**269* Return back true if object references are compressed270* @return true, if object references are compressed271*/272MMINLINE bool273compressObjectReferences()274{275return OMR_COMPRESS_OBJECT_REFERENCES(_compressObjectReferences);276}277278/**279* Special barrier for auto-remembering stack-referenced objects. This must be called280* in two cases:281* 1) an object which was allocated directly into old space.282* 2) an object which is being constructed via JNI283*284* @param vmThread[in] the current thread285* @param object[in] the object to be remembered286*/287virtual void288recentlyAllocatedObject(J9VMThread *vmThread, J9Object *object)289{290/* empty default implementation */291};292293/**294* Record that the specified class is stored in the specified ClassLoader.295* There are three cases in which this must be called:296* 1 - when a newly loaded class stored in its defining loader's table297* 2 - when a newly loaded array class is stored in its component class's arrayClass field298* 3 - when a foreign class is stored in another loader's table299*300* @param[in] vmThread the current thread301* @param[in] destClassLoader the referencing ClassLoader302* @param[in] srcClass the referenced class303*/304virtual void305postStoreClassToClassLoader(J9VMThread *vmThread, J9ClassLoader* destClassLoader, J9Class* srcClass)306{307/* Default behaviour is to do nothing. Only collectors which implement JAZZ 18309 require this barrier. */308}309310/**311* Converts token (e.g. compressed pointer value) into real heap pointer.312* @return the heap pointer value.313*314* @note this function is not virtual because it must be callable from out-of-process315*/316MMINLINE mm_j9object_t317convertPointerFromToken(fj9object_t token)318{319mm_j9object_t result = (mm_j9object_t)(uintptr_t)token;320#if defined(OMR_GC_COMPRESSED_POINTERS)321if (compressObjectReferences()) {322result = (mm_j9object_t)((UDATA)token << compressedPointersShift());323}324#endif /* defined(OMR_GC_COMPRESSED_POINTERS) */325return result;326}327328/**329* Converts real heap pointer into token (e.g. compressed pointer value).330* @return the compressed pointer value.331*332* @note this function is not virtual because it must be callable from out-of-process333*/334MMINLINE fj9object_t335convertTokenFromPointer(mm_j9object_t pointer)336{337fj9object_t result = (fj9object_t)(uintptr_t)pointer;338#if defined(OMR_GC_COMPRESSED_POINTERS)339if (compressObjectReferences()) {340result = (fj9object_t)((UDATA)pointer >> compressedPointersShift());341}342#endif /* defined(OMR_GC_COMPRESSED_POINTERS) */343return result;344}345346/**347* Returns the value to shift a pointer by when converting between the compressed pointers heap and real heap348* @return The shift value.349*350* @note this function is not virtual because it must be callable from out-of-process351*352*/353MMINLINE UDATA354compressedPointersShift()355{356UDATA shift = 0;357#if defined(OMR_GC_COMPRESSED_POINTERS)358if (compressObjectReferences()) {359shift = _compressedPointersShift;360}361#endif /* defined(OMR_GC_COMPRESSED_POINTERS) */362return shift;363}364365virtual UDATA compressedPointersShadowHeapBase(J9VMThread *vmThread);366virtual UDATA compressedPointersShadowHeapTop(J9VMThread *vmThread);367virtual void fillArrayOfObjects(J9VMThread *vmThread, J9IndexableObject *destObject, I_32 destIndex, I_32 count, J9Object *value);368369virtual void initializeForNewThread(MM_EnvironmentBase* env) {};370371/**372* Determine the basic hash code for the specified object. This may modify the object. For example, it may373* set the HAS_BEEN_HASHED bit in the object's header. Object must not be NULL.374*375* @param vm[in] the VM376* @param object[in] the object to be hashed377* @return the persistent, basic hash code for the object378*/379I_32 getObjectHashCode(J9JavaVM *vm, J9Object *object);380381/**382* Set the finalize link field of object to value.383* @param object the object to modify384* @param value[in] the value to store into the object's finalizeLink field385*/386void setFinalizeLink(j9object_t object, j9object_t value);387388/**389* Fetch the finalize link field of object.390* @param object[in] the object to read391* @return the value stored in the object's finalizeLink field392*/393MMINLINE j9object_t getFinalizeLink(j9object_t object)394{395fj9object_t* finalizeLink = getFinalizeLinkAddress(object);396GC_SlotObject slot(_extensions->getOmrVM(), finalizeLink);397return slot.readReferenceFromSlot();398}399400/**401* Fetch the finalize link field of object.402* @param object[in] the object to read403* @param clazz[in] the class to read the finalizeLinkOffset from404* @return the value stored in the object's finalizeLink field405*/406MMINLINE j9object_t getFinalizeLink(j9object_t object, J9Class *clazz)407{408fj9object_t* finalizeLink = getFinalizeLinkAddress(object, clazz);409GC_SlotObject slot(_extensions->getOmrVM(), finalizeLink);410return slot.readReferenceFromSlot();411}412413414/**415* Set the reference link field of the specified reference object to value.416* @param object the object to modify417* @param value the value to store into the object's reference link field418*/419void setReferenceLink(j9object_t object, j9object_t value);420421/**422* Fetch the reference link field of the specified reference object.423* @param object the object to read424* @return the value stored in the object's reference link field425*/426j9object_t getReferenceLink(j9object_t object)427{428UDATA linkOffset = _referenceLinkOffset;429fj9object_t *referenceLink = (fj9object_t*)((UDATA)object + linkOffset);430GC_SlotObject slot(_extensions->getOmrVM(), referenceLink);431return slot.readReferenceFromSlot();432}433434/**435* Set the ownableSynchronizerLink link field of the specified reference object to value.436* @param object the object to modify437* @param value the value to store into the object's reference link field438*/439void setOwnableSynchronizerLink(j9object_t object, j9object_t value);440441/**442* Fetch the ownableSynchronizerLink link field of the specified reference object.(for Compact or forwardedObject case)443* @param object the object(moved object -- new location) to read444* @param originalObject(old location, for checking if it is the last item in the list)445* @return the value stored in the object's reference link field446*/447j9object_t getOwnableSynchronizerLink(j9object_t object, j9object_t originalObject)448{449UDATA linkOffset = _ownableSynchronizerLinkOffset;450fj9object_t *ownableSynchronizerLink = (fj9object_t*)((UDATA)object + linkOffset);451GC_SlotObject slot(_extensions->getOmrVM(), ownableSynchronizerLink);452j9object_t next = slot.readReferenceFromSlot();453if (originalObject == next) {454/* reach end of list(last item points to itself), return NULL */455next = NULL;456}457return next;458}459460/**461* Fetch the ownableSynchronizerLink link field of the specified reference object.462* @param object the object to read463* @return the value stored in the object's reference link field464*/465j9object_t getOwnableSynchronizerLink(j9object_t object)466{467UDATA linkOffset = _ownableSynchronizerLinkOffset;468fj9object_t *ownableSynchronizerLink = (fj9object_t*)((UDATA)object + linkOffset);469GC_SlotObject slot(_extensions->getOmrVM(), ownableSynchronizerLink);470j9object_t next = slot.readReferenceFromSlot();471if (object == next) {472/* reach end of list(last item points to itself), return NULL */473next = NULL;474}475return next;476}477478/**479* check if the object in one of OwnableSynchronizerLists480* @param object the object pointer481* @return the value stored in the object's reference link field482* if reference link field == NULL, it means the object isn't in the list483*/484j9object_t isObjectInOwnableSynchronizerList(j9object_t object)485{486UDATA linkOffset = _ownableSynchronizerLinkOffset;487fj9object_t *ownableSynchronizerLink = (fj9object_t*)((UDATA)object + linkOffset);488GC_SlotObject slot(_extensions->getOmrVM(), ownableSynchronizerLink);489return slot.readReferenceFromSlot();490}491492/**493* Implementation of the JNI GetPrimitiveArrayCritical API.494* See the JNI spec for full details.495*496* @param vmThread current J9VMThread (aka JNIEnv)497* @param array a JNI reference to the primitive array498* @param isCopy NULL, or a pointer to a jboolean that will set to JNI_TRUE if a copy is made499* @return a pointer to the array data; this may be a malloc'd copy, or a pointer into the heap500*/501virtual void* jniGetPrimitiveArrayCritical(J9VMThread* vmThread, jarray array, jboolean *isCopy) = 0;502/**503* Implementation of the JNI ReleasePrimitiveArrayCritical API.504* See the JNI spec for full details.505*506* @param vmThread current J9VMThread (aka JNIEnv)507* @param array a JNI reference to the primitive array508* @param elems the pointer returned by GetPrimitiveArrayCritical509* @param mode how to handle the data; only valid for copied data510*/511virtual void jniReleasePrimitiveArrayCritical(J9VMThread* vmThread, jarray array, void * elems, jint mode) = 0;512/**513* Implementation of the JNI GetStringCritical API.514* See the JNI spec for full details.515*516* @param vmThread current J9VMThread (aka JNIEnv)517* @param str a JNI reference to the java/lang/String object518* @param isCopy NULL, or a pointer to a jboolean that will set to JNI_TRUE if a copy is made519* @return a pointer to the character data; this may be a malloc'd copy, or a pointer into the heap520*/521virtual const jchar* jniGetStringCritical(J9VMThread* vmThread, jstring str, jboolean *isCopy) = 0;522/**523* Implementation of the JNI ReleaseStringCritical API.524* See the JNI spec for full details.525*526* @param vmThread current J9VMThread (aka JNIEnv)527* @param array a JNI reference to the java/lang/String object528* @param elems the pointer returned by GetStringCritical529*/530virtual void jniReleaseStringCritical(J9VMThread* vmThread, jstring str, const jchar* elems) = 0;531/**532* Process objects that are forced onto the finalizable list at shutdown.533* Called from FinalizerSupport finalizeForcedUnfinalizedToFinalizable534*535* @param vmThread current J9VMThread (aka JNIEnv)536* @param object object forced onto the finalizable list537*/538virtual void forcedToFinalizableObject(J9VMThread* vmThread, J9Object *object)539{540/* no-op default implementation */541}542543virtual J9Object *referenceGet(J9VMThread *vmThread, J9Object *refObject)544{545return J9VMJAVALANGREFREFERENCE_REFERENT_VM(vmThread->javaVM, refObject);546}547548virtual void referenceReprocess(J9VMThread *vmThread, J9Object *refObject)549{550/* no-op default implementation */551}552553#if defined(J9VM_GC_DYNAMIC_CLASS_UNLOADING)554/**555* Check is class alive556* Required to prevent visibility of dead classes in incremental GC policies557* The real implementation done for Real Time GC558* @param javaVM pointer to J9JavaVM559* @param classPtr class to check560* @return true if class is alive561*/562virtual bool checkClassLive(J9JavaVM *javaVM, J9Class *classPtr)563{564return true;565}566#endif /* defined(J9VM_GC_DYNAMIC_CLASS_UNLOADING) */567568virtual bool checkStringConstantsLive(J9JavaVM *javaVM, j9object_t stringOne, j9object_t stringTwo)569{570return true;571}572573virtual bool checkStringConstantLive(J9JavaVM *javaVM, j9object_t string)574{575return true;576}577578virtual void jniDeleteGlobalReference(J9VMThread *vmThread, J9Object *reference)579{580/* no-op default implementation */581}582583MM_ObjectAccessBarrier(MM_EnvironmentBase *env) : MM_BaseVirtual()584, _extensions(NULL)585, _heap(NULL)586#if defined(OMR_GC_COMPRESSED_POINTERS)587#if defined(OMR_GC_FULL_POINTERS)588, _compressObjectReferences(false)589#endif /* defined(OMR_GC_FULL_POINTERS) */590, _compressedPointersShift(0)591#endif /* defined(OMR_GC_COMPRESSED_POINTERS) */592, _referenceLinkOffset(UDATA_MAX)593, _ownableSynchronizerLinkOffset(UDATA_MAX)594{595_typeId = __FUNCTION__;596}597598friend class MM_ScavengerDelegate;599};600601#endif /* OBJECTACCESSBARRIER_HPP_ */602603604