2 * Copyright (C) 2009 The Android Open Source Project
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
18 * Declaration of register map data structure and related functions.
20 * These structures should be treated as opaque through most of the VM.
22 #ifndef _DALVIK_REGISTERMAP
23 #define _DALVIK_REGISTERMAP
25 #include "analysis/VerifySubs.h"
26 #include "analysis/CodeVerify.h"
29 * Format enumeration for RegisterMap data area.
31 typedef enum RegisterMapFormat {
32 kRegMapFormatUnknown = 0,
33 kRegMapFormatNone, /* indicates no map data follows */
34 kRegMapFormatCompact8, /* compact layout, 8-bit addresses */
35 kRegMapFormatCompact16, /* compact layout, 16-bit addresses */
36 kRegMapFormatDifferential, /* compressed, differential encoding */
38 kRegMapFormatOnHeap = 0x80, /* bit flag, indicates allocation on heap */
42 * This is a single variable-size structure. It may be allocated on the
43 * heap or mapped out of a (post-dexopt) DEX file.
45 * 32-bit alignment of the structure is NOT guaranteed. This makes it a
46 * little awkward to deal with as a structure; to avoid accidents we use
47 * only byte types. Multi-byte values are little-endian.
49 * Size of (format==FormatNone): 1 byte
50 * Size of (format==FormatCompact8): 4 + (1 + regWidth) * numEntries
51 * Size of (format==FormatCompact16): 4 + (2 + regWidth) * numEntries
55 u1 format; /* enum RegisterMapFormat; MUST be first entry */
56 u1 regWidth; /* bytes per register line, 1+ */
57 u1 numEntries[2]; /* number of entries */
59 /* raw data starts here; need not be aligned */
63 bool dvmRegisterMapStartup(void);
64 void dvmRegisterMapShutdown(void);
69 INLINE RegisterMapFormat dvmRegisterMapGetFormat(const RegisterMap* pMap) {
70 return pMap->format & ~(kRegMapFormatOnHeap);
76 INLINE void dvmRegisterMapSetFormat(RegisterMap* pMap, RegisterMapFormat format)
78 pMap->format &= kRegMapFormatOnHeap;
79 pMap->format |= format;
83 * Get the "on heap" flag.
85 INLINE bool dvmRegisterMapGetOnHeap(const RegisterMap* pMap) {
86 return (pMap->format & kRegMapFormatOnHeap) != 0;
90 * Get the register bit vector width, in bytes.
92 INLINE u1 dvmRegisterMapGetRegWidth(const RegisterMap* pMap) {
93 return pMap->regWidth;
97 * Set the register bit vector width, in bytes.
99 INLINE void dvmRegisterMapSetRegWidth(RegisterMap* pMap, int regWidth) {
100 pMap->regWidth = regWidth;
104 * Set the "on heap" flag.
106 INLINE void dvmRegisterMapSetOnHeap(RegisterMap* pMap, bool val) {
108 pMap->format |= kRegMapFormatOnHeap;
110 pMap->format &= ~(kRegMapFormatOnHeap);
114 * Get the number of entries in this map.
116 INLINE u2 dvmRegisterMapGetNumEntries(const RegisterMap* pMap) {
117 return pMap->numEntries[0] | (pMap->numEntries[1] << 8);
121 * Set the number of entries in this map.
123 INLINE void dvmRegisterMapSetNumEntries(RegisterMap* pMap, u2 numEntries) {
124 pMap->numEntries[0] = (u1) numEntries;
125 pMap->numEntries[1] = numEntries >> 8;
129 * Retrieve the bit vector for the specified address. This is a pointer
130 * to the bit data from an uncompressed map, or to a temporary copy of
131 * data from a compressed map.
133 * The caller must call dvmReleaseRegisterMapLine() with the result.
135 * Returns NULL if not found.
137 const u1* dvmRegisterMapGetLine(const RegisterMap* pMap, int addr);
142 * If "pMap" points to a compressed map from which we have expanded a
143 * single line onto the heap, this will free "data"; otherwise, it does
146 * TODO: decide if this is still a useful concept.
148 INLINE void dvmReleaseRegisterMapLine(const RegisterMap* pMap, const u1* data)
153 * A pool of register maps for methods associated with a single class.
155 * Each entry is a 4-byte method index followed by the 32-bit-aligned
156 * RegisterMap. The size of the RegisterMap is determined by parsing
157 * the map. The lack of an index reduces random access speed, but we
158 * should be doing that rarely (during class load) and it saves space.
160 * These structures are 32-bit aligned.
162 typedef struct RegisterMapMethodPool {
163 u2 methodCount; /* chiefly used as a sanity check */
165 /* stream of per-method data starts here */
167 } RegisterMapMethodPool;
170 * Header for the memory-mapped RegisterMap pool in the DEX file.
172 * The classDataOffset table provides offsets from the start of the
173 * RegisterMapPool structure. There is one entry per class (including
174 * interfaces, which can have static initializers).
176 * The offset points to a RegisterMapMethodPool.
178 * These structures are 32-bit aligned.
180 typedef struct RegisterMapClassPool {
183 /* offset table starts here, 32-bit aligned; offset==0 means no data */
184 u4 classDataOffset[1];
185 } RegisterMapClassPool;
188 * Find the register maps for this class. (Used during class loading.)
189 * If "pNumMaps" is non-NULL, it will return the number of maps in the set.
191 * Returns NULL if none is available.
193 const void* dvmRegisterMapGetClassData(const DexFile* pDexFile, u4 classIdx,
197 * Get the register map for the next method. "*pPtr" will be advanced past
198 * the end of the map. (Used during class loading.)
200 * This should initially be called with the result from
201 * dvmRegisterMapGetClassData().
203 const RegisterMap* dvmRegisterMapGetNext(const void** pPtr);
206 * This holds some meta-data while we construct the set of register maps
209 * In particular, it keeps track of our temporary mmap region so we can
212 typedef struct RegisterMapBuilder {
219 } RegisterMapBuilder;
222 * Generate a register map set for all verified classes in "pDvmDex".
224 RegisterMapBuilder* dvmGenerateRegisterMaps(DvmDex* pDvmDex);
229 void dvmFreeRegisterMapBuilder(RegisterMapBuilder* pBuilder);
233 * Generate the register map for a previously-verified method.
235 * Returns a pointer to a newly-allocated RegisterMap.
237 //RegisterMap* dvmGenerateRegisterMap(const Method* meth);
240 * Various bits of data generated by the verifier, wrapped up in a package
241 * for ease of use by the register map generator.
243 typedef struct VerifierData {
245 * The method we're working on.
247 const Method* method;
250 * Number of instructions in the method.
255 * Number of registers we track for each instruction. This is equal
256 * to the method's declared "registersSize". (Does not include the
257 * pending return value.)
262 * Instruction widths and flags, one entry per code unit.
264 InsnFlags* insnFlags;
267 * Array of SRegType arrays, one entry per code unit. We only need
268 * entries for code units that hold the start of an "interesting"
269 * instruction. For register map generation, we're only interested
276 * Generate the register map for a method that has just been verified
277 * (i.e. we're doing this as part of verification).
279 * Returns a pointer to a newly-allocated RegisterMap, or NULL on failure.
281 RegisterMap* dvmGenerateRegisterMapV(VerifierData* vdata);
284 * Get the expanded form of the register map associated with the specified
285 * method. May update method->registerMap, possibly freeing the previous
288 * Returns NULL on failure (e.g. unable to expand map).
290 * NOTE: this function is not synchronized; external locking is mandatory.
291 * (This is expected to be called at GC time.)
293 const RegisterMap* dvmGetExpandedRegisterMap0(Method* method);
294 INLINE const RegisterMap* dvmGetExpandedRegisterMap(Method* method)
296 const RegisterMap* curMap = method->registerMap;
299 RegisterMapFormat format = dvmRegisterMapGetFormat(curMap);
300 if (format == kRegMapFormatCompact8 || format == kRegMapFormatCompact16) {
303 return dvmGetExpandedRegisterMap0(method);
307 /* dump stats gathered during register map creation process */
308 void dvmRegisterMapDumpStats(void);
310 #endif /*_DALVIK_REGISTERMAP*/