diff options
author | Ian Rogers <irogers@google.com> | 2014-02-27 17:01:55 -0800 |
---|---|---|
committer | Ian Rogers <irogers@google.com> | 2014-02-28 17:39:53 -0800 |
commit | 10af76d5af1d87686ff9ab8d00f3dadc15a84fb7 (patch) | |
tree | 9379ee44171cd5bc848ea5d0854b3cda5e5787da /libdvm/src/main/java/dalvik/system | |
parent | 25f9a3d57eeddd56d86f84c2bd27027b8e91d591 (diff) | |
download | libcore-10af76d5af1d87686ff9ab8d00f3dadc15a84fb7.zip libcore-10af76d5af1d87686ff9ab8d00f3dadc15a84fb7.tar.gz libcore-10af76d5af1d87686ff9ab8d00f3dadc15a84fb7.tar.bz2 |
Add unpadded array allocations.
Unpadded array allocations avoid unused bytes following arrays. API conventions
follow those of newNonMovableArray.
Dalvik implementation assume dlmalloc allocation properties, ART implementation
is handled by resizing the array post-allocation:
https://android-review.googlesource.com/83670
Add VMRuntimeTest to check the properties of the array allocation routines.
Change java.lang.reflect.Array.newInstance to compare more probable array types
before less probable ones.
Bug: 13028925.
Change-Id: Icf6bfb1aa5ad4faa062b393082c689b6118a84b5
Diffstat (limited to 'libdvm/src/main/java/dalvik/system')
-rw-r--r-- | libdvm/src/main/java/dalvik/system/VMRuntime.java | 51 |
1 files changed, 51 insertions, 0 deletions
diff --git a/libdvm/src/main/java/dalvik/system/VMRuntime.java b/libdvm/src/main/java/dalvik/system/VMRuntime.java index f4acf47..47823f0 100644 --- a/libdvm/src/main/java/dalvik/system/VMRuntime.java +++ b/libdvm/src/main/java/dalvik/system/VMRuntime.java @@ -223,6 +223,57 @@ public final class VMRuntime { public native Object newNonMovableArray(Class<?> componentType, int length); /** + * Returns an array of at least minLength, but potentially larger. The increased size comes from + * avoiding any padding after the array. The amount of padding varies depending on the + * componentType and the memory allocator implementation. + */ + public Object newUnpaddedArray(Class<?> componentType, int minLength) { + // Dalvik has 32bit pointers, the array header is 16bytes plus 4bytes for dlmalloc, + // allocations are 8byte aligned so having 4bytes of array data avoids padding. + if (!componentType.isPrimitive()) { + int size = ((minLength & 1) == 0) ? minLength + 1 : minLength; + return java.lang.reflect.Array.newInstance(componentType, size); + } else if (componentType == char.class) { + int bytes = 20 + (2 * minLength); + int alignedUpBytes = (bytes + 7) & -8; + int dataBytes = alignedUpBytes - 20; + int size = dataBytes / 2; + return new char[size]; + } else if (componentType == int.class) { + int size = ((minLength & 1) == 0) ? minLength + 1 : minLength; + return new int[size]; + } else if (componentType == byte.class) { + int bytes = 20 + minLength; + int alignedUpBytes = (bytes + 7) & -8; + int dataBytes = alignedUpBytes - 20; + int size = dataBytes; + return new byte[size]; + } else if (componentType == boolean.class) { + int bytes = 20 + minLength; + int alignedUpBytes = (bytes + 7) & -8; + int dataBytes = alignedUpBytes - 20; + int size = dataBytes; + return new boolean[size]; + } else if (componentType == short.class) { + int bytes = 20 + (2 * minLength); + int alignedUpBytes = (bytes + 7) & -8; + int dataBytes = alignedUpBytes - 20; + int size = dataBytes / 2; + return new short[size]; + } else if (componentType == float.class) { + int size = ((minLength & 1) == 0) ? minLength + 1 : minLength; + return new float[size]; + } else if (componentType == long.class) { + return new long[minLength]; + } else if (componentType == double.class) { + return new double[minLength]; + } else { + assert componentType == void.class; + throw new IllegalArgumentException("Can't allocate an array of void"); + } + } + + /** * Returns the address of array[0]. This differs from using JNI in that JNI might lie and * give you the address of a copy of the array when in forcecopy mode. */ |