Skip to content

Commit 645d27a

Browse files
[GR-59714] Remove calls to System.currentTimeMillis().
PullRequest: graal/19414
2 parents 83e6cf0 + cc2d234 commit 645d27a

File tree

23 files changed

+129
-93
lines changed

23 files changed

+129
-93
lines changed

compiler/src/jdk.graal.compiler.test/src/jdk/graal/compiler/core/test/CheckGraalInvariants.java

+8-5
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@
8484
import jdk.graal.compiler.nodes.graphbuilderconf.GraphBuilderContext;
8585
import jdk.graal.compiler.nodes.graphbuilderconf.InvocationPlugins;
8686
import jdk.graal.compiler.nodes.java.LoadFieldNode;
87+
import jdk.graal.compiler.nodes.java.MethodCallTargetNode;
8788
import jdk.graal.compiler.nodes.memory.MemoryKill;
8889
import jdk.graal.compiler.nodes.memory.MultiMemoryKill;
8990
import jdk.graal.compiler.nodes.memory.SingleMemoryKill;
@@ -101,6 +102,7 @@
101102
import jdk.graal.compiler.phases.tiers.HighTierContext;
102103
import jdk.graal.compiler.phases.util.Providers;
103104
import jdk.graal.compiler.runtime.RuntimeProvider;
105+
import jdk.graal.compiler.serviceprovider.GraalServices;
104106
import jdk.graal.compiler.test.AddExports;
105107
import jdk.graal.compiler.test.SubprocessUtil;
106108
import jdk.internal.misc.Unsafe;
@@ -195,8 +197,11 @@ public boolean shouldVerifyFoldableMethods() {
195197
return true;
196198
}
197199

198-
public boolean shouldVerifyCurrentTimeMillis() {
199-
return true;
200+
public void verifyCurrentTimeMillis(MetaAccessProvider meta, MethodCallTargetNode t, ResolvedJavaType declaringClass) {
201+
final ResolvedJavaType services = meta.lookupJavaType(GraalServices.class);
202+
if (!declaringClass.equals(services)) {
203+
throw new VerificationError(t, "Should use System.nanoTime() for measuring elapsed time or GraalServices.milliTimeStamp() for the time since the epoch");
204+
}
200205
}
201206

202207
/**
@@ -366,9 +371,7 @@ public static void runTest(InvariantsTool tool) {
366371
verifiers.add(foldableMethodsVerifier);
367372
}
368373

369-
if (tool.shouldVerifyCurrentTimeMillis()) {
370-
verifiers.add(new VerifyCurrentTimeMillisUsage());
371-
}
374+
verifiers.add(new VerifyCurrentTimeMillisUsage(tool));
372375

373376
tool.updateVerifiers(verifiers);
374377

compiler/src/jdk.graal.compiler.test/src/jdk/graal/compiler/core/test/VerifyCurrentTimeMillisUsage.java

+9-5
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
*/
2525
package jdk.graal.compiler.core.test;
2626

27+
import jdk.graal.compiler.core.test.CheckGraalInvariants.InvariantsTool;
2728
import jdk.graal.compiler.nodes.StructuredGraph;
2829
import jdk.graal.compiler.nodes.java.MethodCallTargetNode;
2930
import jdk.graal.compiler.nodes.spi.CoreProviders;
@@ -40,6 +41,12 @@
4041
public class VerifyCurrentTimeMillisUsage extends VerifyPhase<CoreProviders> {
4142
private static final String CURRENT_TIME_MILLIS_NAME = "currentTimeMillis";
4243

44+
private final InvariantsTool tool;
45+
46+
public VerifyCurrentTimeMillisUsage(InvariantsTool tool) {
47+
this.tool = tool;
48+
}
49+
4350
@Override
4451
protected void verify(StructuredGraph graph, CoreProviders context) {
4552
final ResolvedJavaType systemType = context.getMetaAccess().lookupJavaType(System.class);
@@ -48,11 +55,8 @@ protected void verify(StructuredGraph graph, CoreProviders context) {
4855
if (callee.getDeclaringClass().equals(systemType)) {
4956
String calleeName = callee.getName();
5057
if (calleeName.equals(CURRENT_TIME_MILLIS_NAME)) {
51-
final ResolvedJavaType services = context.getMetaAccess().lookupJavaType(GraalServices.class);
52-
if (graph.method().getDeclaringClass().equals(services)) {
53-
return;
54-
}
55-
throw new VerificationError(t, "Should use System.nanoTime for measuring elapsed time or GraalServices.milliTimeStamp for the time since the epoch");
58+
final ResolvedJavaType declaringClass = graph.method().getDeclaringClass();
59+
tool.verifyCurrentTimeMillis(context.getMetaAccess(), t, declaringClass);
5660
}
5761
}
5862
}

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

+8-8
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ public final class GCImpl implements GC {
127127
private final CollectionPolicy policy;
128128
private boolean completeCollection = false;
129129
private UnsignedWord collectionEpoch = WordFactory.zero();
130-
private long lastWholeHeapExaminedTimeMillis = -1;
130+
private long lastWholeHeapExaminedNanos = -1;
131131

132132
@Platforms(Platform.HOSTED_ONLY.class)
133133
GCImpl() {
@@ -332,7 +332,7 @@ private boolean doCollectOnce(GCCause cause, long requestingNanoTime, boolean co
332332

333333
doCollectCore(!complete);
334334
if (complete) {
335-
lastWholeHeapExaminedTimeMillis = System.currentTimeMillis();
335+
lastWholeHeapExaminedNanos = System.nanoTime();
336336
}
337337

338338
accounting.afterCollectOnce(completeCollection);
@@ -446,7 +446,7 @@ private void printHeapSizeChange(String text, UnsignedWord before, UnsignedWord
446446
}
447447

448448
private Log printGCPrefixAndTime() {
449-
long uptimeMs = Isolates.getCurrentUptimeMillis();
449+
long uptimeMs = Isolates.getUptimeMillis();
450450
return Log.log().string("[").rational(uptimeMs, TimeUtils.millisPerSecond, 3).string("s").string("] GC(").unsigned(collectionEpoch).string(") ");
451451
}
452452

@@ -1145,14 +1145,14 @@ public UnsignedWord getCollectionEpoch() {
11451145
}
11461146

11471147
public long getMillisSinceLastWholeHeapExamined() {
1148-
long startMillis;
1149-
if (lastWholeHeapExaminedTimeMillis < 0) {
1148+
long start;
1149+
if (lastWholeHeapExaminedNanos < 0) {
11501150
// no full GC has yet been run, use time since the first allocation
1151-
startMillis = Isolates.getCurrentStartTimeMillis();
1151+
start = Isolates.getStartTimeNanos();
11521152
} else {
1153-
startMillis = lastWholeHeapExaminedTimeMillis;
1153+
start = lastWholeHeapExaminedNanos;
11541154
}
1155-
return System.currentTimeMillis() - startMillis;
1155+
return TimeUtils.millisSinceNanos(start);
11561156
}
11571157

11581158
@Fold

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ public long getOpenedTime() {
8888
if (!wasOpened) {
8989
/* If a timer was not opened, pretend it was opened at the start of the VM. */
9090
assert openNanos == 0;
91-
return Isolates.getCurrentStartNanoTime();
91+
return Isolates.getStartTimeNanos();
9292
}
9393
return openNanos;
9494
}

substratevm/src/com.oracle.svm.core.windows/src/com/oracle/svm/core/windows/WindowsPlatformThreads.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -216,7 +216,7 @@ protected void park(boolean isAbsolute, long time) {
216216
if (time == 0) {
217217
millis = SynchAPI.INFINITE() & 0xFFFFFFFFL;
218218
} else if (isAbsolute) {
219-
millis = time - System.currentTimeMillis();
219+
millis = time - TimeUtils.currentTimeMillis();
220220
if (millis <= 0) {
221221
/* Already elapsed. */
222222
return;

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/Isolates.java

+22-20
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
import com.oracle.svm.core.c.CGlobalDataFactory;
3939
import com.oracle.svm.core.c.function.CEntryPointErrors;
4040
import com.oracle.svm.core.os.CommittedMemoryProvider;
41+
import com.oracle.svm.core.util.TimeUtils;
4142
import com.oracle.svm.core.util.VMError;
4243

4344
import jdk.graal.compiler.nodes.NamedLocationIdentity;
@@ -74,8 +75,8 @@ public class Isolates {
7475
/* Only used if SpawnIsolates is disabled. */
7576
private static final CGlobalData<Pointer> SINGLE_ISOLATE_ALREADY_CREATED = CGlobalDataFactory.createWord();
7677

77-
private static long startTimeMillis;
78-
private static long startNanoTime;
78+
private static long startTimeNanos;
79+
private static long initDoneTimeMillis;
7980
private static long isolateId = -1;
8081

8182
/**
@@ -107,29 +108,30 @@ public static void assignIsolateId(boolean isFirstIsolate) {
107108
}
108109
}
109110

110-
public static void assignCurrentStartTime() {
111-
assert startTimeMillis == 0 : startTimeMillis;
112-
assert startNanoTime == 0 : startNanoTime;
113-
startTimeMillis = System.currentTimeMillis();
114-
startNanoTime = System.nanoTime();
111+
public static void assignStartTime() {
112+
assert startTimeNanos == 0 : startTimeNanos;
113+
assert initDoneTimeMillis == 0 : initDoneTimeMillis;
114+
startTimeNanos = System.nanoTime();
115+
initDoneTimeMillis = TimeUtils.currentTimeMillis();
115116
}
116117

117-
@Uninterruptible(reason = "Called from uninterruptible code.", mayBeInlined = true)
118-
public static long getCurrentStartTimeMillis() {
119-
assert startTimeMillis != 0;
120-
return startTimeMillis;
118+
/** Epoch-based timestamp. If possible, {@link #getStartTimeNanos()} should be used instead. */
119+
@Uninterruptible(reason = CALLED_FROM_UNINTERRUPTIBLE_CODE, mayBeInlined = true)
120+
public static long getInitDoneTimeMillis() {
121+
assert initDoneTimeMillis != 0;
122+
return initDoneTimeMillis;
121123
}
122124

123-
@Uninterruptible(reason = "Called from uninterruptible code.", mayBeInlined = true)
124-
public static long getCurrentUptimeMillis() {
125-
assert startTimeMillis != 0;
126-
return System.currentTimeMillis() - startTimeMillis;
125+
@Uninterruptible(reason = CALLED_FROM_UNINTERRUPTIBLE_CODE, mayBeInlined = true)
126+
public static long getUptimeMillis() {
127+
assert startTimeNanos != 0;
128+
return TimeUtils.millisSinceNanos(startTimeNanos);
127129
}
128130

129-
@Uninterruptible(reason = "Called from uninterruptible code.", mayBeInlined = true)
130-
public static long getCurrentStartNanoTime() {
131-
assert startNanoTime != 0;
132-
return startNanoTime;
131+
@Uninterruptible(reason = CALLED_FROM_UNINTERRUPTIBLE_CODE, mayBeInlined = true)
132+
public static long getStartTimeNanos() {
133+
assert startTimeNanos != 0;
134+
return startTimeNanos;
133135
}
134136

135137
@Uninterruptible(reason = CALLED_FROM_UNINTERRUPTIBLE_CODE, mayBeInlined = true)
@@ -169,7 +171,7 @@ public static int create(WordPointer isolatePointer, IsolateArguments arguments)
169171
return CEntryPointErrors.NO_ERROR;
170172
}
171173

172-
@Uninterruptible(reason = "Called from uninterruptible code.", mayBeInlined = true)
174+
@Uninterruptible(reason = CALLED_FROM_UNINTERRUPTIBLE_CODE, mayBeInlined = true)
173175
public static PointerBase getHeapBase(Isolate isolate) {
174176
return isolate;
175177
}

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/SubstrateDiagnostics.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -915,8 +915,8 @@ public void printDiagnostics(Log log, ErrorContext context, int maxDiagnosticLev
915915

916916
log.string("Page size: ").unsigned(VirtualMemoryProvider.get().getGranularity()).newline();
917917
if (!SubstrateOptions.AsyncSignalSafeDiagnostics.getValue()) {
918-
log.string("VM uptime: ").rational(Isolates.getCurrentUptimeMillis(), TimeUtils.millisPerSecond, 3).string("s").newline();
919-
log.string("Current timestamp: ").unsigned(System.currentTimeMillis()).newline();
918+
log.string("VM uptime: ").rational(Isolates.getUptimeMillis(), TimeUtils.millisPerSecond, 3).string("s").newline();
919+
log.string("Current timestamp: ").unsigned(TimeUtils.currentTimeMillis()).newline();
920920
}
921921

922922
CodeInfo info = CodeInfoTable.getFirstImageCodeInfo();

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/code/RuntimeCodeInfoHistory.java

+5-5
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@
2424
*/
2525
package com.oracle.svm.core.code;
2626

27-
import jdk.graal.compiler.api.replacements.Fold;
2827
import org.graalvm.nativeimage.ImageSingletons;
2928
import org.graalvm.nativeimage.Platform;
3029
import org.graalvm.nativeimage.Platforms;
@@ -44,6 +43,8 @@
4443
import com.oracle.svm.core.thread.VMThreads;
4544
import com.oracle.svm.core.util.TimeUtils;
4645

46+
import jdk.graal.compiler.api.replacements.Fold;
47+
4748
public class RuntimeCodeInfoHistory {
4849
private static final RingBuffer.Consumer<CodeCacheLogEntry> PRINT_WITH_JAVA_HEAP_DATA = RuntimeCodeInfoHistory::printEntryWithJavaHeapData;
4950
private static final RingBuffer.Consumer<CodeCacheLogEntry> PRINT_WITHOUT_JAVA_HEAP_DATA = RuntimeCodeInfoHistory::printEntryWithoutJavaHeapData;
@@ -120,7 +121,7 @@ private static void printEntry(Object context, CodeCacheLogEntry entry, boolean
120121
}
121122

122123
private static class CodeCacheLogEntry {
123-
private long timestamp;
124+
private long uptimeMillis;
124125
private String kind;
125126
private String codeName;
126127
private CodeInfo codeInfo;
@@ -142,7 +143,7 @@ public void setValues(String kind, CodeInfo codeInfo, int codeInfoState, String
142143
assert Heap.getHeap().isInImageHeap(kind);
143144

144145
this.safepointId = Safepoint.Master.singleton().getSafepointId();
145-
this.timestamp = System.currentTimeMillis();
146+
this.uptimeMillis = Isolates.getUptimeMillis();
146147
this.kind = kind;
147148
this.codeInfo = codeInfo;
148149
this.codeInfoState = codeInfoState;
@@ -162,8 +163,7 @@ public void setValues(String kind, CodeInfo codeInfo, int codeInfoState, String
162163

163164
public void print(Log log, boolean allowJavaHeapAccess) {
164165
if (kind != null) {
165-
long uptime = timestamp - Isolates.getCurrentStartTimeMillis();
166-
log.rational(uptime, TimeUtils.millisPerSecond, 3).string("s - ").string(kind).spaces(1);
166+
log.rational(uptimeMillis, TimeUtils.millisPerSecond, 3).string("s - ").string(kind).spaces(1);
167167
String name = allowJavaHeapAccess ? codeName : null;
168168
CodeInfoAccess.printCodeInfo(log, codeInfo, codeInfoState, name, codeStart, codeEnd, hasInstalledCode, installedCodeAddress, installedCodeEntryPoint);
169169
log.string(", safepointId: ").unsigned(safepointId).newline();

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/container/Container.java

+4-3
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
import com.oracle.svm.core.c.CGlobalData;
4040
import com.oracle.svm.core.c.CGlobalDataFactory;
4141
import com.oracle.svm.core.feature.AutomaticallyRegisteredImageSingleton;
42+
import com.oracle.svm.core.util.TimeUtils;
4243
import com.oracle.svm.core.util.VMError;
4344

4445
import jdk.graal.compiler.api.replacements.Fold;
@@ -124,7 +125,7 @@ public static void initialize() {
124125
public int getActiveProcessorCount() {
125126
VMError.guarantee(isContainerized());
126127

127-
long currentMs = System.currentTimeMillis();
128+
long currentMs = TimeUtils.currentTimeMillis();
128129
if (currentMs > activeProcessorCountTimeoutMs) {
129130
cachedActiveProcessorCount = ContainerLibrary.getActiveProcessorCount();
130131
activeProcessorCountTimeoutMs = currentMs + CACHE_MS;
@@ -142,7 +143,7 @@ public int getCachedActiveProcessorCount() {
142143
public UnsignedWord getPhysicalMemory() {
143144
VMError.guarantee(isContainerized());
144145

145-
long currentMs = System.currentTimeMillis();
146+
long currentMs = TimeUtils.currentTimeMillis();
146147
if (currentMs > physicalMemoryTimeoutMs) {
147148
cachedPhysicalMemorySize = ContainerLibrary.physicalMemory();
148149
physicalMemoryTimeoutMs = currentMs + CACHE_MS;
@@ -160,7 +161,7 @@ public UnsignedWord getCachedPhysicalMemory() {
160161
public long getMemoryLimitInBytes() {
161162
VMError.guarantee(isContainerized());
162163

163-
long currentMs = System.currentTimeMillis();
164+
long currentMs = TimeUtils.currentTimeMillis();
164165
if (currentMs > memoryLimitInBytesTimeoutMs) {
165166
cachedMemoryLimitInBytes = ContainerLibrary.getMemoryLimitInBytes();
166167
memoryLimitInBytesTimeoutMs = currentMs + CACHE_MS;

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/dcmd/VMUptimeDmd.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ public VMUptimeDmd() {
4444
@BasedOnJDKFile("https://github.com/openjdk/jdk/blob/jdk-24+18/src/hotspot/share/services/diagnosticCommand.cpp#L393-L400")
4545
public String execute(DCmdArguments args) throws Throwable {
4646
StringBuilderLog log = new StringBuilderLog();
47-
log.rational(Isolates.getCurrentUptimeMillis(), TimeUtils.millisPerSecond, 3).string(" s").newline();
47+
log.rational(Isolates.getUptimeMillis(), TimeUtils.millisPerSecond, 3).string(" s").newline();
4848
return log.getResult();
4949
}
5050
}

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/deopt/Deoptimizer.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -1030,7 +1030,7 @@ protected static void writeValueInMaterializedObj(Object materializedObj, Unsign
10301030
}
10311031

10321032
private static void printDeoptimizedFrame(Log log, Pointer sp, DeoptimizedFrame deoptimizedFrame, FrameInfoQueryResult sourceFrameInfo, boolean printOnlyTopFrames) {
1033-
log.string("[Deoptimization of frame (").rational(Isolates.getCurrentUptimeMillis(), TimeUtils.millisPerSecond, 3).string("s)").newline();
1033+
log.string("[Deoptimization of frame (").rational(Isolates.getUptimeMillis(), TimeUtils.millisPerSecond, 3).string("s)").newline();
10341034

10351035
SubstrateInstalledCode installedCode = deoptimizedFrame.getSourceInstalledCode();
10361036
if (installedCode != null) {

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/graal/snippets/CEntryPointSnippets.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -405,7 +405,7 @@ private static int initializeIsolateInterruptibly1(CEntryPointCreateIsolateParam
405405
boolean firstIsolate = Unsafe.getUnsafe().compareAndSetInt(null, initStateAddr, FirstIsolateInitStates.UNINITIALIZED, FirstIsolateInitStates.IN_PROGRESS);
406406

407407
Isolates.assignIsolateId(firstIsolate);
408-
Isolates.assignCurrentStartTime();
408+
Isolates.assignStartTime();
409409

410410
if (!firstIsolate) {
411411
int state = Unsafe.getUnsafe().getInt(initStateAddr);

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/heap/dump/HeapDumpSupportImpl.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -118,10 +118,10 @@ private void dumpHeapOnOutOfMemoryError0() {
118118

119119
try {
120120
Log.log().string("Dumping heap to ").string(path).string(" ...").newline();
121-
long start = System.currentTimeMillis();
121+
long start = System.nanoTime();
122122
if (dumpHeap(fd, false)) {
123123
long fileSize = getFileSupport().size(fd);
124-
long elapsedMs = System.currentTimeMillis() - start;
124+
long elapsedMs = TimeUtils.millisSinceNanos(start);
125125
long seconds = elapsedMs / TimeUtils.millisPerSecond;
126126
long ms = elapsedMs % TimeUtils.millisPerSecond;
127127
Log.log().string("Heap dump file created [").signed(fileSize).string(" bytes in ").signed(seconds).character('.').signed(ms).string(" secs]").newline();

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/heap/dump/HeapDumpWriter.java

+2-1
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@
8585
import com.oracle.svm.core.thread.VMOperation;
8686
import com.oracle.svm.core.thread.VMThreads;
8787
import com.oracle.svm.core.threadlocal.VMThreadLocalSupport;
88+
import com.oracle.svm.core.util.TimeUtils;
8889
import com.oracle.svm.core.util.VMError;
8990

9091
import jdk.graal.compiler.api.replacements.Fold;
@@ -504,7 +505,7 @@ private void writeHeader() {
504505
writeUTF8("JAVA PROFILE 1.0.2");
505506
writeByte((byte) 0);
506507
writeInt(wordSize());
507-
writeLong(System.currentTimeMillis());
508+
writeLong(TimeUtils.currentTimeMillis());
508509
}
509510

510511
private void startTopLevelRecord(HProfTopLevelRecord tag) {

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/heap/dump/HeapDumping.java

+4-2
Original file line numberDiff line numberDiff line change
@@ -28,12 +28,14 @@
2828
import java.nio.file.Files;
2929
import java.nio.file.Paths;
3030

31-
import jdk.graal.compiler.api.replacements.Fold;
3231
import org.graalvm.nativeimage.ImageSingletons;
3332
import org.graalvm.nativeimage.ProcessProperties;
3433
import org.graalvm.nativeimage.impl.HeapDumpSupport;
3534

3635
import com.oracle.svm.core.SubstrateOptions;
36+
import com.oracle.svm.core.util.TimeUtils;
37+
38+
import jdk.graal.compiler.api.replacements.Fold;
3739

3840
public abstract class HeapDumping implements HeapDumpSupport {
3941
@Fold
@@ -58,7 +60,7 @@ public static String getHeapDumpPath(String defaultFilename) {
5860
}
5961

6062
public void dumpHeap(boolean gcBefore) throws IOException {
61-
String suffix = Long.toString(System.currentTimeMillis());
63+
String suffix = Long.toString(TimeUtils.currentTimeMillis());
6264
String defaultFilename = getDefaultHeapDumpFilename(suffix);
6365
dumpHeap(getHeapDumpPath(defaultFilename), gcBefore);
6466
}

0 commit comments

Comments
 (0)