void MM_SweepSchemeSegregated::incrementalSweepLarge(MM_EnvironmentBase *env) { /* Sweep through large objects. */ MM_RegionPoolSegregated *regionPool = _memoryPool->getRegionPool(); MM_HeapRegionQueue *largeSweepRegions = regionPool->getLargeSweepRegions(); MM_HeapRegionQueue *largeFullRegions = regionPool->getLargeFullRegions(); MM_HeapRegionDescriptorSegregated *currentRegion; while ((currentRegion = largeSweepRegions->dequeue()) != NULL) { sweepRegion(env, currentRegion); if (currentRegion->getMemoryPoolACL()->getFreeCount() == 0) { largeFullRegions->enqueue(currentRegion); } else { currentRegion->emptyRegionReturned(env); regionPool->addFreeRegion(env, currentRegion); } yieldFromSweep(env); } }
void MM_SweepSchemeSegregated::incrementalSweepArraylet(MM_EnvironmentBase *env) { uintptr_t arrayletsPerRegion = env->getExtensions()->arrayletsPerRegion; MM_RegionPoolSegregated *regionPool = _memoryPool->getRegionPool(); MM_HeapRegionQueue *arrayletSweepRegions = regionPool->getArrayletSweepRegions(); MM_HeapRegionQueue *arrayletAvailableRegions = regionPool->getArrayletAvailableRegions(); MM_HeapRegionDescriptorSegregated *currentRegion; while ((currentRegion = arrayletSweepRegions->dequeue()) != NULL) { sweepRegion(env, currentRegion); if (currentRegion->getMemoryPoolACL()->getFreeCount() != arrayletsPerRegion) { arrayletAvailableRegions->enqueue(currentRegion); } else { currentRegion->emptyRegionReturned(env); regionPool->addFreeRegion(env, currentRegion); } yieldFromSweep(env); } }
void MM_SweepSchemeSegregated::incrementalSweepSmall(MM_EnvironmentBase *env) { MM_GCExtensionsBase *ext = env->getExtensions(); bool shouldUpdateOccupancy = ext->nonDeterministicSweep; MM_RegionPoolSegregated *regionPool = _memoryPool->getRegionPool(); uintptr_t splitIndex = env->getSlaveID() % (regionPool->getSplitAvailableListSplitCount()); /* * Iterate through the regions so that each region is processed exactly once. * Interleaved sweeping: free up some number of regions of all sizeClasses right away * so that application have somewhere to allocate from and minimize the usage of * non deterministic sweeps. * Any marked objects are unmarked. * If a region holds a marked object, then the region is kept active; * if a region contains no marked objects, then it can be returned to a free list. */ MM_SizeClasses *sizeClasses = ext->defaultSizeClasses; while (regionPool->getCurrentTotalCountOfSweepRegions()) { for (uintptr_t sizeClass = OMR_SIZECLASSES_MIN_SMALL; sizeClass <= OMR_SIZECLASSES_MAX_SMALL; sizeClass++) { while (regionPool->getCurrentCountOfSweepRegions(sizeClass)) { float yetToComplete = (float)regionPool->getCurrentCountOfSweepRegions(sizeClass) / regionPool->getInitialCountOfSweepRegions(sizeClass); float totalYetToComplete = (float)regionPool->getCurrentTotalCountOfSweepRegions() / regionPool->getInitialTotalCountOfSweepRegions(); if (yetToComplete < totalYetToComplete) { break; } MM_HeapRegionQueue *sweepList = regionPool->getSmallSweepRegions(sizeClass); MM_HeapRegionDescriptorSegregated *currentRegion; uintptr_t numCells = sizeClasses->getNumCells(sizeClass); uintptr_t sweepSmallRegionsPerIteration = calcSweepSmallRegionsPerIteration(numCells); uintptr_t yieldSlackTime = resetSweepSmallRegionCount(env, sweepSmallRegionsPerIteration); uintptr_t actualSweepRegions; if ((actualSweepRegions = sweepList->dequeue(env->getRegionWorkList(), sweepSmallRegionsPerIteration)) > 0) { regionPool->decrementCurrentCountOfSweepRegions(sizeClass, actualSweepRegions); regionPool->decrementCurrentTotalCountOfSweepRegions(actualSweepRegions); uintptr_t freedRegions = 0, processedRegions = 0; MM_HeapRegionQueue *fullList = env->getRegionLocalFull(); while ((currentRegion = env->getRegionWorkList()->dequeue()) != NULL) { sweepRegion(env, currentRegion); if (currentRegion->getMemoryPoolACL()->getFreeCount() < numCells) { uintptr_t occupancy = (currentRegion->getMemoryPoolACL()->getMarkCount() * 100) / numCells; /* Maintain average occupancy needed for nondeterministic sweep heuristic */ if (shouldUpdateOccupancy) { regionPool->updateOccupancy(sizeClass, occupancy); } if (currentRegion->getMemoryPoolACL()->getMarkCount() == numCells) { /* Return full regions to full list */ fullList->enqueue(currentRegion); } else { regionPool->enqueueAvailable(currentRegion, sizeClass, occupancy, splitIndex); } } else { currentRegion->emptyRegionReturned(env); currentRegion->setFree(1); env->getRegionLocalFree()->enqueue(currentRegion); freedRegions++; } processedRegions++; if (updateSweepSmallRegionCount()) { yieldFromSweep(env, yieldSlackTime); } } regionPool->addSingleFree(env, env->getRegionLocalFree()); regionPool->getSmallFullRegions(sizeClass)->enqueue(fullList); yieldFromSweep(env, yieldSlackTime); } } /* end of while(currentTotalCountOfSweepRegions); */ } } }