Path: blob/master/runtime/gc_glue_java/MarkingDelegate.hpp
5985 views
/*******************************************************************************1* Copyright (c) 2017, 2021 IBM Corp. and others2*3* This program and the accompanying materials are made available under4* the terms of the Eclipse Public License 2.0 which accompanies this5* distribution and is available at https://www.eclipse.org/legal/epl-2.0/6* or the Apache License, Version 2.0 which accompanies this distribution and7* is available at https://www.apache.org/licenses/LICENSE-2.0.8*9* This Source Code may also be made available under the following10* Secondary Licenses when the conditions for such availability set11* forth in the Eclipse Public License, v. 2.0 are satisfied: GNU12* General Public License, version 2 with the GNU Classpath13* Exception [1] and GNU General Public License, version 2 with the14* OpenJDK Assembly Exception [2].15*16* [1] https://www.gnu.org/software/classpath/license.html17* [2] http://openjdk.java.net/legal/assembly-exception.html18*19* SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 OR LicenseRef-GPL-2.0 WITH Assembly-exception20*******************************************************************************/2122#if !defined(MARKINGDELEGATE_HPP_)23#define MARKINGDELEGATE_HPP_2425#include "j9nonbuilder.h"26#include "objectdescription.h"2728#include "FlattenedArrayObjectScanner.hpp"29#include "GCExtensions.hpp"30#if defined(J9VM_GC_DYNAMIC_CLASS_UNLOADING)31#include "MarkMap.hpp"32#endif /* defined(J9VM_GC_DYNAMIC_CLASS_UNLOADING) */33#include "MixedObjectScanner.hpp"34#include "ModronTypes.hpp"35#include "ReferenceObjectScanner.hpp"36#include "PointerArrayObjectScanner.hpp"3738class GC_ObjectScanner;39class MM_EnvironmentBase;40class MM_HeapRegionDescriptorStandard;41class MM_MarkingScheme;42class MM_ReferenceStats;4344class MM_MarkingDelegate45{46/* Data members & types */47private:48OMR_VM *_omrVM;49MM_GCExtensions *_extensions;50MM_MarkingScheme *_markingScheme;51bool _collectStringConstantsEnabled;52bool _shouldScanUnfinalizedObjects;53bool _shouldScanOwnableSynchronizerObjects;54#if defined(J9VM_GC_DYNAMIC_CLASS_UNLOADING)55MM_MarkMap *_markMap; /**< This is set when dynamic class loading is enabled, NULL otherwise */56volatile bool _anotherClassMarkPass; /**< Used in completeClassMark for another scanning request*/57volatile bool _anotherClassMarkLoopIteration; /**< Used in completeClassMark for another loop iteration request (set by the Main thread)*/58#endif /* defined(J9VM_GC_DYNAMIC_CLASS_UNLOADING) */596061protected:6263public:6465/* Methods */6667private:68MMINLINE void clearReference(MM_EnvironmentBase *env, omrobjectptr_t objectPtr, bool isReferenceCleared, bool referentMustBeCleared);69MMINLINE bool getReferenceStatus(MM_EnvironmentBase *env, omrobjectptr_t objectPtr, bool *referentMustBeMarked, bool *isReferenceCleared);70fomrobject_t *setupReferenceObjectScanner(MM_EnvironmentBase *env, omrobjectptr_t objectPtr, MM_MarkingSchemeScanReason reason);71uintptr_t setupPointerArrayScanner(MM_EnvironmentBase *env, omrobjectptr_t objectPtr, MM_MarkingSchemeScanReason reason, uintptr_t *sizeToDo, uintptr_t *slotsToDo);7273protected:7475public:76MM_MarkingDelegate()77: _omrVM(NULL)78, _extensions(NULL)79, _markingScheme(NULL)80, _collectStringConstantsEnabled(false)81, _shouldScanUnfinalizedObjects(false)82, _shouldScanOwnableSynchronizerObjects(false)83#if defined(J9VM_GC_DYNAMIC_CLASS_UNLOADING)84, _markMap(NULL)85, _anotherClassMarkPass(false)86, _anotherClassMarkLoopIteration(false)87#endif /* defined(J9VM_GC_DYNAMIC_CLASS_UNLOADING) */88{}8990/**91* Initialize the delegate.92*93* @param env environment for calling thread94* @param markingScheme the marking scheme that the delegate is bound to95* @return true if delegate initialized successfully96*/97bool initialize(MM_EnvironmentBase *env, MM_MarkingScheme *markingScheme);9899/**100* Delegate methods interfacing with MM_MarkingScheme.101*/102void workerSetupForGC(MM_EnvironmentBase *env);103void workerCompleteGC(MM_EnvironmentBase *env);104void workerCleanupAfterGC(MM_EnvironmentBase *env);105void mainSetupForGC(MM_EnvironmentBase *env);106void mainSetupForWalk(MM_EnvironmentBase *env);107void mainCleanupAfterGC(MM_EnvironmentBase *env);108void scanRoots(MM_EnvironmentBase *env, bool processLists = true);109void completeMarking(MM_EnvironmentBase *env);110111void startRootListProcessing(MM_EnvironmentBase *env);112113uintptr_t setupIndexableScanner(MM_EnvironmentBase *env, omrobjectptr_t objectPtr, MM_MarkingSchemeScanReason reason, uintptr_t *sizeToDo, uintptr_t *sizeInElementsToDo, fomrobject_t **basePtr, uintptr_t *flags) { return 0; }114115MMINLINE GC_ObjectScanner *116getObjectScanner(MM_EnvironmentBase *env, omrobjectptr_t objectPtr, void *scannerSpace, MM_MarkingSchemeScanReason reason, uintptr_t *sizeToDo)117{118J9Class *clazz = J9GC_J9OBJECT_CLAZZ(objectPtr, env);119UDATA const referenceSize = env->compressObjectReferences() ? sizeof(uint32_t) : sizeof(uintptr_t);120121/* object class must have proper eye catcher */122Assert_MM_true((UDATA)0x99669966 == clazz->eyecatcher);123124GC_ObjectScanner *objectScanner = NULL;125switch(_extensions->objectModel.getScanType(objectPtr)) {126case GC_ObjectModel::SCAN_MIXED_OBJECT_LINKED:127case GC_ObjectModel::SCAN_ATOMIC_MARKABLE_REFERENCE_OBJECT:128case GC_ObjectModel::SCAN_MIXED_OBJECT:129case GC_ObjectModel::SCAN_OWNABLESYNCHRONIZER_OBJECT:130case GC_ObjectModel::SCAN_CLASS_OBJECT:131case GC_ObjectModel::SCAN_CLASSLOADER_OBJECT:132objectScanner = GC_MixedObjectScanner::newInstance(env, objectPtr, scannerSpace, 0);133*sizeToDo = referenceSize + ((GC_MixedObjectScanner *)objectScanner)->getBytesRemaining();134break;135case GC_ObjectModel::SCAN_POINTER_ARRAY_OBJECT:136{137uintptr_t slotsToDo = 0;138uintptr_t startIndex = setupPointerArrayScanner(env, objectPtr, reason, sizeToDo, &slotsToDo);139objectScanner = GC_PointerArrayObjectScanner::newInstance(env, objectPtr, scannerSpace, GC_ObjectScanner::indexableObject, slotsToDo, startIndex);140break;141}142case GC_ObjectModel::SCAN_FLATTENED_ARRAY_OBJECT:143{144/* TODO: Flattened arrays do not support array splitting */145uintptr_t slotsToDo = 0;146uintptr_t startIndex = 0;147objectScanner = GC_FlattenedArrayObjectScanner::newInstance(env, objectPtr, scannerSpace, GC_ObjectScanner::indexableObject, slotsToDo, startIndex);148break;149}150case GC_ObjectModel::SCAN_REFERENCE_MIXED_OBJECT:151{152fomrobject_t *referentSlotPtr = setupReferenceObjectScanner(env, objectPtr, reason);153objectScanner = GC_ReferenceObjectScanner::newInstance(env, objectPtr, referentSlotPtr, scannerSpace, 0);154*sizeToDo = referenceSize + ((GC_ReferenceObjectScanner *)objectScanner)->getBytesRemaining();155break;156}157case GC_ObjectModel::SCAN_PRIMITIVE_ARRAY_OBJECT:158/* nothing to do */159*sizeToDo = 0;160break;161default:162Assert_MM_unreachable();163}164165#if defined(J9VM_GC_DYNAMIC_CLASS_UNLOADING)166if (isDynamicClassUnloadingEnabled()) {167/* only mark the class the first time we scan any array, always mark class for mixed/reference objects */168if ((NULL != objectScanner) && objectScanner->isHeadObjectScanner()) {169/* Note: this code cloned from MM_MarkingScheme::inlineMarkObjectNoCheck(), inaccessible here */170if (_markMap->atomicSetBit(clazz->classObject)) {171/* class object was previously unmarked so push it to workstack */172env->_workStack.push(env, (void *)clazz->classObject);173env->_markStats._objectsMarked += 1;174}175}176}177#endif /* J9VM_GC_DYNAMIC_CLASS_UNLOADING */178179return objectScanner;180}181182/**183* Delegate methods used by MM_MarkingSchemeRootmarker and MM_MarkingSchemeRootClearer.184*/185MMINLINE bool186shouldScanUnfinalizedObjects()187{188return _shouldScanUnfinalizedObjects;189}190191MMINLINE void192shouldScanUnfinalizedObjects(bool shouldScanUnfinalizedObjects)193{194_shouldScanUnfinalizedObjects = shouldScanUnfinalizedObjects;195}196197MMINLINE bool198shouldScanOwnableSynchronizerObjects()199{200return _shouldScanOwnableSynchronizerObjects;201}202203MMINLINE void204shouldScanOwnableSynchronizerObjects(bool shouldScanOwnableSynchronizerObjects)205{206_shouldScanOwnableSynchronizerObjects = shouldScanOwnableSynchronizerObjects;207}208209void scanClass(MM_EnvironmentBase *env, J9Class *clazz);210211bool processReference(MM_EnvironmentBase *env, omrobjectptr_t objectPtr);212void processReferenceList(MM_EnvironmentBase *env, MM_HeapRegionDescriptorStandard* region, omrobjectptr_t headOfList, MM_ReferenceStats *referenceStats);213214void handleWorkPacketOverflowItem(MM_EnvironmentBase *env, omrobjectptr_t objectPtr)215{216if (GC_ObjectModel::SCAN_REFERENCE_MIXED_OBJECT == _extensions->objectModel.getScanType(objectPtr)) {217/* since we popped this object from the work packet, it is our responsibility to record it in the list of reference objects */218/* we know that the object must be in the collection set because it was on a work packet */219/* we don't need to process cleared or enqueued references */220processReference(env, objectPtr);221}222}223224/**225* Helper methods used by classes other than MM_MarkingScheme.226*/227#if defined(J9VM_GC_DYNAMIC_CLASS_UNLOADING)228static void clearClassLoadersScannedFlag(MM_EnvironmentBase *env);229MMINLINE bool isDynamicClassUnloadingEnabled() { return NULL != _markMap; }230#endif /* defined(J9VM_GC_DYNAMIC_CLASS_UNLOADING) */231};232233#endif /* MARKINGDELEGATE_HPP_ */234235236