Path: blob/master/runtime/gc_glue_java/EnvironmentDelegate.hpp
5990 views
1/*******************************************************************************2* Copyright (c) 2017, 2021 IBM Corp. and others3*4* This program and the accompanying materials are made available under5* the terms of the Eclipse Public License 2.0 which accompanies this6* distribution and is available at https://www.eclipse.org/legal/epl-2.0/7* or the Apache License, Version 2.0 which accompanies this distribution and8* is available at https://www.apache.org/licenses/LICENSE-2.0.9*10* This Source Code may also be made available under the following11* Secondary Licenses when the conditions for such availability set12* forth in the Eclipse Public License, v. 2.0 are satisfied: GNU13* General Public License, version 2 with the GNU Classpath14* Exception [1] and GNU General Public License, version 2 with the15* OpenJDK Assembly Exception [2].16*17* [1] https://www.gnu.org/software/classpath/license.html18* [2] http://openjdk.java.net/legal/assembly-exception.html19*20* 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-exception21*******************************************************************************/2223#ifndef ENVIRONMENTDELEGATE_HPP_24#define ENVIRONMENTDELEGATE_HPP_2526#include "objectdescription.h"2728#include "MarkJavaStats.hpp"29#include "ScavengerJavaStats.hpp"30#include "GCExtensionsBase.hpp"31#include "ObjectModel.hpp"3233struct OMR_VMThread;3435typedef struct GCmovedObjectHashCode {36uint32_t originalHashCode;37bool hasBeenMoved;38bool hasBeenHashed;39} GCmovedObjectHashCode;4041class MM_EnvironmentBase;42class MM_OwnableSynchronizerObjectBuffer;43class MM_ReferenceObjectBuffer;44class MM_UnfinalizedObjectBuffer;4546class GC_Environment47{48/* Data members */49private:5051protected:5253public:54MM_MarkJavaStats _markJavaStats;55#if defined(OMR_GC_MODRON_SCAVENGER)56MM_ScavengerJavaStats _scavengerJavaStats;57#endif /* OMR_GC_MODRON_SCAVENGER */58MM_ReferenceObjectBuffer *_referenceObjectBuffer; /**< The thread-specific buffer of recently discovered reference objects */59MM_UnfinalizedObjectBuffer *_unfinalizedObjectBuffer; /**< The thread-specific buffer of recently allocated unfinalized objects */60MM_OwnableSynchronizerObjectBuffer *_ownableSynchronizerObjectBuffer; /**< The thread-specific buffer of recently allocated ownable synchronizer objects */6162struct GCmovedObjectHashCode movedObjectHashCodeCache; /**< Structure to aid on object movement and hashing */6364/* Function members */65private:66protected:67public:68GC_Environment()69:_referenceObjectBuffer(NULL)70,_unfinalizedObjectBuffer(NULL)71,_ownableSynchronizerObjectBuffer(NULL)72{}73};7475class MM_EnvironmentDelegate76{77/* Data members */78private:79MM_EnvironmentBase *_env;80MM_GCExtensionsBase *_extensions;81J9VMThread *_vmThread;82GC_Environment _gcEnv;83protected:84public:8586/* Function members */87private:88protected:89public:90static OMR_VMThread *attachVMThread(OMR_VM *omrVM, const char *threadName, uintptr_t reason);91static void detachVMThread(OMR_VM *omrVM, OMR_VMThread *omrVMThread, uintptr_t reason);9293/**94* Initialize the delegate's internal structures and values.95* @return true if initialization completed, false otherwise96*/97bool initialize(MM_EnvironmentBase *env);9899/**100* Free any internal structures associated to the receiver.101*/102void tearDown();103104GC_Environment * getGCEnvironment() { return &_gcEnv; }105106void flushNonAllocationCaches();107108void setGCMainThread(bool isMainThread);109110/**111* This will be called for every allocated object. Note this is not necessarily done when the object is allocated. You are however112* guaranteed by the start of the next gc, you will be notified for all objects allocated since the last gc.113* hooktool is actually functionality better for this but is probably too heavy-weight for what we want for performant code.114*/115bool objectAllocationNotify(omrobjectptr_t omrObject) { return true; }116117/**118* Acquire shared VM access. Threads must acquire VM access before accessing any OMR internal119* structures such as the heap. Requests for VM access will be blocked if any other thread is120* requesting or has obtained exclusive VM access until exclusive VM access is released.121*122* This implementation is not preemptive. Threads that have obtained shared VM access must123* check frequently whether any other thread is requesting exclusive VM access and release124* shared VM access as quickly as possible in that event.125*/126void acquireVMAccess();127128/**129* Release shared VM access.130*/131void releaseVMAccess();132133/**134* Returns true if a mutator threads entered native code without releasing VM access135*/136bool inNative();137138/**139* Check whether another thread is requesting exclusive VM access. This method must be140* called frequently by all threads that are holding shared VM access if the VM access framework141* is not preemptive. If this method returns true, the calling thread should release shared142* VM access as quickly as possible and reacquire it if necessary.143*144* @return true if another thread is waiting to acquire exclusive VM access145*/146bool isExclusiveAccessRequestWaiting();147148/**149* Acquire exclusive VM access. This method should only be called by the OMR runtime to150* perform stop-the-world operations such as garbage collection. Calling thread will be151* blocked until all other threads holding shared VM access have release VM access.152*/153void acquireExclusiveVMAccess();154155/**156* Release exclusive VM access. If no other thread is waiting for exclusive VM access157* this method will notify all threads waiting for shared VM access to continue and158* acquire shared VM access.159*/160void releaseExclusiveVMAccess();161162uintptr_t relinquishExclusiveVMAccess();163164void assumeExclusiveVMAccess(uintptr_t exclusiveCount);165166void releaseCriticalHeapAccess(uintptr_t *data);167168void reacquireCriticalHeapAccess(uintptr_t data);169170void forceOutOfLineVMAccess();171172/**173* This method is responsible for remembering object information before object is moved. Differently than174* evacuation, we're sliding the object; therefore, we need to remember object's original information175* before object moves and could potentially grow176*177* @param[in] objectPtr points to the object that is about to be moved178* @see postObjectMoveForCompact(omrobjectptr_t)179*/180MMINLINE void181preObjectMoveForCompact(omrobjectptr_t objectPtr)182{183GC_ObjectModel *objectModel = &_extensions->objectModel;184bool hashed = objectModel->hasBeenHashed(objectPtr);185bool moved = objectModel->hasBeenMoved(objectPtr);186187_gcEnv.movedObjectHashCodeCache.hasBeenHashed = hashed;188_gcEnv.movedObjectHashCodeCache.hasBeenMoved = moved;189190if (hashed && !moved) {191/* calculate this BEFORE we (potentially) destroy the object */192_gcEnv.movedObjectHashCodeCache.originalHashCode = computeObjectAddressToHash((J9JavaVM *)_extensions->getOmrVM()->_language_vm, objectPtr);193}194}195196/**197* This method may be called during heap compaction, after the object has been moved to a new location.198* The implementation may apply any information extracted and cached in the calling thread at this point.199* It also updates indexable dataAddr field through fixupDataAddr.200*201* @param[in] destinationObjectPtr points to the object that has just been moved (new location)202* @param[in] sourceObjectPtr points to the old object that has just been moved (old location)203* @see preObjectMoveForCompact(omrobjectptr_t)204*/205MMINLINE void206postObjectMoveForCompact(omrobjectptr_t destinationObjectPtr, omrobjectptr_t sourceObjectPtr)207{208GC_ObjectModel *objectModel = &_extensions->objectModel;209if (_gcEnv.movedObjectHashCodeCache.hasBeenHashed && !_gcEnv.movedObjectHashCodeCache.hasBeenMoved) {210*(uint32_t*)((uintptr_t)destinationObjectPtr + objectModel->getHashcodeOffset(destinationObjectPtr)) = _gcEnv.movedObjectHashCodeCache.originalHashCode;211objectModel->setObjectHasBeenMoved(destinationObjectPtr);212}213214if (_extensions->objectModel.isIndexable(destinationObjectPtr)) {215/* Updates internal field of indexable objects. Every indexable object have an extra field216* that can be used to store any extra information about the indexable object. One use case is217* OpenJ9 where we use this field to point to array data. In this case it will always point to218* the address right after the header, in case of contiguous data it will point to the data219* itself, and in case of discontiguous arraylet it will point to the first arrayiod. How to220* updated dataAddr is up to the target language that must override fixupDataAddr */221_extensions->indexableObjectModel.fixupDataAddr(destinationObjectPtr);222223if (_extensions->isVLHGC()) {224_extensions->indexableObjectModel.fixupInternalLeafPointersAfterCopy((J9IndexableObject *)destinationObjectPtr, (J9IndexableObject *)sourceObjectPtr);225}226}227}228229#if defined (OMR_GC_THREAD_LOCAL_HEAP)230/**231* Disable inline TLH allocates by hiding the real heap top address from232* JIT/Interpreter in realHeapTop and setting HeapTop == heapALloc so TLH233* looks full.234*235*/236void disableInlineTLHAllocate();237238/**239* Re-enable inline TLH allocate by restoring heapTop from realHeapTop240*/241void enableInlineTLHAllocate();242243/**244* Determine if inline TLH allocate is enabled; its enabled if realheapTop is NULL.245* @return TRUE if inline TLH allocates currently enabled for this thread; FALSE otherwise246*/247bool isInlineTLHAllocateEnabled();248249/**250* Set TLH Sampling Top by hiding the real heap top address from251* JIT/Interpreter in realHeapTop and setting HeapTop = (HeapAlloc + size) if size < (HeapTop - HeapAlloc)252* so out of line allocate would happen at TLH Sampling Top.253* If size >= (HeapTop - HeapAlloc) resetTLHSamplingTop()254*255* @param size the number of bytes to next sampling point256*/257void setTLHSamplingTop(uintptr_t size);258259/**260* Restore heapTop from realHeapTop if realHeapTop != NULL261*/262void resetTLHSamplingTop();263264/**265* Retrieve allocation size inside TLH Cache.266* @return (heapAlloc - heapBase)267*/268uintptr_t getAllocatedSizeInsideTLH();269270#endif /* OMR_GC_THREAD_LOCAL_HEAP */271272MM_EnvironmentDelegate()273274275: _env(NULL)276, _extensions(NULL)277, _vmThread(NULL)278{ }279};280281#endif /* ENVIRONMENTDELEGATE_HPP_ */282283284