-
Notifications
You must be signed in to change notification settings - Fork 738
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Pruning the cards from InterRegionRememberedsets after GMP #8804
Conversation
bool needToFlush = true; | ||
if (needToCheckMarkMap) { | ||
void* heapAddress = convertHeapAddressFromRememberedSetCard(envBase, card); | ||
uint64_t* map4Card = (uint64_t*) &((uintptr_t *)(markMap->getMarkBits()))[markMap->getSlotIndex((omrobjectptr_t) heapAddress)]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this needs to go to MarkMap class, a helper like:
bool anyLiveObjectInCard(void *heapAddress);
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
and state in a comment that implementation assumes that card covers exactly 512 bytes, 1 mark bit is 8 bytes of heap and heap address is card size aligned.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you can add compile time assert that BITS_PER_BYTE is 8 and CARD_SIZE_SHIFT is 9
writeFlushToCardState(cardAddress, gmpIsActive); | ||
bool needToFlush = true; | ||
if (needToCheckMarkMap) { | ||
void* heapAddress = convertHeapAddressFromRememberedSetCard(envBase, card); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
interRegionRememberedSet is available. you can use its convertHeapAddressFromRememberedSetCard(), and no need to clone it in this class
needToRemove = true; | ||
} | ||
|
||
if (!needToRemove && needToCheckMarkMap) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The new check is just more generic variant of fromRegion->containsObjects().
So I recommend you introduce a helper that will replace that containsObjects() check:
inline bool IRRS::cardContainsObjects(card, fromRegion, needToCheckMarkMap) {
if needToCheckMarkMap
return markMap->anyLiveObjectInCard(card)
else
return !fromRegion->containsObjects()
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can later consider checking against MarkMap all the time (not just after GMP), if it's not much slower. But that might be tricky since for evacuated regions clearing of mark map might be done late(r).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The new check is just more generic variant of fromRegion->containsObjects().
So I recommend you introduce a helper that will replace that containsObjects() check:inline bool IRRS::cardContainsObjects(card, fromRegion, needToCheckMarkMap) {
if needToCheckMarkMap
return markMap->anyLiveObjectInCard(card)
else
return !fromRegion->containsObjects()
}
good idea! it is good for clearFromRegionReferencesForMarkDirect(), but for clearFromRegionReferencesForMarkOptimized() (it is default, using compressed card table ), it is little bit tricky, partial logic for checking empty region is in rebuildCompressedCardTableForMark(), we can add CheckMarkMap in rebuildCompressedCardTableForMark, but it need to check every card in the regions, it might be expensive?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see. Actually, I think it is CompressedCardTable::rebuildCompressedCardTableForPartialCollect that would be more impacted. We could try that later and see if it will slow it down.
Still I think you can introduce the helper and use it here, and in 'else' clause of 'if (compressedCardTable->isReady()) {', while the existing areAnyLiveObjectsInCard() check you can move up in 'then' clause of 'if (compressedCardTable->isReady()) {'
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if we use the helper in "else" clause, so we have to add the logic in rebuildCompressedCardTableForPartialCollect(), otherwise if compressedCardTable->isReady() case, we would miss to check markMap.
if (compressedCardTable->isReady()) {
....
} else {
}
We need to think/test if Mark Map based check is needed in first PGC after a Mark-Compact based PGC, since it may also create populated regions with empty chunks (at least a tail, if not a chunk in a middle). |
7b3c5eb
to
9469d5a
Compare
there is pruning card at the beginning of compact, clearFromRegionReferencesForCompact(), not sure if it covered the cases. |
32d98bc
to
84d4894
Compare
84d4894
to
d1c00ab
Compare
499e655
to
47aa9c2
Compare
Card *cardAddress = interRegionRememberedSet->rememberedSetCardToCardAddr(env, card); | ||
writeFlushToCardState(cardAddress, gmpIsActive); | ||
if (interRegionRememberedSet->cardMayContainObjects(card, referencingRegion, needToCheckMarkMap, markMap) && !referencingRegion->_markData._shouldMark) { | ||
bool needToFlush = true; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
no need for needToFlush flag, any more. here, and at a couple of other similar spots.
if (fromRegion->_markData._shouldMark || !fromRegion->containsObjects() || isDirtyCardForPartialCollect(env, cardTable, cardAddress)) { | ||
/* Regions that are completely swept after a GMP, might still have outgoing references (thus we consider cardContainsNoObjects) */ | ||
if (fromRegion->_markData._shouldMark || !cardMayContainObjects(card, fromRegion, needToCheckMarkMap, markMap) || isDirtyCardForPartialCollect(env, cardTable, cardAddress)) { | ||
needToRemove = true; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
no need for needToRemove
* Helper function isCompressedCardDirtyForPartialCollect | ||
* extended from compressedCardTable->isCompressedCardDirtyForPartialCollect(), only in case first PGC after GMP, also dirty card if card Contains No Object. | ||
*/ | ||
MMINLINE bool isCompressedCardDirtyForPartialCollect(MM_EnvironmentVLHGC* env, UDATA card, bool needToCheckMarkMap) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
pass compressedCardTable and mark map
47aa9c2
to
b850c12
Compare
@@ -933,11 +935,12 @@ MM_InterRegionRememberedSet::clearFromRegionReferencesForMarkDirect(MM_Environme | |||
while(0 != (card = rsclCardIterator.nextReferencingCard(env))) { | |||
MM_HeapRegionDescriptorVLHGC *fromRegion = tableDescriptorForRememberedSetCard(card); | |||
Card * cardAddress = rememberedSetCardToCardAddr(env, card); | |||
/* Regions that are completely swept after a GMP, might still have outgoing references (thus we consider empty regions too) */ | |||
if (fromRegion->_markData._shouldMark || !fromRegion->containsObjects() || isDirtyCardForPartialCollect(env, cardTable, cardAddress)) { | |||
/* Regions that are completely swept after a GMP, might still have outgoing references (thus we consider cardContainsNoObjects) */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This whole comment should be updated:
Regions that are completely swept or parts of regions that are partially swept after a GMP might still have outgoing references. If they are (if they may not contain objects), cards should be removed.
fe52ec3
to
3d321a7
Compare
* if this is first PGC after GMP, check if markMap->areAnyLiveObjectsInCard() | ||
* otherwise check if region->containsObjects() | ||
*/ | ||
MMINLINE bool cardMayContainObjects(UDATA card, MM_HeapRegionDescriptorVLHGC *fromRegion, bool needToCheckMarkMap, MM_MarkMap *markMap) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
both helpers could be static (hence saving by not passing implicit 'this' pointer)
3d321a7
to
e27f867
Compare
@@ -96,6 +97,11 @@ MM_CardListFlushTask::run(MM_EnvironmentBase *envBase) | |||
{ | |||
MM_EnvironmentVLHGC *env = MM_EnvironmentVLHGC::getEnvironment(envBase); | |||
MM_GCExtensions *extensions = MM_GCExtensions::getExtensions(env); | |||
MM_MarkMap *markMap = NULL; | |||
if (static_cast<MM_CycleStateVLHGC*>(envBase->_cycleState)->_schedulingDelegate->isFirstPGCAfterGMP()) | |||
{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
move open bracket to previous line
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
your fixed the other two, but not this one :)
MM_CardTable *cardTable = extensions->cardTable; | ||
MM_MarkMap *markMap = NULL; | ||
if (static_cast<MM_CycleStateVLHGC*>(env->_cycleState)->_schedulingDelegate->isFirstPGCAfterGMP()) | ||
{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
move bracket
MM_CompressedCardTable *compressedCardTable = extensions->compressedCardTable; | ||
MM_MarkMap *markMap = NULL; | ||
if (static_cast<MM_CycleStateVLHGC*>(env->_cycleState)->_schedulingDelegate->isFirstPGCAfterGMP()) | ||
{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
bracket
|
||
/** | ||
* Helper function isCompressedCardDirtyForPartialCollect | ||
* extended from compressedCardTable->isCompressedCardDirtyForPartialCollect(), only in case first PGC after GMP, also dirty card if card Contains No Object. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
comment says 'also dirty card'
did you mean 'also remove card'?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
compressedCardTable->isCompressedCardDirtyForPartialCollect() return true if the card is dirty, extra condition if the card Contains No Object return true (the card is dirty)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, then it should say 'also return as dirty'. As-is I understood you imply an action of dirtying the card.
e27f867
to
1f047a6
Compare
{ | ||
void* heapAddress = convertHeapAddressFromRememberedSetCard(card); | ||
bool ret = compressedCardTable->isCompressedCardDirtyForPartialCollect(env, heapAddress); | ||
if (!ret && (NULL != markMap)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
add comment:
TODO: consider incorporating areAnyLiveObjectsInCard info when building Compressed Card Table
1f047a6
to
08dd3be
Compare
Jenkins test sanity all jdk8 |
08dd3be
to
81ae862
Compare
* if this is first PGC after GMP, check if markMap->areAnyLiveObjectsInCard() | ||
* otherwise check if region->containsObjects() | ||
*/ | ||
MMINLINE static bool cardMayContainObjects(UDATA card, MM_HeapRegionDescriptorVLHGC *fromRegion, MM_MarkMap *markMap) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These helpers won't be able to be static, afterall :( . It may work now, but once OMR_GC_FULL_POINTERS is enabled, they will indirectly rely on class member _compressObjectReferences
After Global Marking Phase, the cards reference from "free memory" should be pruned from InterRegionRememberedsets, in order to reuse the free memory in future, currently we have card refresh and card pruning in beginning PGC, so piggyback existing logic add extra condition for pruning cards related with "free memory" in first PGC after GMP. - During Rememberedsets flush in the beginning PGC(for collection set), extra condition check for dirty card (do not dirty card if corresponding MarkMap is 0) - During global Rememberedsets prune, extra condition check for pruning the card (do remove the card if corresponding MarkMap is 0). Signed-off-by: Lin Hu <linhu@ca.ibm.com>
81ae862
to
c9711af
Compare
Jenkins test sanity all jdk8 |
depends on: eclipse-omr/omr#4928
fix partial #9247
Signed-off-by: Lin Hu linhu@ca.ibm.com