Path: blob/master/runtime/gc_vlhgc/CardListFlushTask.cpp
5986 views
/*******************************************************************************1* Copyright (c) 1991, 2020 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*******************************************************************************/21222324#include "j9.h"25#include "j9cfg.h"26#include "j9consts.h"27#include "ModronAssertions.h"2829#include "CardListFlushTask.hpp"3031#include "CardTable.hpp"32#include "CycleState.hpp"33#include "EnvironmentVLHGC.hpp"34#include "HeapRegionIteratorVLHGC.hpp"35#include "HeapRegionManager.hpp"36#include "InterRegionRememberedSet.hpp"37#include "ParallelDispatcher.hpp"38#include "RememberedSetCardListBufferIterator.hpp"39#include "RememberedSetCardListCardIterator.hpp"40#include "MarkMap.hpp"41#include "SchedulingDelegate.hpp"4243void44MM_CardListFlushTask::mainSetup(MM_EnvironmentBase *env)45{46Assert_MM_true(MM_CycleState::CT_PARTIAL_GARBAGE_COLLECTION == env->_cycleState->_collectionType);47}4849void50MM_CardListFlushTask::mainCleanup(MM_EnvironmentBase *env)51{52}5354void55MM_CardListFlushTask::writeFlushToCardState(Card *card, bool gmpIsActive)56{57Card fromState = *card;58switch(fromState) {59case CARD_CLEAN:60if (gmpIsActive) {61*card = CARD_REMEMBERED_AND_GMP_SCAN;62} else {63*card = CARD_REMEMBERED;64}65break;66case CARD_GMP_MUST_SCAN:67*card = CARD_REMEMBERED_AND_GMP_SCAN;68break;69case CARD_REMEMBERED_AND_GMP_SCAN:70case CARD_DIRTY:71/* do nothing */72break;73case CARD_REMEMBERED:74if (gmpIsActive) {75*card = CARD_REMEMBERED_AND_GMP_SCAN;76} else {77/* do nothing */78}79break;80case CARD_PGC_MUST_SCAN:81if (gmpIsActive) {82/* PGC_MUST_SCAN is a slightly stronger statement than REMEMBERED so we only add the GMP requirement by marking this DIRTY */83*card = CARD_DIRTY;84} else {85/* do nothing */86}87break;88default:89Assert_MM_unreachable();90break;91}92}9394void95MM_CardListFlushTask::run(MM_EnvironmentBase *envBase)96{97MM_EnvironmentVLHGC *env = MM_EnvironmentVLHGC::getEnvironment(envBase);98MM_GCExtensions *extensions = MM_GCExtensions::getExtensions(env);99MM_MarkMap *markMap = NULL;100if (static_cast<MM_CycleStateVLHGC*>(envBase->_cycleState)->_schedulingDelegate->isFirstPGCAfterGMP()) {101markMap = env->_cycleState->_markMap;102}103104/* this function has knowledge of the collection set, which is only valid during a PGC */105Assert_MM_true(MM_CycleState::CT_PARTIAL_GARBAGE_COLLECTION == env->_cycleState->_collectionType);106bool gmpIsActive = (NULL != env->_cycleState->_externalCycleState);107108/* flush RS Lists for CollectionSet and dirty card table */109GC_HeapRegionIteratorVLHGC regionIterator(_regionManager);110MM_HeapRegionDescriptorVLHGC *region = NULL;111MM_InterRegionRememberedSet *interRegionRememberedSet = extensions->interRegionRememberedSet;112bool shouldFlushBuffersForUnregisteredRegions = interRegionRememberedSet->getShouldFlushBuffersForDecommitedRegions();113114while (NULL != (region = regionIterator.nextRegion())) {115if (NULL != region->getMemoryPool()) {116if(region->_markData._shouldMark) {117if(J9MODRON_HANDLE_NEXT_WORK_UNIT(env)) {118Assert_MM_true(region->getRememberedSetCardList()->isAccurate());119/* Iterate non-overflowed buckets of the list */120GC_RememberedSetCardListCardIterator rsclCardIterator(region->getRememberedSetCardList());121UDATA card = 0;122while(0 != (card = rsclCardIterator.nextReferencingCard(env))) {123/* For Marking purposes we do not need to track references within Collection Set */124MM_HeapRegionDescriptorVLHGC *referencingRegion = interRegionRememberedSet->tableDescriptorForRememberedSetCard(card);125if (interRegionRememberedSet->cardMayContainObjects(card, referencingRegion, markMap) && !referencingRegion->_markData._shouldMark) {126Card *cardAddress = interRegionRememberedSet->rememberedSetCardToCardAddr(env, card);127writeFlushToCardState(cardAddress, gmpIsActive);128}129}130131/* Clear remembered references to each region in Collection Set (completely clear RS Card List for those regions132* and appropriately update RSM). We are about to rebuild those references in PGC.133*/134_interRegionRememberedSet->clearReferencesToRegion(env, region);135}136} else if (shouldFlushBuffersForUnregisteredRegions) {137if (J9MODRON_HANDLE_NEXT_WORK_UNIT(env)) {138/* flush the content of buffers owned by decommitted regions (but used/borrowed by other active regions) */139bool const compressed = env->compressObjectReferences();140UDATA toRemoveCount = 0;141UDATA totalCountBefore = region->getRememberedSetCardList()->getSize(env);142MM_RememberedSetCard *lastCardInCurrentBuffer = NULL;143MM_CardBufferControlBlock *cardBufferControlBlockCurrent = NULL;144GC_RememberedSetCardListBufferIterator rsclBufferIterator(region->getRememberedSetCardList());145while (NULL != (cardBufferControlBlockCurrent = rsclBufferIterator.nextBuffer(env, &lastCardInCurrentBuffer))) {146/* find a region owning current Buffer being iterated */147MM_HeapRegionDescriptorVLHGC *bufferOwningRegion = interRegionRememberedSet->getBufferOwningRegion(cardBufferControlBlockCurrent);148/* owned by a decommited region, which hasn't released its buffer pool yet? */149if (!bufferOwningRegion->isCommitted()) {150Assert_MM_true(NULL != bufferOwningRegion->getRsclBufferPool());151rsclBufferIterator.unlinkCurrentBuffer(env);152for (MM_RememberedSetCard *cardSlot = cardBufferControlBlockCurrent->_card; cardSlot < lastCardInCurrentBuffer; cardSlot = MM_RememberedSetCard::addToCardAddress(cardSlot, 1, compressed)) {153UDATA card = MM_RememberedSetCard::readCard(cardSlot, compressed);154MM_HeapRegionDescriptorVLHGC *referencingRegion = interRegionRememberedSet->tableDescriptorForRememberedSetCard(card);155if (interRegionRememberedSet->cardMayContainObjects(card, referencingRegion, markMap) && !referencingRegion->_markData._shouldMark) {156Card *cardAddress = interRegionRememberedSet->rememberedSetCardToCardAddr(env, card);157writeFlushToCardState(cardAddress, gmpIsActive);158}159toRemoveCount += 1;160}161}162}163UDATA totalCountAfter = region->getRememberedSetCardList()->getSize(env);164Assert_MM_true(totalCountBefore == (toRemoveCount + totalCountAfter));165}166}167}168}169}170171void172MM_CardListFlushTask::setup(MM_EnvironmentBase *env)173{174if (env->isMainThread()) {175Assert_MM_true(_cycleState == env->_cycleState);176} else {177Assert_MM_true(NULL == env->_cycleState);178env->_cycleState = _cycleState;179}180}181182void183MM_CardListFlushTask::cleanup(MM_EnvironmentBase *env)184{185if (env->isMainThread()) {186Assert_MM_true(_cycleState == env->_cycleState);187} else {188env->_cycleState = NULL;189}190}191192#if defined(J9MODRON_TGC_PARALLEL_STATISTICS)193void194MM_CardListFlushTask::synchronizeGCThreads(MM_EnvironmentBase *env, const char *id)195{196/* unused in this task */197Assert_MM_unreachable();198}199200bool201MM_CardListFlushTask::synchronizeGCThreadsAndReleaseMain(MM_EnvironmentBase *env, const char *id)202{203/* unused in this task */204Assert_MM_unreachable();205return true;206}207208bool209MM_CardListFlushTask::synchronizeGCThreadsAndReleaseSingleThread(MM_EnvironmentBase *env, const char *id)210{211/* unused in this task */212Assert_MM_unreachable();213return true;214}215#endif /* J9MODRON_TGC_PARALLEL_STATISTICS */216217218