1/*
2 * Copyright (C) 2014 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package dalvik.system;
18
19import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
20
21/**
22 * Delegate used to provide implementation of a select few native methods of {@link VMRuntime}
23 * <p/>
24 * Through the layoutlib_create tool, the original native methods of VMRuntime have been replaced
25 * by calls to methods of the same name in this delegate class.
26 */
27public class VMRuntime_Delegate {
28
29    // Copied from libcore/libdvm/src/main/java/dalvik/system/VMRuntime
30    @LayoutlibDelegate
31    /*package*/ static Object newUnpaddedArray(VMRuntime runtime, Class<?> componentType,
32            int minLength) {
33        // Dalvik has 32bit pointers, the array header is 16bytes plus 4bytes for dlmalloc,
34        // allocations are 8byte aligned so having 4bytes of array data avoids padding.
35        if (!componentType.isPrimitive()) {
36            int size = ((minLength & 1) == 0) ? minLength + 1 : minLength;
37            return java.lang.reflect.Array.newInstance(componentType, size);
38        } else if (componentType == char.class) {
39            int bytes = 20 + (2 * minLength);
40            int alignedUpBytes = (bytes + 7) & -8;
41            int dataBytes = alignedUpBytes - 20;
42            int size = dataBytes / 2;
43            return new char[size];
44        } else if (componentType == int.class) {
45            int size = ((minLength & 1) == 0) ? minLength + 1 : minLength;
46            return new int[size];
47        } else if (componentType == byte.class) {
48            int bytes = 20 + minLength;
49            int alignedUpBytes = (bytes + 7) & -8;
50            int dataBytes = alignedUpBytes - 20;
51            int size = dataBytes;
52            return new byte[size];
53        } else if (componentType == boolean.class) {
54            int bytes = 20 + minLength;
55            int alignedUpBytes = (bytes + 7) & -8;
56            int dataBytes = alignedUpBytes - 20;
57            int size = dataBytes;
58            return new boolean[size];
59        } else if (componentType == short.class) {
60            int bytes = 20 + (2 * minLength);
61            int alignedUpBytes = (bytes + 7) & -8;
62            int dataBytes = alignedUpBytes - 20;
63            int size = dataBytes / 2;
64            return new short[size];
65        } else if (componentType == float.class) {
66            int size = ((minLength & 1) == 0) ? minLength + 1 : minLength;
67            return new float[size];
68        } else if (componentType == long.class) {
69            return new long[minLength];
70        } else if (componentType == double.class) {
71            return new double[minLength];
72        } else {
73            assert componentType == void.class;
74            throw new IllegalArgumentException("Can't allocate an array of void");
75        }
76    }
77
78}
79