DvmDex.h revision 375fb116bcb817b37509ab579dbd55cdbb765cbf
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/*
18 * The VM wraps some additional data structures around the DexFile.  These
19 * are defined here.
20 */
21#ifndef DALVIK_DVMDEX_H_
22#define DALVIK_DVMDEX_H_
23
24#include "libdex/DexFile.h"
25
26/* extern */
27struct ClassObject;
28struct HashTable;
29struct InstField;
30struct Method;
31struct StringObject;
32
33
34/*
35 * Some additional VM data structures that are associated with the DEX file.
36 */
37struct DvmDex {
38    /* pointer to the DexFile we're associated with */
39    DexFile*            pDexFile;
40
41    /* clone of pDexFile->pHeader (it's used frequently enough) */
42    const DexHeader*    pHeader;
43
44    /* interned strings; parallel to "stringIds" */
45    struct StringObject** pResStrings;
46
47    /* resolved classes; parallel to "typeIds" */
48    struct ClassObject** pResClasses;
49
50    /* resolved methods; parallel to "methodIds" */
51    struct Method**     pResMethods;
52
53    /* resolved instance fields; parallel to "fieldIds" */
54    /* (this holds both InstField and StaticField) */
55    struct Field**      pResFields;
56
57    /* interface method lookup cache */
58    struct AtomicCache* pInterfaceCache;
59
60    /* shared memory region with file contents */
61    bool                isMappedReadOnly;
62    MemMapping          memMap;
63
64    /* lock ensuring mutual exclusion during updates */
65    pthread_mutex_t     modLock;
66};
67
68
69/*
70 * Given a file descriptor for an open "optimized" DEX file, map it into
71 * memory and parse the contents.
72 *
73 * On success, returns 0 and sets "*ppDvmDex" to a newly-allocated DvmDex.
74 * On failure, returns a meaningful error code [currently just -1].
75 */
76int dvmDexFileOpenFromFd(int fd, DvmDex** ppDvmDex);
77
78/*
79 * Open a partial DEX file.  Only useful as part of the optimization process.
80 */
81int dvmDexFileOpenPartial(const void* addr, int len, DvmDex** ppDvmDex);
82
83/*
84 * Free a DvmDex structure, along with any associated structures.
85 */
86void dvmDexFileFree(DvmDex* pDvmDex);
87
88
89/*
90 * Change the 1- or 2-byte value at the specified address to a new value.  If
91 * the location already has the new value, do nothing.
92 *
93 * This does not make any synchronization guarantees.  The caller must
94 * ensure exclusivity vs. other callers.
95 *
96 * For the 2-byte call, the pointer should have 16-bit alignment.
97 *
98 * Returns "true" on success.
99 */
100bool dvmDexChangeDex1(DvmDex* pDvmDex, u1* addr, u1 newVal);
101bool dvmDexChangeDex2(DvmDex* pDvmDex, u2* addr, u2 newVal);
102
103
104/*
105 * Return the requested item if it has been resolved, or NULL if it hasn't.
106 */
107INLINE struct StringObject* dvmDexGetResolvedString(const DvmDex* pDvmDex,
108    u4 stringIdx)
109{
110    assert(stringIdx < pDvmDex->pHeader->stringIdsSize);
111    return pDvmDex->pResStrings[stringIdx];
112}
113INLINE struct ClassObject* dvmDexGetResolvedClass(const DvmDex* pDvmDex,
114    u4 classIdx)
115{
116    assert(classIdx < pDvmDex->pHeader->typeIdsSize);
117    return pDvmDex->pResClasses[classIdx];
118}
119INLINE struct Method* dvmDexGetResolvedMethod(const DvmDex* pDvmDex,
120    u4 methodIdx)
121{
122    assert(methodIdx < pDvmDex->pHeader->methodIdsSize);
123    return pDvmDex->pResMethods[methodIdx];
124}
125INLINE struct Field* dvmDexGetResolvedField(const DvmDex* pDvmDex,
126    u4 fieldIdx)
127{
128    assert(fieldIdx < pDvmDex->pHeader->fieldIdsSize);
129    return pDvmDex->pResFields[fieldIdx];
130}
131
132/*
133 * Update the resolved item table.  Resolution always produces the same
134 * result, so we're not worried about atomicity here.
135 */
136INLINE void dvmDexSetResolvedString(DvmDex* pDvmDex, u4 stringIdx,
137    struct StringObject* str)
138{
139    assert(stringIdx < pDvmDex->pHeader->stringIdsSize);
140    pDvmDex->pResStrings[stringIdx] = str;
141}
142INLINE void dvmDexSetResolvedClass(DvmDex* pDvmDex, u4 classIdx,
143    struct ClassObject* clazz)
144{
145    assert(classIdx < pDvmDex->pHeader->typeIdsSize);
146    pDvmDex->pResClasses[classIdx] = clazz;
147}
148INLINE void dvmDexSetResolvedMethod(DvmDex* pDvmDex, u4 methodIdx,
149    struct Method* method)
150{
151    assert(methodIdx < pDvmDex->pHeader->methodIdsSize);
152    pDvmDex->pResMethods[methodIdx] = method;
153}
154INLINE void dvmDexSetResolvedField(DvmDex* pDvmDex, u4 fieldIdx,
155    struct Field* field)
156{
157    assert(fieldIdx < pDvmDex->pHeader->fieldIdsSize);
158    pDvmDex->pResFields[fieldIdx] = field;
159}
160
161#endif  // DALVIK_DVMDEX_H_
162