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); */
		}
	}
}