diff options
author | Jiyoung Yun <jy910.yun@samsung.com> | 2017-06-13 18:47:36 +0900 |
---|---|---|
committer | Jiyoung Yun <jy910.yun@samsung.com> | 2017-06-13 18:47:36 +0900 |
commit | 61d6a817e39d3bae0f47dbc09838d51db22a5d30 (patch) | |
tree | cb37caa1784bc738b976273335d6ed04a7cc80b0 /src/gc | |
parent | 5b975f8233e8c8d17b215372f89ca713b45d6a0b (diff) | |
download | coreclr-61d6a817e39d3bae0f47dbc09838d51db22a5d30.tar.gz coreclr-61d6a817e39d3bae0f47dbc09838d51db22a5d30.tar.bz2 coreclr-61d6a817e39d3bae0f47dbc09838d51db22a5d30.zip |
Imported Upstream version 2.0.0.11992upstream/2.0.0.11992
Diffstat (limited to 'src/gc')
-rw-r--r-- | src/gc/handletablecore.cpp | 26 | ||||
-rw-r--r-- | src/gc/objecthandle.cpp | 3 |
2 files changed, 28 insertions, 1 deletions
diff --git a/src/gc/handletablecore.cpp b/src/gc/handletablecore.cpp index 00ab6a24b9..228b8bfa09 100644 --- a/src/gc/handletablecore.cpp +++ b/src/gc/handletablecore.cpp @@ -1592,6 +1592,7 @@ void SegmentResortChains(TableSegment *pSegment) // clear the sort flag for this segment pSegment->fResortChains = FALSE; + BOOL fScavengingOccurred = FALSE; // first, do we need to scavenge any blocks? if (pSegment->fNeedsScavenging) @@ -1599,6 +1600,8 @@ void SegmentResortChains(TableSegment *pSegment) // clear the scavenge flag pSegment->fNeedsScavenging = FALSE; + fScavengingOccurred = TRUE; + // we may need to explicitly scan the user data chain too BOOL fCleanupUserData = FALSE; @@ -1758,6 +1761,21 @@ void SegmentResortChains(TableSegment *pSegment) if (pSegment->rgBlockType[pSegment->rgHint[uType]] != uType) pSegment->rgHint[uType] = bBlock; } + else + { + // No blocks of this type were found in the rgBlockType array, meaning either there were no + // such blocks on entry to this function (in which case the associated tail is guaranteed + // to already be marked invalid) OR that there were blocks but all of them were reclaimed + // by the scavenging logic above (in which case the associated tail is guaranteed to point + // to one of the scavenged blocks). In the latter case, the tail is currently "stale" + // and therefore needs to be manually updated. + if (pSegment->rgTail[uType] != BLOCK_INVALID) + { + _ASSERTE(fScavengingOccurred); + pSegment->rgTail[uType] = BLOCK_INVALID; + pSegment->rgHint[uType] = BLOCK_INVALID; + } + } } // store the new free list head @@ -2549,6 +2567,14 @@ uint32_t BlockFreeHandles(TableSegment *pSegment, uint32_t uBlock, OBJECTHANDLE if (fAllMasksWeTouchedAreFree) { // is the block unlocked? + // NOTE: This check is incorrect and defeats the intended purpose of scavenging. If the + // current block is locked and has just been emptied, then it cannot be removed right now + // and therefore will nominally need to be scavenged. The only code that triggers + // scavenging is in SegmentRemoveFreeBlocks, and setting the flag is the only way to + // trigger a call into SegmentRemoveFreeBlocks call. As a result, by NOT setting the flag + // this code is generally PREVENTING scavenging in exactly the cases where scavenging is + // needed. The code is not being changed because it has always been this way and scavenging + // itself generally has extremely low value. if (!BlockIsLocked(pSegment, uBlock)) { // tell the caller it might be a good idea to scan for free blocks diff --git a/src/gc/objecthandle.cpp b/src/gc/objecthandle.cpp index dd43ec23d5..7df915fb72 100644 --- a/src/gc/objecthandle.cpp +++ b/src/gc/objecthandle.cpp @@ -608,7 +608,8 @@ HandleTableBucketHolder::~HandleTableBucketHolder() } delete [] m_bucket->pTable; } - delete m_bucket; + + // we do not own m_bucket, so we shouldn't delete it here. } bool Ref_Initialize() |