2929import org .graalvm .word .UnsignedWord ;
3030
3131import com .oracle .svm .core .Isolates ;
32- import com .oracle .svm .core .Uninterruptible ;
3332import com .oracle .svm .core .heap .GCCause ;
33+ import com .oracle .svm .core .thread .VMOperation ;
3434import com .oracle .svm .core .util .BasedOnJDKFile ;
3535import com .oracle .svm .core .util .TimeUtils ;
3636import com .oracle .svm .core .util .Timer ;
@@ -108,7 +108,8 @@ class AdaptiveCollectionPolicy extends AbstractCollectionPolicy {
108108 private static final int ADAPTIVE_SIZE_POLICY_INITIALIZING_STEPS = ADAPTIVE_SIZE_POLICY_READY_THRESHOLD ;
109109 /**
110110 * The minimum estimated decrease in {@link #gcCost()} in percent to decide in favor of
111- * expanding a space by 1% of the combined size of {@link #edenSize} and {@link #promoSize}.
111+ * expanding a space by 1% of the combined size of {@link SizeParameters#getEdenSize} and
112+ * {@link SizeParameters#getPromoSize}.
112113 */
113114 private static final double ADAPTIVE_SIZE_ESTIMATOR_MIN_TOTAL_SIZE_COST_TRADEOFF = 0.5 ;
114115 /** The effective number of most recent data points used by estimator (exponential decay). */
@@ -212,7 +213,7 @@ public boolean shouldCollectCompletely(boolean followingIncrementalCollection, b
212213 */
213214 UnsignedWord averagePromoted = UnsignedUtils .fromDouble (avgPromoted .getPaddedAverage ());
214215 UnsignedWord promotionEstimate = UnsignedUtils .min (averagePromoted , youngUsed );
215- UnsignedWord oldFree = oldSize .subtract (oldUsed );
216+ UnsignedWord oldFree = sizes . getOldSize () .subtract (oldUsed );
216217 return promotionEstimate .aboveThan (oldFree );
217218 }
218219
@@ -254,7 +255,7 @@ private void computeSurvivorSpaceSizeAndThreshold(boolean isSurvivorOverflow, Un
254255 targetSize = survivorLimit ;
255256 decrTenuringThreshold = true ;
256257 }
257- survivorSize = targetSize ;
258+ sizes . setSurvivorSize ( targetSize ) ;
258259
259260 if (decrTenuringThreshold ) {
260261 tenuringThreshold = Math .max (tenuringThreshold - 1 , 1 );
@@ -264,44 +265,47 @@ private void computeSurvivorSpaceSizeAndThreshold(boolean isSurvivorOverflow, Un
264265 }
265266
266267 protected void computeEdenSpaceSize (@ SuppressWarnings ("unused" ) boolean completeCollection , @ SuppressWarnings ("unused" ) GCCause cause ) {
268+ UnsignedWord curEden = sizes .getEdenSize ();
269+ UnsignedWord curPromo = sizes .getPromoSize ();
270+
267271 boolean expansionReducesCost = true ; // general assumption
268272 if (shouldUseEstimator (youngGenChangeForMinorThroughput , minorGcCost ())) {
269- expansionReducesCost = expansionSignificantlyReducesTotalCost (minorCostEstimator , edenSize , majorGcCost (), promoSize );
273+ expansionReducesCost = expansionSignificantlyReducesTotalCost (minorCostEstimator , curEden , majorGcCost (), curPromo );
270274 /*
271275 * Note that if the estimator thinks expanding does not lead to significant improvement,
272276 * shrink so to not get stuck in a supposed optimum and to keep collecting data points.
273277 */
274278 }
275279
276- UnsignedWord desiredEdenSize = edenSize ;
280+ UnsignedWord desiredEdenSize = curEden ;
277281 if (expansionReducesCost && adjustedMutatorCost () < THROUGHPUT_GOAL && gcCost () > 0 ) {
278282 // from adjust_eden_for_throughput():
279- UnsignedWord edenHeapDelta = edenIncrementWithSupplementAlignedUp (edenSize );
283+ UnsignedWord edenHeapDelta = edenIncrementWithSupplementAlignedUp (curEden );
280284 double scaleByRatio = minorGcCost () / gcCost ();
281285 assert scaleByRatio >= 0 && scaleByRatio <= 1 ;
282286 UnsignedWord scaledEdenHeapDelta = UnsignedUtils .fromDouble (scaleByRatio * UnsignedUtils .toDouble (edenHeapDelta ));
283287
284288 desiredEdenSize = alignUp (desiredEdenSize .add (scaledEdenHeapDelta ));
285- desiredEdenSize = UnsignedUtils .max (desiredEdenSize , edenSize );
289+ desiredEdenSize = UnsignedUtils .max (desiredEdenSize , curEden );
286290 youngGenChangeForMinorThroughput ++;
287291 }
288292 if (!expansionReducesCost || (USE_ADAPTIVE_SIZE_POLICY_FOOTPRINT_GOAL && youngGenPolicyIsReady && adjustedMutatorCost () >= THROUGHPUT_GOAL )) {
289- UnsignedWord desiredSum = edenSize .add (promoSize );
290- desiredEdenSize = adjustEdenForFootprint (edenSize , desiredSum );
293+ UnsignedWord desiredSum = curEden .add (curPromo );
294+ desiredEdenSize = adjustEdenForFootprint (curEden , desiredSum );
291295 }
292296 assert isAligned (desiredEdenSize );
293297 desiredEdenSize = minSpaceSize (desiredEdenSize );
294298
295- UnsignedWord edenLimit = getMaximumEdenSize ();
299+ UnsignedWord edenLimit = computeEdenLimit ();
296300 if (desiredEdenSize .aboveThan (edenLimit )) {
297301 /*
298302 * If the policy says to get a larger eden but is hitting the limit, don't decrease
299303 * eden. This can lead to a general drifting down of the eden size. Let the tenuring
300304 * calculation push more into the old gen.
301305 */
302- desiredEdenSize = UnsignedUtils .max (edenLimit , edenSize );
306+ desiredEdenSize = UnsignedUtils .max (edenLimit , curEden );
303307 }
304- edenSize = desiredEdenSize ;
308+ sizes . setEdenSize ( desiredEdenSize ) ;
305309 }
306310
307311 private static boolean shouldUseEstimator (long genChangeForThroughput , double cost ) {
@@ -435,13 +439,13 @@ public void onCollectionEnd(boolean completeCollection, GCCause cause) { // {maj
435439
436440 if (completeCollection ) {
437441 updateCollectionEndAverages (avgMajorGcCost , avgMajorPause , majorCostEstimator , avgMajorIntervalSeconds ,
438- cause , latestMajorMutatorIntervalNanos , timer .lastIntervalNanos (), promoSize );
442+ cause , latestMajorMutatorIntervalNanos , timer .lastIntervalNanos (), sizes . getPromoSize () );
439443 majorCount ++;
440444 minorCountSinceMajorCollection = 0 ;
441445
442446 } else {
443447 updateCollectionEndAverages (avgMinorGcCost , avgMinorPause , minorCostEstimator , null ,
444- cause , latestMinorMutatorIntervalNanos , timer .lastIntervalNanos (), edenSize );
448+ cause , latestMinorMutatorIntervalNanos , timer .lastIntervalNanos (), sizes . getEdenSize () );
445449 minorCount ++;
446450 minorCountSinceMajorCollection ++;
447451
@@ -455,7 +459,7 @@ public void onCollectionEnd(boolean completeCollection, GCCause cause) { // {maj
455459
456460 GCAccounting accounting = GCImpl .getAccounting ();
457461 UnsignedWord oldLive = accounting .getOldGenerationAfterChunkBytes ();
458- oldSizeExceededInPreviousCollection = oldLive .aboveThan (oldSize );
462+ oldSizeExceededInPreviousCollection = oldLive .aboveThan (sizes . getOldSize () );
459463
460464 if (!completeCollection ) {
461465 /*
@@ -471,7 +475,7 @@ public void onCollectionEnd(boolean completeCollection, GCCause cause) { // {maj
471475 UnsignedWord tenuredChunkBytes = accounting .getLastIncrementalCollectionPromotedChunkBytes ();
472476 updateAverages (survivorOverflow , survivedChunkBytes , tenuredChunkBytes );
473477
474- computeSurvivorSpaceSizeAndThreshold (survivorOverflow , sizes .maxSurvivorSize ());
478+ computeSurvivorSpaceSizeAndThreshold (survivorOverflow , sizes .getMaxSurvivorSize ());
475479 }
476480 if (shouldUpdateStats (cause )) {
477481 computeEdenSpaceSize (completeCollection , cause );
@@ -483,51 +487,55 @@ public void onCollectionEnd(boolean completeCollection, GCCause cause) { // {maj
483487 }
484488
485489 private void computeOldGenSpaceSize (UnsignedWord oldLive ) { // compute_old_gen_free_space
490+ UnsignedWord curEden = sizes .getEdenSize ();
491+ UnsignedWord curPromo = sizes .getPromoSize ();
492+ UnsignedWord curMaxOld = sizes .getMaxOldSize ();
493+
486494 avgOldLive .sample (oldLive );
487495
488496 // NOTE: if maxOldSize shrunk and difference is negative, unsigned conversion results in 0
489- UnsignedWord promoLimit = UnsignedUtils .fromDouble (UnsignedUtils .toDouble (sizes . maxOldSize () ) - avgOldLive .getAverage ());
490- promoLimit = alignDown (UnsignedUtils .max (promoSize , promoLimit ));
497+ UnsignedWord promoLimit = UnsignedUtils .fromDouble (UnsignedUtils .toDouble (curMaxOld ) - avgOldLive .getAverage ());
498+ promoLimit = alignDown (UnsignedUtils .max (curPromo , promoLimit ));
491499
492500 boolean expansionReducesCost = true ; // general assumption
493501 if (shouldUseEstimator (oldGenChangeForMajorThroughput , majorGcCost ())) {
494- expansionReducesCost = expansionSignificantlyReducesTotalCost (majorCostEstimator , promoSize , minorGcCost (), edenSize );
502+ expansionReducesCost = expansionSignificantlyReducesTotalCost (majorCostEstimator , curPromo , minorGcCost (), curEden );
495503 /*
496504 * Note that if the estimator thinks expanding does not lead to significant improvement,
497505 * shrink so to not get stuck in a supposed optimum and to keep collecting data points.
498506 */
499507 }
500508
501- UnsignedWord desiredPromoSize = promoSize ;
509+ UnsignedWord desiredPromoSize = curPromo ;
502510 if (expansionReducesCost && adjustedMutatorCost () < THROUGHPUT_GOAL && gcCost () > 0 ) {
503511 // from adjust_promo_for_throughput():
504- UnsignedWord promoHeapDelta = promoIncrementWithSupplementAlignedUp (promoSize );
512+ UnsignedWord promoHeapDelta = promoIncrementWithSupplementAlignedUp (curPromo );
505513 double scaleByRatio = majorGcCost () / gcCost ();
506514 assert scaleByRatio >= 0 && scaleByRatio <= 1 ;
507515 UnsignedWord scaledPromoHeapDelta = UnsignedUtils .fromDouble (scaleByRatio * UnsignedUtils .toDouble (promoHeapDelta ));
508516
509- desiredPromoSize = alignUp (promoSize .add (scaledPromoHeapDelta ));
510- desiredPromoSize = UnsignedUtils .max (desiredPromoSize , promoSize );
517+ desiredPromoSize = alignUp (curPromo .add (scaledPromoHeapDelta ));
518+ desiredPromoSize = UnsignedUtils .max (desiredPromoSize , curPromo );
511519 oldGenChangeForMajorThroughput ++;
512520 }
513521 if (!expansionReducesCost || (USE_ADAPTIVE_SIZE_POLICY_FOOTPRINT_GOAL && youngGenPolicyIsReady && adjustedMutatorCost () >= THROUGHPUT_GOAL )) {
514- UnsignedWord desiredSum = edenSize .add (promoSize );
515- desiredPromoSize = adjustPromoForFootprint (promoSize , desiredSum );
522+ UnsignedWord desiredSum = curEden .add (curPromo );
523+ desiredPromoSize = adjustPromoForFootprint (curPromo , desiredSum );
516524 }
517525 assert isAligned (desiredPromoSize );
518526 desiredPromoSize = minSpaceSize (desiredPromoSize );
519527
520528 desiredPromoSize = UnsignedUtils .min (desiredPromoSize , promoLimit );
521- promoSize = desiredPromoSize ;
529+ sizes . setPromoSize ( desiredPromoSize ) ;
522530
523531 // from PSOldGen::resize
524532 UnsignedWord desiredFreeSpace = calculatedOldFreeSizeInBytes ();
525533 UnsignedWord desiredOldSize = alignUp (oldLive .add (desiredFreeSpace ));
526- oldSize = UnsignedUtils .clamp (desiredOldSize , minSpaceSize (), sizes . maxOldSize ( ));
534+ sizes . setOldSize ( UnsignedUtils .clamp (desiredOldSize , minSpaceSize (), curMaxOld ));
527535 }
528536
529537 UnsignedWord calculatedOldFreeSizeInBytes () {
530- return UnsignedUtils .fromDouble (UnsignedUtils .toDouble (promoSize ) + avgPromoted .getPaddedAverage ());
538+ return UnsignedUtils .fromDouble (UnsignedUtils .toDouble (sizes . getPromoSize () ) + avgPromoted .getPaddedAverage ());
531539 }
532540
533541 private static UnsignedWord adjustPromoForFootprint (UnsignedWord curPromo , UnsignedWord desiredSum ) {
@@ -573,6 +581,11 @@ protected boolean shouldUpdateStats(GCCause cause) { // should_update_{eden,prom
573581 return cause == GenScavengeGCCause .OnAllocation || USE_ADAPTIVE_SIZE_POLICY_WITH_SYSTEM_GC ;
574582 }
575583
584+ protected UnsignedWord computeEdenLimit () {
585+ assert VMOperation .isGCInProgress () : "result wouldn't be consistent otherwise" ;
586+ return alignDown (sizes .getMaxYoungSize ().subtract (sizes .getSurvivorSize ().multiply (2 )));
587+ }
588+
576589 private void updateCollectionEndAverages (AdaptiveWeightedAverage costAverage , AdaptivePaddedAverage pauseAverage , ReciprocalLeastSquareFit costEstimator ,
577590 AdaptiveWeightedAverage intervalSeconds , GCCause cause , long mutatorNanos , long pauseNanos , UnsignedWord sizeBytes ) {
578591 if (shouldUpdateStats (cause )) {
@@ -591,10 +604,4 @@ private void updateCollectionEndAverages(AdaptiveWeightedAverage costAverage, Ad
591604 costEstimator .sample (UnsignedUtils .toDouble (sizeBytes ), cost );
592605 }
593606 }
594-
595- @ Override
596- @ Uninterruptible (reason = "Called from uninterruptible code." , mayBeInlined = true )
597- protected long gcCount () {
598- return minorCount + majorCount ;
599- }
600607}
0 commit comments