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 
17 package dalvik.system;
18 
19 import 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  */
27 public class VMRuntime_Delegate {
28 
29     // Copied from libcore/libdvm/src/main/java/dalvik/system/VMRuntime
30     @LayoutlibDelegate
newUnpaddedArray(VMRuntime runtime, Class<?> componentType, int minLength)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     @LayoutlibDelegate
getNotifyNativeInterval()79     /*package*/ static int getNotifyNativeInterval() {
80         // This cannot return 0, otherwise it is responsible for triggering an exception
81         // whenever trying to use a NativeAllocationRegistry with size 0
82         return 1;
83     }
84 }
85