8068730: Increase the precision of the implementation of java.time.Clock.systemUTC()
authordfuchs
Wed, 28 Jan 2015 17:52:48 +0100
changeset 28737 ca4b6a6e5cc8
parent 28736 33ab13e70aa0
child 28740 3ebd3353fda5
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
hotspot/make/aix/makefiles/mapfile-vers-debug
hotspot/make/aix/makefiles/mapfile-vers-product
hotspot/make/bsd/makefiles/mapfile-vers-darwin-debug
hotspot/make/bsd/makefiles/mapfile-vers-darwin-product
hotspot/make/bsd/makefiles/mapfile-vers-debug
hotspot/make/bsd/makefiles/mapfile-vers-product
hotspot/make/linux/makefiles/mapfile-vers-debug
hotspot/make/linux/makefiles/mapfile-vers-product
hotspot/make/solaris/makefiles/mapfile-vers
hotspot/src/os/aix/vm/os_aix.cpp
hotspot/src/os/bsd/vm/os_bsd.cpp
hotspot/src/os/linux/vm/os_linux.cpp
hotspot/src/os/solaris/vm/os_solaris.cpp
hotspot/src/os/windows/vm/os_windows.cpp
hotspot/src/share/vm/prims/jvm.cpp
hotspot/src/share/vm/prims/jvm.h
hotspot/src/share/vm/runtime/os.hpp
--- 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;
--- 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;
--- 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
--- 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
--- 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;
--- 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;
--- 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;
--- 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;
--- 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;
--- 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++)
--- 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)
--- 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
--- 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();
 }
--- 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.
--- 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))
--- 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);
--- 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();