1f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
2f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Copyright (C) 2009 The Android Open Source Project
3f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
4f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
5f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * you may not use this file except in compliance with the License.
6f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * You may obtain a copy of the License at
7f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
8f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
9f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
10f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
11f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
12f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * See the License for the specific language governing permissions and
14f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * limitations under the License.
15f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
16f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
17f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
18f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Declaration of register map data structure and related functions.
1999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project *
2099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * These structures should be treated as opaque through most of the VM.
21f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
22f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#ifndef _DALVIK_REGISTERMAP
23f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define _DALVIK_REGISTERMAP
24f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project#include "analysis/VerifySubs.h"
2699409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project#include "analysis/CodeVerify.h"
2799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project
28f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
29f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Format enumeration for RegisterMap data area.
30f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
31f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projecttypedef enum RegisterMapFormat {
3299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project    kRegMapFormatUnknown = 0,
3399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project    kRegMapFormatNone,          /* indicates no map data follows */
3499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project    kRegMapFormatCompact8,      /* compact layout, 8-bit addresses */
3599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project    kRegMapFormatCompact16,     /* compact layout, 16-bit addresses */
36d45a88794c6470d96e2139cbe803002d9d5d3a6cAndy McFadden    kRegMapFormatDifferential,  /* compressed, differential encoding */
3799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project
3899409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project    kRegMapFormatOnHeap = 0x80, /* bit flag, indicates allocation on heap */
39f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} RegisterMapFormat;
40f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
41f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
42f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * This is a single variable-size structure.  It may be allocated on the
43f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * heap or mapped out of a (post-dexopt) DEX file.
4499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project *
4599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * 32-bit alignment of the structure is NOT guaranteed.  This makes it a
4699409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * little awkward to deal with as a structure; to avoid accidents we use
4799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * only byte types.  Multi-byte values are little-endian.
4899409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project *
4999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * Size of (format==FormatNone): 1 byte
5099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * Size of (format==FormatCompact8): 4 + (1 + regWidth) * numEntries
5199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * Size of (format==FormatCompact16): 4 + (2 + regWidth) * numEntries
52f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
53f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstruct RegisterMap {
54f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /* header */
5599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project    u1      format;         /* enum RegisterMapFormat; MUST be first entry */
56f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    u1      regWidth;       /* bytes per register line, 1+ */
5799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project    u1      numEntries[2];  /* number of entries */
58f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
5999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project    /* raw data starts here; need not be aligned */
60f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    u1      data[1];
61f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project};
62f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
6399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Projectbool dvmRegisterMapStartup(void);
6499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Projectvoid dvmRegisterMapShutdown(void);
6599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project
6699409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project/*
6799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * Get the format.
6899409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project */
691d47a87b38e41f9957849ba685af1f41e53f8a05Andy McFaddenINLINE RegisterMapFormat dvmRegisterMapGetFormat(const RegisterMap* pMap) {
7099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project    return pMap->format & ~(kRegMapFormatOnHeap);
7199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project}
7299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project
7399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project/*
74d45a88794c6470d96e2139cbe803002d9d5d3a6cAndy McFadden * Set the format.
75d45a88794c6470d96e2139cbe803002d9d5d3a6cAndy McFadden */
76d45a88794c6470d96e2139cbe803002d9d5d3a6cAndy McFaddenINLINE void dvmRegisterMapSetFormat(RegisterMap* pMap, RegisterMapFormat format)
77d45a88794c6470d96e2139cbe803002d9d5d3a6cAndy McFadden{
78d45a88794c6470d96e2139cbe803002d9d5d3a6cAndy McFadden    pMap->format &= kRegMapFormatOnHeap;
79d45a88794c6470d96e2139cbe803002d9d5d3a6cAndy McFadden    pMap->format |= format;
80d45a88794c6470d96e2139cbe803002d9d5d3a6cAndy McFadden}
81d45a88794c6470d96e2139cbe803002d9d5d3a6cAndy McFadden
82d45a88794c6470d96e2139cbe803002d9d5d3a6cAndy McFadden/*
8399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * Get the "on heap" flag.
8499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project */
85d45a88794c6470d96e2139cbe803002d9d5d3a6cAndy McFaddenINLINE bool dvmRegisterMapGetOnHeap(const RegisterMap* pMap) {
8699409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project    return (pMap->format & kRegMapFormatOnHeap) != 0;
8799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project}
8899409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project
8999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project/*
90d45a88794c6470d96e2139cbe803002d9d5d3a6cAndy McFadden * Get the register bit vector width, in bytes.
91d45a88794c6470d96e2139cbe803002d9d5d3a6cAndy McFadden */
92d45a88794c6470d96e2139cbe803002d9d5d3a6cAndy McFaddenINLINE u1 dvmRegisterMapGetRegWidth(const RegisterMap* pMap) {
93d45a88794c6470d96e2139cbe803002d9d5d3a6cAndy McFadden    return pMap->regWidth;
94d45a88794c6470d96e2139cbe803002d9d5d3a6cAndy McFadden}
95d45a88794c6470d96e2139cbe803002d9d5d3a6cAndy McFadden
96d45a88794c6470d96e2139cbe803002d9d5d3a6cAndy McFadden/*
97d45a88794c6470d96e2139cbe803002d9d5d3a6cAndy McFadden * Set the register bit vector width, in bytes.
98d45a88794c6470d96e2139cbe803002d9d5d3a6cAndy McFadden */
99d45a88794c6470d96e2139cbe803002d9d5d3a6cAndy McFaddenINLINE void dvmRegisterMapSetRegWidth(RegisterMap* pMap, int regWidth) {
100d45a88794c6470d96e2139cbe803002d9d5d3a6cAndy McFadden    pMap->regWidth = regWidth;
101d45a88794c6470d96e2139cbe803002d9d5d3a6cAndy McFadden}
102d45a88794c6470d96e2139cbe803002d9d5d3a6cAndy McFadden
103d45a88794c6470d96e2139cbe803002d9d5d3a6cAndy McFadden/*
10499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * Set the "on heap" flag.
10599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project */
106d45a88794c6470d96e2139cbe803002d9d5d3a6cAndy McFaddenINLINE void dvmRegisterMapSetOnHeap(RegisterMap* pMap, bool val) {
10799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project    if (val)
10899409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project        pMap->format |= kRegMapFormatOnHeap;
10999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project    else
11099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project        pMap->format &= ~(kRegMapFormatOnHeap);
11199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project}
11299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project
11399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project/*
11499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * Get the number of entries in this map.
11599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project */
11699409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source ProjectINLINE u2 dvmRegisterMapGetNumEntries(const RegisterMap* pMap) {
11799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project    return pMap->numEntries[0] | (pMap->numEntries[1] << 8);
11899409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project}
11999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project
12099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project/*
12199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * Set the number of entries in this map.
12299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project */
12399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source ProjectINLINE void dvmRegisterMapSetNumEntries(RegisterMap* pMap, u2 numEntries) {
12499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project    pMap->numEntries[0] = (u1) numEntries;
12599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project    pMap->numEntries[1] = numEntries >> 8;
12699409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project}
12799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project
12899409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project/*
12999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * Retrieve the bit vector for the specified address.  This is a pointer
13099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * to the bit data from an uncompressed map, or to a temporary copy of
13199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * data from a compressed map.
13299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project *
13399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * The caller must call dvmReleaseRegisterMapLine() with the result.
13499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project *
13599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * Returns NULL if not found.
13699409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project */
137d45a88794c6470d96e2139cbe803002d9d5d3a6cAndy McFaddenconst u1* dvmRegisterMapGetLine(const RegisterMap* pMap, int addr);
13899409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project
13999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project/*
14099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * Release "data".
14199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project *
1421d47a87b38e41f9957849ba685af1f41e53f8a05Andy McFadden * If "pMap" points to a compressed map from which we have expanded a
1431d47a87b38e41f9957849ba685af1f41e53f8a05Andy McFadden * single line onto the heap, this will free "data"; otherwise, it does
1441d47a87b38e41f9957849ba685af1f41e53f8a05Andy McFadden * nothing.
1451d47a87b38e41f9957849ba685af1f41e53f8a05Andy McFadden *
1461d47a87b38e41f9957849ba685af1f41e53f8a05Andy McFadden * TODO: decide if this is still a useful concept.
14799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project */
14899409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source ProjectINLINE void dvmReleaseRegisterMapLine(const RegisterMap* pMap, const u1* data)
14999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project{}
15099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project
15199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project
15299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project/*
15399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * A pool of register maps for methods associated with a single class.
15499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project *
15599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * Each entry is a 4-byte method index followed by the 32-bit-aligned
15699409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * RegisterMap.  The size of the RegisterMap is determined by parsing
15799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * the map.  The lack of an index reduces random access speed, but we
15899409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * should be doing that rarely (during class load) and it saves space.
15999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project *
16099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * These structures are 32-bit aligned.
16199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project */
16299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Projecttypedef struct RegisterMapMethodPool {
16399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project    u2      methodCount;            /* chiefly used as a sanity check */
16499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project
16599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project    /* stream of per-method data starts here */
16699409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project    u4      methodData[1];
16799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project} RegisterMapMethodPool;
16899409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project
16999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project/*
17099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * Header for the memory-mapped RegisterMap pool in the DEX file.
17199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project *
17299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * The classDataOffset table provides offsets from the start of the
17399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * RegisterMapPool structure.  There is one entry per class (including
17499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * interfaces, which can have static initializers).
17599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project *
17699409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * The offset points to a RegisterMapMethodPool.
17799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project *
17899409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * These structures are 32-bit aligned.
17999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project */
18099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Projecttypedef struct RegisterMapClassPool {
18199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project    u4      numClasses;
18299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project
18399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project    /* offset table starts here, 32-bit aligned; offset==0 means no data */
18499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project    u4      classDataOffset[1];
18599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project} RegisterMapClassPool;
18699409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project
18799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project/*
18899409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * Find the register maps for this class.  (Used during class loading.)
18999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * If "pNumMaps" is non-NULL, it will return the number of maps in the set.
19099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project *
19199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * Returns NULL if none is available.
19299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project */
193d45a88794c6470d96e2139cbe803002d9d5d3a6cAndy McFaddenconst void* dvmRegisterMapGetClassData(const DexFile* pDexFile, u4 classIdx,
19499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project    u4* pNumMaps);
19599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project
19699409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project/*
19799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * Get the register map for the next method.  "*pPtr" will be advanced past
19899409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * the end of the map.  (Used during class loading.)
19999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project *
20099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * This should initially be called with the result from
201d45a88794c6470d96e2139cbe803002d9d5d3a6cAndy McFadden * dvmRegisterMapGetClassData().
20299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project */
203d45a88794c6470d96e2139cbe803002d9d5d3a6cAndy McFaddenconst RegisterMap* dvmRegisterMapGetNext(const void** pPtr);
20499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project
20599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project/*
20699409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * This holds some meta-data while we construct the set of register maps
20799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * for a DEX file.
20899409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project *
20999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * In particular, it keeps track of our temporary mmap region so we can
21099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * free it later.
21199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project */
21299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Projecttypedef struct RegisterMapBuilder {
21399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project    /* public */
21499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project    void*       data;
21599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project    size_t      size;
21699409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project
21799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project    /* private */
21899409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project    MemMapping  memMap;
21999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project} RegisterMapBuilder;
22099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project
22199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project/*
22299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * Generate a register map set for all verified classes in "pDvmDex".
22399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project */
22499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source ProjectRegisterMapBuilder* dvmGenerateRegisterMaps(DvmDex* pDvmDex);
22599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project
22699409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project/*
22799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * Free the builder.
22899409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project */
22999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Projectvoid dvmFreeRegisterMapBuilder(RegisterMapBuilder* pBuilder);
23099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project
23199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project
232f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
233f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Generate the register map for a previously-verified method.
234f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
235f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns a pointer to a newly-allocated RegisterMap.
236f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
237f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project//RegisterMap* dvmGenerateRegisterMap(const Method* meth);
238f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
239f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
240f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Various bits of data generated by the verifier, wrapped up in a package
241f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * for ease of use by the register map generator.
242f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
243f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projecttypedef struct VerifierData {
244f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /*
245f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * The method we're working on.
246f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
247f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    const Method* method;
248f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
249f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /*
250f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Number of instructions in the method.
251f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
252f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    int         insnsSize;
253f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
254f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /*
255f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Number of registers we track for each instruction.  This is equal
256f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * to the method's declared "registersSize".  (Does not include the
257f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * pending return value.)
258f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
259f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    int         insnRegCount;
260f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
261f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /*
262f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Instruction widths and flags, one entry per code unit.
263f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
264f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    InsnFlags*  insnFlags;
265f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
266f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /*
267f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Array of SRegType arrays, one entry per code unit.  We only need
268f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * entries for code units that hold the start of an "interesting"
269f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * instruction.  For register map generation, we're only interested
270f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * in GC points.
271f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
272f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    RegType**   addrRegs;
273f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} VerifierData;
274f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
275f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
276f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Generate the register map for a method that has just been verified
277f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * (i.e. we're doing this as part of verification).
278f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
279f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns a pointer to a newly-allocated RegisterMap, or NULL on failure.
280f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
281f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectRegisterMap* dvmGenerateRegisterMapV(VerifierData* vdata);
282f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
283d45a88794c6470d96e2139cbe803002d9d5d3a6cAndy McFadden/*
284d45a88794c6470d96e2139cbe803002d9d5d3a6cAndy McFadden * Get the expanded form of the register map associated with the specified
285d45a88794c6470d96e2139cbe803002d9d5d3a6cAndy McFadden * method.  May update method->registerMap, possibly freeing the previous
286d45a88794c6470d96e2139cbe803002d9d5d3a6cAndy McFadden * map.
287d45a88794c6470d96e2139cbe803002d9d5d3a6cAndy McFadden *
288d45a88794c6470d96e2139cbe803002d9d5d3a6cAndy McFadden * Returns NULL on failure (e.g. unable to expand map).
289d45a88794c6470d96e2139cbe803002d9d5d3a6cAndy McFadden *
290d45a88794c6470d96e2139cbe803002d9d5d3a6cAndy McFadden * NOTE: this function is not synchronized; external locking is mandatory.
291d45a88794c6470d96e2139cbe803002d9d5d3a6cAndy McFadden * (This is expected to be called at GC time.)
292d45a88794c6470d96e2139cbe803002d9d5d3a6cAndy McFadden */
293d45a88794c6470d96e2139cbe803002d9d5d3a6cAndy McFaddenconst RegisterMap* dvmGetExpandedRegisterMap0(Method* method);
294d45a88794c6470d96e2139cbe803002d9d5d3a6cAndy McFaddenINLINE const RegisterMap* dvmGetExpandedRegisterMap(Method* method)
295d45a88794c6470d96e2139cbe803002d9d5d3a6cAndy McFadden{
296d45a88794c6470d96e2139cbe803002d9d5d3a6cAndy McFadden    const RegisterMap* curMap = method->registerMap;
297d45a88794c6470d96e2139cbe803002d9d5d3a6cAndy McFadden    if (curMap == NULL)
298d45a88794c6470d96e2139cbe803002d9d5d3a6cAndy McFadden        return NULL;
299d45a88794c6470d96e2139cbe803002d9d5d3a6cAndy McFadden    RegisterMapFormat format = dvmRegisterMapGetFormat(curMap);
300d45a88794c6470d96e2139cbe803002d9d5d3a6cAndy McFadden    if (format == kRegMapFormatCompact8 || format == kRegMapFormatCompact16) {
301d45a88794c6470d96e2139cbe803002d9d5d3a6cAndy McFadden        return curMap;
302d45a88794c6470d96e2139cbe803002d9d5d3a6cAndy McFadden    } else {
303d45a88794c6470d96e2139cbe803002d9d5d3a6cAndy McFadden        return dvmGetExpandedRegisterMap0(method);
304d45a88794c6470d96e2139cbe803002d9d5d3a6cAndy McFadden    }
305d45a88794c6470d96e2139cbe803002d9d5d3a6cAndy McFadden}
306d45a88794c6470d96e2139cbe803002d9d5d3a6cAndy McFadden
30799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project/* dump stats gathered during register map creation process */
30899409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Projectvoid dvmRegisterMapDumpStats(void);
30999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project
310f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#endif /*_DALVIK_REGISTERMAP*/
311