Skip to content

Commit 40b566f

Browse files
Remove the Java heap allocation in AbstractCollectionPolicy.updateSizeParameters().
1 parent 70f997d commit 40b566f

File tree

11 files changed

+635
-293
lines changed

11 files changed

+635
-293
lines changed

substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/AbstractCollectionPolicy.java

Lines changed: 506 additions & 162 deletions
Large diffs are not rendered by default.

substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/AdaptiveCollectionPolicy.java

Lines changed: 35 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@
2929
import org.graalvm.word.UnsignedWord;
3030

3131
import com.oracle.svm.core.Isolates;
32-
import com.oracle.svm.core.Uninterruptible;
3332
import com.oracle.svm.core.heap.GCCause;
3433
import com.oracle.svm.core.util.BasedOnJDKFile;
3534
import com.oracle.svm.core.util.TimeUtils;
@@ -108,7 +107,8 @@ class AdaptiveCollectionPolicy extends AbstractCollectionPolicy {
108107
private static final int ADAPTIVE_SIZE_POLICY_INITIALIZING_STEPS = ADAPTIVE_SIZE_POLICY_READY_THRESHOLD;
109108
/**
110109
* 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}.
110+
* expanding a space by 1% of the combined size of {@link SizeParameters#getEdenSize} and
111+
* {@link SizeParameters#getPromoSize}.
112112
*/
113113
private static final double ADAPTIVE_SIZE_ESTIMATOR_MIN_TOTAL_SIZE_COST_TRADEOFF = 0.5;
114114
/** The effective number of most recent data points used by estimator (exponential decay). */
@@ -212,7 +212,7 @@ public boolean shouldCollectCompletely(boolean followingIncrementalCollection, b
212212
*/
213213
UnsignedWord averagePromoted = UnsignedUtils.fromDouble(avgPromoted.getPaddedAverage());
214214
UnsignedWord promotionEstimate = UnsignedUtils.min(averagePromoted, youngUsed);
215-
UnsignedWord oldFree = oldSize.subtract(oldUsed);
215+
UnsignedWord oldFree = sizes.getOldSize().subtract(oldUsed);
216216
return promotionEstimate.aboveThan(oldFree);
217217
}
218218

@@ -254,7 +254,7 @@ private void computeSurvivorSpaceSizeAndThreshold(boolean isSurvivorOverflow, Un
254254
targetSize = survivorLimit;
255255
decrTenuringThreshold = true;
256256
}
257-
survivorSize = targetSize;
257+
sizes.setSurvivorSize(targetSize);
258258

259259
if (decrTenuringThreshold) {
260260
tenuringThreshold = Math.max(tenuringThreshold - 1, 1);
@@ -264,30 +264,33 @@ private void computeSurvivorSpaceSizeAndThreshold(boolean isSurvivorOverflow, Un
264264
}
265265

266266
protected void computeEdenSpaceSize(@SuppressWarnings("unused") boolean completeCollection, @SuppressWarnings("unused") GCCause cause) {
267+
UnsignedWord curEdenSize = sizes.getEdenSize();
268+
UnsignedWord curPromoSize = sizes.getPromoSize();
269+
267270
boolean expansionReducesCost = true; // general assumption
268271
if (shouldUseEstimator(youngGenChangeForMinorThroughput, minorGcCost())) {
269-
expansionReducesCost = expansionSignificantlyReducesTotalCost(minorCostEstimator, edenSize, majorGcCost(), promoSize);
272+
expansionReducesCost = expansionSignificantlyReducesTotalCost(minorCostEstimator, curEdenSize, majorGcCost(), curPromoSize);
270273
/*
271274
* Note that if the estimator thinks expanding does not lead to significant improvement,
272275
* shrink so to not get stuck in a supposed optimum and to keep collecting data points.
273276
*/
274277
}
275278

276-
UnsignedWord desiredEdenSize = edenSize;
279+
UnsignedWord desiredEdenSize = curEdenSize;
277280
if (expansionReducesCost && adjustedMutatorCost() < THROUGHPUT_GOAL && gcCost() > 0) {
278281
// from adjust_eden_for_throughput():
279-
UnsignedWord edenHeapDelta = edenIncrementWithSupplementAlignedUp(edenSize);
282+
UnsignedWord edenHeapDelta = edenIncrementWithSupplementAlignedUp(curEdenSize);
280283
double scaleByRatio = minorGcCost() / gcCost();
281284
assert scaleByRatio >= 0 && scaleByRatio <= 1;
282285
UnsignedWord scaledEdenHeapDelta = UnsignedUtils.fromDouble(scaleByRatio * UnsignedUtils.toDouble(edenHeapDelta));
283286

284287
desiredEdenSize = alignUp(desiredEdenSize.add(scaledEdenHeapDelta));
285-
desiredEdenSize = UnsignedUtils.max(desiredEdenSize, edenSize);
288+
desiredEdenSize = UnsignedUtils.max(desiredEdenSize, curEdenSize);
286289
youngGenChangeForMinorThroughput++;
287290
}
288291
if (!expansionReducesCost || (USE_ADAPTIVE_SIZE_POLICY_FOOTPRINT_GOAL && youngGenPolicyIsReady && adjustedMutatorCost() >= THROUGHPUT_GOAL)) {
289-
UnsignedWord desiredSum = edenSize.add(promoSize);
290-
desiredEdenSize = adjustEdenForFootprint(edenSize, desiredSum);
292+
UnsignedWord desiredSum = curEdenSize.add(curPromoSize);
293+
desiredEdenSize = adjustEdenForFootprint(curEdenSize, desiredSum);
291294
}
292295
assert isAligned(desiredEdenSize);
293296
desiredEdenSize = minSpaceSize(desiredEdenSize);
@@ -299,9 +302,9 @@ protected void computeEdenSpaceSize(@SuppressWarnings("unused") boolean complete
299302
* eden. This can lead to a general drifting down of the eden size. Let the tenuring
300303
* calculation push more into the old gen.
301304
*/
302-
desiredEdenSize = UnsignedUtils.max(edenLimit, edenSize);
305+
desiredEdenSize = UnsignedUtils.max(edenLimit, curEdenSize);
303306
}
304-
edenSize = desiredEdenSize;
307+
sizes.setEdenSize(desiredEdenSize);
305308
}
306309

307310
private static boolean shouldUseEstimator(long genChangeForThroughput, double cost) {
@@ -435,13 +438,13 @@ public void onCollectionEnd(boolean completeCollection, GCCause cause) { // {maj
435438

436439
if (completeCollection) {
437440
updateCollectionEndAverages(avgMajorGcCost, avgMajorPause, majorCostEstimator, avgMajorIntervalSeconds,
438-
cause, latestMajorMutatorIntervalNanos, timer.lastIntervalNanos(), promoSize);
441+
cause, latestMajorMutatorIntervalNanos, timer.lastIntervalNanos(), sizes.getPromoSize());
439442
majorCount++;
440443
minorCountSinceMajorCollection = 0;
441444

442445
} else {
443446
updateCollectionEndAverages(avgMinorGcCost, avgMinorPause, minorCostEstimator, null,
444-
cause, latestMinorMutatorIntervalNanos, timer.lastIntervalNanos(), edenSize);
447+
cause, latestMinorMutatorIntervalNanos, timer.lastIntervalNanos(), sizes.getEdenSize());
445448
minorCount++;
446449
minorCountSinceMajorCollection++;
447450

@@ -455,7 +458,7 @@ public void onCollectionEnd(boolean completeCollection, GCCause cause) { // {maj
455458

456459
GCAccounting accounting = GCImpl.getAccounting();
457460
UnsignedWord oldLive = accounting.getOldGenerationAfterChunkBytes();
458-
oldSizeExceededInPreviousCollection = oldLive.aboveThan(oldSize);
461+
oldSizeExceededInPreviousCollection = oldLive.aboveThan(sizes.getOldSize());
459462

460463
if (!completeCollection) {
461464
/*
@@ -471,7 +474,7 @@ public void onCollectionEnd(boolean completeCollection, GCCause cause) { // {maj
471474
UnsignedWord tenuredChunkBytes = accounting.getLastIncrementalCollectionPromotedChunkBytes();
472475
updateAverages(survivorOverflow, survivedChunkBytes, tenuredChunkBytes);
473476

474-
computeSurvivorSpaceSizeAndThreshold(survivorOverflow, sizes.maxSurvivorSize());
477+
computeSurvivorSpaceSizeAndThreshold(survivorOverflow, sizes.getMaxSurvivorSize());
475478
}
476479
if (shouldUpdateStats(cause)) {
477480
computeEdenSpaceSize(completeCollection, cause);
@@ -483,51 +486,55 @@ public void onCollectionEnd(boolean completeCollection, GCCause cause) { // {maj
483486
}
484487

485488
private void computeOldGenSpaceSize(UnsignedWord oldLive) { // compute_old_gen_free_space
489+
UnsignedWord curEdenSize = sizes.getEdenSize();
490+
UnsignedWord curMaxOldSize = sizes.getMaxOldSize();
491+
UnsignedWord curPromoSize = sizes.getPromoSize();
492+
486493
avgOldLive.sample(oldLive);
487494

488495
// 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));
496+
UnsignedWord promoLimit = UnsignedUtils.fromDouble(UnsignedUtils.toDouble(curMaxOldSize) - avgOldLive.getAverage());
497+
promoLimit = alignDown(UnsignedUtils.max(curPromoSize, promoLimit));
491498

492499
boolean expansionReducesCost = true; // general assumption
493500
if (shouldUseEstimator(oldGenChangeForMajorThroughput, majorGcCost())) {
494-
expansionReducesCost = expansionSignificantlyReducesTotalCost(majorCostEstimator, promoSize, minorGcCost(), edenSize);
501+
expansionReducesCost = expansionSignificantlyReducesTotalCost(majorCostEstimator, curPromoSize, minorGcCost(), curEdenSize);
495502
/*
496503
* Note that if the estimator thinks expanding does not lead to significant improvement,
497504
* shrink so to not get stuck in a supposed optimum and to keep collecting data points.
498505
*/
499506
}
500507

501-
UnsignedWord desiredPromoSize = promoSize;
508+
UnsignedWord desiredPromoSize = curPromoSize;
502509
if (expansionReducesCost && adjustedMutatorCost() < THROUGHPUT_GOAL && gcCost() > 0) {
503510
// from adjust_promo_for_throughput():
504-
UnsignedWord promoHeapDelta = promoIncrementWithSupplementAlignedUp(promoSize);
511+
UnsignedWord promoHeapDelta = promoIncrementWithSupplementAlignedUp(curPromoSize);
505512
double scaleByRatio = majorGcCost() / gcCost();
506513
assert scaleByRatio >= 0 && scaleByRatio <= 1;
507514
UnsignedWord scaledPromoHeapDelta = UnsignedUtils.fromDouble(scaleByRatio * UnsignedUtils.toDouble(promoHeapDelta));
508515

509-
desiredPromoSize = alignUp(promoSize.add(scaledPromoHeapDelta));
510-
desiredPromoSize = UnsignedUtils.max(desiredPromoSize, promoSize);
516+
desiredPromoSize = alignUp(curPromoSize.add(scaledPromoHeapDelta));
517+
desiredPromoSize = UnsignedUtils.max(desiredPromoSize, curPromoSize);
511518
oldGenChangeForMajorThroughput++;
512519
}
513520
if (!expansionReducesCost || (USE_ADAPTIVE_SIZE_POLICY_FOOTPRINT_GOAL && youngGenPolicyIsReady && adjustedMutatorCost() >= THROUGHPUT_GOAL)) {
514-
UnsignedWord desiredSum = edenSize.add(promoSize);
515-
desiredPromoSize = adjustPromoForFootprint(promoSize, desiredSum);
521+
UnsignedWord desiredSum = curEdenSize.add(curPromoSize);
522+
desiredPromoSize = adjustPromoForFootprint(curPromoSize, desiredSum);
516523
}
517524
assert isAligned(desiredPromoSize);
518525
desiredPromoSize = minSpaceSize(desiredPromoSize);
519526

520527
desiredPromoSize = UnsignedUtils.min(desiredPromoSize, promoLimit);
521-
promoSize = desiredPromoSize;
528+
sizes.setPromoSize(desiredPromoSize);
522529

523530
// from PSOldGen::resize
524531
UnsignedWord desiredFreeSpace = calculatedOldFreeSizeInBytes();
525532
UnsignedWord desiredOldSize = alignUp(oldLive.add(desiredFreeSpace));
526-
oldSize = UnsignedUtils.clamp(desiredOldSize, minSpaceSize(), sizes.maxOldSize());
533+
sizes.setOldSize(UnsignedUtils.clamp(desiredOldSize, minSpaceSize(), curMaxOldSize));
527534
}
528535

529536
UnsignedWord calculatedOldFreeSizeInBytes() {
530-
return UnsignedUtils.fromDouble(UnsignedUtils.toDouble(promoSize) + avgPromoted.getPaddedAverage());
537+
return UnsignedUtils.fromDouble(UnsignedUtils.toDouble(sizes.getPromoSize()) + avgPromoted.getPaddedAverage());
531538
}
532539

533540
private static UnsignedWord adjustPromoForFootprint(UnsignedWord curPromo, UnsignedWord desiredSum) {
@@ -591,10 +598,4 @@ private void updateCollectionEndAverages(AdaptiveWeightedAverage costAverage, Ad
591598
costEstimator.sample(UnsignedUtils.toDouble(sizeBytes), cost);
592599
}
593600
}
594-
595-
@Override
596-
@Uninterruptible(reason = "Called from uninterruptible code.", mayBeInlined = true)
597-
protected long gcCount() {
598-
return minorCount + majorCount;
599-
}
600601
}

substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/CollectionPolicy.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -228,4 +228,8 @@ default boolean isOutOfMemory(UnsignedWord usedBytes) {
228228
default void onMaximumHeapSizeExceeded() {
229229
throw OutOfMemoryUtil.heapSizeExceeded();
230230
}
231+
232+
@Uninterruptible(reason = "Tear-down in progress.")
233+
default void tearDown() {
234+
}
231235
}

substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/DynamicCollectionPolicy.java

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -50,20 +50,21 @@ protected long getMaximumHeapSizeOptionValue() {
5050

5151
@Override
5252
public boolean isOutOfMemory(UnsignedWord usedBytes) {
53-
if (ImageSingletons.contains(DynamicHeapSizeManager.class)) {
54-
return ImageSingletons.lookup(DynamicHeapSizeManager.class).outOfMemory(usedBytes);
53+
boolean outOfMemory = super.isOutOfMemory(usedBytes);
54+
if (ImageSingletons.contains(DynamicHeapSizeManager.class) && outOfMemory) {
55+
outOfMemory = ImageSingletons.lookup(DynamicHeapSizeManager.class).outOfMemory(usedBytes);
56+
if (!outOfMemory) {
57+
/* No longer out-of-memory - update the heap size parameters to reflect that. */
58+
GCImpl.getPolicy().updateSizeParameters();
59+
}
5560
}
56-
57-
return super.isOutOfMemory(usedBytes);
61+
return outOfMemory;
5862
}
5963

6064
@Override
6165
public void onMaximumHeapSizeExceeded() {
6266
if (isOutOfMemory(HeapImpl.getAccounting().getUsedBytes())) {
6367
super.onMaximumHeapSizeExceeded();
64-
} else {
65-
/* No longer out-of-memory - update the heap size parameters to reflect that. */
66-
GCImpl.getPolicy().updateSizeParameters();
6768
}
6869
}
6970
}

substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/GCImpl.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,11 @@ public final class GCImpl implements GC {
151151
}
152152
}
153153

154+
@Uninterruptible(reason = "Tear-down in progress.")
155+
public void tearDown() {
156+
policy.tearDown();
157+
}
158+
154159
@Override
155160
public String getName() {
156161
if (SubstrateOptions.useEpsilonGC()) {

substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/HeapImpl.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -212,7 +212,8 @@ public void walkObjects(ObjectVisitor visitor) {
212212
public boolean tearDown() {
213213
youngGeneration.tearDown();
214214
oldGeneration.tearDown();
215-
getChunkProvider().tearDown();
215+
chunkProvider.tearDown();
216+
gcImpl.tearDown();
216217

217218
if (Metaspace.isSupported()) {
218219
MetaspaceImpl.singleton().tearDown();
@@ -1017,7 +1018,7 @@ private long totalMemory() {
10171018

10181019
@Substitute
10191020
private long maxMemory() {
1020-
GCImpl.getPolicy().updateSizeParameters();
1021+
GCImpl.getPolicy().ensureSizeParametersInitialized();
10211022
return GCImpl.getPolicy().getMaximumHeapSize().rawValue();
10221023
}
10231024

substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/HeapParameters.java

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,7 @@ public static UnsignedWord getMaximumHeapFree() {
124124
return Word.unsigned(SerialGCOptions.MaxHeapFree.getValue());
125125
}
126126

127+
@Fold
127128
public static int getHeapChunkHeaderPadding() {
128129
return SerialAndEpsilonGCOptions.HeapChunkHeaderPadding.getValue();
129130
}
@@ -160,15 +161,12 @@ public static UnsignedWord getLargeArrayThreshold() {
160161
return Word.unsigned(SerialAndEpsilonGCOptions.LargeArrayThreshold.getValue());
161162
}
162163

163-
/*
164-
* Zapping
165-
*/
166-
167-
@Uninterruptible(reason = "Called from uninterruptible code.", mayBeInlined = true)
164+
@Fold
168165
public static boolean getZapProducedHeapChunks() {
169166
return SerialAndEpsilonGCOptions.ZapChunks.getValue() || SerialAndEpsilonGCOptions.ZapProducedHeapChunks.getValue();
170167
}
171168

169+
@Fold
172170
public static boolean getZapConsumedHeapChunks() {
173171
return SerialAndEpsilonGCOptions.ZapChunks.getValue() || SerialAndEpsilonGCOptions.ZapConsumedHeapChunks.getValue();
174172
}

substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/LibGraalCollectionPolicy.java

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ public boolean shouldCollectOnHint(boolean fullGC) {
9191
edenUsedBytes = edenUsedBytes.add(FULL_GC_BONUS);
9292
}
9393
return edenUsedBytes.aboveOrEqual(Word.unsigned(Options.ExpectedEdenSize.getValue())) ||
94-
(UnsignedUtils.toDouble(edenUsedBytes) / UnsignedUtils.toDouble(edenSize) >= Options.UsedEdenProportionThreshold.getValue());
94+
(UnsignedUtils.toDouble(edenUsedBytes) / UnsignedUtils.toDouble(sizes.getEdenSize()) >= Options.UsedEdenProportionThreshold.getValue());
9595
}
9696

9797
@Override
@@ -142,17 +142,19 @@ protected boolean shouldUpdateStats(GCCause cause) {
142142
protected void computeEdenSpaceSize(boolean completeCollection, GCCause cause) {
143143
if (cause == GCCause.HintedGC) {
144144
if (completeCollection && lastGCCause == GCCause.HintedGC) {
145-
UnsignedWord newEdenSize = UnsignedUtils.max(sizes.initialEdenSize, alignUp(edenSize.unsignedDivide(2)));
146-
if (edenSize.aboveThan(newEdenSize)) {
147-
edenSize = newEdenSize;
145+
UnsignedWord curEdenSize = sizes.getEdenSize();
146+
UnsignedWord newEdenSize = UnsignedUtils.max(sizes.getInitialEdenSize(), alignUp(curEdenSize.unsignedDivide(2)));
147+
if (curEdenSize.aboveThan(newEdenSize)) {
148+
sizes.setEdenSize(newEdenSize);
148149
}
149150
}
150151
} else {
151152
UnsignedWord sizeAfter = GCImpl.getChunkBytes();
152153
if (sizeBefore.notEqual(0) && sizeBefore.belowThan(sizeAfter.multiply(2))) {
153-
UnsignedWord newEdenSize = UnsignedUtils.min(getMaximumEdenSize(), alignUp(edenSize.multiply(2)));
154-
if (edenSize.belowThan(newEdenSize)) {
155-
edenSize = newEdenSize;
154+
UnsignedWord curEdenSize = sizes.getEdenSize();
155+
UnsignedWord newEdenSize = UnsignedUtils.min(getMaximumEdenSize(), alignUp(curEdenSize.multiply(2)));
156+
if (curEdenSize.belowThan(newEdenSize)) {
157+
sizes.setEdenSize(newEdenSize);
156158
}
157159
} else {
158160
super.computeEdenSpaceSize(completeCollection, cause);

0 commit comments

Comments
 (0)