Merge changes from topic "getNanoTimeAdjustment" am: 4c37a04b40

Original change: https://android-review.googlesource.com/c/platform/libcore/+/2053978

Change-Id: If9432362f8895cf203b33e2f7800a44d78fbfffb
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
diff --git a/ojluni/src/main/java/java/time/Clock.java b/ojluni/src/main/java/java/time/Clock.java
index fb0255c..37e723e 100644
--- a/ojluni/src/main/java/java/time/Clock.java
+++ b/ojluni/src/main/java/java/time/Clock.java
@@ -522,8 +522,6 @@
         }
         @Override
         public Instant instant() {
-            // BEGIN Android-changed: Use OpenJDK 8 implementation until getNanoTimeAdjustment() is supported.
-            /*
             // Take a local copy of offset. offset can be updated concurrently
             // by other threads (even if we haven't made it volatile) so we will
             // work with a local copy.
@@ -558,9 +556,6 @@
                 }
             }
             return Instant.ofEpochSecond(localOffset, adjustment);
-             */
-            return Instant.ofEpochMilli(millis());
-            // END Android-changed: Use OpenJDK 8 implementation until getNanoTimeAdjustment() is supported.
         }
         @Override
         public boolean equals(Object obj) {
diff --git a/ojluni/src/main/java/jdk/internal/misc/VM.java b/ojluni/src/main/java/jdk/internal/misc/VM.java
index b108027..3c799bc 100644
--- a/ojluni/src/main/java/jdk/internal/misc/VM.java
+++ b/ojluni/src/main/java/jdk/internal/misc/VM.java
@@ -26,6 +26,8 @@
 package jdk.internal.misc;
 
 import static java.lang.Thread.State.*;
+
+import dalvik.annotation.optimization.CriticalNative;
 import java.util.Properties;
 import java.util.HashMap;
 import java.util.Map;
@@ -403,6 +405,38 @@
     private final static int JVMTI_THREAD_STATE_WAITING_INDEFINITELY = 0x0010;
     private final static int JVMTI_THREAD_STATE_WAITING_WITH_TIMEOUT = 0x0020;
 
+    // Android-changed: Add @CriticalNative for performance to be consistent with System.currentTimeMillis().
+    /**
+     * Get a nanosecond time stamp adjustment in the form of a single long.
+     *
+     * This value can be used to create an instant using
+     * {@link java.time.Instant#ofEpochSecond(long, long)
+     *  java.time.Instant.ofEpochSecond(offsetInSeconds,
+     *  getNanoTimeAdjustment(offsetInSeconds))}.
+     * <p>
+     * The value returned has the best resolution available to the JVM on
+     * the current system.
+     * This is usually down to microseconds - or tenth of microseconds -
+     * depending on the OS/Hardware and the JVM implementation.
+     *
+     * @param offsetInSeconds The offset in seconds from which the nanosecond
+     *        time stamp should be computed.
+     *
+     * @apiNote The offset should be recent enough - so that
+     *         {@code offsetInSeconds} is within {@code +/- 2^32} seconds of the
+     *         current UTC time. If the offset is too far off, {@code -1} will be
+     *         returned. As such, {@code -1} must not be considered as a valid
+     *         nano time adjustment, but as an exception value indicating
+     *         that an offset closer to the current time should be used.
+     *
+     * @return A nanosecond time stamp adjustment in the form of a single long.
+     *     If the offset is too far off the current time, this method returns -1.
+     *     In that case, the caller should call this method again, passing a
+     *     more accurate offset.
+     */
+    @CriticalNative
+    public static native long getNanoTimeAdjustment(long offsetInSeconds);
+
     // BEGIN Android-removed: latestUserDefinedLoader()/initialize() not supported.
     // /*
     //  * Returns the first non-null class loader up the execution stack,
diff --git a/ojluni/src/main/native/Android.bp b/ojluni/src/main/native/Android.bp
index 162a73c..5edf48a 100644
--- a/ojluni/src/main/native/Android.bp
+++ b/ojluni/src/main/native/Android.bp
@@ -85,5 +85,6 @@
         "socket_tagger_util.cpp",
         "OnLoad.cpp",
         "JniConstants.cpp",
+        "jdk_internal_misc_VM.cpp",
     ],
 }
diff --git a/ojluni/src/main/native/OnLoad.cpp b/ojluni/src/main/native/OnLoad.cpp
index f0b8566..3424402 100644
--- a/ojluni/src/main/native/OnLoad.cpp
+++ b/ojluni/src/main/native/OnLoad.cpp
@@ -61,6 +61,7 @@
 extern "C" void register_java_lang_Runtime(JNIEnv* env);
 extern "C" void register_java_lang_UNIXProcess(JNIEnv* env);
 void register_java_lang_Character(JNIEnv* env);
+void register_jdk_internal_misc_VM(JNIEnv* env);
 
 extern "C" JNIEXPORT jint JNI_OnLoad(JavaVM* vm, void*) {
   jint version = JNI_VERSION_1_6;
@@ -131,6 +132,7 @@
   register_java_lang_Runtime(env);
   register_java_lang_UNIXProcess(env);
   register_java_lang_Character(env);
+  register_jdk_internal_misc_VM(env);
 
   env->PopLocalFrame(/* result */ nullptr);  // Pop the local frame.
   return version;
diff --git a/ojluni/src/main/native/jdk_internal_misc_VM.cpp b/ojluni/src/main/native/jdk_internal_misc_VM.cpp
new file mode 100644
index 0000000..8e41328
--- /dev/null
+++ b/ojluni/src/main/native/jdk_internal_misc_VM.cpp
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * 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.  The Android Open Source
+ * Project designates this particular file as subject to the "Classpath"
+ * exception as provided by The Android Open Source Project in the LICENSE
+ * file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include "jni.h"
+#include "jvm.h"
+
+#include <nativehelper/JNIHelp.h>
+#include <nativehelper/jni_macros.h>
+
+JNIEXPORT jlong JNICALL VM_getNanoTimeAdjustment(jlong offsetInSeconds) {
+    return JVM_GetNanoTimeAdjustment(nullptr, nullptr, offsetInSeconds);
+}
+
+static JNINativeMethod gMethods[] = {
+  CRITICAL_NATIVE_METHOD(VM, getNanoTimeAdjustment, "(J)J"),
+};
+
+void register_jdk_internal_misc_VM(JNIEnv* env) {
+    jniRegisterNativeMethods(env, "jdk/internal/misc/VM", gMethods, NELEM(gMethods));
+}
\ No newline at end of file
diff --git a/ojluni/src/main/native/jvm.h b/ojluni/src/main/native/jvm.h
index fd15abf..5421419 100644
--- a/ojluni/src/main/native/jvm.h
+++ b/ojluni/src/main/native/jvm.h
@@ -105,6 +105,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 --git a/ojluni/src/test/java/time/test/java/time/TestClock_System.java b/ojluni/src/test/java/time/test/java/time/TestClock_System.java
index be24242..55ef1cd 100644
--- a/ojluni/src/test/java/time/test/java/time/TestClock_System.java
+++ b/ojluni/src/test/java/time/test/java/time/TestClock_System.java
@@ -126,8 +126,6 @@
                         + time.getNano();
     }
 
-    // Android-changed: Disable the test until the SystemClock has higher resolution.
-    @Test(enabled = false)
     public void test_ClockResolution() {
         Clock highestUTC = Clock.systemUTC();
 
@@ -396,8 +394,6 @@
                 System.currentTimeMillis()/1000 + 1024);
     }
 
-    // Android-changed: Disable the test until the SystemClock has higher resolution.
-    @Test(enabled = false)
     public void test_OffsetLimits() throws IllegalAccessException {
         System.out.println("*** Testing limits ***");
         SystemClockOffset.testWithOffset("System.currentTimeMillis()/1000 - MAX_OFFSET + 1",