< prev index next >

hotspot/src/share/vm/prims/jvm.cpp

Print this page

        

@@ -1,7 +1,7 @@
 /*
- * 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
  * under the terms of the GNU General Public License version 2 only, as
  * published by the Free Software Foundation.

@@ -298,10 +298,52 @@
 JVM_LEAF(jlong, JVM_NanoTime(JNIEnv *env, jclass ignored))
   JVMWrapper("JVM_NanoTime");
   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))
   JVMWrapper("JVM_ArrayCopy");
   // Check if we have null pointers
< prev index next >