package com.oracle.svm.core.genscavenge;
import com.oracle.svm.core.log.Log;
final class Timer implements AutoCloseable {
private final String name;
private long openNanos;
private long closeNanos;
private long collectedNanos;
Timer(String name) {
this.name = name;
}
public String getName() {
return name;
}
public Timer open() {
openNanos = System.nanoTime();
closeNanos = 0L;
return this;
}
@Override
public void close() {
if (openNanos == 0L) {
openNanos = HeapImpl.getChunkProvider().getFirstAllocationTime();
}
closeNanos = System.nanoTime();
collectedNanos += closeNanos - openNanos;
}
public void reset() {
openNanos = 0L;
closeNanos = 0L;
collectedNanos = 0L;
}
public long getFinish() {
assert closeNanos > 0L : "Should have closed timer";
return closeNanos;
}
long getMeasuredNanos() {
return collectedNanos;
}
long getLastIntervalNanos() {
assert openNanos > 0L : "Should have opened timer";
assert closeNanos > 0L : "Should have closed timer";
return closeNanos - openNanos;
}
static long getTimeSinceFirstAllocation(long nanos) {
return nanos - HeapImpl.getChunkProvider().getFirstAllocationTime();
}
}
final class Timers {
final Timer blackenImageHeapRoots = new Timer("blackenImageHeapRoots");
final Timer blackenDirtyCardRoots = new Timer("blackenDirtyCardRoots");
final Timer blackenStackRoots = new Timer("blackenStackRoots");
final Timer cheneyScanFromRoots = new Timer("cheneyScanFromRoots");
final Timer cheneyScanFromDirtyRoots = new Timer("cheneyScanFromDirtyRoots");
final Timer collection = new Timer("collection");
final Timer cleanCodeCache = new Timer("cleanCodeCache");
final Timer referenceObjects = new Timer("referenceObjects");
final Timer promotePinnedObjects = new Timer("promotePinnedObjects");
final Timer rootScan = new Timer("rootScan");
final Timer scanGreyObjects = new Timer("scanGreyObjects");
final Timer releaseSpaces = new Timer("releaseSpaces");
final Timer verifyAfter = new Timer("verifyAfter");
final Timer verifyBefore = new Timer("verifyBefore");
final Timer walkThreadLocals = new Timer("walkThreadLocals");
final Timer walkRuntimeCodeCache = new Timer("walkRuntimeCodeCache");
final Timer cleanRuntimeCodeCache = new Timer("cleanRuntimeCodeCache");
final Timer mutator = new Timer("mutator");
Timers() {
}
void resetAllExceptMutator() {
Log trace = Log.noopLog();
trace.string("[Timers.resetAllExceptMutator:");
verifyBefore.reset();
collection.reset();
rootScan.reset();
cheneyScanFromRoots.reset();
cheneyScanFromDirtyRoots.reset();
promotePinnedObjects.reset();
blackenStackRoots.reset();
walkThreadLocals.reset();
walkRuntimeCodeCache.reset();
cleanRuntimeCodeCache.reset();
blackenImageHeapRoots.reset();
blackenDirtyCardRoots.reset();
scanGreyObjects.reset();
cleanCodeCache.reset();
referenceObjects.reset();
releaseSpaces.reset();
verifyAfter.reset();
trace.string("]").newline();
}
void logAfterCollection(Log log) {
if (log.isEnabled()) {
log.newline();
log.string(" [GC nanoseconds:");
logOneTimer(log, " ", verifyBefore);
logOneTimer(log, " ", collection);
logOneTimer(log, " ", rootScan);
logOneTimer(log, " ", cheneyScanFromRoots);
logOneTimer(log, " ", cheneyScanFromDirtyRoots);
logOneTimer(log, " ", promotePinnedObjects);
logOneTimer(log, " ", blackenStackRoots);
logOneTimer(log, " ", walkThreadLocals);
logOneTimer(log, " ", walkRuntimeCodeCache);
logOneTimer(log, " ", cleanRuntimeCodeCache);
logOneTimer(log, " ", blackenImageHeapRoots);
logOneTimer(log, " ", blackenDirtyCardRoots);
logOneTimer(log, " ", scanGreyObjects);
logOneTimer(log, " ", cleanCodeCache);
logOneTimer(log, " ", referenceObjects);
logOneTimer(log, " ", releaseSpaces);
logOneTimer(log, " ", verifyAfter);
logGCLoad(log, " ", "GCLoad", collection, mutator);
log.string("]");
}
}
static void logOneTimer(Log log, String prefix, Timer timer) {
if (timer.getMeasuredNanos() > 0) {
log.newline().string(prefix).string(timer.getName()).string(": ").signed(timer.getMeasuredNanos());
}
}
private static void logGCLoad(Log log, String prefix, String label, Timer cTimer, Timer mTimer) {
long collectionNanos = cTimer.getLastIntervalNanos();
long mutatorNanos = mTimer.getLastIntervalNanos();
long intervalNanos = mutatorNanos + collectionNanos;
long intervalGCPercent = (((100 * collectionNanos) + (intervalNanos / 2)) / intervalNanos);
log.newline().string(prefix).string(label).string(": ").signed(intervalGCPercent).string("%");
}
}