Path: blob/master/runtime/gc_vlhgc/CopyForwardScheme.hpp
5986 views
/*******************************************************************************1* Copyright (c) 1991, 2022 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_Modron_Standard25*/2627#if !defined(COPYFORWARDSCHEME_HPP_)28#define COPYFORWARDSCHEME_HPP_2930#include "j9.h"31#include "j9cfg.h"32#include "modronopt.h"3334#include "BaseNonVirtual.hpp"3536#include "CopyScanCacheListVLHGC.hpp"37#include "EnvironmentVLHGC.hpp"38#include "GCExtensions.hpp"39#include "ModronTypes.hpp"4041class GC_SlotObject;42class MM_AllocationContextTarok;43class MM_CardCleaner;44class MM_CopyForwardCompactGroup;45class MM_CopyForwardGMPCardCleaner;46class MM_CopyForwardNoGMPCardCleaner;47class MM_CopyForwardVerifyScanner;48class MM_ForwardedHeader;49class MM_ParallelDispatcher;50class MM_HeapRegionManager;51class MM_HeapRegionDescriptorVLHGC;52class MM_InterRegionRememberedSet;53class MM_MarkMap;54class MM_MemoryPoolAddressOrderedList;55class MM_ReferenceStats;5657/* Forward declaration of classes defined within the cpp */58class MM_CopyForwardSchemeAbortScanner;59class MM_CopyForwardSchemeRootScanner;60class MM_CopyForwardSchemeRootClearer;61class MM_CopyForwardSchemeTask;6263/**64* Copy Forward scheme used for highly mobile partial collection operations.65* @ingroup GC_Modron_Standard66*/67class MM_CopyForwardScheme : public MM_BaseNonVirtual68{69private:70J9JavaVM *_javaVM;71MM_GCExtensions *_extensions;7273enum ScanReason {74SCAN_REASON_NONE = 0, /**< Indicates there is no item for scan */75SCAN_REASON_PACKET = 1, /**< Indicates the object being scanned came from a work packet */76SCAN_REASON_COPYSCANCACHE = 2,77SCAN_REASON_DIRTY_CARD = 3, /**< Indicates the object being scanned was found in a dirty card */78SCAN_REASON_OVERFLOWED_REGION = 4, /**< Indicates the object being scanned was in an overflowed region */79};8081MM_HeapRegionManager *_regionManager; /**< Region manager for the heap instance */82MM_InterRegionRememberedSet *_interRegionRememberedSet; /**< A cached pointer to the inter-region reference tracking mechanism */8384class MM_ReservedRegionListHeader {85/* Fields */86public:87enum { MAX_SUBLISTS = 8 }; /* arbitrary value for maximum split */88struct Sublist {89MM_HeapRegionDescriptorVLHGC *_head; /**< Head of the reserved regions list */90MM_LightweightNonReentrantLock _lock; /**< Lock for reserved regions list */91volatile UDATA _cacheAcquireCount; /**< The number of times threads acquired caches from this list */92UDATA _cacheAcquireBytes; /**< The number of bytes acquired for caches from this list */93} _sublists[MAX_SUBLISTS];94UDATA _evacuateRegionCount; /**< The number of evacuate regions in this group */95UDATA _maxSublistCount; /**< The highest value _sublistCount is permitted to reach in this group */96volatile UDATA _sublistCount; /**< The number of active sublists in this list */97MM_HeapRegionDescriptorVLHGC *_freeMemoryCandidates; /**< A linked list of regions in this compact group which have free memory */98MM_LightweightNonReentrantLock _freeMemoryCandidatesLock; /**< Lock to protect _freeMemoryCandidates */99UDATA _freeMemoryCandidateCount; /**< The number of regions in the _freeMemoryCandidates list */ protected:100private:101/* Methods */102public:103protected:104private:105};106MM_ReservedRegionListHeader *_reservedRegionList; /**< List of reserved regions during a copy forward operation */107UDATA _compactGroupMaxCount; /**< The maximum number of compact groups that exist in the system */108109UDATA _phantomReferenceRegionsToProcess; /**< A count, for verification purposes, of the number of regions to be processed for phantom references */110111UDATA _minCacheSize; /**< Minimum size in bytes that will be returned as a general purpose cache area */112UDATA _maxCacheSize; /**< Maximum size in bytes that will be requested for a general purpose cache area */113114MM_ParallelDispatcher *_dispatcher;115116MM_CopyScanCacheListVLHGC _cacheFreeList; /**< Caches which are not bound to heap memory and available to be populated */117MM_CopyScanCacheListVLHGC *_cacheScanLists; /**< An array of per-node caches which contains objects still to be scanned (1+node_count elements in array)*/118UDATA _scanCacheListSize; /**< The number of entries in _cacheScanLists */119volatile UDATA _scanCacheWaitCount; /**< The number of threads currently sleeping on _scanCacheMonitor, awaiting scan cache work */120omrthread_monitor_t _scanCacheMonitor; /**< Used when waiting on work on any of the _cacheScanLists */121122volatile UDATA* _workQueueWaitCountPtr; /**< The number of threads currently sleeping on *_workQueueMonitorPtr, awaiting scan cache work or work from packets*/123omrthread_monitor_t* _workQueueMonitorPtr; /**< Used when waiting on work on any of the _cacheScanLists or workPackets*/124125volatile UDATA _doneIndex; /**< Incremented when _cacheScanLists are empty and we want all threads to fall out of *_workQueueMonitorPtr */126127MM_MarkMap *_markMap; /**< Cached reference to the previous mark map */128129void *_heapBase; /**< Cached base pointer of heap */130void *_heapTop; /**< Cached top pointer of heap */131132volatile bool _abortFlag; /**< Flag indicating whether the current copy forward cycle should be aborted due to insufficient heap to complete */133bool _abortInProgress; /**< Flag indicating that the copy forward mechanism is now operating in abort mode, which is attempting to secure integrity of the heap to continue execution */134135UDATA _regionCountCannotBeEvacuated; /**<The number of regions, which can not be copyforward in collectionSet */136UDATA _regionCountReservedNonEvacuated; /** the number of regions need to set Mark only in order to try to avoid abort case */137138UDATA _cacheLineAlignment; /**< The number of bytes per cache line which is used to determine which boundaries in memory represent the beginning of a cache line */139140bool _clearableProcessingStarted; /**< Flag indicating that clearable processing had been started during this cycle (used for abort purposes) */141142#if defined(J9VM_GC_DYNAMIC_CLASS_UNLOADING)143bool _dynamicClassUnloadingEnabled; /**< Local cached value from cycle state for performance reasons (TODO: Reevaluate) */144#endif /* J9VM_GC_DYNAMIC_CLASS_UNLOADING */145bool _collectStringConstantsEnabled; /**< Local cached value which determines whether string constants are roots */146147bool _tracingEnabled; /**< Temporary variable to enable tracing of activity */148MM_AllocationContextTarok *_commonContext; /**< The common context is used as an opaque token to represent cases where we don't want to relocate objects during NUMA-aware copy-forward since relocating to the common context is currently disabled */149MM_CopyForwardCompactGroup *_compactGroupBlock; /**< A block of MM_CopyForwardCompactGroup structs which is subdivided among the GC threads */150UDATA _arraySplitSize; /**< The number of elements to be scanned in each array chunk (this determines the degree of parallelization) */151152UDATA _regionSublistContentionThreshold /**< The number of threads which must be contending on the same region sublist for us to decide that another sublist should be created to alleviate contention (reset at the beginning of every CopyForward task) */;153154volatile bool _failedToExpand; /**< Record if we've failed to expand in this collection already, in order to avoid repeated expansion attempts */155bool _shouldScanFinalizableObjects; /**< Set to true at the beginning of a collection if there are any pending finalizable objects */156const UDATA _objectAlignmentInBytes; /**< Run-time objects alignment in bytes */157158UDATA *_compressedSurvivorTable; /**< start address of compressed survivor table (1 bit presents CARD_SIZE of Heap) */159160protected:161public:162private:163164/* Temporary verification functions */165void verifyDumpObjectDetails(MM_EnvironmentVLHGC *env, const char *title, J9Object *object);166void verifyCopyForwardResult(MM_EnvironmentVLHGC *env);167bool verifyIsPointerInSurvivor(MM_EnvironmentVLHGC *env, J9Object *object);168bool verifyIsPointerInEvacute(MM_EnvironmentVLHGC *env, J9Object *object);169void verifyObject(MM_EnvironmentVLHGC *env, J9Object *objectPtr);170void verifyMixedObjectSlots(MM_EnvironmentVLHGC *env, J9Object *objectPtr);171void verifyReferenceObjectSlots(MM_EnvironmentVLHGC *env, J9Object *objectPtr);172void verifyPointerArrayObjectSlots(MM_EnvironmentVLHGC *env, J9Object *objectPtr);173void verifyClassObjectSlots(MM_EnvironmentVLHGC *env, J9Object *classObject);174void verifyClassLoaderObjectSlots(MM_EnvironmentVLHGC *env, J9Object *classLoaderObject);175void verifyExternalState(MM_EnvironmentVLHGC *env);176friend class MM_CopyForwardVerifyScanner;177178/**179* Called to retire a copy cache once a thread no longer wants to use it as a copy destination.180* @param env[in] A GC thread181* @param compactGroup The index of the compact group whose thread-local copy cache should be deleted182* @return the copy cache which was affected183*/184MM_CopyScanCacheVLHGC * stopCopyingIntoCache(MM_EnvironmentVLHGC *env, UDATA compactGroup);185186/*187* Called to update a region's projected live bytes with the bytes copied by the copy scan cache.188* @param env[in] A GC thread189* @param cache[in] The copy cache to update a region's live bytes from190*/191void updateProjectedLiveBytesFromCopyScanCache(MM_EnvironmentVLHGC *env, MM_CopyScanCacheVLHGC *cache);192193/**194* Discard any remaining memory in the specified copy cache, returning it to the pool if possible, and updating195* memory statistics. The implementation will attempt to return any unused portion of the cache to the owning pool196* if possible (and will internally lock to corresponding region list to ensure that the allocation pointer can be197* updated safely). The copy cache flag is unset. Additionally, the top of the cache will be updated to reflect198* that no further allocation is possible if the excess at the top of the cache was successfully returned to the199* pool.200* @param env[in] A GC thread201* @param cache[in] The copy cache to retire202* @param cacheLock[in] The lock associated with the cache's owning list203* @param wastedMemory[in] The number of bytes of memory which couldn't be used in the allocated portion of the copy cache and should be considered free memory when flushed back to the pool204*/205void discardRemainingCache(MM_EnvironmentVLHGC *env, MM_CopyScanCacheVLHGC *cache, MM_LightweightNonReentrantLock *cacheLock, UDATA wastedMemory);206207/**208* Determine whether the object pointer is found within the heap proper.209* @return Boolean indicating if the object pointer is within the heap boundaries.210*/211MMINLINE bool isHeapObject(J9Object* objectPtr)212{213return ((_heapBase <= (U_8 *)objectPtr) && (_heapTop > (U_8 *)objectPtr));214}215216/**217* Determine whether the object is live relying on survivor/evacuate region flags and mark map. null object is considered marked.218* @return Boolean true if object is live219*/220bool isLiveObject(J9Object *objectPtr);221222/**223* Determine whether string constants should be treated as clearable.224* @return Boolean indicating if strings constants are clearable.225*/226MMINLINE bool isCollectStringConstantsEnabled() { return _collectStringConstantsEnabled; };227228#if defined(J9VM_GC_DYNAMIC_CLASS_UNLOADING)229/**230* Determine whether class unloading is enabled this collection cycle.231* @return Boolean indicating if class unloading is enabled this cycle.232*/233MMINLINE bool isDynamicClassUnloadingEnabled() { return _dynamicClassUnloadingEnabled; };234#endif /* J9VM_GC_DYNAMIC_CLASS_UNLOADING */235236/**237* Determine whether the copy forward abort flag is raised or not.238* @return boolean indicating the start of the copy forward abort flag.239*/240MMINLINE bool abortFlagRaised() { return _abortFlag; }241242/**243* Clear the abort copy forward flag.244*/245MMINLINE void clearAbortFlag() { _abortFlag = false; }246247/**248* Raise the abort copy forward flag.249* @param env GC thread.250*/251MMINLINE void raiseAbortFlag(MM_EnvironmentVLHGC *env);252253/**254* Reinitializes the cache with the given base address, top address, as a copy cache. Also updates the mark map cache values in the env's255* CopyForwardCompactGroup for the given cache.256* @param env[in] The thread taking ownership of the cache257* @param cache[in] cache to be reinitialized258* @param base[in] base address of cache259* @param top[in] top address of cache260* @param compactGroup the compact group to which the cache belongs261*/262MMINLINE void reinitCache(MM_EnvironmentVLHGC *env, MM_CopyScanCacheVLHGC *cache, void *base, void *top, UDATA compactGroup);263264/**265* Reinitializes the cache with the array and next scan index as an array split cache.266* @param env[in] The thread taking ownership of the cache267* @param cache[in] cache to be reinitialized268* @param array[in] The array to scan269* @param nextIndex[in] The next index in the array to scan270*/271MMINLINE void reinitArraySplitCache(MM_EnvironmentVLHGC *env, MM_CopyScanCacheVLHGC *cache, J9IndexableObject *array, UDATA nextIndex);272273MM_CopyScanCacheVLHGC *getFreeCache(MM_EnvironmentVLHGC *env);274/**275* Adds the given newCacheEntry to the free cache list.276* @note The implementation will lock the list prior to modification.277* @param env current GC thread.278* @param newCacheEntry[in] The entry to add to cacheList279*/280void addCacheEntryToFreeCacheList(MM_EnvironmentVLHGC *env, MM_CopyScanCacheVLHGC *newCacheEntry);281/**282* Adds the given newCacheEntry to the scan cache list and will notify any waiting threads if the list was empty prior to adding newCacheEntry.283* @note The implementation will lock the list prior to modification.284* @param env current GC thread.285* @param newCacheEntry[in] The entry to add to cacheList286*/287void addCacheEntryToScanCacheListAndNotify(MM_EnvironmentVLHGC *env, MM_CopyScanCacheVLHGC *newCacheEntry);288289void flushCache(MM_EnvironmentVLHGC *env, MM_CopyScanCacheVLHGC *cache);290bool clearCache(MM_EnvironmentVLHGC *env, MM_CopyScanCacheVLHGC *cache);291292/**293* add OwnableSynchronizerObject in the buffer if reason == SCAN_REASON_COPYSCANCACHE || SCAN_REASON_PACKET294* and call scanMixedObjectSlots().295*296* @param env current GC thread.297* @param reservingContext[in] The context to which we would prefer to copy any objects discovered in this method298* @param objectPtr current object being scanned.299* @param reason to scan (dirty card, packet, scan cache, overflow)300*/301MMINLINE void scanOwnableSynchronizerObjectSlots(MM_EnvironmentVLHGC *env, MM_AllocationContextTarok *reservingContext, J9Object *objectPtr, ScanReason reason);302303/**304* Called whenever a ownable synchronizer object is scaned during CopyForwardScheme. Places the object on the thread-specific buffer of gc work thread.305* @param env -- current thread environment306* @param object -- The object of type or subclass of java.util.concurrent.locks.AbstractOwnableSynchronizer.307*/308MMINLINE void addOwnableSynchronizerObjectInList(MM_EnvironmentVLHGC *env, j9object_t object);309310/**311* Scan the slots of a mixed object.312* Copy and forward all relevant slots values found in the object.313* @param env current GC thread.314* @param reservingContext[in] The context to which we would prefer to copy any objects discovered in this method315* @param objectPtr current object being scanned.316* @param reason to scan (dirty card, packet, scan cache, overflow)317*/318void scanMixedObjectSlots(MM_EnvironmentVLHGC *env, MM_AllocationContextTarok *reservingContext, J9Object *objectPtr, ScanReason reason);319/**320* Scan the slots of a reference mixed object.321* Copy and forward all relevant slots values found in the object.322* @param env current GC thread.323* @param reservingContext[in] The context to which we would prefer to copy any objects discovered in this method324* @param objectPtr current object being scanned.325* @param reason to scan (dirty card, packet, scan cache, overflow) *326*/327void scanReferenceObjectSlots(MM_EnvironmentVLHGC *env, MM_AllocationContextTarok *reservingContext, J9Object *objectPtr, ScanReason reason);328329/**330* Called by the root scanner to scan all WeakReference objects discovered by the mark phase,331* clearing and enqueuing them if necessary.332* @param env[in] the current thread333*/334void scanWeakReferenceObjects(MM_EnvironmentVLHGC *env);335336/**337* Called by the root scanner to scan all SoftReference objects discovered by the mark phase,338* clearing and enqueuing them if necessary.339* @param env[in] the current thread340*/341void scanSoftReferenceObjects(MM_EnvironmentVLHGC *env);342343/**344* Called by the root scanner to scan all PhantomReference objects discovered by the mark phase,345* clearing and enqueuing them if necessary.346* @param env[in] the current thread347*/348void scanPhantomReferenceObjects(MM_EnvironmentVLHGC *env);349350/**351* Set region as survivor. Also set the special state if region was created by phantom reference processing.352* @param env[in] the current thread353* @param region[in] region to set as survivor354* @param freshSurvivor[in] if true, it is survivor region from free region355*/356void setRegionAsSurvivor(MM_EnvironmentVLHGC* env, MM_HeapRegionDescriptorVLHGC *region, bool freshSurvivor);357358/**359* Process the list of reference objects recorded in the specified list.360* References with unmarked referents are cleared and optionally enqueued.361* SoftReferences have their ages incremented.362* @param env[in] the current thread363* @param region[in] the region all the objects in the list belong to364* @param headOfList[in] the first object in the linked list365* @param referenceStats copy forward stats substructure to be updated366*/367void processReferenceList(MM_EnvironmentVLHGC *env, MM_HeapRegionDescriptorVLHGC* region, J9Object* headOfList, MM_ReferenceStats *referenceStats);368369/**370* Walk the list of reference objects recorded in the specified list, changing them to the REMEMBERED state.371* @param env[in] the current thread372* @param headOfList[in] the first object in the linked list373*/374void rememberReferenceList(MM_EnvironmentVLHGC *env, J9Object* headOfList);375376/**377* Walk all regions in the evacuate set in parallel, remembering any objects on their reference378* lists so that they may be restored at the end of the PGC.379* @param env[in] the current thread380*/381void rememberReferenceListsFromExternalCycle(MM_EnvironmentVLHGC *env);382383/**384* Call rememberReferenceList() for each of the weak, soft and phantom lists in referenceObjectList, then reset them.385* @param env[in] the current thread386* @param region[in] region which lists to remember and reset387*/388void rememberAndResetReferenceLists(MM_EnvironmentVLHGC *env, MM_HeapRegionDescriptorVLHGC *region);389390/**391* Partially scan the slots of a pointer array object.392* This is only called during abort phase (workstack driven). Otherwise, scanPointerArrayObjectSlotsSplit() is used.393* Create a new packet work item to allow other threads to complete scanning of the array while this scan proceeds.394* @param env current GC thread.395* @param reservingContext[in] The context to which we would prefer to copy any objects discovered in this method396* @param arrayPtr current array being scanned.397* @param reason to scan (dirty card, packet, scan cache, overflow)398*/399void scanPointerArrayObjectSlots(MM_EnvironmentVLHGC *env, MM_AllocationContextTarok *reservingContext, J9IndexableObject *arrayPtr, ScanReason reason);400401/**402* Partially scan the slots of a pointer array object.403* Copy and forward all relevant slots values found in the object.404* Create a new scan cache to allow other threads to complete scanning of the array while this scan proceeds.405* @param env current GC thread.406* @param reservingContext[in] The context to which we would prefer to copy any objects discovered in this method407* @param arrayPtr current array being scanned.408* @param startIndex the index to start from409* @param currentSplitUnitOnly[in] do only current array split work unit; do not push the rest of array on the work stack410* @return number of slots scanned411*/412UDATA scanPointerArrayObjectSlotsSplit(MM_EnvironmentVLHGC *env, MM_AllocationContextTarok *reservingContext, J9IndexableObject *arrayPtr, UDATA startIndex, bool currentSplitUnitOnly = false);413414/**415* For the given object and current starting index, determine the number of slots being scanned now, and create a work unit for the rest of the array.416* Works for both copy-scan cache and workstack driven phases.417* @param env[in] the current thread418* @param arrayPtr[in] current array object being scanned.419* @param startIndex[in] starting index for the current split scan420* @param currentSplitUnitOnly[in] do only current array split work unit; do not push the rest of array on the work stack*421* @return the number of the slots to be scanned for the current split422*/423UDATA createNextSplitArrayWorkUnit(MM_EnvironmentVLHGC *env, J9IndexableObject *arrayPtr, UDATA startIndex, bool currentSplitUnitOnly = false);424425/**426* Scan the slots of a java.lang.Class object.427* Copy and forward all relevant slots values found in the object, as well428* as those found in the backing J9Class structure.429* @param env current GC thread.430* @param reservingContext[in] The context to which we would prefer to copy any objects discovered in this method431* @param objectPtr current object being scanned.432* @param reason to scan (dirty card, packet, scan cache, overflow)433*/434void scanClassObjectSlots(MM_EnvironmentVLHGC *env, MM_AllocationContextTarok *reservingContext, J9Object *classObject, ScanReason reason = SCAN_REASON_COPYSCANCACHE);435/**436* Scan the slots of a java.lang.ClassLoader object.437* Copy and forward all relevant slots values found in the object, as well438* as those found in the backing J9ClassLoader structure.439* @param env current GC thread.440* @param reservingContext[in] The context to which we would prefer to copy any objects discovered in this method441* @param objectPtr current object being scanned.442* @param reason to scan (dirty card, packet, scan cache, overflow)443*/444void scanClassLoaderObjectSlots(MM_EnvironmentVLHGC *env, MM_AllocationContextTarok *reservingContext, J9Object *classLoaderObject, ScanReason reason = SCAN_REASON_COPYSCANCACHE);445446/**447* Determine whether the object is in evacuate memory or not.448* @param objectPtr[in] Object pointer whose properties are being examined.449* @return true if the object is found in evacuate memory, false otherwise.450*/451MMINLINE bool isObjectInEvacuateMemory(J9Object *objectPtr);452MMINLINE bool isObjectInEvacuateMemoryNoCheck(J9Object *objectPtr);453454/**455* Determine whether the object is in survivor memory or not.456* @param objectPtr[in] Object pointer whose properties are being examined.457* @return true if the object is found in survivor memory, false otherwise.458*/459MMINLINE bool isObjectInSurvivorMemory(J9Object *objectPtr);460461/**462* Determine whether the object is in evacuate/survivor memory or not.463* @param objectPtr[in] Object pointer whose properties are being examined.464* @return true if the object is found in evacuate/survivor memory, false otherwise.465*/466MMINLINE bool isObjectInNurseryMemory(J9Object *objectPtr);467468/**469* Remove any remaining regions from the reserved allocation list.470* @param env GC thread.471*/472void clearReservedRegionLists(MM_EnvironmentVLHGC *env);473474/**475* Acquire an empty region for use as a survivor area during copy and forward.476* @param env GC thread.477* @param regionList Internally managed region list to which the region should be assigned to.478* @param compactGroup Compact group for acquired region479* @return the newly acquired region or NULL if no region was available480*/481MM_HeapRegionDescriptorVLHGC *acquireEmptyRegion(MM_EnvironmentVLHGC *env, MM_ReservedRegionListHeader::Sublist *regionList, UDATA compactGroup);482483/**484* Inserts newRegion into the given regionList. The implementation assumes that the calling thread can modify regionList without locking485* it so the callsite either needs to have locked the list or be single-threaded.486* @param env[in] The GC thread487* @param regionList[in] The region list to which the implementation will add newRegion (call site must ensure that no other thread is able to view this until the method returns)488* @param newRegion[in] The region which the implementation must add to regionList (the implementation assumes that newRegion is not already in a region list)489*/490void insertRegionIntoLockedList(MM_EnvironmentVLHGC *env, MM_ReservedRegionListHeader::Sublist *regionList, MM_HeapRegionDescriptorVLHGC *newRegion);491492/**493* Release a region as it is deemed to be full and no longer useful.494* @param env GC thread.495* @param regionList Internally managed region list from which the region should be removed from.496* @param region The region to release.497*/498void releaseRegion(MM_EnvironmentVLHGC *env, MM_ReservedRegionListHeader::Sublist *regionList, MM_HeapRegionDescriptorVLHGC *region);499500/**501* Insert the specified free memory candidate into the candidate list. The implementation assumes that the calling thread can modify502* regionList without locking it so the callsite either needs to have locked the list or be single-threaded.503* @param env[in] The GC thread504* @param regionList[in] The region list to which Region should be added as a candidate505* @param region[in] The region to add506*/507void insertFreeMemoryCandidate(MM_EnvironmentVLHGC* env, MM_ReservedRegionListHeader* regionList, MM_HeapRegionDescriptorVLHGC *region);508509/**510* Remove the specified free memory candidate from the candidate list. The implementation assumes that the calling thread can modify511* regionList without locking it so the callsite either needs to have locked the list or be single-threaded.512* @param env[in] The GC thread513* @param regionList[in] The region list which Region belongs to514* @param region[in] The region to remove515*/516void removeFreeMemoryCandidate(MM_EnvironmentVLHGC* env, MM_ReservedRegionListHeader* regionList, MM_HeapRegionDescriptorVLHGC *region);517518/**519* Reserve memory for an object to be copied to survivor space.520* @param env[in] GC thread.521* @param compactGroup The compact group number that the object should be associated with.522* @param objectSize Size in bytes to be reserved (precisely, no more or less) for the object to be copied.523* @param listLock[out] Returns the lock associated with the returned memory524* @return a pointer to the storage reserved for allocation, or NULL on failure.525*/526void *reserveMemoryForObject(MM_EnvironmentVLHGC *env, uintptr_t compactGroup, uintptr_t objectSize, MM_LightweightNonReentrantLock** listLock);527528/**529* Reserve memory for a general cache to be used as the copy destination of a survivor space.530* @param env[in] GC thread.531* @param compactGroup The compact group number that the cache should be associated with.532* @param maxCacheSize The max (give or take) size of the cache being requested.533* @param addrBase[out] Location to store the base address of the cache that is acquired.534* @param addrTop[out] local to store the top address of the cache that is acquired.535* @param listLock[out] Returns the lock associated with the returned memory536* @return true if the cache was allocated, false otherwise.537*/538bool reserveMemoryForCache(MM_EnvironmentVLHGC *env, uintptr_t compactGroup, uintptr_t maxCacheSize, void **addrBase, void **addrTop, MM_LightweightNonReentrantLock** listLock);539540/**541* Creates a new chunk of scan caches by using heap memory and attaches them to the free cache list.542* @param env[in] A GC thread543* @return A new cache entry if the allocation of scan caches succeeded, NULL otherwise544*/545MM_CopyScanCacheVLHGC * createScanCacheForOverflowInHeap(MM_EnvironmentVLHGC *env);546547/**548* Reserve the specified number of bytes to accommodate an object copy.549* @param env The GC thread requesting the heap memory to be allocated.550* @param objectToEvacuate Object being copied.551* @param reservingContext[in] The context to which we would prefer to copy any objects discovered in this method552* @param objectReserveSizeInBytes Amount of bytes to be reserved (can be greater than the original object size) for copying.553* @return a CopyScanCache which contains the reserved memory or NULL if the reserve was not successful.554*/555MMINLINE MM_CopyScanCacheVLHGC *reserveMemoryForCopy(MM_EnvironmentVLHGC *env, J9Object *objectToEvacuate, MM_AllocationContextTarok *reservingContext, uintptr_t objectReserveSizeInBytes);556557void flushCaches(MM_CopyScanCacheVLHGC *cache);558559/**560* Called at the end of the copy forward operation to flush any remaining data from copy caches and return them to the free list.561* @param env[in] the thread whose copy caches should be flushed562*/563void addCopyCachesToFreeList(MM_EnvironmentVLHGC *env);564565J9Object *updateForwardedPointer(J9Object *objectPtr);566567/**568* Checks to see if there is any scan work in the given list.569* @param scanCacheList[in] The list to check570* @return True if there is work available in the given list571*/572bool isScanCacheWorkAvailable(MM_CopyScanCacheListVLHGC *scanCacheList);573/**574* Checks to see if there is any scan work in any of the lists.575* @return True if any scan lists contain work576*/577bool isAnyScanCacheWorkAvailable();578579/**580* Checks to see if there is any scan work in any of scanCacheLists or workPackets581* it is only for CopyForwardHybrid mode582* @return True if there is any scan work583*/584bool isAnyScanWorkAvailable(MM_EnvironmentVLHGC *env);585586/**587* Return the next available survivor (destination) copy scan cache that has work available for scanning.588* @param env GC thread.589* @return a copy scan cache to be scanned, or NULL if none are available.590*/591MM_CopyScanCacheVLHGC *getSurvivorCacheForScan(MM_EnvironmentVLHGC *env);592593/**594* Tries to find next scan work from both scanCache and workPackets595* return SCAN_REASON_NONE if there is no scan work596* @param env[in] The GC thread597* @param preferredNumaNode[in] The NUMA node number where the caller would prefer to find a scan cache598* @return possible return value(SCAN_REASON_NONE, SCAN_REASON_COPYSCANCACHE, SCAN_REASON_PACKET)599*/600ScanReason getNextWorkUnit(MM_EnvironmentVLHGC *env, UDATA preferredNumaNode);601602/**603* @param env[in] The GC thread604* @param preferredNumaNode[in] The NUMA node number where the caller would prefer to find a scan cache605* @return possible return value(SCAN_REASON_NONE, SCAN_REASON_COPYSCANCACHE, SCAN_REASON_PACKET)606*/607ScanReason getNextWorkUnitNoWait(MM_EnvironmentVLHGC *env, UDATA preferredNumaNode);608609/**610* Tries to find a scan cache from the specified NUMA node or return SCAN_REASON_NONE if there was no work available on that node611* @return possible return value(SCAN_REASON_NONE, SCAN_REASON_COPYSCANCACHE)612*/613ScanReason getNextWorkUnitOnNode(MM_EnvironmentVLHGC *env, UDATA numaNode);614615/**616* Complete scanning in Copy-Forward fashion (consume&produce CopyScanCaches)617* If abort happens midway through all produced work is pushed on Marking WorkStack618* @param env[in] The GC thread619*/620void completeScan(MM_EnvironmentVLHGC *env);621/**622* Complete scanning in Marking fashion (consume&produce on WorkStack)623* @param env[in] The GC thread624*/625void completeScanForAbort(MM_EnvironmentVLHGC *env);626/**627* Rescan all objects in the specified overflowed region.628*/629void cleanOverflowedRegion(MM_EnvironmentVLHGC *env, MM_HeapRegionDescriptorVLHGC *region, U_8 flagToClean);630/**631* Handling of Work Packets overflow case632* Active STW Card Based Overflow Handler only.633* For other types of STW Overflow Handlers always return false634* @param env[in] The main GC thread635* @return true if overflow flag is set636*/637bool handleOverflow(MM_EnvironmentVLHGC *env);638639/**640* Check if Work Packets overflow641* @return true if overflow flag is set642*/643bool isWorkPacketsOverflow(MM_EnvironmentVLHGC *env);644645void completeScanCache(MM_EnvironmentVLHGC *env);646/**647* complete scan works from _workStack648* only for CopyForward Hybrid mode649*/650void completeScanWorkPacket(MM_EnvironmentVLHGC *env);651652/**653* Scans all the slots of the given object. Used only in copy-scan cache driven phase.654* @param env[in] the current thread655* @param reservingContext[in] The context to which we would prefer to copy any objects discovered in this method656* @param objectPtr[in] current object being scanned657* @param reason[in] reason to scan (dirty card, packet, scan cache, overflow)658*/659MMINLINE void scanObject(MM_EnvironmentVLHGC *env, MM_AllocationContextTarok *reservingContext, J9Object *objectPtr, ScanReason reason);660661/**662* Update scan for abort phase (workstack phase)663* @param env[in] the current thread664* @param objectPtr[in] current object being scanned.665* @param reason[in] reason to scan (dirty card, packet, scan cache, overflow)666*/667MMINLINE void updateScanStats(MM_EnvironmentVLHGC *env, J9Object *objectPtr, ScanReason reason);668669MMINLINE UDATA scanToCopyDistance(MM_CopyScanCacheVLHGC* cache);670MMINLINE bool bestCacheForScanning(MM_CopyScanCacheVLHGC* copyCache, MM_CopyScanCacheVLHGC** scanCache);671672/**673* Calculates whether to change the current cache being scanned for a copy cache, deciding674* between one of the two copy caches available, using bestCacheForScanning.675*676* On entry, nextScanCache should contain the current scan cache. On exit, it may contain677* the updated scan cache to use next.678*679* @param nextScanCache the current scan cache, which may be updated on exit.680* @return true if the nextScanCache has been updated with the best cache to scan.681*/682MMINLINE bool aliasToCopyCache(MM_EnvironmentVLHGC *env, MM_CopyScanCacheVLHGC** nextScanCache);683684/**685* Scans the slots of a MixedObject, remembering objects as required. Scanning is interrupted686* as soon as there is a copy cache that is preferred to the current scan cache. This is returned687* in nextScanCache.688*689* @note <an iterator>.nextSlot() is one of the hottest methods in scavenging, so690* it needs to be inlined as much as possible, but we also need to store that iterator state in the691* copy/scan cache. Using the local (ie stack or register) instance of the class (through the default692* constructor) allows the compiler to inline the virtual method. Using a pointer from the copy/scan693* cache to the abstract class ObjectIterator would not allow the compiler to inline. Hence the694* Iterator member functions restore and save.695* @param reservingContext[in] The context to which we would prefer to copy any objects discovered in this method696* @param scanCache current cache being scanned697* @param objectPtr current object being scanned698* @param hasPartiallyScannedObject whether current object has been partially scanned already699* @param nextScanCache the updated scanCache after re-aliasing.700* @return whether current object is still only partially scanned701*/702MMINLINE bool incrementalScanMixedObjectSlots(MM_EnvironmentVLHGC *env, MM_AllocationContextTarok *reservingContext, MM_CopyScanCacheVLHGC* scanCache, J9Object *objectPtr,703bool hasPartiallyScannedObject, MM_CopyScanCacheVLHGC** nextScanCache);704/**705* Scans the slots of a java.lang.Class object, remembering objects as required.706* This scan will visit both the object itself (as a mixed object) as well as the backing J9Class structure.707* Scanning is interrupted as soon as there is a copy cache that is preferred to the current scan cache.708* This is returned in nextScanCache.709* @param reservingContext[in] The context to which we would prefer to copy any objects discovered in this method710* @note The current implementation will not interrupt, completing the scan of the object before returning.711* @see MM_CopyForwardScheme:incrementalScanMixedObjectSlots712*/713MMINLINE bool incrementalScanClassObjectSlots(MM_EnvironmentVLHGC *env, MM_AllocationContextTarok *reservingContext, MM_CopyScanCacheVLHGC* scanCache, J9Object *objectPtr,714bool hasPartiallyScannedObject, MM_CopyScanCacheVLHGC** nextScanCache);715/**716* Scans the slots of a java.lang.ClassLoader object, remembering objects as required.717* This scan will visit both the object itself (as a mixed object) as well as the backing J9ClassLoader structure.718* Scanning is interrupted as soon as there is a copy cache that is preferred to the current scan cache.719* This is returned in nextScanCache.720* @param reservingContext[in] The context to which we would prefer to copy any objects discovered in this method721* @note The current implementation will not interrupt, completing the scan of the object before returning.722* @see MM_CopyForwardScheme:incrementalScanMixedObjectSlots723*/724MMINLINE bool incrementalScanClassLoaderObjectSlots(MM_EnvironmentVLHGC *env, MM_AllocationContextTarok *reservingContext, MM_CopyScanCacheVLHGC* scanCache, J9Object *objectPtr,725bool hasPartiallyScannedObject, MM_CopyScanCacheVLHGC** nextScanCache);726/**727* Scans the slots of a PointerArrayObject, remembering objects as required. Scanning is interrupted728* as soon as there is a copy cache that is preferred to the current scan cache. This is returned729* in nextScanCache.730* @param reservingContext[in] The context to which we would prefer to copy any objects discovered in this method731* @see MM_CopyForwardScheme:incrementalScanMixedObjectSlots732*/733MMINLINE bool incrementalScanPointerArrayObjectSlots(MM_EnvironmentVLHGC *env, MM_AllocationContextTarok *reservingContext, MM_CopyScanCacheVLHGC* scanCache, J9Object *objectPtr,734bool hasPartiallyScannedObject, MM_CopyScanCacheVLHGC** nextScanCache);735/**736* Scans the slots of a ReferenceObject, remembering objects as required. Scanning is interrupted737* as soon as there is a copy cache that is preferred to the current scan cache. This is returned738* in nextScanCache.739* @param reservingContext[in] The context to which we would prefer to copy any objects discovered in this method740* @see MM_CopyForwardScheme:incrementalScanMixedObjectSlots741*/742MMINLINE bool incrementalScanReferenceObjectSlots(MM_EnvironmentVLHGC *env, MM_AllocationContextTarok *reservingContext, MM_CopyScanCacheVLHGC* scanCache, J9Object *objectPtr,743bool hasPartiallyScannedObject, MM_CopyScanCacheVLHGC** nextScanCache);744/**745* Scans the objects to scan in the env->_scanCache.746* Slots are scanned until there is an opportunity to alias the scan cache to a copy cache. When747* this happens, scanning is interrupted and the present scan cache is either pushed onto the scan748* list or "deferred" in thread-local storage. Deferring is done to reduce contention due to the749* increased need to change scan cache. If the cache is scanned completely without interruption750* the cache is flushed at the end.751*/752void incrementalScanCacheBySlot(MM_EnvironmentVLHGC *env);753754#if defined(J9VM_GC_FINALIZATION)755/**756* Scan all unfinalized objects in the collection set.757* @param env[in] the current thread758*/759void scanUnfinalizedObjects(MM_EnvironmentVLHGC *env);760761void scanFinalizableObjects(MM_EnvironmentVLHGC *env);762763/**764* Helper method called by scanFinalizableObjects to scan765* a list of finalizable objects.766*767* @param env[in] the current thread768* @param headObject[in] the object at the head of the list769*/770void scanFinalizableList(MM_EnvironmentVLHGC *env, j9object_t headObject);771#endif /* J9VM_GC_FINALIZATION */772773/**774* Clear the cycle's mark map for all regions that are part of the evacuate set.775* @param env GC thread.776*/777void clearMarkMapForPartialCollect(MM_EnvironmentVLHGC *env);778/**779* Clear the cycle's card table for all regions that are part of the evacuate set, if GMP in progress.780* Called only, if regions are completely evacuated (no abort)781* @param env GC thread.782*/783void clearCardTableForPartialCollect(MM_EnvironmentVLHGC *env);784785void workThreadGarbageCollect(MM_EnvironmentVLHGC *env);786787/**788* Update the given slot to point at the new location of the object, after copying the object if it was not already.789* Attempt to copy (either flip or tenure) the object and install a forwarding pointer at the new location. The object790* may have already been copied. In either case, update the slot to point at the new location of the object.791*792* @param reservingContext[in] The context to which we would prefer to copy any objects discovered in this method793* @param objectPtr[in] Object being scanned.794* @param slotObject the slot to be copied or updated795* @return true if copy succeeded (or no copying was involved)796*/797MMINLINE bool copyAndForward(MM_EnvironmentVLHGC *env, MM_AllocationContextTarok *reservingContext, J9Object *objectPtr, volatile j9object_t* slot);798799/**800* Update the given slot to point at the new location of the object, after copying the object if it was not already.801* Attempt to copy (either flip or tenure) the object and install a forwarding pointer at the new location. The object802* may have already been copied. In either case, update the slot to point at the new location of the object.803*804* @param reservingContext[in] The context to which we would prefer to copy any objects discovered in this method805* @param objectPtr[in] Object being scanned.806* @param slot the slot to be copied or updated807* @param leafType true if slotObject is leaf Object808* @return true if copy succeeded (or no copying was involved)809*/810MMINLINE bool copyAndForward(MM_EnvironmentVLHGC *env, MM_AllocationContextTarok *reservingContext, J9Object *objectPtr, GC_SlotObject *slotObject, bool leafType = false);811812/**813* Update the given slot to point at the new location of the object, after copying the object if it was not already.814* Attempt to copy (either flip or tenure) the object and install a forwarding pointer at the new location. The object815* may have already been copied. In either case, update the slot to point at the new location of the object.816*817* @param reservingContext[in] The context to which we would prefer to copy any objects discovered in this method818* @param objectPtr[in] Array object being scanned.819* @param startIndex[in] First index of the sub (split)array being scanned.820* @param slotObject the slot to be copied or updated821* @return true if copy succeeded (or no copying was involved)822*/823MMINLINE bool copyAndForwardPointerArray(MM_EnvironmentVLHGC *env, MM_AllocationContextTarok *reservingContext, J9IndexableObject *arrayPtr, UDATA startIndex, GC_SlotObject *slotObject);824825826/**827* Update the given slot to point at the new location of the object, after copying the object if it was not already.828* Attempt to copy (either flip or tenure) the object and install a forwarding pointer at the new location. The object829* may have already been copied. In either case, update the slot to point at the new location of the object.830*831* @param reservingContext[in] The context to which we would prefer to copy any objects discovered in this method832* @param objectPtrIndirect the slot to be copied or updated833* @param leafType true if the slot is leaf Object834* @return true if copy succeeded (or no copying was involved)835*/836MMINLINE bool copyAndForward(MM_EnvironmentVLHGC *env, MM_AllocationContextTarok *reservingContext, volatile j9object_t* objectPtrIndirect, bool leafType = false);837838/**839* If class unloading is enabled, copy the specified object's class object and remember the object as an instance.840* @param env[in] the current thread841* @param reservingContext[in] The context to which we would prefer to copy any objects discovered in this method842* @param objectPtr[in] the object whose class should be copied843* @return true if copy succeeded (or no copying was involved)844*/845MMINLINE bool copyAndForwardObjectClass(MM_EnvironmentVLHGC *env, MM_AllocationContextTarok *reservingContext, J9Object *objectPtr);846847/**848* Answer the new location of an object after it has been copied and forwarded.849* Attempt to copy and forward the given object header between the evacuate and survivor areas. If the object has already850* been copied, or the copy is successful, return the updated information. If the copy is not successful due to insufficient851* heap memory, return the original object pointer and raise the "abort" flag.852* @param reservingContext[in] The context to which we would prefer to copy any objects discovered in this method853* @param leafType true if the object is leaf object, default = false854* @note This routine can set the abort flag for a copy forward.855* @note This will respect any alignment requirements due to hot fields etc.856* @return an object pointer representing the new location of the object, or the original object pointer on failure.857*/858J9Object *copy(MM_EnvironmentVLHGC *env, MM_AllocationContextTarok *reservingContext, MM_ForwardedHeader* forwardedHeader, bool leafType = false);859860861/* Depth copy the hot fields of an object.862* @param forwardedHeader - forwarded header of an object863* @param destinationObjectPtr - destinationObjectPtr of the object described by the forwardedHeader864*/865MMINLINE void depthCopyHotFields(MM_EnvironmentVLHGC *env, J9Class *clazz, J9Object *destinationObjectPtr, MM_AllocationContextTarok *reservingContext);866867/* Copy the hot field of an object.868* Valid if scavenger dynamicBreadthScanOrdering is enabled.869* @param destinationObjectPtr - the object who's hot field will be copied870* @param offset - the object field offset of the hot field to be copied871*/872MMINLINE void copyHotField(MM_EnvironmentVLHGC *env, J9Object *destinationObjectPtr, U_8 offset, MM_AllocationContextTarok *reservingContext);873/**874* Push any remaining cached mark map data out before the copy scan cache is released.875* @param env GC thread.876* @param cache Location of cached mark map data to push out.877*/878void flushCacheMarkMap(MM_EnvironmentVLHGC *env, MM_CopyScanCacheVLHGC *cache);879880/**881* Update the mark map information (PGC or GMP) for a given copy scan cache.882* @param env GC thread.883* @param markMap Mark map to update (if necessary).884* @param object Heap object reference whose bit in the mark map should be updated.885* @param slotIndexIndirect Indirect pointer to the cached slot index to examine and update.886* @param bitMaskIndirect Indirect pointer to the cached bit mask to use for updating.887* @param atomicHeadSlotIndex Slot index of mark map where the update must be atomic.888* @param atomicTailSlotIndex Slot index of mark map where the update must be atomic.889*/890MMINLINE void updateMarkMapCache(MM_EnvironmentVLHGC *env, MM_MarkMap *markMap, J9Object *object,891UDATA *slotIndexIndirect, UDATA *bitMaskIndirect, UDATA atomicHeadSlotIndex, UDATA atomicTailSlotIndex);892893/**894* Update any mark maps and transfer card table data as appropriate for a successful copy.895* @param env GC thread.896* @param srcObject Source object that was copy forwarded.897* @param dstObject Destination object that was copy forwarded to.898* @param dstCache Destination copy scan cache for the forwarded object.899*/900MMINLINE void updateMarkMapAndCardTableOnCopy(MM_EnvironmentVLHGC *env, J9Object *srcObject, J9Object *dstObject, MM_CopyScanCacheVLHGC *dstCache);901902/**903* Determine whether a copy forward cycle that has been started did complete successfully.904* @return true if the copy forward cycle completed successfully, false otherwise.905*/906bool copyForwardCompletedSuccessfully(MM_EnvironmentVLHGC *env);907908/**909* Used by the logic which relocates objects to different NUMA nodes by looking up the context which owns a given "source" address in the heap.910* @param address[in] A heap address for which the receiver will look up the owning context (must be in the heap)911* @return The allocation context which owns the region within which address exists912*/913MMINLINE MM_AllocationContextTarok *getContextForHeapAddress(void *address);914915/**916* Determine the desired copy cache size for the specified compact group for the current thread.917* The size is chosen to balance the opposing problems of fragmentation and contention.918*919* @param env[in] the current thread920* @param compactGroup the compact group to calculate the size for921* @return the desired copy cache size, in bytes922*/923UDATA getDesiredCopyCacheSize(MM_EnvironmentVLHGC *env, UDATA compactGroup);924925/**926* Set the specified free memory candidate region to be a survivor region.927* 1. Update its free memory in preparation for copying objects into it928* 2. Prepare its reference lists for processing929* The caller is responsible for calling rememberAndResetReferenceLists() on the list once it's released all locks.930* @param env[in] the current thread931* @param region[in] the free memory region to convert932*/933void convertFreeMemoryCandidateToSurvivorRegion(MM_EnvironmentVLHGC* env, MM_HeapRegionDescriptorVLHGC *region);934935/**936* Scan the root set, copying-and-forwarding any objects found.937* @param env[in] the current thread938*/939void scanRoots(MM_EnvironmentVLHGC* env);940941#if defined(J9VM_GC_LEAF_BITS)942/**943* Copy any leaf children of the specified object.944* @param env[in] the current thread945* @param reservingContext[in] The context to which we would prefer to copy any objects discovered in this method946* @param objectPtr[in] the object whose children should be copied947*/948void copyLeafChildren(MM_EnvironmentVLHGC* env, MM_AllocationContextTarok *reservingContext, J9Object* objectPtr);949#endif /* J9VM_GC_LEAF_BITS */950951/**952* Calculate estimation for allocation age based on compact group and set it to the merged region953* @param[in] env The current thread954* @param[in] region The region to adjust age to955*/956void setAllocationAgeForMergedRegion(MM_EnvironmentVLHGC* env, MM_HeapRegionDescriptorVLHGC *region);957958/**959* check if the Object in jni critical region960*/961bool isObjectInNoEvacuationRegions(MM_EnvironmentVLHGC *env, J9Object *objectPtr);962963bool randomDecideForceNonEvacuatedRegion(UDATA ratio);964965/**966* Iterate the slot reference and parse and pass leaf bit of the reference to copy forward967* to avoid to push leaf object to work stack in case the reference need to be marked instead of copied.968*/969MMINLINE bool iterateAndCopyforwardSlotReference(MM_EnvironmentVLHGC *env, MM_AllocationContextTarok *reservingContext, J9Object *objectPtr);970971void verifyObjectsInRange(MM_EnvironmentVLHGC *env, UDATA *lowAddress, UDATA *highAddress);972void verifyChunkSlotsAndMapSlotsInRange(MM_EnvironmentVLHGC *env, UDATA *lowAddress, UDATA *highAddress);973void checkConsistencyGMPMapAndPGCMap(MM_EnvironmentVLHGC *env, MM_HeapRegionDescriptorVLHGC *region, UDATA *lowAddress, UDATA *highAddress);974void cleanOverflowInRange(MM_EnvironmentVLHGC *env, UDATA *lowAddress, UDATA *highAddress);975976MMINLINE bool isCompressedSurvivor(void *heapAddr);977MMINLINE void setCompressedSurvivorCards(MM_EnvironmentVLHGC *env, void *startHeapAddress, void *endHeapAddress);978MMINLINE void cleanCompressedSurvivorCardTable(MM_EnvironmentVLHGC *env);979980protected:981982MM_CopyForwardScheme(MM_EnvironmentVLHGC *env, MM_HeapRegionManager *manager);983984/**985* Initialize the receivers internal support structures and state.986* @param env[in] Main thread.987*/988bool initialize(MM_EnvironmentVLHGC *env);989990/**991* Clean up the receivers internal support structures and state.992* @param env[in] Main thread.993*/994void tearDown(MM_EnvironmentVLHGC *env);995996void mainSetupForCopyForward(MM_EnvironmentVLHGC *env);997void mainCleanupForCopyForward(MM_EnvironmentVLHGC *env);998void workerSetupForCopyForward(MM_EnvironmentVLHGC *env);9991000void clearGCStats(MM_EnvironmentVLHGC *env);10011002/**1003* Merge the current threads copy forward stats into the global copy forward stats.1004*/1005void mergeGCStats(MM_EnvironmentVLHGC *env);10061007/**1008* After successful copy forward cycle, update leaf region base pointers to newly copied spine locations and1009* recycle any with spines remaining in evacuate space.1010*/1011void updateLeafRegions(MM_EnvironmentVLHGC *env);10121013/**1014* Before a copy forward operation, perform any pre processing required on regions.1015*/1016void preProcessRegions(MM_EnvironmentVLHGC *env);10171018/**1019* After successful copy forward operation, perform any post processing required on regions.1020*/1021void postProcessRegions(MM_EnvironmentVLHGC *env);10221023/**1024* Clean cards for the purpose of finding "roots" into the collection set.1025* @param env A GC thread involved in the cleaning.1026*/1027void cleanCardTable(MM_EnvironmentVLHGC *env);10281029/**1030* Helper routine to clean cards during a partial collection for the purpose of finding "roots" into the collection set.1031* @param env A GC thread involved in the cleaning.1032* @param cardCleaner Card handling instance to manage state transition and actions.1033*/1034void cleanCardTableForPartialCollect(MM_EnvironmentVLHGC *env, MM_CardCleaner *cardCleaner);10351036/**1037* Update or delete any external cycle object data that was involved in the collection set.1038* This routine will clear the external mark map for the collection set (if successful) or adjust the map on moved objects (abort) and1039* remove any dead objects from external cycle work packets. It will also update (forward) any work packet pointers which have survived1040* the collection. The responsibility of setting the external cycle mark map survivor bits and updating cards lies with object copying.1041*/1042void updateOrDeleteObjectsFromExternalCycle(MM_EnvironmentVLHGC *env);10431044/**1045* Scans the marked objects in the [lowAddress..highAddress) range. If rememberedObjectsOnly is set, we will further constrain1046* this scanned set by only scanning objects in the range which have the OBJECT_HEADER_REMEMBERED bit set. The receiver uses1047* its _markMap to determine which objects in the range are marked.1048*1049* @param env[in] A GC thread (note that this method could be called by multiple threads, in parallel, but on disjoint address ranges)1050* @param lowAddress[in] The heap address where the receiver will begin walking objects1051* @param highAddress[in] The heap address after the last address we will potentially find a live object1052* @param rememberedObjectsOnly If true, the receiver only scans remembered live objects in the range. If false, it scans all live objects in the range1053* @return true if all the objects in the given range were scanned without causing an abort1054*/1055bool scanObjectsInRange(MM_EnvironmentVLHGC *env, void *lowAddress, void *highAddress, bool rememberedObjectsOnly);10561057/**1058* Checks whether the suggestedContext passed in is a preferred allocation context for1059* object relocation. If so the same context is returned if not the object's original context1060* is returned.1061* @param[in] suggestedContext The allocation context we intended to copy the object into1062* @param[in] objectPtr A pointer to the object being copied1063* @return The reservingContext or the object's owning context if the suggestedContext is not a preferred object relocation context1064*/1065MMINLINE MM_AllocationContextTarok *getPreferredAllocationContext(MM_AllocationContextTarok *suggestedContext, J9Object *objectPtr);10661067public:10681069static MM_CopyForwardScheme *newInstance(MM_EnvironmentVLHGC *env, MM_HeapRegionManager *manager);1070void kill(MM_EnvironmentVLHGC *env);10711072/**1073* Pre Copy Forward process. Clear GC stats, pre process regions and perform any main-specific setup1074*/1075void copyForwardPreProcess(MM_EnvironmentVLHGC *env);10761077/**1078* Post Copy Forward process. Sets persistent flag indicating if copy forward collection was successful or not.1079*/1080void copyForwardPostProcess(MM_EnvironmentVLHGC *env);10811082/**1083* Run a copy forward collection operation on the already determined collection set.1084* @param env[in] Main thread.1085*/1086void copyForwardCollectionSet(MM_EnvironmentVLHGC *env);10871088/**1089* Return true if CopyForward is running under Hybrid mode1090*/1091bool isHybrid(MM_EnvironmentVLHGC *env)1092{1093return (0 != _regionCountCannotBeEvacuated);1094}10951096void setReservedNonEvacuatedRegions(UDATA regionCount)1097{1098_regionCountReservedNonEvacuated = regionCount;1099}11001101#if defined(OMR_GC_VLHGC_CONCURRENT_COPY_FORWARD)1102/**1103* Run concurrent copy forward collection increment. Contrary to regular copyForwardCollectionSet(),1104* this method will be called twice for each PGC cycle (whenever concurrent copy forward is1105* enabled), once for initial STW increment and once for the final STW increment. For each of1106* those increments isConcurrentCycleInProgress state/value will get updated. For initial increment,1107* it will change from false to true causing only preProcess step to be performed, and for the1108* final increment it will change from true to false causing only postProcess step to be performed.1109*1110* @param env[in] Main thread.1111*/1112void concurrentCopyForwardCollectionSet(MM_EnvironmentVLHGC *env);1113#endif /* defined(OMR_GC_VLHGC_CONCURRENT_COPY_FORWARD) */11141115/**1116* True if concurrent CopyForward cycle is active at any point (STW or concurrent1117* task active, or even short gaps between STW and concurrent tasks). Equivalent to1118* isConcurrentCycleInProgress() from Scavenger1119*/1120MMINLINE bool isConcurrentCycleInProgress() {1121/* Unimplemented */1122return false;1123}11241125void abandonTLHRemainders(MM_EnvironmentVLHGC *env);11261127friend class MM_CopyForwardGMPCardCleaner;1128friend class MM_CopyForwardNoGMPCardCleaner;1129friend class MM_CopyForwardSchemeTask;1130friend class MM_CopyForwardSchemeRootScanner;1131friend class MM_CopyForwardSchemeRootClearer;1132friend class MM_CopyForwardSchemeAbortScanner;1133};11341135#endif /* COPYFORWARDSCHEME_HPP_ */113611371138