2 * Copyright (C) 2008 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.
17 * The VM wraps some additional data structures around the DexFile. These
20 #ifndef _DALVIK_DVMDEX
21 #define _DALVIK_DVMDEX
23 #include "libdex/DexFile.h"
34 * Some additional VM data structures that are associated with the DEX file.
36 typedef struct DvmDex {
37 /* pointer to the DexFile we're associated with */
40 /* clone of pDexFile->pHeader (it's used frequently enough) */
41 const DexHeader* pHeader;
43 /* interned strings; parallel to "stringIds" */
44 struct StringObject** pResStrings;
46 /* resolved classes; parallel to "typeIds" */
47 struct ClassObject** pResClasses;
49 /* resolved methods; parallel to "methodIds" */
50 struct Method** pResMethods;
52 /* resolved instance fields; parallel to "fieldIds" */
53 /* (this holds both InstField and StaticField) */
54 struct Field** pResFields;
56 /* interface method lookup cache */
57 struct AtomicCache* pInterfaceCache;
59 /* shared memory region with file contents */
65 * Given a file descriptor for an open "optimized" DEX file, map it into
66 * memory and parse the contents.
68 * On success, returns 0 and sets "*ppDvmDex" to a newly-allocated DvmDex.
69 * On failure, returns a meaningful error code [currently just -1].
71 int dvmDexFileOpenFromFd(int fd, DvmDex** ppDvmDex);
74 * Open a partial DEX file. Only useful as part of the optimization process.
76 int dvmDexFileOpenPartial(const void* addr, int len, DvmDex** ppDvmDex);
79 * Free a DvmDex structure, along with any associated structures.
81 void dvmDexFileFree(DvmDex* pDvmDex);
84 #if DVM_RESOLVER_CACHE == DVM_RC_DISABLED
88 * Return the requested item if it has been resolved, or NULL if it hasn't.
90 INLINE struct StringObject* dvmDexGetResolvedString(const DvmDex* pDvmDex,
93 assert(stringIdx < pDvmDex->pHeader->stringIdsSize);
94 return pDvmDex->pResStrings[stringIdx];
96 INLINE struct ClassObject* dvmDexGetResolvedClass(const DvmDex* pDvmDex,
99 assert(classIdx < pDvmDex->pHeader->typeIdsSize);
100 return pDvmDex->pResClasses[classIdx];
102 INLINE struct Method* dvmDexGetResolvedMethod(const DvmDex* pDvmDex,
105 assert(methodIdx < pDvmDex->pHeader->methodIdsSize);
106 return pDvmDex->pResMethods[methodIdx];
108 INLINE struct Field* dvmDexGetResolvedField(const DvmDex* pDvmDex,
111 assert(fieldIdx < pDvmDex->pHeader->fieldIdsSize);
112 return pDvmDex->pResFields[fieldIdx];
116 * Update the resolved item table. Resolution always produces the same
117 * result, so we're not worried about atomicity here.
119 INLINE void dvmDexSetResolvedString(DvmDex* pDvmDex, u4 stringIdx,
120 struct StringObject* str)
122 assert(stringIdx < pDvmDex->pHeader->stringIdsSize);
123 pDvmDex->pResStrings[stringIdx] = str;
125 INLINE void dvmDexSetResolvedClass(DvmDex* pDvmDex, u4 classIdx,
126 struct ClassObject* clazz)
128 assert(classIdx < pDvmDex->pHeader->typeIdsSize);
129 pDvmDex->pResClasses[classIdx] = clazz;
131 INLINE void dvmDexSetResolvedMethod(DvmDex* pDvmDex, u4 methodIdx,
132 struct Method* method)
134 assert(methodIdx < pDvmDex->pHeader->methodIdsSize);
135 pDvmDex->pResMethods[methodIdx] = method;
137 INLINE void dvmDexSetResolvedField(DvmDex* pDvmDex, u4 fieldIdx,
140 assert(fieldIdx < pDvmDex->pHeader->fieldIdsSize);
141 pDvmDex->pResFields[fieldIdx] = field;
144 #elif DVM_RESOLVER_CACHE == DVM_RC_REDUCING
145 /* reduce request to fit in a less-than-full-size cache table */
148 * Return the requested item if it has been resolved, or NULL if it hasn't.
150 * If we have a mapping table defined for this category, but there's no
151 * entry for this index, we always return NULL. Otherwise, we return the
152 * entry. (To regain some performance we may want to assume that the
153 * table exists when compiled in this mode -- avoids a null check but
154 * prevents us from switching back and forth without rebuilding the VM.)
156 * We could save an integer compare here by ensuring that map[kNoIndexMapping]
157 * always evalutes to NULL (e.g. set kNoIndexMapping = 0).
159 INLINE struct StringObject* dvmDexGetResolvedString(const DvmDex* pDvmDex,
162 const DexIndexMap* pIndexMap = &pDvmDex->pDexFile->indexMap;
164 assert(stringIdx < pDvmDex->pHeader->stringIdsSize);
165 if (pIndexMap->stringReducedCount > 0) {
166 stringIdx = pIndexMap->stringMap[stringIdx];
167 if (stringIdx == kNoIndexMapping)
170 return pDvmDex->pResStrings[stringIdx];
172 INLINE struct ClassObject* dvmDexGetResolvedClass(const DvmDex* pDvmDex,
175 const DexIndexMap* pIndexMap = &pDvmDex->pDexFile->indexMap;
177 assert(classIdx < pDvmDex->pHeader->typeIdsSize);
178 if (pIndexMap->classReducedCount > 0) {
179 classIdx = pIndexMap->classMap[classIdx];
180 if (classIdx == kNoIndexMapping)
183 return pDvmDex->pResClasses[classIdx];
185 INLINE struct Method* dvmDexGetResolvedMethod(const DvmDex* pDvmDex,
188 const DexIndexMap* pIndexMap = &pDvmDex->pDexFile->indexMap;
190 assert(methodIdx < pDvmDex->pHeader->methodIdsSize);
191 if (pIndexMap->methodReducedCount > 0) {
192 methodIdx = pIndexMap->methodMap[methodIdx];
193 if (methodIdx == kNoIndexMapping)
196 return pDvmDex->pResMethods[methodIdx];
198 INLINE struct Field* dvmDexGetResolvedField(const DvmDex* pDvmDex,
201 const DexIndexMap* pIndexMap = &pDvmDex->pDexFile->indexMap;
203 assert(fieldIdx < pDvmDex->pHeader->fieldIdsSize);
204 if (pIndexMap->fieldReducedCount > 0) {
205 fieldIdx = pIndexMap->fieldMap[fieldIdx];
206 if (fieldIdx == kNoIndexMapping)
209 return pDvmDex->pResFields[fieldIdx];
213 * Update the resolved item table. Resolution always produces the same
214 * result, so we're not worried about atomicity here.
216 INLINE void dvmDexSetResolvedString(DvmDex* pDvmDex, u4 stringIdx,
217 struct StringObject* str)
219 const DexIndexMap* pIndexMap = &pDvmDex->pDexFile->indexMap;
222 assert(stringIdx < pDvmDex->pHeader->stringIdsSize);
223 if (pIndexMap->stringReducedCount > 0) {
224 newIdx = pIndexMap->stringMap[stringIdx];
225 if (newIdx != kNoIndexMapping)
226 pDvmDex->pResStrings[newIdx] = str;
229 INLINE void dvmDexSetResolvedClass(DvmDex* pDvmDex, u4 classIdx,
230 struct ClassObject* clazz)
232 const DexIndexMap* pIndexMap = &pDvmDex->pDexFile->indexMap;
235 assert(classIdx < pDvmDex->pHeader->typeIdsSize);
236 if (pIndexMap->classReducedCount > 0) {
237 newIdx = pIndexMap->classMap[classIdx];
238 if (newIdx != kNoIndexMapping)
239 pDvmDex->pResClasses[newIdx] = clazz;
242 INLINE void dvmDexSetResolvedMethod(DvmDex* pDvmDex, u4 methodIdx,
243 struct Method* method)
245 const DexIndexMap* pIndexMap = &pDvmDex->pDexFile->indexMap;
248 assert(methodIdx < pDvmDex->pHeader->methodIdsSize);
249 if (pIndexMap->methodReducedCount > 0) {
250 newIdx = pIndexMap->methodMap[methodIdx];
251 if (newIdx != kNoIndexMapping)
252 pDvmDex->pResMethods[newIdx] = method;
255 INLINE void dvmDexSetResolvedField(DvmDex* pDvmDex, u4 fieldIdx,
258 const DexIndexMap* pIndexMap = &pDvmDex->pDexFile->indexMap;
261 assert(fieldIdx < pDvmDex->pHeader->fieldIdsSize);
262 if (pIndexMap->fieldReducedCount > 0) {
263 newIdx = pIndexMap->fieldMap[fieldIdx];
264 if (newIdx != kNoIndexMapping)
265 pDvmDex->pResFields[newIdx] = field;
269 #elif DVM_RESOLVER_CACHE == DVM_RC_EXPANDING
271 #error "not implemented" /* TODO */
273 #elif DVM_RESOLVER_CACHE == DVM_RC_NO_CACHE
276 * There's no cache, so we always return NULL.
278 INLINE struct StringObject* dvmDexGetResolvedString(const DvmDex* pDvmDex,
283 INLINE struct ClassObject* dvmDexGetResolvedClass(const DvmDex* pDvmDex,
288 INLINE struct Method* dvmDexGetResolvedMethod(const DvmDex* pDvmDex,
293 INLINE struct Field* dvmDexGetResolvedField(const DvmDex* pDvmDex,
300 * Update the resolved item table. There is no table, so do nothing.
302 INLINE void dvmDexSetResolvedString(DvmDex* pDvmDex, u4 stringIdx,
303 struct StringObject* str)
305 INLINE void dvmDexSetResolvedClass(DvmDex* pDvmDex, u4 classIdx,
306 struct ClassObject* clazz)
308 INLINE void dvmDexSetResolvedMethod(DvmDex* pDvmDex, u4 methodIdx,
309 struct Method* method)
311 INLINE void dvmDexSetResolvedField(DvmDex* pDvmDex, u4 fieldIdx,
317 #endif /*DVM_RESOLVER_CACHE==N*/
319 #endif /*_DALVIK_DVMDEX*/