summaryrefslogtreecommitdiffstats
path: root/libdvm/src/main/java/dalvik/system
diff options
context:
space:
mode:
authorIan Rogers <irogers@google.com>2014-02-27 17:01:55 -0800
committerIan Rogers <irogers@google.com>2014-02-28 17:39:53 -0800
commit10af76d5af1d87686ff9ab8d00f3dadc15a84fb7 (patch)
tree9379ee44171cd5bc848ea5d0854b3cda5e5787da /libdvm/src/main/java/dalvik/system
parent25f9a3d57eeddd56d86f84c2bd27027b8e91d591 (diff)
downloadlibcore-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.java51
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.
*/