OSDN Git Service

Don't init class during reflection signature scan.
[android-x86/dalvik.git] / vm / arch / arm / HintsEABI.c
1 /*
2  * Copyright (C) 2008 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  * Target-specific optimization and run-time hints
18  */
19
20
21 #include "Dalvik.h"
22 #include "libdex/DexClass.h"
23
24 #include <stdlib.h>
25 #include <stddef.h>
26 #include <sys/stat.h>
27
28
29 /*
30  * The class loader will associate with each method a 32-bit info word
31  * (jniArgInfo) to support JNI calls.  The high order 4 bits of this word
32  * are the same for all targets, while the lower 28 are used for hints to
33  * allow accelerated JNI bridge transfers.
34  *
35  * jniArgInfo (32-bit int) layout:
36  *
37  *    SRRRHHHH HHHHHHHH HHHHHHHH HHHHHHHH
38  *
39  *    S - if set, ignore the hints and do things the hard way (scan signature)
40  *    R - return-type enumeration
41  *    H - target-specific hints (see below for details)
42  *
43  * This function produces arm-specific hints - specifically a description
44  * of padding required to keep all 64-bit parameters properly aligned.
45  *
46  * ARM JNI hint format
47  *
48  *       LLLL FFFFFFFF FFFFFFFF FFFFFFFF
49  *
50  *   L - number of double-words of storage required on the stack (0-30 words)
51  *   F - pad flag -- if set, write a pad word to the stack before copying
52  *       the next 32 bits
53  *
54  * If there are too many arguments to construct valid hints, this function will
55  * return a result with the S bit set.
56  */
57 u4 dvmPlatformInvokeHints(const DexProto* proto)
58 {
59     const char* sig = dexProtoGetShorty(proto);
60     int padFlags, jniHints;
61     char sigByte;
62     int stackOffset, padMask, hints;
63
64     stackOffset = padFlags = 0;
65     padMask = 0x00000001;
66
67     /* Skip past the return type */
68     sig++;
69
70     while (true) {
71         sigByte = *(sig++);
72
73         if (sigByte == '\0')
74             break;
75
76         if (sigByte == 'D' || sigByte == 'J') {
77             if ((stackOffset & 1) != 0) {
78                 padFlags |= padMask;
79                 stackOffset++;
80                 padMask <<= 1;
81             }
82             stackOffset += 2;
83             padMask <<= 2;
84         } else {
85             stackOffset++;
86             padMask <<= 1;
87         }
88     }
89
90     jniHints = 0;
91
92     if (stackOffset > DALVIK_JNI_COUNT_SHIFT) {
93         /* too big for "fast" version */
94         jniHints = DALVIK_JNI_NO_ARG_INFO;
95     } else {
96         assert((padFlags & (0xffffffff << DALVIK_JNI_COUNT_SHIFT)) == 0);
97         stackOffset -= 2;           // r2/r3 holds first two items
98         if (stackOffset < 0)
99             stackOffset = 0;
100         jniHints |= ((stackOffset+1) / 2) << DALVIK_JNI_COUNT_SHIFT;
101         jniHints |= padFlags;
102     }
103
104     return jniHints;
105 }