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
This commit is contained in:
Daniel Colascione
2019-10-07 14:18:09 -07:00
parent ff3cf4315a
commit 012ab8e9fa
3 changed files with 15 additions and 0 deletions

View File

@@ -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();

View File

@@ -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},

View File

@@ -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<IBinder>& 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)) {