From 012ab8e9faf8b2a641c8c5082987d07163fec0e9 Mon Sep 17 00:00:00 2001 From: Daniel Colascione Date: Mon, 7 Oct 2019 14:18:09 -0700 Subject: Mark common android.os.Parcel methods as FastNative Mark the marshaling functions for non-primitive parameters as being @FastNative: they're all expected to complete quickly. According to the table in CriticalNative.java, the difference between a regular JNI call and a FastNative call is about 80ns, so this change should shave about 160ns per non-primitive parameter off the latency of a binder transaction. The actual savings will be greater as we also use these Parcel methods to marshal and unmarshal complex objects like PackageInfo sent as objects over Binder. Bug: 142271139 Test: boots Change-Id: I85c3ee8498640193b9c0777c8c5e7eb349c7b23c --- core/java/android/os/Parcel.java | 6 ++++++ core/jni/android_os_Parcel.cpp | 6 ++++++ core/jni/android_util_Binder.cpp | 3 +++ 3 files changed, 15 insertions(+) diff --git a/core/java/android/os/Parcel.java b/core/java/android/os/Parcel.java index 50487e9e7a99..783ab44bc4e2 100644 --- a/core/java/android/os/Parcel.java +++ b/core/java/android/os/Parcel.java @@ -305,8 +305,11 @@ public final class Parcel { private static native void nativeWriteFloat(long nativePtr, float val); @FastNative private static native void nativeWriteDouble(long nativePtr, double val); + @FastNative static native void nativeWriteString(long nativePtr, String val); + @FastNative private static native void nativeWriteStrongBinder(long nativePtr, IBinder val); + @FastNative private static native long nativeWriteFileDescriptor(long nativePtr, FileDescriptor val); private static native byte[] nativeCreateByteArray(long nativePtr); @@ -320,8 +323,11 @@ public final class Parcel { private static native float nativeReadFloat(long nativePtr); @CriticalNative private static native double nativeReadDouble(long nativePtr); + @FastNative static native String nativeReadString(long nativePtr); + @FastNative private static native IBinder nativeReadStrongBinder(long nativePtr); + @FastNative private static native FileDescriptor nativeReadFileDescriptor(long nativePtr); private static native long nativeCreate(); diff --git a/core/jni/android_os_Parcel.cpp b/core/jni/android_os_Parcel.cpp index d80c071c3e26..483b455965f7 100644 --- a/core/jni/android_os_Parcel.cpp +++ b/core/jni/android_os_Parcel.cpp @@ -721,8 +721,11 @@ static const JNINativeMethod gParcelMethods[] = { {"nativeWriteFloat", "(JF)V", (void*)android_os_Parcel_writeFloat}, // @FastNative {"nativeWriteDouble", "(JD)V", (void*)android_os_Parcel_writeDouble}, + // @FastNative {"nativeWriteString", "(JLjava/lang/String;)V", (void*)android_os_Parcel_writeString}, + // @FastNative {"nativeWriteStrongBinder", "(JLandroid/os/IBinder;)V", (void*)android_os_Parcel_writeStrongBinder}, + // @FastNative {"nativeWriteFileDescriptor", "(JLjava/io/FileDescriptor;)J", (void*)android_os_Parcel_writeFileDescriptor}, {"nativeCreateByteArray", "(J)[B", (void*)android_os_Parcel_createByteArray}, @@ -736,8 +739,11 @@ static const JNINativeMethod gParcelMethods[] = { {"nativeReadFloat", "(J)F", (void*)android_os_Parcel_readFloat}, // @CriticalNative {"nativeReadDouble", "(J)D", (void*)android_os_Parcel_readDouble}, + // @FastNative {"nativeReadString", "(J)Ljava/lang/String;", (void*)android_os_Parcel_readString}, + // @FastNative {"nativeReadStrongBinder", "(J)Landroid/os/IBinder;", (void*)android_os_Parcel_readStrongBinder}, + // @FastNative {"nativeReadFileDescriptor", "(J)Ljava/io/FileDescriptor;", (void*)android_os_Parcel_readFileDescriptor}, {"nativeCreate", "()J", (void*)android_os_Parcel_create}, diff --git a/core/jni/android_util_Binder.cpp b/core/jni/android_util_Binder.cpp index 0afbaa0e174c..e406e2257c67 100644 --- a/core/jni/android_util_Binder.cpp +++ b/core/jni/android_util_Binder.cpp @@ -697,6 +697,9 @@ BinderProxyNativeData* getBPNativeData(JNIEnv* env, jobject obj) { // same IBinder, and the original BinderProxy is still alive, return the same BinderProxy. jobject javaObjectForIBinder(JNIEnv* env, const sp& val) { + // N.B. This function is called from a @FastNative JNI method, so don't take locks around + // calls to Java code or block the calling thread for a long time for any reason. + if (val == NULL) return NULL; if (val->checkSubclass(&gBinderOffsets)) { -- cgit v1.2.3-59-g8ed1b