# HG changeset patch # User dfuchs # Date 1422463968 -3600 # Node ID ca4b6a6e5cc86f6102755d0ce9ba767470979298 # Parent 33ab13e70aa0015b1c6b7214e5ca672d5c6bf701 8068730: Increase the precision of the implementation of java.time.Clock.systemUTC() Summary: Changes the implementation of java.time.Clock.systemUTC() to take advantage of the maximum resolution of the underlying native clock on which System.currentTimeMillis() is based. Reviewed-by: dholmes, rriggs, scolebourne, sla diff -r 33ab13e70aa0 -r ca4b6a6e5cc8 hotspot/make/aix/makefiles/mapfile-vers-debug --- a/hotspot/make/aix/makefiles/mapfile-vers-debug Wed Jan 28 09:27:49 2015 +0100 +++ b/hotspot/make/aix/makefiles/mapfile-vers-debug Wed Jan 28 17:52:48 2015 +0100 @@ -1,5 +1,5 @@ # -# Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2002, 2015, 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 @@ -132,6 +132,7 @@ JVM_GetMethodIxSignatureUTF; JVM_GetMethodParameters; JVM_GetMethodTypeAnnotations; + JVM_GetNanoTimeAdjustment; JVM_GetPrimitiveArrayElement; JVM_GetProtectionDomain; JVM_GetStackAccessControlContext; diff -r 33ab13e70aa0 -r ca4b6a6e5cc8 hotspot/make/aix/makefiles/mapfile-vers-product --- a/hotspot/make/aix/makefiles/mapfile-vers-product Wed Jan 28 09:27:49 2015 +0100 +++ b/hotspot/make/aix/makefiles/mapfile-vers-product Wed Jan 28 17:52:48 2015 +0100 @@ -1,5 +1,5 @@ # -# Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2002, 2015, 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 @@ -130,6 +130,7 @@ JVM_GetMethodIxNameUTF; JVM_GetMethodIxSignatureUTF; JVM_GetMethodParameters; + JVM_GetNanoTimeAdjustment; JVM_GetPrimitiveArrayElement; JVM_GetProtectionDomain; JVM_GetStackAccessControlContext; diff -r 33ab13e70aa0 -r ca4b6a6e5cc8 hotspot/make/bsd/makefiles/mapfile-vers-darwin-debug --- a/hotspot/make/bsd/makefiles/mapfile-vers-darwin-debug Wed Jan 28 09:27:49 2015 +0100 +++ b/hotspot/make/bsd/makefiles/mapfile-vers-darwin-debug Wed Jan 28 17:52:48 2015 +0100 @@ -1,5 +1,5 @@ # -# Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2002, 2015, 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 @@ -130,6 +130,7 @@ _JVM_GetMethodIxSignatureUTF _JVM_GetMethodParameters _JVM_GetMethodTypeAnnotations + _JVM_GetNanoTimeAdjustment _JVM_GetPrimitiveArrayElement _JVM_GetProtectionDomain _JVM_GetStackAccessControlContext diff -r 33ab13e70aa0 -r ca4b6a6e5cc8 hotspot/make/bsd/makefiles/mapfile-vers-darwin-product --- a/hotspot/make/bsd/makefiles/mapfile-vers-darwin-product Wed Jan 28 09:27:49 2015 +0100 +++ b/hotspot/make/bsd/makefiles/mapfile-vers-darwin-product Wed Jan 28 17:52:48 2015 +0100 @@ -1,5 +1,5 @@ # -# Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2002, 2015, 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 @@ -130,6 +130,7 @@ _JVM_GetMethodIxSignatureUTF _JVM_GetMethodParameters _JVM_GetMethodTypeAnnotations + _JVM_GetNanoTimeAdjustment _JVM_GetPrimitiveArrayElement _JVM_GetProtectionDomain _JVM_GetStackAccessControlContext diff -r 33ab13e70aa0 -r ca4b6a6e5cc8 hotspot/make/bsd/makefiles/mapfile-vers-debug --- a/hotspot/make/bsd/makefiles/mapfile-vers-debug Wed Jan 28 09:27:49 2015 +0100 +++ b/hotspot/make/bsd/makefiles/mapfile-vers-debug Wed Jan 28 17:52:48 2015 +0100 @@ -1,5 +1,5 @@ # -# Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2002, 2015, 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 @@ -132,6 +132,7 @@ JVM_GetMethodIxSignatureUTF; JVM_GetMethodParameters; JVM_GetMethodTypeAnnotations; + JVM_GetNanoTimeAdjustment; JVM_GetPrimitiveArrayElement; JVM_GetProtectionDomain; JVM_GetStackAccessControlContext; diff -r 33ab13e70aa0 -r ca4b6a6e5cc8 hotspot/make/bsd/makefiles/mapfile-vers-product --- a/hotspot/make/bsd/makefiles/mapfile-vers-product Wed Jan 28 09:27:49 2015 +0100 +++ b/hotspot/make/bsd/makefiles/mapfile-vers-product Wed Jan 28 17:52:48 2015 +0100 @@ -1,5 +1,5 @@ # -# Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2002, 2015, 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 @@ -132,6 +132,7 @@ JVM_GetMethodIxSignatureUTF; JVM_GetMethodParameters; JVM_GetMethodTypeAnnotations; + JVM_GetNanoTimeAdjustment; JVM_GetPrimitiveArrayElement; JVM_GetProtectionDomain; JVM_GetStackAccessControlContext; diff -r 33ab13e70aa0 -r ca4b6a6e5cc8 hotspot/make/linux/makefiles/mapfile-vers-debug --- a/hotspot/make/linux/makefiles/mapfile-vers-debug Wed Jan 28 09:27:49 2015 +0100 +++ b/hotspot/make/linux/makefiles/mapfile-vers-debug Wed Jan 28 17:52:48 2015 +0100 @@ -1,5 +1,5 @@ # -# Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2002, 2015, 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 @@ -132,6 +132,7 @@ JVM_GetMethodIxSignatureUTF; JVM_GetMethodParameters; JVM_GetMethodTypeAnnotations; + JVM_GetNanoTimeAdjustment; JVM_GetPrimitiveArrayElement; JVM_GetProtectionDomain; JVM_GetStackAccessControlContext; diff -r 33ab13e70aa0 -r ca4b6a6e5cc8 hotspot/make/linux/makefiles/mapfile-vers-product --- a/hotspot/make/linux/makefiles/mapfile-vers-product Wed Jan 28 09:27:49 2015 +0100 +++ b/hotspot/make/linux/makefiles/mapfile-vers-product Wed Jan 28 17:52:48 2015 +0100 @@ -1,5 +1,5 @@ # -# Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2002, 2015, 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 @@ -132,6 +132,7 @@ JVM_GetMethodIxSignatureUTF; JVM_GetMethodParameters; JVM_GetMethodTypeAnnotations; + JVM_GetNanoTimeAdjustment; JVM_GetPrimitiveArrayElement; JVM_GetProtectionDomain; JVM_GetStackAccessControlContext; diff -r 33ab13e70aa0 -r ca4b6a6e5cc8 hotspot/make/solaris/makefiles/mapfile-vers --- a/hotspot/make/solaris/makefiles/mapfile-vers Wed Jan 28 09:27:49 2015 +0100 +++ b/hotspot/make/solaris/makefiles/mapfile-vers Wed Jan 28 17:52:48 2015 +0100 @@ -1,5 +1,5 @@ # -# Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2000, 2015, 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 @@ -132,6 +132,7 @@ JVM_GetMethodIxSignatureUTF; JVM_GetMethodParameters; JVM_GetMethodTypeAnnotations; + JVM_GetNanoTimeAdjustment; JVM_GetPrimitiveArrayElement; JVM_GetProtectionDomain; JVM_GetStackAccessControlContext; diff -r 33ab13e70aa0 -r ca4b6a6e5cc8 hotspot/src/os/aix/vm/os_aix.cpp --- a/hotspot/src/os/aix/vm/os_aix.cpp Wed Jan 28 09:27:49 2015 +0100 +++ b/hotspot/src/os/aix/vm/os_aix.cpp Wed Jan 28 17:52:48 2015 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved. * Copyright 2012, 2014 SAP AG. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -1115,6 +1115,15 @@ return jlong(time.tv_sec) * 1000 + jlong(time.tv_usec / 1000); } +void os::javaTimeSystemUTC(jlong &seconds, jlong &nanos) { + timeval time; + int status = gettimeofday(&time, NULL); + assert(status != -1, "aix error at gettimeofday()"); + seconds = jlong(time.tv_sec); + nanos = jlong(time.tv_usec) * 1000; +} + + // We need to manually declare mread_real_time, // because IBM didn't provide a prototype in time.h. // (they probably only ever tested in C, not C++) diff -r 33ab13e70aa0 -r ca4b6a6e5cc8 hotspot/src/os/bsd/vm/os_bsd.cpp --- a/hotspot/src/os/bsd/vm/os_bsd.cpp Wed Jan 28 09:27:49 2015 +0100 +++ b/hotspot/src/os/bsd/vm/os_bsd.cpp Wed Jan 28 17:52:48 2015 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2015, 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 @@ -984,6 +984,14 @@ return jlong(time.tv_sec) * 1000 + jlong(time.tv_usec / 1000); } +void os::javaTimeSystemUTC(jlong &seconds, jlong &nanos) { + timeval time; + int status = gettimeofday(&time, NULL); + assert(status != -1, "bsd error"); + seconds = jlong(time.tv_sec); + nanos = jlong(time.tv_usec) * 1000; +} + #ifndef __APPLE__ #ifndef CLOCK_MONOTONIC #define CLOCK_MONOTONIC (1) diff -r 33ab13e70aa0 -r ca4b6a6e5cc8 hotspot/src/os/linux/vm/os_linux.cpp --- a/hotspot/src/os/linux/vm/os_linux.cpp Wed Jan 28 09:27:49 2015 +0100 +++ b/hotspot/src/os/linux/vm/os_linux.cpp Wed Jan 28 17:52:48 2015 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2015, 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 @@ -1322,6 +1322,15 @@ return jlong(time.tv_sec) * 1000 + jlong(time.tv_usec / 1000); } +void os::javaTimeSystemUTC(jlong &seconds, jlong &nanos) { + timeval time; + int status = gettimeofday(&time, NULL); + assert(status != -1, "linux error"); + seconds = jlong(time.tv_sec); + nanos = jlong(time.tv_usec) * 1000; +} + + #ifndef CLOCK_MONOTONIC #define CLOCK_MONOTONIC (1) #endif diff -r 33ab13e70aa0 -r ca4b6a6e5cc8 hotspot/src/os/solaris/vm/os_solaris.cpp --- a/hotspot/src/os/solaris/vm/os_solaris.cpp Wed Jan 28 09:27:49 2015 +0100 +++ b/hotspot/src/os/solaris/vm/os_solaris.cpp Wed Jan 28 17:52:48 2015 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2015, 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 @@ -1475,6 +1475,16 @@ return jlong(t.tv_sec) * 1000 + jlong(t.tv_usec) / 1000; } +void os::javaTimeSystemUTC(jlong &seconds, jlong &nanos) { + timeval t; + if (gettimeofday(&t, NULL) == -1) { + fatal(err_msg("os::javaTimeSystemUTC: gettimeofday (%s)", strerror(errno))); + } + seconds = jlong(t.tv_sec); + nanos = jlong(t.tv_usec) * 1000; +} + + jlong os::javaTimeNanos() { return (jlong)getTimeNanos(); } diff -r 33ab13e70aa0 -r ca4b6a6e5cc8 hotspot/src/os/windows/vm/os_windows.cpp --- a/hotspot/src/os/windows/vm/os_windows.cpp Wed Jan 28 09:27:49 2015 +0100 +++ b/hotspot/src/os/windows/vm/os_windows.cpp Wed Jan 28 17:52:48 2015 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2015, 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 @@ -839,6 +839,12 @@ return (a - offset()) / 10000; } +// Returns time ticks in (10th of micro seconds) +jlong windows_to_time_ticks(FILETIME wt) { + jlong a = jlong_from(wt.dwHighDateTime, wt.dwLowDateTime); + return (a - offset()); +} + FILETIME java_to_windows_time(jlong l) { jlong a = (l * 10000) + offset(); FILETIME result; @@ -874,6 +880,15 @@ } } +void os::javaTimeSystemUTC(jlong &seconds, jlong &nanos) { + FILETIME wt; + GetSystemTimeAsFileTime(&wt); + jlong ticks = windows_to_time_ticks(wt); // 10th of micros + jlong secs = jlong(ticks / 10000000); // 10000 * 1000 + seconds = secs; + nanos = jlong(ticks - (secs*10000000)) * 100; +} + jlong os::javaTimeNanos() { if (!win32::_has_performance_count) { return javaTimeMillis() * NANOSECS_PER_MILLISEC; // the best we can do. diff -r 33ab13e70aa0 -r ca4b6a6e5cc8 hotspot/src/share/vm/prims/jvm.cpp --- a/hotspot/src/share/vm/prims/jvm.cpp Wed Jan 28 09:27:49 2015 +0100 +++ b/hotspot/src/share/vm/prims/jvm.cpp Wed Jan 28 17:52:48 2015 +0100 @@ -300,6 +300,48 @@ return os::javaTimeNanos(); JVM_END +// The function below is actually exposed by sun.misc.VM and not +// java.lang.System, but we choose to keep it here so that it stays next +// to JVM_CurrentTimeMillis and JVM_NanoTime + +const jlong MAX_DIFF_SECS = 0x0100000000; // 2^32 +const jlong MIN_DIFF_SECS = -MAX_DIFF_SECS; // -2^32 + +JVM_LEAF(jlong, JVM_GetNanoTimeAdjustment(JNIEnv *env, jclass ignored, jlong offset_secs)) + JVMWrapper("JVM_GetNanoTimeAdjustment"); + jlong seconds; + jlong nanos; + + os::javaTimeSystemUTC(seconds, nanos); + + // We're going to verify that the result can fit in a long. + // For that we need the difference in seconds between 'seconds' + // and 'offset_secs' to be such that: + // |seconds - offset_secs| < (2^63/10^9) + // We're going to approximate 10^9 ~< 2^30 (1000^3 ~< 1024^3) + // which makes |seconds - offset_secs| < 2^33 + // and we will prefer +/- 2^32 as the maximum acceptable diff + // as 2^32 has a more natural feel than 2^33... + // + // So if |seconds - offset_secs| >= 2^32 - we return a special + // sentinel value (-1) which the caller should take as an + // exception value indicating that the offset given to us is + // too far from range of the current time - leading to too big + // a nano adjustment. The caller is expected to recover by + // computing a more accurate offset and calling this method + // again. (For the record 2^32 secs is ~136 years, so that + // should rarely happen) + // + jlong diff = seconds - offset_secs; + if (diff >= MAX_DIFF_SECS || diff <= MIN_DIFF_SECS) { + return -1; // sentinel value: the offset is too far off the target + } + + // return the adjustment. If you compute a time by adding + // this number of nanoseconds along with the number of seconds + // in the offset you should get the current UTC time. + return (diff * (jlong)1000000000) + nanos; +JVM_END JVM_ENTRY(void, JVM_ArrayCopy(JNIEnv *env, jclass ignored, jobject src, jint src_pos, jobject dst, jint dst_pos, jint length)) diff -r 33ab13e70aa0 -r ca4b6a6e5cc8 hotspot/src/share/vm/prims/jvm.h --- a/hotspot/src/share/vm/prims/jvm.h Wed Jan 28 09:27:49 2015 +0100 +++ b/hotspot/src/share/vm/prims/jvm.h Wed Jan 28 17:52:48 2015 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2015, 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 @@ -131,6 +131,9 @@ JNIEXPORT jlong JNICALL JVM_NanoTime(JNIEnv *env, jclass ignored); +JNIEXPORT jlong JNICALL +JVM_GetNanoTimeAdjustment(JNIEnv *env, jclass ignored, jlong offset_secs); + JNIEXPORT void JNICALL JVM_ArrayCopy(JNIEnv *env, jclass ignored, jobject src, jint src_pos, jobject dst, jint dst_pos, jint length); diff -r 33ab13e70aa0 -r ca4b6a6e5cc8 hotspot/src/share/vm/runtime/os.hpp --- a/hotspot/src/share/vm/runtime/os.hpp Wed Jan 28 09:27:49 2015 +0100 +++ b/hotspot/src/share/vm/runtime/os.hpp Wed Jan 28 17:52:48 2015 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2015, 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 @@ -172,10 +172,10 @@ static jlong javaTimeMillis(); static jlong javaTimeNanos(); static void javaTimeNanos_info(jvmtiTimerInfo *info_ptr); + static void javaTimeSystemUTC(jlong &seconds, jlong &nanos); static void run_periodic_checks(); static bool supports_monotonic_clock(); - // Returns the elapsed time in seconds since the vm started. static double elapsedTime();