Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openj9
Path: blob/master/runtime/gc_vlhgc/CardListFlushTask.cpp
5986 views
1
/*******************************************************************************
2
* Copyright (c) 1991, 2020 IBM Corp. and others
3
*
4
* This program and the accompanying materials are made available under
5
* the terms of the Eclipse Public License 2.0 which accompanies this
6
* 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 and
8
* is available at https://www.apache.org/licenses/LICENSE-2.0.
9
*
10
* This Source Code may also be made available under the following
11
* Secondary Licenses when the conditions for such availability set
12
* forth in the Eclipse Public License, v. 2.0 are satisfied: GNU
13
* General Public License, version 2 with the GNU Classpath
14
* Exception [1] and GNU General Public License, version 2 with the
15
* OpenJDK Assembly Exception [2].
16
*
17
* [1] https://www.gnu.org/software/classpath/license.html
18
* [2] http://openjdk.java.net/legal/assembly-exception.html
19
*
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-exception
21
*******************************************************************************/
22
23
24
25
#include "j9.h"
26
#include "j9cfg.h"
27
#include "j9consts.h"
28
#include "ModronAssertions.h"
29
30
#include "CardListFlushTask.hpp"
31
32
#include "CardTable.hpp"
33
#include "CycleState.hpp"
34
#include "EnvironmentVLHGC.hpp"
35
#include "HeapRegionIteratorVLHGC.hpp"
36
#include "HeapRegionManager.hpp"
37
#include "InterRegionRememberedSet.hpp"
38
#include "ParallelDispatcher.hpp"
39
#include "RememberedSetCardListBufferIterator.hpp"
40
#include "RememberedSetCardListCardIterator.hpp"
41
#include "MarkMap.hpp"
42
#include "SchedulingDelegate.hpp"
43
44
void
45
MM_CardListFlushTask::mainSetup(MM_EnvironmentBase *env)
46
{
47
Assert_MM_true(MM_CycleState::CT_PARTIAL_GARBAGE_COLLECTION == env->_cycleState->_collectionType);
48
}
49
50
void
51
MM_CardListFlushTask::mainCleanup(MM_EnvironmentBase *env)
52
{
53
}
54
55
void
56
MM_CardListFlushTask::writeFlushToCardState(Card *card, bool gmpIsActive)
57
{
58
Card fromState = *card;
59
switch(fromState) {
60
case CARD_CLEAN:
61
if (gmpIsActive) {
62
*card = CARD_REMEMBERED_AND_GMP_SCAN;
63
} else {
64
*card = CARD_REMEMBERED;
65
}
66
break;
67
case CARD_GMP_MUST_SCAN:
68
*card = CARD_REMEMBERED_AND_GMP_SCAN;
69
break;
70
case CARD_REMEMBERED_AND_GMP_SCAN:
71
case CARD_DIRTY:
72
/* do nothing */
73
break;
74
case CARD_REMEMBERED:
75
if (gmpIsActive) {
76
*card = CARD_REMEMBERED_AND_GMP_SCAN;
77
} else {
78
/* do nothing */
79
}
80
break;
81
case CARD_PGC_MUST_SCAN:
82
if (gmpIsActive) {
83
/* PGC_MUST_SCAN is a slightly stronger statement than REMEMBERED so we only add the GMP requirement by marking this DIRTY */
84
*card = CARD_DIRTY;
85
} else {
86
/* do nothing */
87
}
88
break;
89
default:
90
Assert_MM_unreachable();
91
break;
92
}
93
}
94
95
void
96
MM_CardListFlushTask::run(MM_EnvironmentBase *envBase)
97
{
98
MM_EnvironmentVLHGC *env = MM_EnvironmentVLHGC::getEnvironment(envBase);
99
MM_GCExtensions *extensions = MM_GCExtensions::getExtensions(env);
100
MM_MarkMap *markMap = NULL;
101
if (static_cast<MM_CycleStateVLHGC*>(envBase->_cycleState)->_schedulingDelegate->isFirstPGCAfterGMP()) {
102
markMap = env->_cycleState->_markMap;
103
}
104
105
/* this function has knowledge of the collection set, which is only valid during a PGC */
106
Assert_MM_true(MM_CycleState::CT_PARTIAL_GARBAGE_COLLECTION == env->_cycleState->_collectionType);
107
bool gmpIsActive = (NULL != env->_cycleState->_externalCycleState);
108
109
/* flush RS Lists for CollectionSet and dirty card table */
110
GC_HeapRegionIteratorVLHGC regionIterator(_regionManager);
111
MM_HeapRegionDescriptorVLHGC *region = NULL;
112
MM_InterRegionRememberedSet *interRegionRememberedSet = extensions->interRegionRememberedSet;
113
bool shouldFlushBuffersForUnregisteredRegions = interRegionRememberedSet->getShouldFlushBuffersForDecommitedRegions();
114
115
while (NULL != (region = regionIterator.nextRegion())) {
116
if (NULL != region->getMemoryPool()) {
117
if(region->_markData._shouldMark) {
118
if(J9MODRON_HANDLE_NEXT_WORK_UNIT(env)) {
119
Assert_MM_true(region->getRememberedSetCardList()->isAccurate());
120
/* Iterate non-overflowed buckets of the list */
121
GC_RememberedSetCardListCardIterator rsclCardIterator(region->getRememberedSetCardList());
122
UDATA card = 0;
123
while(0 != (card = rsclCardIterator.nextReferencingCard(env))) {
124
/* For Marking purposes we do not need to track references within Collection Set */
125
MM_HeapRegionDescriptorVLHGC *referencingRegion = interRegionRememberedSet->tableDescriptorForRememberedSetCard(card);
126
if (interRegionRememberedSet->cardMayContainObjects(card, referencingRegion, markMap) && !referencingRegion->_markData._shouldMark) {
127
Card *cardAddress = interRegionRememberedSet->rememberedSetCardToCardAddr(env, card);
128
writeFlushToCardState(cardAddress, gmpIsActive);
129
}
130
}
131
132
/* Clear remembered references to each region in Collection Set (completely clear RS Card List for those regions
133
* and appropriately update RSM). We are about to rebuild those references in PGC.
134
*/
135
_interRegionRememberedSet->clearReferencesToRegion(env, region);
136
}
137
} else if (shouldFlushBuffersForUnregisteredRegions) {
138
if (J9MODRON_HANDLE_NEXT_WORK_UNIT(env)) {
139
/* flush the content of buffers owned by decommitted regions (but used/borrowed by other active regions) */
140
bool const compressed = env->compressObjectReferences();
141
UDATA toRemoveCount = 0;
142
UDATA totalCountBefore = region->getRememberedSetCardList()->getSize(env);
143
MM_RememberedSetCard *lastCardInCurrentBuffer = NULL;
144
MM_CardBufferControlBlock *cardBufferControlBlockCurrent = NULL;
145
GC_RememberedSetCardListBufferIterator rsclBufferIterator(region->getRememberedSetCardList());
146
while (NULL != (cardBufferControlBlockCurrent = rsclBufferIterator.nextBuffer(env, &lastCardInCurrentBuffer))) {
147
/* find a region owning current Buffer being iterated */
148
MM_HeapRegionDescriptorVLHGC *bufferOwningRegion = interRegionRememberedSet->getBufferOwningRegion(cardBufferControlBlockCurrent);
149
/* owned by a decommited region, which hasn't released its buffer pool yet? */
150
if (!bufferOwningRegion->isCommitted()) {
151
Assert_MM_true(NULL != bufferOwningRegion->getRsclBufferPool());
152
rsclBufferIterator.unlinkCurrentBuffer(env);
153
for (MM_RememberedSetCard *cardSlot = cardBufferControlBlockCurrent->_card; cardSlot < lastCardInCurrentBuffer; cardSlot = MM_RememberedSetCard::addToCardAddress(cardSlot, 1, compressed)) {
154
UDATA card = MM_RememberedSetCard::readCard(cardSlot, compressed);
155
MM_HeapRegionDescriptorVLHGC *referencingRegion = interRegionRememberedSet->tableDescriptorForRememberedSetCard(card);
156
if (interRegionRememberedSet->cardMayContainObjects(card, referencingRegion, markMap) && !referencingRegion->_markData._shouldMark) {
157
Card *cardAddress = interRegionRememberedSet->rememberedSetCardToCardAddr(env, card);
158
writeFlushToCardState(cardAddress, gmpIsActive);
159
}
160
toRemoveCount += 1;
161
}
162
}
163
}
164
UDATA totalCountAfter = region->getRememberedSetCardList()->getSize(env);
165
Assert_MM_true(totalCountBefore == (toRemoveCount + totalCountAfter));
166
}
167
}
168
}
169
}
170
}
171
172
void
173
MM_CardListFlushTask::setup(MM_EnvironmentBase *env)
174
{
175
if (env->isMainThread()) {
176
Assert_MM_true(_cycleState == env->_cycleState);
177
} else {
178
Assert_MM_true(NULL == env->_cycleState);
179
env->_cycleState = _cycleState;
180
}
181
}
182
183
void
184
MM_CardListFlushTask::cleanup(MM_EnvironmentBase *env)
185
{
186
if (env->isMainThread()) {
187
Assert_MM_true(_cycleState == env->_cycleState);
188
} else {
189
env->_cycleState = NULL;
190
}
191
}
192
193
#if defined(J9MODRON_TGC_PARALLEL_STATISTICS)
194
void
195
MM_CardListFlushTask::synchronizeGCThreads(MM_EnvironmentBase *env, const char *id)
196
{
197
/* unused in this task */
198
Assert_MM_unreachable();
199
}
200
201
bool
202
MM_CardListFlushTask::synchronizeGCThreadsAndReleaseMain(MM_EnvironmentBase *env, const char *id)
203
{
204
/* unused in this task */
205
Assert_MM_unreachable();
206
return true;
207
}
208
209
bool
210
MM_CardListFlushTask::synchronizeGCThreadsAndReleaseSingleThread(MM_EnvironmentBase *env, const char *id)
211
{
212
/* unused in this task */
213
Assert_MM_unreachable();
214
return true;
215
}
216
#endif /* J9MODRON_TGC_PARALLEL_STATISTICS */
217
218