From 71207b5a11c1aaede2ccc2380a9c55b6ff0162d3 Mon Sep 17 00:00:00 2001 From: John Reck Date: Wed, 28 Sep 2016 13:28:09 -0700 Subject: Switch Parcel to FastNative Also fixes ParcelBenchmark to have bounded memory usage to avoid OOM'ing during runs Test: refactor, no behavior change ParcelBenchmark results from bullhead Before: timeReadByte 74.43ns timeReadInt 74.49ns timeReadLong 74.13ns timeWriteByte 81.81ns timeWriteInt 82.09ns timeWriteLong 81.84ns After: timeReadByte 47.08ns timeReadInt 48.38ns timeReadLong 48.16ns timeWriteByte 55.90ns timeWriteInt 55.85ns timeWriteLong 56.58ns Change-Id: I61b823d1d2beb86e00c196abd4dce65efa8fa7f0 --- core/java/android/os/Parcel.java | 19 ++++++++ core/jni/android_os_Parcel.cpp | 56 ++++++++++++++-------- .../benchmarks/src/android/os/ParcelBenchmark.java | 48 +++++++++++++------ 3 files changed, 89 insertions(+), 34 deletions(-) diff --git a/core/java/android/os/Parcel.java b/core/java/android/os/Parcel.java index f6e6ad6067bb..85f999b26176 100644 --- a/core/java/android/os/Parcel.java +++ b/core/java/android/os/Parcel.java @@ -46,6 +46,7 @@ import java.util.List; import java.util.Map; import java.util.Set; +import dalvik.annotation.optimization.FastNative; import dalvik.system.VMRuntime; /** @@ -254,22 +255,35 @@ public final class Parcel { // see libbinder's binder/Status.h private static final int EX_TRANSACTION_FAILED = -129; + @FastNative private static native int nativeDataSize(long nativePtr); + @FastNative private static native int nativeDataAvail(long nativePtr); + @FastNative private static native int nativeDataPosition(long nativePtr); + @FastNative private static native int nativeDataCapacity(long nativePtr); + @FastNative private static native long nativeSetDataSize(long nativePtr, int size); + @FastNative private static native void nativeSetDataPosition(long nativePtr, int pos); + @FastNative private static native void nativeSetDataCapacity(long nativePtr, int size); + @FastNative private static native boolean nativePushAllowFds(long nativePtr, boolean allowFds); + @FastNative private static native void nativeRestoreAllowFds(long nativePtr, boolean lastValue); private static native void nativeWriteByteArray(long nativePtr, byte[] b, int offset, int len); private static native void nativeWriteBlob(long nativePtr, byte[] b, int offset, int len); + @FastNative private static native void nativeWriteInt(long nativePtr, int val); + @FastNative private static native void nativeWriteLong(long nativePtr, long val); + @FastNative private static native void nativeWriteFloat(long nativePtr, float val); + @FastNative private static native void nativeWriteDouble(long nativePtr, double val); private static native void nativeWriteString(long nativePtr, String val); private static native void nativeWriteStrongBinder(long nativePtr, IBinder val); @@ -277,9 +291,13 @@ public final class Parcel { private static native byte[] nativeCreateByteArray(long nativePtr); private static native byte[] nativeReadBlob(long nativePtr); + @FastNative private static native int nativeReadInt(long nativePtr); + @FastNative private static native long nativeReadLong(long nativePtr); + @FastNative private static native float nativeReadFloat(long nativePtr); + @FastNative private static native double nativeReadDouble(long nativePtr); private static native String nativeReadString(long nativePtr); private static native IBinder nativeReadStrongBinder(long nativePtr); @@ -294,6 +312,7 @@ public final class Parcel { long nativePtr, byte[] data, int offset, int length); private static native long nativeAppendFrom( long thisNativePtr, long otherNativePtr, int offset, int length); + @FastNative private static native boolean nativeHasFileDescriptors(long nativePtr); private static native void nativeWriteInterfaceToken(long nativePtr, String interfaceName); private static native void nativeEnforceInterface(long nativePtr, String interfaceName); diff --git a/core/jni/android_os_Parcel.cpp b/core/jni/android_os_Parcel.cpp index 0a8ae2bdeecd..8f7908a0e048 100644 --- a/core/jni/android_os_Parcel.cpp +++ b/core/jni/android_os_Parcel.cpp @@ -722,33 +722,50 @@ static jlong android_os_Parcel_getBlobAshmemSize(JNIEnv* env, jclass clazz, jlon // ---------------------------------------------------------------------------- static const JNINativeMethod gParcelMethods[] = { - {"nativeDataSize", "!(J)I", (void*)android_os_Parcel_dataSize}, - {"nativeDataAvail", "!(J)I", (void*)android_os_Parcel_dataAvail}, - {"nativeDataPosition", "!(J)I", (void*)android_os_Parcel_dataPosition}, - {"nativeDataCapacity", "!(J)I", (void*)android_os_Parcel_dataCapacity}, - {"nativeSetDataSize", "!(JI)J", (void*)android_os_Parcel_setDataSize}, - {"nativeSetDataPosition", "!(JI)V", (void*)android_os_Parcel_setDataPosition}, - {"nativeSetDataCapacity", "!(JI)V", (void*)android_os_Parcel_setDataCapacity}, - - {"nativePushAllowFds", "!(JZ)Z", (void*)android_os_Parcel_pushAllowFds}, - {"nativeRestoreAllowFds", "!(JZ)V", (void*)android_os_Parcel_restoreAllowFds}, + // @FastNative + {"nativeDataSize", "(J)I", (void*)android_os_Parcel_dataSize}, + // @FastNative + {"nativeDataAvail", "(J)I", (void*)android_os_Parcel_dataAvail}, + // @FastNative + {"nativeDataPosition", "(J)I", (void*)android_os_Parcel_dataPosition}, + // @FastNative + {"nativeDataCapacity", "(J)I", (void*)android_os_Parcel_dataCapacity}, + // @FastNative + {"nativeSetDataSize", "(JI)J", (void*)android_os_Parcel_setDataSize}, + // @FastNative + {"nativeSetDataPosition", "(JI)V", (void*)android_os_Parcel_setDataPosition}, + // @FastNative + {"nativeSetDataCapacity", "(JI)V", (void*)android_os_Parcel_setDataCapacity}, + + // @FastNative + {"nativePushAllowFds", "(JZ)Z", (void*)android_os_Parcel_pushAllowFds}, + // @FastNative + {"nativeRestoreAllowFds", "(JZ)V", (void*)android_os_Parcel_restoreAllowFds}, {"nativeWriteByteArray", "(J[BII)V", (void*)android_os_Parcel_writeNative}, {"nativeWriteBlob", "(J[BII)V", (void*)android_os_Parcel_writeBlob}, - {"nativeWriteInt", "!(JI)V", (void*)android_os_Parcel_writeInt}, - {"nativeWriteLong", "!(JJ)V", (void*)android_os_Parcel_writeLong}, - {"nativeWriteFloat", "!(JF)V", (void*)android_os_Parcel_writeFloat}, - {"nativeWriteDouble", "!(JD)V", (void*)android_os_Parcel_writeDouble}, + // @FastNative + {"nativeWriteInt", "(JI)V", (void*)android_os_Parcel_writeInt}, + // @FastNative + {"nativeWriteLong", "(JJ)V", (void*)android_os_Parcel_writeLong}, + // @FastNative + {"nativeWriteFloat", "(JF)V", (void*)android_os_Parcel_writeFloat}, + // @FastNative + {"nativeWriteDouble", "(JD)V", (void*)android_os_Parcel_writeDouble}, {"nativeWriteString", "(JLjava/lang/String;)V", (void*)android_os_Parcel_writeString}, {"nativeWriteStrongBinder", "(JLandroid/os/IBinder;)V", (void*)android_os_Parcel_writeStrongBinder}, {"nativeWriteFileDescriptor", "(JLjava/io/FileDescriptor;)J", (void*)android_os_Parcel_writeFileDescriptor}, {"nativeCreateByteArray", "(J)[B", (void*)android_os_Parcel_createByteArray}, {"nativeReadBlob", "(J)[B", (void*)android_os_Parcel_readBlob}, - {"nativeReadInt", "!(J)I", (void*)android_os_Parcel_readInt}, - {"nativeReadLong", "!(J)J", (void*)android_os_Parcel_readLong}, - {"nativeReadFloat", "!(J)F", (void*)android_os_Parcel_readFloat}, - {"nativeReadDouble", "!(J)D", (void*)android_os_Parcel_readDouble}, + // @FastNative + {"nativeReadInt", "(J)I", (void*)android_os_Parcel_readInt}, + // @FastNative + {"nativeReadLong", "(J)J", (void*)android_os_Parcel_readLong}, + // @FastNative + {"nativeReadFloat", "(J)F", (void*)android_os_Parcel_readFloat}, + // @FastNative + {"nativeReadDouble", "(J)D", (void*)android_os_Parcel_readDouble}, {"nativeReadString", "(J)Ljava/lang/String;", (void*)android_os_Parcel_readString}, {"nativeReadStrongBinder", "(J)Landroid/os/IBinder;", (void*)android_os_Parcel_readStrongBinder}, {"nativeReadFileDescriptor", "(J)Ljava/io/FileDescriptor;", (void*)android_os_Parcel_readFileDescriptor}, @@ -765,7 +782,8 @@ static const JNINativeMethod gParcelMethods[] = { {"nativeMarshall", "(J)[B", (void*)android_os_Parcel_marshall}, {"nativeUnmarshall", "(J[BII)J", (void*)android_os_Parcel_unmarshall}, {"nativeAppendFrom", "(JJII)J", (void*)android_os_Parcel_appendFrom}, - {"nativeHasFileDescriptors", "!(J)Z", (void*)android_os_Parcel_hasFileDescriptors}, + // @FastNative + {"nativeHasFileDescriptors", "(J)Z", (void*)android_os_Parcel_hasFileDescriptors}, {"nativeWriteInterfaceToken", "(JLjava/lang/String;)V", (void*)android_os_Parcel_writeInterfaceToken}, {"nativeEnforceInterface", "(JLjava/lang/String;)V", (void*)android_os_Parcel_enforceInterface}, diff --git a/core/tests/benchmarks/src/android/os/ParcelBenchmark.java b/core/tests/benchmarks/src/android/os/ParcelBenchmark.java index 4bd2d009dcf3..6c45ae858aca 100644 --- a/core/tests/benchmarks/src/android/os/ParcelBenchmark.java +++ b/core/tests/benchmarks/src/android/os/ParcelBenchmark.java @@ -20,12 +20,15 @@ import com.google.caliper.AfterExperiment; import com.google.caliper.BeforeExperiment; public class ParcelBenchmark { + private static final int INNER_REPS = 1000; private Parcel mParcel; @BeforeExperiment protected void setUp() { mParcel = Parcel.obtain(); + mParcel.setDataPosition(0); + mParcel.setDataCapacity(INNER_REPS * 8); } @AfterExperiment @@ -36,43 +39,58 @@ public class ParcelBenchmark { public void timeWriteByte(int reps) { final byte val = 0xF; - for (int i = 0; i < reps; i++) { - mParcel.writeByte(val); + for (int i = 0; i < (reps / INNER_REPS); i++) { + mParcel.setDataPosition(0); + for (int j = 0; j < INNER_REPS; j++) { + mParcel.writeByte(val); + } } } public void timeReadByte(int reps) { - mParcel.setDataCapacity(reps); - for (int i = 0; i < reps; i++) { - mParcel.readByte(); + for (int i = 0; i < (reps / INNER_REPS); i++) { + mParcel.setDataPosition(0); + for (int j = 0; j < INNER_REPS; j++) { + mParcel.readByte(); + } } } public void timeWriteInt(int reps) { final int val = 0xF; - for (int i = 0; i < reps; i++) { - mParcel.writeInt(val); + for (int i = 0; i < (reps / INNER_REPS); i++) { + mParcel.setDataPosition(0); + for (int j = 0; j < INNER_REPS; j++) { + mParcel.writeInt(val); + } } } public void timeReadInt(int reps) { - mParcel.setDataCapacity(reps << 2); - for (int i = 0; i < reps; i++) { - mParcel.readInt(); + for (int i = 0; i < (reps / INNER_REPS); i++) { + mParcel.setDataPosition(0); + for (int j = 0; j < INNER_REPS; j++) { + mParcel.readInt(); + } } } public void timeWriteLong(int reps) { final long val = 0xF; - for (int i = 0; i < reps; i++) { - mParcel.writeLong(val); + for (int i = 0; i < (reps / INNER_REPS); i++) { + mParcel.setDataPosition(0); + for (int j = 0; j < INNER_REPS; j++) { + mParcel.writeLong(val); + } } } public void timeReadLong(int reps) { - mParcel.setDataCapacity(reps << 3); - for (int i = 0; i < reps; i++) { - mParcel.readLong(); + for (int i = 0; i < (reps / INNER_REPS); i++) { + mParcel.setDataPosition(0); + for (int j = 0; j < INNER_REPS; j++) { + mParcel.readLong(); + } } } } -- cgit v1.2.3-59-g8ed1b