Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openj9
Path: blob/master/runtime/gc_vlhgc/CollectionSetDelegate.cpp
5986 views
1
/*******************************************************************************
2
* Copyright (c) 1991, 2021 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
* @file
25
* @ingroup GC_Modron_Tarok
26
*/
27
28
#include "j9.h"
29
#include "j9cfg.h"
30
#include "j9comp.h"
31
#include "j9port.h"
32
#include "gcutils.h"
33
#include "ModronAssertions.h"
34
35
#include "AllocationContextTarok.hpp"
36
#include "CollectionSetDelegate.hpp"
37
#include "CompactGroupManager.hpp"
38
#include "CompactGroupPersistentStats.hpp"
39
#include "CycleState.hpp"
40
#include "EnvironmentVLHGC.hpp"
41
#include "GlobalAllocationManagerTarok.hpp"
42
#include "MemorySubSpace.hpp"
43
#include "HeapMapWordIterator.hpp"
44
#include "HeapRegionDescriptorVLHGC.hpp"
45
#include "HeapRegionIteratorVLHGC.hpp"
46
#include "HeapRegionManager.hpp"
47
#include "HeapRegionManagerTarok.hpp"
48
#include "MarkMap.hpp"
49
#include "MemoryPool.hpp"
50
#include "RegionValidator.hpp"
51
52
MM_CollectionSetDelegate::MM_CollectionSetDelegate(MM_EnvironmentBase *env, MM_HeapRegionManager *manager)
53
: MM_BaseNonVirtual()
54
, _extensions(MM_GCExtensions::getExtensions(env))
55
, _regionManager(manager)
56
, _setSelectionDataTable(NULL)
57
, _dynamicSelectionList(NULL)
58
{
59
_typeId = __FUNCTION__;
60
}
61
62
bool
63
MM_CollectionSetDelegate::initialize(MM_EnvironmentVLHGC *env)
64
{
65
if(_extensions->tarokEnableDynamicCollectionSetSelection) {
66
UDATA setSelectionEntryCount = MM_CompactGroupManager::getCompactGroupMaxCount(env);
67
UDATA tableAllocationSizeInBytes = sizeof(SetSelectionData) * setSelectionEntryCount;
68
_setSelectionDataTable = (SetSelectionData *)env->getForge()->allocate(tableAllocationSizeInBytes, MM_AllocationCategory::FIXED, J9_GET_CALLSITE());
69
if(NULL == _setSelectionDataTable) {
70
goto error_no_memory;
71
}
72
memset((void *)_setSelectionDataTable, 0, tableAllocationSizeInBytes);
73
for(UDATA index = 0; index < setSelectionEntryCount; index++) {
74
_setSelectionDataTable[index]._compactGroup = index;
75
}
76
77
/* Publish table for TGC purposes */
78
_extensions->tarokTgcSetSelectionDataTable = (void *)_setSelectionDataTable;
79
80
_dynamicSelectionList = (SetSelectionData **)env->getForge()->allocate(sizeof(SetSelectionData *) * setSelectionEntryCount, MM_AllocationCategory::FIXED, J9_GET_CALLSITE());
81
if(NULL == _dynamicSelectionList) {
82
goto error_no_memory;
83
}
84
}
85
86
return true;
87
88
error_no_memory:
89
return false;
90
}
91
92
void
93
MM_CollectionSetDelegate::tearDown(MM_EnvironmentVLHGC *env)
94
{
95
if(NULL != _setSelectionDataTable) {
96
env->getForge()->free(_setSelectionDataTable);
97
_setSelectionDataTable = NULL;
98
}
99
100
if(NULL != _dynamicSelectionList) {
101
env->getForge()->free(_dynamicSelectionList);
102
_dynamicSelectionList = NULL;
103
}
104
}
105
106
/**
107
* Helper function used by J9_SORT to sort rate of return element lists.
108
*/
109
static int
110
compareRateOfReturnScoreFunc(const void *element1, const void *element2)
111
{
112
MM_CollectionSetDelegate::SetSelectionData *ror1 = *(MM_CollectionSetDelegate::SetSelectionData **)element1;
113
MM_CollectionSetDelegate::SetSelectionData *ror2 = *(MM_CollectionSetDelegate::SetSelectionData **)element2;
114
115
/* We actually do the checks instead of simple math (w/ multiplier) to catch slight differences. Perhaps if we multiply by 1000 then the differences are
116
* so minor it doesn't matter?
117
*/
118
if(ror1->_rateOfReturn == ror2->_rateOfReturn) {
119
return 0;
120
} else if(ror1->_rateOfReturn < ror2->_rateOfReturn ) {
121
return 1;
122
} else {
123
return -1;
124
}
125
}
126
127
/**
128
* Helper function used by J9_SORT to sort core sample element lists.
129
*/
130
static int
131
compareCoreSampleScoreFunc(const void *element1, const void *element2)
132
{
133
MM_CollectionSetDelegate::SetSelectionData *coreSample1 = *(MM_CollectionSetDelegate::SetSelectionData **)element1;
134
MM_CollectionSetDelegate::SetSelectionData *coreSample2 = *(MM_CollectionSetDelegate::SetSelectionData **)element2;
135
136
if(coreSample1->_regionCount == coreSample2->_regionCount) {
137
return 0;
138
} else if(coreSample1->_regionCount < coreSample2->_regionCount) {
139
return 1;
140
} else {
141
return -1;
142
}
143
}
144
145
UDATA
146
MM_CollectionSetDelegate::createNurseryCollectionSet(MM_EnvironmentVLHGC *env)
147
{
148
bool dynamicCollectionSet = _extensions->tarokEnableDynamicCollectionSetSelection;
149
Trc_MM_CollectionSetDelegate_createNurseryCollectionSet_Entry(env->getLanguageVMThread(), dynamicCollectionSet ? "true" : "false");
150
Assert_MM_true(MM_CycleState::CT_PARTIAL_GARBAGE_COLLECTION == env->_cycleState->_collectionType);
151
152
UDATA nurseryRegionCount = 0;
153
154
/* Calculate the core "required" collection set for the Partial GC, which constitutes all regions that are equal to
155
* or below the nursery age.
156
*/
157
GC_HeapRegionIteratorVLHGC regionIterator(_regionManager, MM_HeapRegionDescriptor::MANAGED);
158
MM_HeapRegionDescriptorVLHGC *region = NULL;
159
while (NULL != (region = regionIterator.nextRegion())) {
160
Assert_MM_true(MM_RegionValidator(region).validate(env));
161
Assert_MM_false(region->_markData._shouldMark);
162
Assert_MM_false(region->_reclaimData._shouldReclaim);
163
if (region->containsObjects()) {
164
bool regionHasCriticalRegions = (0 != region->_criticalRegionsInUse);
165
bool isSelectionForCopyForward = env->_cycleState->_shouldRunCopyForward;
166
167
/* We allow eden regions, which have jniCritical, to be part of nursery collectionSet; those regions would be marked instead of copyforwarded. */
168
if (region->getRememberedSetCardList()->isAccurate() && (!isSelectionForCopyForward || !regionHasCriticalRegions || (regionHasCriticalRegions && region->isEden()))) {
169
170
if(MM_CompactGroupManager::isRegionInNursery(env, region)) {
171
UDATA compactGroup = MM_CompactGroupManager::getCompactGroupNumber(env, region);
172
/* on collection phase, mark all non-overflowed regions and those that RSCL is not being rebuilt */
173
/* sweep/compact flags are set in ReclaimDelegate */
174
region->_markData._shouldMark = true;
175
region->_reclaimData._shouldReclaim = true;
176
region->_compactData._shouldCompact = false;
177
/* Collected regions are no longer target for defragmentation until next GMP */
178
region->_defragmentationTarget = false;
179
_extensions->compactGroupPersistentStats[compactGroup]._regionsInRegionCollectionSetForPGC += 1;
180
nurseryRegionCount += 1;
181
} else {
182
Assert_MM_true(!region->isEden());
183
}
184
185
/* Add the region to appropriate dynamic collection set data age group (building up information for later use) */
186
if(dynamicCollectionSet) {
187
UDATA compactGroup = MM_CompactGroupManager::getCompactGroupNumber(env, region);
188
_setSelectionDataTable[compactGroup].addRegion(region);
189
}
190
} else {
191
Assert_MM_true(!region->isEden());
192
}
193
}
194
}
195
196
Trc_MM_CollectionSetDelegate_createNurseryCollectionSet_Exit(env->getLanguageVMThread(), nurseryRegionCount);
197
return nurseryRegionCount;
198
}
199
200
UDATA
201
MM_CollectionSetDelegate::selectRegionsForBudget(MM_EnvironmentVLHGC *env, UDATA ageGroupBudget, SetSelectionData *setSelectionData)
202
{
203
Trc_MM_CollectionSetDelegate_selectRegionsForBudget_Entry(env->getLanguageVMThread(), ageGroupBudget);
204
UDATA ageGroupBudgetRemaining = ageGroupBudget;
205
UDATA regionSize = _regionManager->getRegionSize();
206
207
/* Walk the rate of return age group using a remainder skip-system to select the appropriate % of regions to collect (based on budget) */
208
UDATA regionSelectionIndex = 0;
209
UDATA regionSelectionIncrement = ageGroupBudget;
210
UDATA regionSelectionThreshold = setSelectionData->_regionCount;
211
MM_HeapRegionDescriptorVLHGC *regionSelectionPtr = setSelectionData->_regionList;
212
while((0 != ageGroupBudgetRemaining) && (NULL != regionSelectionPtr)) {
213
regionSelectionIndex += regionSelectionIncrement;
214
if(regionSelectionIndex >= regionSelectionThreshold) {
215
/* The region is to be selected as part of the dynamic set */
216
regionSelectionPtr->_markData._shouldMark = true;
217
regionSelectionPtr->_reclaimData._shouldReclaim = true;
218
regionSelectionPtr->_compactData._shouldCompact = false;
219
/* Collected regions are no longer target for defragmentation until the next GMP */
220
regionSelectionPtr->_defragmentationTarget = false;
221
ageGroupBudgetRemaining -= 1;
222
223
UDATA tableIndex = _regionManager->mapDescriptorToRegionTableIndex(regionSelectionPtr);
224
UDATA compactGroup = MM_CompactGroupManager::getCompactGroupNumber(env, regionSelectionPtr);
225
UDATA freeMemory = regionSelectionPtr->getMemoryPool()->getFreeMemoryAndDarkMatterBytes();
226
_extensions->compactGroupPersistentStats[compactGroup]._regionsInRegionCollectionSetForPGC += 1;
227
228
Trc_MM_CollectionSetDelegate_selectRegionsForBudget(env->getLanguageVMThread(), tableIndex, compactGroup, (100 * freeMemory)/regionSize, (UDATA) 0, (UDATA) 0);
229
}
230
regionSelectionIndex %= regionSelectionThreshold;
231
232
regionSelectionPtr = regionSelectionPtr->getDynamicSelectionNext();
233
}
234
235
Assert_MM_true(ageGroupBudgetRemaining <= ageGroupBudget);
236
Trc_MM_CollectionSetDelegate_selectRegionsForBudget_Exit(env->getLanguageVMThread(), ageGroupBudget - ageGroupBudgetRemaining);
237
return ageGroupBudgetRemaining;
238
}
239
240
void
241
MM_CollectionSetDelegate::createRateOfReturnCollectionSet(MM_EnvironmentVLHGC *env, UDATA nurseryRegionCount)
242
{
243
/* Build and sort the rate of return list into budget consumption priority order */
244
UDATA sortListSize = 0;
245
UDATA compactGroupCount = MM_CompactGroupManager::getCompactGroupMaxCount(env);
246
247
for (UDATA compactGroup = 0; compactGroup < compactGroupCount; compactGroup++) {
248
if (MM_CompactGroupManager::isCompactGroupDCSSCandidate(env, compactGroup)) {
249
SetSelectionData *tableEntry = &_setSelectionDataTable[compactGroup];
250
if ((0.0 != tableEntry->_rateOfReturn) && (0 != tableEntry->_regionCount)) {
251
_dynamicSelectionList[sortListSize] = tableEntry;
252
sortListSize += 1;
253
}
254
}
255
}
256
257
J9_SORT(_dynamicSelectionList, sortListSize, sizeof(SetSelectionData *), compareRateOfReturnScoreFunc);
258
259
/* Walk the ROR priority list and select regions based on remaining available budget */
260
UDATA regionBudget = 0;
261
if(0 != _extensions->tarokDynamicCollectionSetSelectionAbsoluteBudget) {
262
regionBudget = _extensions->tarokDynamicCollectionSetSelectionAbsoluteBudget;
263
} else {
264
regionBudget = (UDATA)(nurseryRegionCount * _extensions->tarokDynamicCollectionSetSelectionPercentageBudget);
265
}
266
267
Trc_MM_CollectionSetDelegate_createRegionCollectionSetForPartialGC_dynamicRegionSelectionBudget(
268
env->getLanguageVMThread(),
269
nurseryRegionCount,
270
regionBudget
271
);
272
273
UDATA rorIndex = 0;
274
while((0 != regionBudget) && (rorIndex < sortListSize)) {
275
SetSelectionData *rorEntry = _dynamicSelectionList[rorIndex];
276
277
/* Determine the budget available for collection in the current compact group */
278
UDATA compactGroupBudget = (UDATA)( ((double)regionBudget) * rorEntry->_rateOfReturn );
279
Assert_MM_true(compactGroupBudget <= regionBudget);
280
compactGroupBudget = OMR_MIN(compactGroupBudget, rorEntry->_regionCount);
281
282
UDATA compactGroupBudgetRemaining = 0;
283
284
if(compactGroupBudget > 0) {
285
/* The age group is participating in dynamic set selection */
286
rorEntry->_dynamicSelectionThisCycle = true;
287
288
compactGroupBudgetRemaining = selectRegionsForBudget(env, compactGroupBudget, rorEntry);
289
}
290
291
/* Deduct the age group budget used from the overall budget */
292
Assert_MM_true(compactGroupBudget >= compactGroupBudgetRemaining);
293
UDATA budgetConsumed = compactGroupBudget - compactGroupBudgetRemaining;
294
Assert_MM_true(regionBudget >= budgetConsumed);
295
regionBudget -= budgetConsumed;
296
297
Trc_MM_CollectionSetDelegate_createRegionCollectionSetForPartialGC_dynamicRegionSelection(
298
env->getLanguageVMThread(),
299
rorEntry->_compactGroup,
300
rorEntry->_regionCount,
301
1000.0 * rorEntry->_rateOfReturn,
302
compactGroupBudget,
303
budgetConsumed
304
);
305
306
/* Move to the next ROR entry */
307
rorIndex += 1;
308
}
309
Trc_MM_CollectionSetDelegate_createRegionCollectionSetForPartialGC_dynamicRegionSelectionBudgetRemaining(
310
env->getLanguageVMThread(),
311
regionBudget
312
);
313
}
314
315
void
316
MM_CollectionSetDelegate::createCoreSamplingCollectionSet(MM_EnvironmentVLHGC *env, UDATA nurseryRegionCount)
317
{
318
/* Collect and sort all regions into the core sample buckets so that we can find them quickly (this is an optimization) */
319
UDATA totalCoreSampleRegions = 0;
320
UDATA sortListSize = 0;
321
UDATA compactGroupCount = MM_CompactGroupManager::getCompactGroupMaxCount(env);
322
323
for (UDATA compactGroup = 0; compactGroup < compactGroupCount; compactGroup++) {
324
if (MM_CompactGroupManager::isCompactGroupDCSSCandidate(env, compactGroup)) {
325
SetSelectionData *tableEntry = &_setSelectionDataTable[compactGroup];
326
if (!tableEntry->_dynamicSelectionThisCycle && (0 != tableEntry->_regionCount)) {
327
/* The region is a collection candidate and eligible for dynamic selection - count it as part of the total possible core sampling group */
328
totalCoreSampleRegions += tableEntry->_regionCount;
329
_dynamicSelectionList[sortListSize] = tableEntry;
330
sortListSize += 1;
331
}
332
}
333
}
334
335
J9_SORT(_dynamicSelectionList, sortListSize, sizeof(SetSelectionData *), compareCoreSampleScoreFunc);
336
337
/* Given a region budget, select regions for core sampling according to population and whether the age group has participated in other
338
* dynamically added activities.
339
*/
340
UDATA regionBudget = 0;
341
if(0 != _extensions->tarokCoreSamplingAbsoluteBudget) {
342
regionBudget = _extensions->tarokCoreSamplingAbsoluteBudget;
343
} else {
344
regionBudget = (UDATA)(nurseryRegionCount * _extensions->tarokCoreSamplingPercentageBudget);
345
}
346
347
Trc_MM_CollectionSetDelegate_createRegionCollectionSetForPartialGC_coreSamplingBudget(
348
env->getLanguageVMThread(),
349
totalCoreSampleRegions,
350
regionBudget
351
);
352
353
UDATA coreSampleIndex = 0;
354
while((regionBudget != 0) && (coreSampleIndex < sortListSize)) {
355
SetSelectionData *coreSample = _dynamicSelectionList[coreSampleIndex];
356
UDATA compactGroup = coreSample->_compactGroup;
357
358
Assert_MM_true(!_setSelectionDataTable[compactGroup]._dynamicSelectionThisCycle);
359
360
/* Determine the budget available for collection in the current compact group */
361
Assert_MM_true(totalCoreSampleRegions > 0);
362
UDATA compactGroupBudget = (UDATA) (((double)regionBudget) * ((double)coreSample->_regionCount) / ((double)totalCoreSampleRegions));
363
Assert_MM_true(compactGroupBudget <= regionBudget);
364
compactGroupBudget = OMR_MIN(compactGroupBudget, coreSample->_regionCount);
365
/* Want at least one region out of this */
366
compactGroupBudget = OMR_MAX(compactGroupBudget, 1);
367
368
UDATA compactGroupBudgetRemaining = 0;
369
370
if(compactGroupBudget > 0) {
371
compactGroupBudgetRemaining = selectRegionsForBudget(env, compactGroupBudget, coreSample);
372
}
373
374
/* Deduct the compact group budget used from the overall budget */
375
Assert_MM_true(compactGroupBudget >= compactGroupBudgetRemaining);
376
UDATA budgetConsumed = compactGroupBudget - compactGroupBudgetRemaining;
377
Assert_MM_true(regionBudget >= budgetConsumed);
378
regionBudget -= budgetConsumed;
379
380
Trc_MM_CollectionSetDelegate_createRegionCollectionSetForPartialGC_coreSamplingSelection(
381
env->getLanguageVMThread(),
382
compactGroup,
383
coreSample->_regionCount,
384
compactGroupBudget,
385
budgetConsumed
386
);
387
388
coreSampleIndex += 1;
389
}
390
391
Trc_MM_CollectionSetDelegate_createRegionCollectionSetForPartialGC_coreSamplingBudgetRemaining(
392
env->getLanguageVMThread(),
393
regionBudget
394
);
395
}
396
397
398
void
399
MM_CollectionSetDelegate::createRegionCollectionSetForPartialGC(MM_EnvironmentVLHGC *env)
400
{
401
Assert_MM_true(MM_CycleState::CT_PARTIAL_GARBAGE_COLLECTION == env->_cycleState->_collectionType);
402
403
bool dynamicCollectionSet = _extensions->tarokEnableDynamicCollectionSetSelection;
404
405
/* If dynamic collection sets are enabled, reset all related data structures that are used for selection */
406
if(dynamicCollectionSet) {
407
MM_CompactGroupPersistentStats *persistentStats = _extensions->compactGroupPersistentStats;
408
UDATA compactGroupCount = MM_CompactGroupManager::getCompactGroupMaxCount(env);
409
410
for(UDATA compactGroup = 0; compactGroup < compactGroupCount; compactGroup++) {
411
Assert_MM_true(compactGroup == _setSelectionDataTable[compactGroup]._compactGroup);
412
_setSelectionDataTable[compactGroup]._regionCount = 0;
413
_setSelectionDataTable[compactGroup]._regionList = NULL;
414
/* cache the survival rate in this table since we sort based on rate of return (1-survival) */
415
/* survival rate can be more than 100% if the compact group is being used as a migration target due to NUMA proximity */
416
double survivalRate = OMR_MIN(1.0, persistentStats[compactGroup]._historicalSurvivalRate);
417
_setSelectionDataTable[compactGroup]._rateOfReturn = (1.0 - survivalRate);
418
_setSelectionDataTable[compactGroup]._dynamicSelectionThisCycle = false;
419
}
420
}
421
422
UDATA nurseryRegionCount = createNurseryCollectionSet(env);
423
424
425
/* Add any non-nursery regions to the collection set as the rate-of-return and region budget dictates */
426
if(dynamicCollectionSet) {
427
createRateOfReturnCollectionSet(env, nurseryRegionCount);
428
createCoreSamplingCollectionSet(env, nurseryRegionCount);
429
430
/* Clean up any linkage data that was computed during set selection but will potentially become stale over the course of the run */
431
432
/* Reset base region counts and lists */
433
UDATA compactGroupCount = MM_CompactGroupManager::getCompactGroupMaxCount(env);
434
435
for(UDATA compactGroup = 0; compactGroup < compactGroupCount; compactGroup++) {
436
_setSelectionDataTable[compactGroup]._regionCount = 0;
437
_setSelectionDataTable[compactGroup]._regionList = NULL;
438
}
439
440
/* Clean list linkage between all regions (age group lists) */
441
GC_HeapRegionIteratorVLHGC regionIterator(_regionManager, MM_HeapRegionDescriptor::MANAGED);
442
MM_HeapRegionDescriptorVLHGC *region = NULL;
443
while (NULL != (region = regionIterator.nextRegion())) {
444
region->setDynamicSelectionNext(NULL);
445
}
446
}
447
}
448
449
void
450
MM_CollectionSetDelegate::deleteRegionCollectionSetForPartialGC(MM_EnvironmentVLHGC *env)
451
{
452
Assert_MM_true(MM_CycleState::CT_PARTIAL_GARBAGE_COLLECTION == env->_cycleState->_collectionType);
453
454
GC_HeapRegionIteratorVLHGC regionIterator(_regionManager);
455
MM_HeapRegionDescriptorVLHGC *region = NULL;
456
while (NULL != (region = regionIterator.nextRegion())) {
457
/* there shouldn't be any regions that have some occupancy but not marked left if the increment is done */
458
Assert_MM_false(MM_HeapRegionDescriptor::ADDRESS_ORDERED == region->getRegionType());
459
Assert_MM_true(MM_RegionValidator(region).validate(env));
460
461
region->_markData._shouldMark = false;
462
region->_reclaimData._shouldReclaim = false;
463
region->_markData._noEvacuation = false;
464
}
465
}
466
467
void
468
MM_CollectionSetDelegate::createRegionCollectionSetForGlobalGC(MM_EnvironmentVLHGC *env)
469
{
470
Assert_MM_true(MM_CycleState::CT_GLOBAL_GARBAGE_COLLECTION == env->_cycleState->_collectionType);
471
472
GC_HeapRegionIteratorVLHGC regionIterator(_regionManager, MM_HeapRegionDescriptor::MANAGED);
473
MM_HeapRegionDescriptorVLHGC *region = NULL;
474
while (NULL != (region = regionIterator.nextRegion())) {
475
Assert_MM_true(MM_RegionValidator(region).validate(env));
476
Assert_MM_false(region->_reclaimData._shouldReclaim);
477
if (region->containsObjects()) {
478
region->_reclaimData._shouldReclaim = true;
479
region->_compactData._shouldCompact = false;
480
}
481
}
482
}
483
484
void
485
MM_CollectionSetDelegate::deleteRegionCollectionSetForGlobalGC(MM_EnvironmentVLHGC *env)
486
{
487
Assert_MM_true(MM_CycleState::CT_GLOBAL_GARBAGE_COLLECTION == env->_cycleState->_collectionType);
488
489
GC_HeapRegionIteratorVLHGC regionIterator(_regionManager);
490
MM_HeapRegionDescriptorVLHGC *region = NULL;
491
while (NULL != (region = regionIterator.nextRegion())) {
492
/* there shouldn't be any regions that have some occupancy but not marked left */
493
Assert_MM_false(MM_HeapRegionDescriptor::ADDRESS_ORDERED == region->getRegionType());
494
Assert_MM_true(MM_RegionValidator(region).validate(env));
495
496
region->_reclaimData._shouldReclaim = false;
497
}
498
}
499
500
MM_HeapRegionDescriptorVLHGC*
501
MM_CollectionSetDelegate::getNextRegion(MM_HeapRegionDescriptorVLHGC* cursor)
502
{
503
MM_HeapRegionDescriptorVLHGC* result = cursor;
504
if (NULL != result) {
505
result = (MM_HeapRegionDescriptorVLHGC*)_regionManager->getNextTableRegion(result);
506
}
507
if (NULL == result) {
508
result = (MM_HeapRegionDescriptorVLHGC*)_regionManager->getFirstTableRegion();
509
}
510
Assert_MM_true(NULL != result);
511
return result;
512
}
513
514
void
515
MM_CollectionSetDelegate::rateOfReturnCalculationBeforeSweep(MM_EnvironmentVLHGC *env)
516
{
517
if(_extensions->tarokEnableDynamicCollectionSetSelection) {
518
UDATA compactGroupCount = MM_CompactGroupManager::getCompactGroupMaxCount(env);
519
for (UDATA compactGroup = 0; compactGroup < compactGroupCount; compactGroup++) {
520
/* Clear the current trace reclaim rate table information as we'll be building a new set */
521
_setSelectionDataTable[compactGroup]._reclaimStats.reset();
522
}
523
524
/* Walk and count all regions, and count any region that will be included in the sweep set (those in trace or those that require re-sweeping due to a GMP) */
525
GC_HeapRegionIteratorVLHGC regionIterator(_regionManager, MM_HeapRegionDescriptor::ALL);
526
MM_HeapRegionDescriptorVLHGC *region = NULL;
527
while (NULL != (region = regionIterator.nextRegion())) {
528
if(region->containsObjects()) {
529
SetSelectionData *stats = &_setSelectionDataTable[MM_CompactGroupManager::getCompactGroupNumber(env, region)];
530
MM_MemoryPool *memoryPool = region->getMemoryPool();
531
532
stats->_reclaimStats._regionCountBefore += 1;
533
if(!region->_sweepData._alreadySwept) {
534
stats->_reclaimStats._reclaimableRegionCountBefore += 1;
535
536
stats->_reclaimStats._regionBytesFreeBefore += memoryPool->getActualFreeMemorySize();
537
stats->_reclaimStats._regionDarkMatterBefore += memoryPool->getDarkMatterBytes();
538
}
539
if(!region->getRememberedSetCardList()->isAccurate()) {
540
stats->_reclaimStats._regionCountOverflow += 1;
541
}
542
} else if(region->isArrayletLeaf()) {
543
MM_HeapRegionDescriptorVLHGC *parentRegion = (MM_HeapRegionDescriptorVLHGC *)_regionManager->regionDescriptorForAddress((void *)region->_allocateData.getSpine());
544
Assert_MM_true(parentRegion->containsObjects());
545
SetSelectionData *stats = &_setSelectionDataTable[MM_CompactGroupManager::getCompactGroupNumber(env, parentRegion)];
546
547
stats->_reclaimStats._regionCountBefore += 1;
548
stats->_reclaimStats._regionCountArrayletLeafBefore += 1;
549
550
if(!parentRegion->_sweepData._alreadySwept) {
551
stats->_reclaimStats._reclaimableRegionCountBefore += 1;
552
stats->_reclaimStats._reclaimableRegionCountArrayletLeafBefore += 1;
553
}
554
if(!parentRegion->getRememberedSetCardList()->isAccurate()) {
555
stats->_reclaimStats._regionCountArrayletLeafOverflow += 1;
556
}
557
}
558
}
559
}
560
}
561
562
void
563
MM_CollectionSetDelegate::rateOfReturnCalculationAfterSweep(MM_EnvironmentVLHGC *env)
564
{
565
if(_extensions->tarokEnableDynamicCollectionSetSelection) {
566
/* Walk and count all regions */
567
GC_HeapRegionIteratorVLHGC regionIterator(_regionManager, MM_HeapRegionDescriptor::ALL);
568
MM_HeapRegionDescriptorVLHGC *region = NULL;
569
while (NULL != (region = regionIterator.nextRegion())) {
570
if(region->containsObjects()) {
571
UDATA compactGroup = MM_CompactGroupManager::getCompactGroupNumber(env, region);
572
SetSelectionData *stats = &_setSelectionDataTable[compactGroup];
573
MM_MemoryPool *memoryPool = region->getMemoryPool();
574
575
stats->_reclaimStats._regionCountAfter += 1;
576
577
if(!region->_sweepData._alreadySwept) {
578
stats->_reclaimStats._reclaimableRegionCountAfter += 1;
579
580
stats->_reclaimStats._regionBytesFreeAfter += memoryPool->getActualFreeMemorySize();
581
stats->_reclaimStats._regionDarkMatterAfter += memoryPool->getDarkMatterBytes();
582
}
583
} else if(region->isArrayletLeaf()) {
584
MM_HeapRegionDescriptorVLHGC *parentRegion = (MM_HeapRegionDescriptorVLHGC *)_regionManager->regionDescriptorForAddress((void *)region->_allocateData.getSpine());
585
Assert_MM_true(parentRegion->containsObjects());
586
SetSelectionData *stats = &_setSelectionDataTable[MM_CompactGroupManager::getCompactGroupNumber(env, parentRegion)];
587
588
stats->_reclaimStats._regionCountAfter += 1;
589
stats->_reclaimStats._regionCountArrayletLeafAfter += 1;
590
591
if(!parentRegion->_sweepData._alreadySwept) {
592
stats->_reclaimStats._reclaimableRegionCountAfter += 1;
593
stats->_reclaimStats._reclaimableRegionCountArrayletLeafAfter += 1;
594
}
595
}
596
}
597
598
/* We now have an expected change as a result of tracing and sweeping (parts of) the heap. Calculate the rate-of-return (ROR) on
599
* tracing for age groups where work was done.
600
* Use a weighted running average to calculate the ROR, where the weight is the % of regions in an age group that we are examining.
601
* NOTE: We leave the ROR for the last age group as 0.
602
*/
603
UDATA compactGroupCount = MM_CompactGroupManager::getCompactGroupMaxCount(env);
604
605
for(UDATA compactGroup = 0; compactGroup < compactGroupCount; compactGroup++) {
606
if (MM_CompactGroupManager::getRegionAgeFromGroup(env, compactGroup) < _extensions->tarokRegionMaxAge) {
607
/* We set the compact group for each entry every time through a table. This is overkill, but allows us to be sure when examining a ROR element whether
608
* in fact it represents the compact group with think it does.
609
*/
610
SetSelectionData *stats = &_setSelectionDataTable[compactGroup];
611
stats->_compactGroup = compactGroup;
612
613
if(0 == stats->_reclaimStats._reclaimableRegionCountBefore) {
614
Assert_MM_true(stats->_reclaimStats._regionCountBefore == stats->_reclaimStats._regionCountAfter);
615
} else {
616
Assert_MM_true(stats->_reclaimStats._regionCountBefore >= stats->_reclaimStats._reclaimableRegionCountBefore);
617
Assert_MM_true(stats->_reclaimStats._regionCountBefore >= stats->_reclaimStats._regionCountAfter);
618
Assert_MM_true(stats->_reclaimStats._reclaimableRegionCountBefore >= stats->_reclaimStats._reclaimableRegionCountAfter);
619
620
UDATA bytesConsumedBefore =
621
(stats->_reclaimStats._reclaimableRegionCountBefore * _extensions->regionSize)
622
- stats->_reclaimStats._regionBytesFreeBefore
623
- stats->_reclaimStats._regionDarkMatterBefore;
624
stats->_reclaimStats._reclaimableBytesConsumedBefore = bytesConsumedBefore;
625
UDATA bytesConsumedAfter =
626
(stats->_reclaimStats._reclaimableRegionCountAfter * _extensions->regionSize)
627
- stats->_reclaimStats._regionBytesFreeAfter
628
- stats->_reclaimStats._regionDarkMatterAfter;
629
stats->_reclaimStats._reclaimableBytesConsumedAfter = bytesConsumedAfter;
630
}
631
}
632
}
633
}
634
}
635
636