diff --git a/src/hotspot/os/aix/os_perf_aix.cpp b/src/hotspot/os/aix/os_perf_aix.cpp index f66c60d1e61..15eca737fdf 100644 --- a/src/hotspot/os/aix/os_perf_aix.cpp +++ b/src/hotspot/os/aix/os_perf_aix.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -371,19 +371,21 @@ static int get_boot_time(uint64_t* time) { static int perf_context_switch_rate(double* rate) { static pthread_mutex_t contextSwitchLock = PTHREAD_MUTEX_INITIALIZER; - static uint64_t lastTime; + static uint64_t bootTime; + static uint64_t lastTimeNanos; static uint64_t lastSwitches; static double lastRate; - uint64_t lt = 0; + uint64_t bt = 0; int res = 0; - if (lastTime == 0) { + // First time through bootTime will be zero. + if (bootTime == 0) { uint64_t tmp; if (get_boot_time(&tmp) < 0) { return OS_ERR; } - lt = tmp * 1000; + bt = tmp * 1000; } res = OS_OK; @@ -394,20 +396,29 @@ static int perf_context_switch_rate(double* rate) { uint64_t sw; s8 t, d; - if (lastTime == 0) { - lastTime = lt; + if (bootTime == 0) { + // First interval is measured from boot time which is + // seconds since the epoch. Thereafter we measure the + // elapsed time using javaTimeNanos as it is monotonic- + // non-decreasing. + lastTimeNanos = os::javaTimeNanos(); + t = os::javaTimeMillis(); + d = t - bt; + // keep bootTime zero for now to use as a first-time-through flag + } else { + t = os::javaTimeNanos(); + d = nanos_to_millis(t - lastTimeNanos); } - t = os::javaTimeMillis(); - d = t - lastTime; - if (d == 0) { *rate = lastRate; - } else if (!get_noof_context_switches(&sw)) { + } else if (get_noof_context_switches(&sw) == 0) { *rate = ( (double)(sw - lastSwitches) / d ) * 1000; lastRate = *rate; lastSwitches = sw; - lastTime = t; + if (bootTime != 0) { + lastTimeNanos = t; + } } else { *rate = 0; res = OS_ERR; @@ -416,6 +427,10 @@ static int perf_context_switch_rate(double* rate) { *rate = 0; lastRate = 0; } + + if (bootTime == 0) { + bootTime = bt; + } } pthread_mutex_unlock(&contextSwitchLock); diff --git a/src/hotspot/os/bsd/semaphore_bsd.cpp b/src/hotspot/os/bsd/semaphore_bsd.cpp index 63290572711..b13e0c47ed0 100644 --- a/src/hotspot/os/bsd/semaphore_bsd.cpp +++ b/src/hotspot/os/bsd/semaphore_bsd.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -76,17 +76,17 @@ bool OSXSemaphore::timedwait(int64_t millis) { // kernel semaphores take a relative timeout mach_timespec_t waitspec; int secs = millis / MILLIUNITS; - int nsecs = (millis % MILLIUNITS) * NANOSECS_PER_MILLISEC; + int nsecs = millis_to_nanos(millis % MILLIUNITS); waitspec.tv_sec = secs; waitspec.tv_nsec = nsecs; - int64_t starttime = os::javaTimeMillis() * NANOSECS_PER_MILLISEC; + int64_t starttime = os::javaTimeNanos(); kr = semaphore_timedwait(_semaphore, waitspec); while (kr == KERN_ABORTED) { // reduce the timout and try again - int64_t totalwait = millis * NANOSECS_PER_MILLISEC; - int64_t current = os::javaTimeMillis() * NANOSECS_PER_MILLISEC; + int64_t totalwait = millis_to_nanos(millis); + int64_t current = os::javaTimeNanos(); int64_t passedtime = current - starttime; if (passedtime >= totalwait) { diff --git a/src/hotspot/os/linux/os_perf_linux.cpp b/src/hotspot/os/linux/os_perf_linux.cpp index 28273615a7c..7c42379a0a7 100644 --- a/src/hotspot/os/linux/os_perf_linux.cpp +++ b/src/hotspot/os/linux/os_perf_linux.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -431,19 +431,21 @@ static int get_boot_time(uint64_t* time) { static int perf_context_switch_rate(double* rate) { static pthread_mutex_t contextSwitchLock = PTHREAD_MUTEX_INITIALIZER; - static uint64_t lastTime; + static uint64_t bootTime; + static uint64_t lastTimeNanos; static uint64_t lastSwitches; static double lastRate; - uint64_t lt = 0; + uint64_t bt = 0; int res = 0; - if (lastTime == 0) { + // First time through bootTime will be zero. + if (bootTime == 0) { uint64_t tmp; if (get_boot_time(&tmp) < 0) { return OS_ERR; } - lt = tmp * 1000; + bt = tmp * 1000; } res = OS_OK; @@ -454,20 +456,29 @@ static int perf_context_switch_rate(double* rate) { uint64_t sw; s8 t, d; - if (lastTime == 0) { - lastTime = lt; + if (bootTime == 0) { + // First interval is measured from boot time which is + // seconds since the epoch. Thereafter we measure the + // elapsed time using javaTimeNanos as it is monotonic- + // non-decreasing. + lastTimeNanos = os::javaTimeNanos(); + t = os::javaTimeMillis(); + d = t - bt; + // keep bootTime zero for now to use as a first-time-through flag + } else { + t = os::javaTimeNanos(); + d = nanos_to_millis(t - lastTimeNanos); } - t = os::javaTimeMillis(); - d = t - lastTime; - if (d == 0) { *rate = lastRate; - } else if (!get_noof_context_switches(&sw)) { + } else if (get_noof_context_switches(&sw) == 0) { *rate = ( (double)(sw - lastSwitches) / d ) * 1000; lastRate = *rate; lastSwitches = sw; - lastTime = t; + if (bootTime != 0) { + lastTimeNanos = t; + } } else { *rate = 0; res = OS_ERR; @@ -476,6 +487,10 @@ static int perf_context_switch_rate(double* rate) { *rate = 0; lastRate = 0; } + + if (bootTime == 0) { + bootTime = bt; + } } pthread_mutex_unlock(&contextSwitchLock); diff --git a/src/hotspot/os/posix/os_posix.cpp b/src/hotspot/os/posix/os_posix.cpp index 5bd916b1725..7b62e8a7e2a 100644 --- a/src/hotspot/os/posix/os_posix.cpp +++ b/src/hotspot/os/posix/os_posix.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -681,7 +681,7 @@ void os::naked_short_nanosleep(jlong ns) { void os::naked_short_sleep(jlong ms) { assert(ms < MILLIUNITS, "Un-interruptable sleep, short time use only"); - os::naked_short_nanosleep(ms * (NANOUNITS / MILLIUNITS)); + os::naked_short_nanosleep(millis_to_nanos(ms)); return; } @@ -1833,18 +1833,18 @@ static void unpack_abs_time(timespec* abstime, jlong deadline, jlong now_sec) { abstime->tv_nsec = 0; } else { abstime->tv_sec = seconds; - abstime->tv_nsec = millis * (NANOUNITS / MILLIUNITS); + abstime->tv_nsec = millis_to_nanos(millis); } } -static jlong millis_to_nanos(jlong millis) { +static jlong millis_to_nanos_bounded(jlong millis) { // We have to watch for overflow when converting millis to nanos, // but if millis is that large then we will end up limiting to // MAX_SECS anyway, so just do that here. if (millis / MILLIUNITS > MAX_SECS) { millis = jlong(MAX_SECS) * MILLIUNITS; } - return millis * (NANOUNITS / MILLIUNITS); + return millis_to_nanos(millis); } static void to_abstime(timespec* abstime, jlong timeout, @@ -1897,7 +1897,7 @@ static void to_abstime(timespec* abstime, jlong timeout, // Create an absolute time 'millis' milliseconds in the future, using the // real-time (time-of-day) clock. Used by PosixSemaphore. void os::Posix::to_RTC_abstime(timespec* abstime, int64_t millis) { - to_abstime(abstime, millis_to_nanos(millis), + to_abstime(abstime, millis_to_nanos_bounded(millis), false /* not absolute */, true /* use real-time clock */); } @@ -1992,7 +1992,7 @@ int os::PlatformEvent::park(jlong millis) { if (v == 0) { // Do this the hard way by blocking ... struct timespec abst; - to_abstime(&abst, millis_to_nanos(millis), false, false); + to_abstime(&abst, millis_to_nanos_bounded(millis), false, false); int ret = OS_TIMEOUT; int status = pthread_mutex_lock(_mutex); @@ -2318,7 +2318,7 @@ int os::PlatformMonitor::wait(jlong millis) { if (millis / MILLIUNITS > MAX_SECS) { millis = jlong(MAX_SECS) * MILLIUNITS; } - to_abstime(&abst, millis * (NANOUNITS / MILLIUNITS), false, false); + to_abstime(&abst, millis_to_nanos(millis), false, false); int ret = OS_TIMEOUT; int status = pthread_cond_timedwait(cond(), mutex(), &abst); diff --git a/src/hotspot/os/windows/os_perf_windows.cpp b/src/hotspot/os/windows/os_perf_windows.cpp index 9a0e35b0592..5ac44f8b67b 100644 --- a/src/hotspot/os/windows/os_perf_windows.cpp +++ b/src/hotspot/os/windows/os_perf_windows.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -97,7 +97,7 @@ static const int min_update_interval_millis = 500; */ typedef struct { HQUERY query; - s8 lastUpdate; // Last time query was updated (current millis). + s8 lastUpdate; // Last time query was updated. } UpdateQueryS, *UpdateQueryP; @@ -287,8 +287,8 @@ static OSReturn add_process_counter(MultiCounterQueryP query, int slot_index, co static int collect_query_data(UpdateQueryP update_query) { assert(update_query != NULL, "invariant"); - const s8 now = os::javaTimeMillis(); - if (now - update_query->lastUpdate > min_update_interval_millis) { + const s8 now = os::javaTimeNanos(); + if (nanos_to_millis(now - update_query->lastUpdate) > min_update_interval_millis) { if (PdhDll::PdhCollectQueryData(update_query->query) != ERROR_SUCCESS) { return OS_ERR; } diff --git a/src/hotspot/share/compiler/compilationPolicy.cpp b/src/hotspot/share/compiler/compilationPolicy.cpp index fd4bf38be71..0e637d4c227 100644 --- a/src/hotspot/share/compiler/compilationPolicy.cpp +++ b/src/hotspot/share/compiler/compilationPolicy.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -289,14 +289,14 @@ class CounterDecay : public AllStatic { public: static void decay(); static bool is_decay_needed() { - return (os::javaTimeMillis() - _last_timestamp) > CounterDecayMinIntervalLength; + return nanos_to_millis(os::javaTimeNanos() - _last_timestamp) > CounterDecayMinIntervalLength; } }; jlong CounterDecay::_last_timestamp = 0; void CounterDecay::decay() { - _last_timestamp = os::javaTimeMillis(); + _last_timestamp = os::javaTimeNanos(); // This operation is going to be performed only at the end of a safepoint // and hence GC's will not be going on, all Java mutators are suspended diff --git a/src/hotspot/share/compiler/tieredThresholdPolicy.cpp b/src/hotspot/share/compiler/tieredThresholdPolicy.cpp index 2976a1134da..fb76545ce41 100644 --- a/src/hotspot/share/compiler/tieredThresholdPolicy.cpp +++ b/src/hotspot/share/compiler/tieredThresholdPolicy.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -304,7 +304,7 @@ void TieredThresholdPolicy::initialize() { #endif set_increase_threshold_at_ratio(); - set_start_time(os::javaTimeMillis()); + set_start_time(nanos_to_millis(os::javaTimeNanos())); } @@ -404,7 +404,7 @@ CompileTask* TieredThresholdPolicy::select_task(CompileQueue* compile_queue) { CompileTask *max_blocking_task = NULL; CompileTask *max_task = NULL; Method* max_method = NULL; - jlong t = os::javaTimeMillis(); + jlong t = nanos_to_millis(os::javaTimeNanos()); // Iterate through the queue and find a method with a maximum rate. for (CompileTask* task = compile_queue->first(); task != NULL;) { CompileTask* next_task = task->next(); @@ -596,7 +596,7 @@ void TieredThresholdPolicy::compile(const methodHandle& mh, int bci, CompLevel l print_event(COMPILE, mh(), mh(), bci, level); } int hot_count = (bci == InvocationEntryBci) ? mh->invocation_count() : mh->backedge_count(); - update_rate(os::javaTimeMillis(), mh()); + update_rate(nanos_to_millis(os::javaTimeNanos()), mh()); CompileBroker::compile_method(mh, bci, level, mh, hot_count, CompileTask::Reason_Tiered, thread); } } @@ -616,7 +616,7 @@ void TieredThresholdPolicy::update_rate(jlong t, Method* m) { // We don't update the rate if we've just came out of a safepoint. // delta_s is the time since last safepoint in milliseconds. - jlong delta_s = t - SafepointTracing::end_of_last_safepoint_epoch_ms(); + jlong delta_s = t - SafepointTracing::end_of_last_safepoint_ms(); jlong delta_t = t - (m->prev_time() != 0 ? m->prev_time() : start_time()); // milliseconds since the last measurement // How many events were there since the last time? int event_count = m->invocation_count() + m->backedge_count(); @@ -641,7 +641,7 @@ void TieredThresholdPolicy::update_rate(jlong t, Method* m) { // Check if this method has been stale for a given number of milliseconds. // See select_task(). bool TieredThresholdPolicy::is_stale(jlong t, jlong timeout, Method* m) { - jlong delta_s = t - SafepointTracing::end_of_last_safepoint_epoch_ms(); + jlong delta_s = t - SafepointTracing::end_of_last_safepoint_ms(); jlong delta_t = t - m->prev_time(); if (delta_t > timeout && delta_s > timeout) { int event_count = m->invocation_count() + m->backedge_count(); diff --git a/src/hotspot/share/gc/shenandoah/shenandoahHeapRegionCounters.cpp b/src/hotspot/share/gc/shenandoah/shenandoahHeapRegionCounters.cpp index aad2cbc9c1e..1d7c98e78fe 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahHeapRegionCounters.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahHeapRegionCounters.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2019, Red Hat, Inc. All rights reserved. + * Copyright (c) 2016, 2020, Red Hat, Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -75,7 +75,7 @@ ShenandoahHeapRegionCounters::~ShenandoahHeapRegionCounters() { void ShenandoahHeapRegionCounters::update() { if (ShenandoahRegionSampling) { - jlong current = os::javaTimeMillis(); + jlong current = nanos_to_millis(os::javaTimeNanos()); jlong last = _last_sample_millis; if (current - last > ShenandoahRegionSamplingRate && Atomic::cmpxchg(&_last_sample_millis, last, current) == last) { diff --git a/src/hotspot/share/jfr/recorder/repository/jfrChunk.cpp b/src/hotspot/share/jfr/recorder/repository/jfrChunk.cpp index 05482570cc3..63cd0483857 100644 --- a/src/hotspot/share/jfr/recorder/repository/jfrChunk.cpp +++ b/src/hotspot/share/jfr/recorder/repository/jfrChunk.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -37,6 +37,8 @@ static const u2 JFR_VERSION_MINOR = 1; // strictly monotone static jlong nanos_now() { static jlong last = 0; + // We use javaTimeMillis so this can be correlated with + // external timestamps. const jlong now = os::javaTimeMillis() * JfrTimeConverter::NANOS_PER_MILLISEC; if (now > last) { last = now; diff --git a/src/hotspot/share/jvmci/jvmciCompiler.cpp b/src/hotspot/share/jvmci/jvmciCompiler.cpp index b5620fe4332..b24b101afae 100644 --- a/src/hotspot/share/jvmci/jvmciCompiler.cpp +++ b/src/hotspot/share/jvmci/jvmciCompiler.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -61,7 +61,7 @@ void JVMCICompiler::bootstrap(TRAPS) { if (PrintBootstrap) { tty->print("Bootstrapping JVMCI"); } - jlong start = os::javaTimeMillis(); + jlong start = os::javaTimeNanos(); Array* objectMethods = SystemDictionary::Object_klass()->methods(); // Initialize compile queue with a selected set of methods. @@ -94,7 +94,8 @@ void JVMCICompiler::bootstrap(TRAPS) { } while (qsize != 0); if (PrintBootstrap) { - tty->print_cr(" in " JLONG_FORMAT " ms (compiled %d methods)", os::javaTimeMillis() - start, _methods_compiled); + tty->print_cr(" in " JLONG_FORMAT " ms (compiled %d methods)", + nanos_to_millis(os::javaTimeNanos() - start), _methods_compiled); } _bootstrapping = false; JVMCI::compiler_runtime()->bootstrap_finished(CHECK); diff --git a/src/hotspot/share/logging/logDecorations.cpp b/src/hotspot/share/logging/logDecorations.cpp index 0f3a843d63e..10bb2f4b17b 100644 --- a/src/hotspot/share/logging/logDecorations.cpp +++ b/src/hotspot/share/logging/logDecorations.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -34,7 +34,7 @@ jlong LogDecorations::_vm_start_time_millis = 0; const char* volatile LogDecorations::_host_name = NULL; LogDecorations::LogDecorations(LogLevelType level, const LogTagSet &tagset, const LogDecorators &decorators) - : _level(level), _tagset(tagset), _millis(-1) { + : _level(level), _tagset(tagset) { create_decorations(decorators); } @@ -71,13 +71,6 @@ void LogDecorations::create_decorations(const LogDecorators &decorators) { #undef DECORATOR } -jlong LogDecorations::java_millis() { - if (_millis < 0) { - _millis = os::javaTimeMillis(); - } - return _millis; -} - #define ASSERT_AND_RETURN(written, pos) \ assert(written >= 0, "Decorations buffer overflow"); \ return pos + written; @@ -100,13 +93,13 @@ char * LogDecorations::create_uptime_decoration(char* pos) { } char * LogDecorations::create_timemillis_decoration(char* pos) { - int written = jio_snprintf(pos, DecorationsBufferSize - (pos - _decorations_buffer), INT64_FORMAT "ms", java_millis()); + int written = jio_snprintf(pos, DecorationsBufferSize - (pos - _decorations_buffer), INT64_FORMAT "ms", os::javaTimeMillis()); ASSERT_AND_RETURN(written, pos) } char * LogDecorations::create_uptimemillis_decoration(char* pos) { int written = jio_snprintf(pos, DecorationsBufferSize - (pos - _decorations_buffer), - INT64_FORMAT "ms", java_millis() - _vm_start_time_millis); + INT64_FORMAT "ms", nanos_to_millis(os::elapsed_counter())); ASSERT_AND_RETURN(written, pos) } diff --git a/src/hotspot/share/logging/logDecorations.hpp b/src/hotspot/share/logging/logDecorations.hpp index a7aa1147a72..a35d2a75bf0 100644 --- a/src/hotspot/share/logging/logDecorations.hpp +++ b/src/hotspot/share/logging/logDecorations.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -36,12 +36,10 @@ class LogDecorations { char* _decoration_offset[LogDecorators::Count]; LogLevelType _level; const LogTagSet& _tagset; - jlong _millis; static jlong _vm_start_time_millis; static const char* volatile _host_name; const char* host_name(); - jlong java_millis(); void create_decorations(const LogDecorators& decorators); #define DECORATOR(name, abbr) char* create_##name##_decoration(char* pos); diff --git a/src/hotspot/share/runtime/biasedLocking.cpp b/src/hotspot/share/runtime/biasedLocking.cpp index 226024825c1..1ab60899fce 100644 --- a/src/hotspot/share/runtime/biasedLocking.cpp +++ b/src/hotspot/share/runtime/biasedLocking.cpp @@ -324,7 +324,7 @@ static HeuristicsResult update_heuristics(oop o) { // and don't allow rebiasing of these objects. Disable // allocation of objects of that type with the bias bit set. Klass* k = o->klass(); - jlong cur_time = os::javaTimeMillis(); + jlong cur_time = nanos_to_millis(os::javaTimeNanos()); jlong last_bulk_revocation_time = k->last_biased_lock_bulk_revocation_time(); int revocation_count = k->biased_lock_revocation_count(); if ((revocation_count >= BiasedLockingBulkRebiasThreshold) && @@ -374,7 +374,7 @@ void BiasedLocking::bulk_revoke_at_safepoint(oop o, bool bulk_rebias, JavaThread o->mark().value(), o->klass()->external_name()); - jlong cur_time = os::javaTimeMillis(); + jlong cur_time = nanos_to_millis(os::javaTimeNanos()); o->klass()->set_last_biased_lock_bulk_revocation_time(cur_time); Klass* k_o = o->klass(); diff --git a/src/hotspot/share/runtime/safepoint.cpp b/src/hotspot/share/runtime/safepoint.cpp index 832e45f8ee1..c71e6f40c41 100644 --- a/src/hotspot/share/runtime/safepoint.cpp +++ b/src/hotspot/share/runtime/safepoint.cpp @@ -1142,7 +1142,6 @@ jlong SafepointTracing::_last_safepoint_begin_time_ns = 0; jlong SafepointTracing::_last_safepoint_sync_time_ns = 0; jlong SafepointTracing::_last_safepoint_cleanup_time_ns = 0; jlong SafepointTracing::_last_safepoint_end_time_ns = 0; -jlong SafepointTracing::_last_safepoint_end_time_epoch_ms = 0; jlong SafepointTracing::_last_app_time_ns = 0; int SafepointTracing::_nof_threads = 0; int SafepointTracing::_nof_running = 0; @@ -1155,8 +1154,6 @@ uint64_t SafepointTracing::_op_count[VM_Operation::VMOp_Terminating] = {0}; void SafepointTracing::init() { // Application start _last_safepoint_end_time_ns = os::javaTimeNanos(); - // amount of time since epoch - _last_safepoint_end_time_epoch_ms = os::javaTimeMillis(); } // Helper method to print the header. @@ -1256,8 +1253,6 @@ void SafepointTracing::cleanup() { void SafepointTracing::end() { _last_safepoint_end_time_ns = os::javaTimeNanos(); - // amount of time since epoch - _last_safepoint_end_time_epoch_ms = os::javaTimeMillis(); if (_max_sync_time < (_last_safepoint_sync_time_ns - _last_safepoint_begin_time_ns)) { _max_sync_time = _last_safepoint_sync_time_ns - _last_safepoint_begin_time_ns; diff --git a/src/hotspot/share/runtime/safepoint.hpp b/src/hotspot/share/runtime/safepoint.hpp index 8f142b65ea1..9a5d299aaba 100644 --- a/src/hotspot/share/runtime/safepoint.hpp +++ b/src/hotspot/share/runtime/safepoint.hpp @@ -252,8 +252,7 @@ class SafepointTracing : public AllStatic { static jlong _last_safepoint_sync_time_ns; static jlong _last_safepoint_cleanup_time_ns; static jlong _last_safepoint_end_time_ns; - // amount of ms since epoch - static jlong _last_safepoint_end_time_epoch_ms; + // Relative static jlong _last_app_time_ns; @@ -279,11 +278,11 @@ class SafepointTracing : public AllStatic { static void statistics_exit_log(); static jlong time_since_last_safepoint_ms() { - return (os::javaTimeNanos() - _last_safepoint_end_time_ns) / (NANOUNITS / MILLIUNITS); + return nanos_to_millis(os::javaTimeNanos() - _last_safepoint_end_time_ns); } - static jlong end_of_last_safepoint_epoch_ms() { - return _last_safepoint_end_time_epoch_ms; + static jlong end_of_last_safepoint_ms() { + return nanos_to_millis(_last_safepoint_end_time_ns); } static jlong start_of_safepoint() { diff --git a/src/hotspot/share/runtime/threadStatisticalInfo.hpp b/src/hotspot/share/runtime/threadStatisticalInfo.hpp index 3164b9acb1f..f0353a0f8f6 100644 --- a/src/hotspot/share/runtime/threadStatisticalInfo.hpp +++ b/src/hotspot/share/runtime/threadStatisticalInfo.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2018 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -37,12 +37,11 @@ class ThreadStatisticalInfo { uint64_t _define_class_count; public: - ThreadStatisticalInfo() : _start_time_stamp(os::javaTimeMillis()), _define_class_count(0) {} - uint64_t getStartTime() const { return _start_time_stamp; } - uint64_t getDefineClassCount() const { return _define_class_count; } + ThreadStatisticalInfo() : _start_time_stamp(os::javaTimeNanos()), _define_class_count(0) {} + uint64_t getDefineClassCount() const { return _define_class_count; } void setDefineClassCount(uint64_t defineClassCount) { _define_class_count = defineClassCount; } - void incr_define_class_count() { _define_class_count += 1; } - uint64_t getElapsedTime() const { return os::javaTimeMillis() - getStartTime(); } + void incr_define_class_count() { _define_class_count += 1; } + uint64_t getElapsedTime() const { return nanos_to_millis(os::javaTimeNanos() - _start_time_stamp); } }; #endif // SHARE_RUNTIME_THREADSTATISTICALINFO_HPP diff --git a/src/hotspot/share/runtime/vmOperations.hpp b/src/hotspot/share/runtime/vmOperations.hpp index 1dc79ff6ec2..a77929c6fa5 100644 --- a/src/hotspot/share/runtime/vmOperations.hpp +++ b/src/hotspot/share/runtime/vmOperations.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -136,7 +136,7 @@ class VM_Operation : public StackObj { private: Thread* _calling_thread; - long _timestamp; + uint64_t _timestamp; VM_Operation* _next; VM_Operation* _prev; @@ -150,8 +150,8 @@ class VM_Operation : public StackObj { Thread* calling_thread() const { return _calling_thread; } void set_calling_thread(Thread* thread); - long timestamp() const { return _timestamp; } - void set_timestamp(long timestamp) { _timestamp = timestamp; } + uint64_t timestamp() const { return _timestamp; } + void set_timestamp(uint64_t timestamp) { _timestamp = timestamp; } // Called by VM thread - does in turn invoke doit(). Do not override this void evaluate(); diff --git a/src/hotspot/share/runtime/vmThread.cpp b/src/hotspot/share/runtime/vmThread.cpp index cd1eb8b483f..bb41a3c1fc5 100644 --- a/src/hotspot/share/runtime/vmThread.cpp +++ b/src/hotspot/share/runtime/vmThread.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -167,7 +167,7 @@ VM_Operation* VMOperationQueue::remove_next() { void VMOperationTimeoutTask::task() { assert(AbortVMOnVMOperationTimeout, "only if enabled"); if (is_armed()) { - jlong delay = (os::javaTimeMillis() - _arm_time); + jlong delay = nanos_to_millis(os::javaTimeNanos() - _arm_time); if (delay > AbortVMOnVMOperationTimeoutDelay) { fatal("VM operation took too long: " JLONG_FORMAT " ms (timeout: " INTX_FORMAT " ms)", delay, AbortVMOnVMOperationTimeoutDelay); @@ -180,7 +180,7 @@ bool VMOperationTimeoutTask::is_armed() { } void VMOperationTimeoutTask::arm() { - _arm_time = os::javaTimeMillis(); + _arm_time = os::javaTimeNanos(); Atomic::release_store_fence(&_armed, 1); } @@ -446,9 +446,9 @@ void VMThread::loop() { // Stall time tracking code if (PrintVMQWaitTime && _cur_vm_operation != NULL) { - long stall = os::javaTimeMillis() - _cur_vm_operation->timestamp(); + jlong stall = nanos_to_millis(os::javaTimeNanos() - _cur_vm_operation->timestamp()); if (stall > 0) - tty->print_cr("%s stall: %ld", _cur_vm_operation->name(), stall); + tty->print_cr("%s stall: " JLONG_FORMAT, _cur_vm_operation->name(), stall); } while (!should_terminate() && _cur_vm_operation == NULL) { @@ -640,7 +640,7 @@ void VMThread::execute(VM_Operation* op) { MonitorLocker ml(VMOperationQueue_lock, Mutex::_no_safepoint_check_flag); log_debug(vmthread)("Adding VM operation: %s", op->name()); _vm_queue->add(op); - op->set_timestamp(os::javaTimeMillis()); + op->set_timestamp(os::javaTimeNanos()); ml.notify(); } { diff --git a/src/hotspot/share/services/gcNotifier.cpp b/src/hotspot/share/services/gcNotifier.cpp index ab2739e49fb..b9a1e9b5852 100644 --- a/src/hotspot/share/services/gcNotifier.cpp +++ b/src/hotspot/share/services/gcNotifier.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -49,6 +49,7 @@ void GCNotifier::pushNotification(GCMemoryManager *mgr, const char *action, cons // stat is deallocated inside GCNotificationRequest GCStatInfo* stat = new(ResourceObj::C_HEAP, mtGC) GCStatInfo(num_pools); mgr->get_last_gc_stat(stat); + // timestamp is current time in ms GCNotificationRequest *request = new GCNotificationRequest(os::javaTimeMillis(),mgr,action,cause,stat); addRequest(request); } diff --git a/src/hotspot/share/services/heapDumper.cpp b/src/hotspot/share/services/heapDumper.cpp index 58138a6e9c4..f9084b3b075 100644 --- a/src/hotspot/share/services/heapDumper.cpp +++ b/src/hotspot/share/services/heapDumper.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -1827,6 +1827,7 @@ void VM_HeapDumper::doit() { writer()->write_raw((void*)header, (int)strlen(header)); writer()->write_u1(0); // terminator writer()->write_u4(oopSize); + // timestamp is current time in ms writer()->write_u8(os::javaTimeMillis()); // HPROF_UTF8 records diff --git a/src/hotspot/share/utilities/globalDefinitions.hpp b/src/hotspot/share/utilities/globalDefinitions.hpp index d65758c2199..6bdbd789b48 100644 --- a/src/hotspot/share/utilities/globalDefinitions.hpp +++ b/src/hotspot/share/utilities/globalDefinitions.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -254,10 +254,22 @@ const size_t HWperKB = K / sizeof(HeapWord); const int MILLIUNITS = 1000; // milli units per base unit const int MICROUNITS = 1000000; // micro units per base unit const int NANOUNITS = 1000000000; // nano units per base unit +const int NANOUNITS_PER_MILLIUNIT = NANOUNITS / MILLIUNITS; const jlong NANOSECS_PER_SEC = CONST64(1000000000); const jint NANOSECS_PER_MILLISEC = 1000000; + +// Unit conversion functions +// The caller is responsible for considering overlow. + +inline int64_t nanos_to_millis(int64_t nanos) { + return nanos / NANOUNITS_PER_MILLIUNIT; +} +inline int64_t millis_to_nanos(int64_t millis) { + return millis * NANOUNITS_PER_MILLIUNIT; +} + // Proper units routines try to maintain at least three significant digits. // In worst case, it would print five significant digits with lower prefix. // G is close to MAX_SIZE on 32-bit platforms, so its product can easily overflow, diff --git a/src/hotspot/share/utilities/ostream.cpp b/src/hotspot/share/utilities/ostream.cpp index 4ef1c54a0d0..7fedb7038e2 100644 --- a/src/hotspot/share/utilities/ostream.cpp +++ b/src/hotspot/share/utilities/ostream.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -659,9 +659,10 @@ void defaultStream::start_log() { // Write XML header. xs->print_cr(""); // (For now, don't bother to issue a DTD for this private format.) + + // Calculate the start time of the log as ms since the epoch: this is + // the current time in ms minus the uptime in ms. jlong time_ms = os::javaTimeMillis() - tty->time_stamp().milliseconds(); - // %%% Should be: jlong time_ms = os::start_time_milliseconds(), if - // we ever get round to introduce that method on the os class xs->head("hotspot_log version='%d %d'" " process='%d' time_ms='" INT64_FORMAT "'", LOG_MAJOR_VERSION, LOG_MINOR_VERSION,