aboutsummaryrefslogtreecommitdiff
path: root/vm/interp/Jit.h
blob: 962040b8089e28a869f2ee117dc4ffd557e6ca38 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
/*
 * Copyright (C) 2009 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
/*
 * Jit control
 */
#ifndef DALVIK_INTERP_JIT_H_
#define DALVIK_INTERP_JIT_H_

#include "InterpDefs.h"
#include "mterp/common/jit-config.h"

#define JIT_MAX_TRACE_LEN 100

#if defined (WITH_SELF_VERIFICATION)

#define REG_SPACE 256                /* default size of shadow space */
#define HEAP_SPACE JIT_MAX_TRACE_LEN /* default size of heap space */

struct ShadowHeap {
    int addr;
    int data;
};

struct InstructionTrace {
    int addr;
    DecodedInstruction decInsn;
};

struct ShadowSpace {
    const u2* startPC;          /* starting pc of jitted region */
    u4* fp;                     /* starting fp of jitted region */
    const Method *method;
    DvmDex* methodClassDex;
    JValue retval;
    const u1* interpStackEnd;
    SelfVerificationState jitExitState;  /* exit point for JIT'ed code */
    SelfVerificationState selfVerificationState;  /* current SV running state */
    const u2* endPC;            /* ending pc of jitted region */
    void* shadowFP;       /* pointer to fp in shadow space */
    int* registerSpace;         /* copy of register state */
    int registerSpaceSize;      /* current size of register space */
    ShadowHeap heapSpace[HEAP_SPACE]; /* copy of heap space */
    ShadowHeap* heapSpaceTail;        /* tail pointer to heapSpace */
    const void* endShadowFP;    /* ending fp in shadow space */
    InstructionTrace trace[JIT_MAX_TRACE_LEN]; /* opcode trace for debugging */
    int traceLength;            /* counter for current trace length */
};

/*
 * Self verification functions.
 */
extern "C" {
void* dvmSelfVerificationShadowSpaceAlloc(Thread* self);
void dvmSelfVerificationShadowSpaceFree(Thread* self);
void* dvmSelfVerificationSaveState(const u2* pc, u4* fp,
                                   Thread* self,
                                   int targetTrace);
void* dvmSelfVerificationRestoreState(const u2* pc, u4* fp,
                                      SelfVerificationState exitPoint,
                                      Thread *self);
void dvmCheckSelfVerification(const u2* pc, Thread* self);
}
#endif

/*
 * Offsets for metadata in the trace run array from the trace that ends with
 * invoke instructions.
 */
#define JIT_TRACE_CLASS_DESC    1
#define JIT_TRACE_CLASS_LOADER  2
#define JIT_TRACE_CUR_METHOD    3

/*
 * JitTable hash function.
 */

static inline u4 dvmJitHashMask( const u2* p, u4 mask ) {
    return ((((u4)p>>12)^(u4)p)>>1) & (mask);
}

static inline u4 dvmJitHash( const u2* p ) {
    return dvmJitHashMask( p, gDvmJit.jitTableMask );
}

/*
 * The width of the chain field in JitEntryInfo sets the upper
 * bound on the number of translations.  Be careful if changing
 * the size of JitEntry struct - the Dalvik PC to JitEntry
 * hash functions have built-in knowledge of the size.
 */
#define JIT_ENTRY_CHAIN_WIDTH 2
#define JIT_MAX_ENTRIES (1 << (JIT_ENTRY_CHAIN_WIDTH * 8))

/*
 * The trace profiling counters are allocated in blocks and individual
 * counters must not move so long as any referencing trace exists.
 */
#define JIT_PROF_BLOCK_ENTRIES 1024
#define JIT_PROF_BLOCK_BUCKETS (JIT_MAX_ENTRIES / JIT_PROF_BLOCK_ENTRIES)

typedef s4 JitTraceCounter_t;

struct JitTraceProfCounters {
    unsigned int           next;
    JitTraceCounter_t      *buckets[JIT_PROF_BLOCK_BUCKETS];
};

/*
 * Entries in the JIT's address lookup hash table.
 * Fields which may be updated by multiple threads packed into a
 * single 32-bit word to allow use of atomic update.
 */

struct JitEntryInfo {
    unsigned int           isMethodEntry:1;
    unsigned int           inlineCandidate:1;
    unsigned int           profileEnabled:1;
    JitInstructionSetType  instructionSet:3;
    unsigned int           profileOffset:5;
    unsigned int           unused:5;
    u2                     chain;                 /* Index of next in chain */
};

union JitEntryInfoUnion {
    JitEntryInfo info;
    volatile int infoWord;
};

struct JitEntry {
    JitEntryInfoUnion   u;
    const u2*           dPC;            /* Dalvik code address */
    void*               codeAddress;    /* Code address of native translation */
};

extern "C" {
void dvmCheckJit(const u2* pc, Thread* self);
void* dvmJitGetTraceAddr(const u2* dPC);
void* dvmJitGetMethodAddr(const u2* dPC);
void* dvmJitGetTraceAddrThread(const u2* dPC, Thread* self);
void* dvmJitGetMethodAddrThread(const u2* dPC, Thread* self);
void dvmJitCheckTraceRequest(Thread* self);
void dvmJitStopTranslationRequests(void);
#if defined(WITH_JIT_TUNING)
void dvmBumpNoChain(int from);
void dvmBumpNormal(void);
void dvmBumpPunt(int from);
#endif
void dvmJitStats(void);
bool dvmJitResizeJitTable(unsigned int size);
void dvmJitResetTable(void);
JitEntry *dvmJitFindEntry(const u2* pc, bool isMethodEntry);
s8 dvmJitd2l(double d);
s8 dvmJitf2l(float f);
void dvmJitSetCodeAddr(const u2* dPC, void *nPC, JitInstructionSetType set,
                       bool isMethodEntry, int profilePrefixSize);
void dvmJitEndTraceSelect(Thread* self, const u2* dPC);
JitTraceCounter_t *dvmJitNextTraceCounter(void);
void dvmJitTraceProfilingOff(void);
void dvmJitTraceProfilingOn(void);
void dvmJitChangeProfileMode(TraceProfilingModes newState);
void dvmJitDumpTraceDesc(JitTraceDescription *trace);
void dvmJitUpdateThreadStateSingle(Thread* threead);
void dvmJitUpdateThreadStateAll(void);
void dvmJitResumeTranslation(Thread* self, const u2* pc, const u4* fp);
}

#endif  // DALVIK_INTERP_JIT_H_