OSDN Git Service

Merge "Undecoded jobject leaking in through attachThread"
[android-x86/dalvik.git] / vm / compiler / Compiler.h
1 /*
2  * Copyright (C) 2009 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 #include <Thread.h>
18 #include <setjmp.h>
19
20 #ifndef _DALVIK_VM_COMPILER
21 #define _DALVIK_VM_COMPILER
22
23 /*
24  * Uncomment the following to enable JIT signature breakpoint
25  * #define SIGNATURE_BREAKPOINT
26  */
27
28 #define MAX_JIT_RUN_LEN                 64
29 #define COMPILER_WORK_QUEUE_SIZE        100
30 #define COMPILER_IC_PATCH_QUEUE_SIZE    64
31
32 /* Architectural-independent parameters for predicted chains */
33 #define PREDICTED_CHAIN_CLAZZ_INIT       0
34 #define PREDICTED_CHAIN_METHOD_INIT      0
35 #define PREDICTED_CHAIN_COUNTER_INIT     0
36 /* A fake value which will avoid initialization and won't match any class */
37 #define PREDICTED_CHAIN_FAKE_CLAZZ       0xdeadc001
38 /* Has to be positive */
39 #define PREDICTED_CHAIN_COUNTER_AVOID    0x7fffffff
40 /* Rechain after this many misses - shared globally and has to be positive */
41 #define PREDICTED_CHAIN_COUNTER_RECHAIN  8192
42
43 #define COMPILER_TRACED(X)
44 #define COMPILER_TRACEE(X)
45 #define COMPILER_TRACE_CHAINING(X)
46
47 /* Macro to change the permissions applied to a chunk of the code cache */
48 #if !defined(WITH_JIT_TUNING)
49 #define PROTECT_CODE_CACHE_ATTRS       (PROT_READ | PROT_EXEC)
50 #define UNPROTECT_CODE_CACHE_ATTRS     (PROT_READ | PROT_EXEC | PROT_WRITE)
51 #else
52 /* When doing JIT profiling always grant the write permission */
53 #define PROTECT_CODE_CACHE_ATTRS       (PROT_READ | PROT_EXEC |                \
54                                   (gDvmJit.profile ? PROT_WRITE : 0))
55 #define UNPROTECT_CODE_CACHE_ATTRS     (PROT_READ | PROT_EXEC | PROT_WRITE)
56 #endif
57
58 /* Acquire the lock before removing PROT_WRITE from the specified mem region */
59 #define UNPROTECT_CODE_CACHE(addr, size)                                       \
60     {                                                                          \
61         dvmLockMutex(&gDvmJit.codeCacheProtectionLock);                        \
62         mprotect((void *) (((intptr_t) (addr)) & ~gDvmJit.pageSizeMask),       \
63                  (size) + (((intptr_t) (addr)) & gDvmJit.pageSizeMask),        \
64                  (UNPROTECT_CODE_CACHE_ATTRS));                                \
65     }
66
67 /* Add the PROT_WRITE to the specified memory region then release the lock */
68 #define PROTECT_CODE_CACHE(addr, size)                                         \
69     {                                                                          \
70         mprotect((void *) (((intptr_t) (addr)) & ~gDvmJit.pageSizeMask),       \
71                  (size) + (((intptr_t) (addr)) & gDvmJit.pageSizeMask),        \
72                  (PROTECT_CODE_CACHE_ATTRS));                                  \
73         dvmUnlockMutex(&gDvmJit.codeCacheProtectionLock);                      \
74     }
75
76 #define SINGLE_STEP_OP(opcode)                                                 \
77     (gDvmJit.includeSelectedOp !=                                              \
78      ((gDvmJit.opList[opcode >> 3] & (1 << (opcode & 0x7))) != 0))
79
80 typedef enum JitInstructionSetType {
81     DALVIK_JIT_NONE = 0,
82     DALVIK_JIT_ARM,
83     DALVIK_JIT_THUMB,
84     DALVIK_JIT_THUMB2,
85     DALVIK_JIT_THUMB2EE,
86     DALVIK_JIT_X86
87 } JitInstructionSetType;
88
89 /* Description of a compiled trace. */
90 typedef struct JitTranslationInfo {
91     void *codeAddress;
92     JitInstructionSetType instructionSet;
93     bool discardResult;         // Used for debugging divergence and IC patching
94     bool methodCompilationAborted;  // Cannot compile the whole method
95     Thread *requestingThread;   // For debugging purpose
96 } JitTranslationInfo;
97
98 typedef enum WorkOrderKind {
99     kWorkOrderInvalid = 0,      // Should never see by the backend
100     kWorkOrderMethod = 1,       // Work is to compile a whole method
101     kWorkOrderTrace = 2,        // Work is to compile code fragment(s)
102     kWorkOrderTraceDebug = 3,   // Work is to compile/debug code fragment(s)
103 } WorkOrderKind;
104
105 typedef struct CompilerWorkOrder {
106     const u2* pc;
107     WorkOrderKind kind;
108     void* info;
109     JitTranslationInfo result;
110     jmp_buf *bailPtr;
111 } CompilerWorkOrder;
112
113 /* Chain cell for predicted method invocation */
114 typedef struct PredictedChainingCell {
115     u4 branch;                  /* Branch to chained destination */
116     const ClassObject *clazz;   /* key for prediction */
117     const Method *method;       /* to lookup native PC from dalvik PC */
118     const ClassObject *stagedClazz;   /* possible next key for prediction */
119 } PredictedChainingCell;
120
121 /* Work order for inline cache patching */
122 typedef struct ICPatchWorkOrder {
123     PredictedChainingCell *cellAddr;    /* Address to be patched */
124     PredictedChainingCell cellContent;  /* content of the new cell */
125 } ICPatchWorkOrder;
126
127 /* States of the dbg interpreter when serving a JIT-related request */
128 typedef enum JitState {
129     /* Entering states in the debug interpreter */
130     kJitNot = 0,               // Non-JIT related reasons */
131     kJitTSelectRequest = 1,    // Request a trace (subject to filtering)
132     kJitTSelectRequestHot = 2, // Request a hot trace (bypass the filter)
133     kJitSelfVerification = 3,  // Self Verification Mode
134
135     /* Operational states in the debug interpreter */
136     kJitTSelect = 4,           // Actively selecting a trace
137     kJitTSelectEnd = 5,        // Done with the trace - wrap it up
138     kJitSingleStep = 6,        // Single step interpretation
139     kJitSingleStepEnd = 7,     // Done with single step, ready return to mterp
140     kJitDone = 8,              // Ready to leave the debug interpreter
141 } JitState;
142
143 #if defined(WITH_SELF_VERIFICATION)
144 typedef enum SelfVerificationState {
145     kSVSIdle = 0,           // Idle
146     kSVSStart = 1,          // Shadow space set up, running compiled code
147     kSVSPunt = 2,           // Exiting compiled code by punting
148     kSVSSingleStep = 3,     // Exiting compiled code by single stepping
149     kSVSNoProfile = 4,      // Exiting compiled code and don't collect profiles
150     kSVSTraceSelect = 5,    // Exiting compiled code and compile the next pc
151     kSVSNormal = 6,         // Exiting compiled code normally
152     kSVSNoChain = 7,        // Exiting compiled code by no chain
153     kSVSBackwardBranch = 8, // Exiting compiled code with backward branch trace
154     kSVSDebugInterp = 9,    // Normal state restored, running debug interpreter
155 } SelfVerificationState;
156 #endif
157
158 typedef enum JitHint {
159    kJitHintNone = 0,
160    kJitHintTaken = 1,         // Last inst in run was taken branch
161    kJitHintNotTaken = 2,      // Last inst in run was not taken branch
162    kJitHintNoBias = 3,        // Last inst in run was unbiased branch
163 } jitHint;
164
165 /*
166  * Element of a Jit trace description. If the isCode bit is set, it describes
167  * a contiguous sequence of Dalvik byte codes.
168  */
169 typedef struct {
170     unsigned isCode:1;       // If set denotes code fragments
171     unsigned numInsts:8;     // Number of Byte codes in run
172     unsigned runEnd:1;       // Run ends with last byte code
173     jitHint  hint:6;         // Hint to apply to final code of run
174     u2    startOffset;       // Starting offset for trace run
175 } JitCodeDesc;
176
177 /*
178  * A complete list of trace runs passed to the compiler looks like the
179  * following:
180  *   frag1
181  *   frag2
182  *   frag3
183  *   meta1
184  *   meta2
185  *   frag4
186  *
187  * frags 1-4 have the "isCode" field set, and metas 1-2 are plain pointers or
188  * pointers to auxiliary data structures as long as the LSB is null.
189  * The meaning of the meta content is loosely defined. It is usually the code
190  * fragment right before the first meta field (frag3 in this case) to
191  * understand and parse them. Frag4 could be a dummy one with 0 "numInsts" but
192  * the "runEnd" field set.
193  *
194  * For example, if a trace run contains a method inlining target, the class
195  * type of "this" and the currently resolved method pointer are two instances
196  * of meta information stored there.
197  */
198 typedef union {
199     JitCodeDesc frag;
200     void*       meta;
201 } JitTraceRun;
202
203 /*
204  * Trace description as will appear in the translation cache.  Note
205  * flexible array at end, as these will be of variable size.  To
206  * conserve space in the translation cache, total length of JitTraceRun
207  * array must be recomputed via seqential scan if needed.
208  */
209 typedef struct {
210     const Method* method;
211     JitTraceRun trace[0];       // Variable-length trace descriptors
212 } JitTraceDescription;
213
214 typedef enum JitMethodAttributes {
215     kIsCallee = 0,      /* Code is part of a callee (invoked by a hot trace) */
216     kIsHot,             /* Code is part of a hot trace */
217     kIsLeaf,            /* Method is leaf */
218     kIsEmpty,           /* Method is empty */
219     kIsThrowFree,       /* Method doesn't throw */
220     kIsGetter,          /* Method fits the getter pattern */
221     kIsSetter,          /* Method fits the setter pattern */
222 } JitMethodAttributes;
223
224 #define METHOD_IS_CALLEE        (1 << kIsCallee)
225 #define METHOD_IS_HOT           (1 << kIsHot)
226 #define METHOD_IS_LEAF          (1 << kIsLeaf)
227 #define METHOD_IS_EMPTY         (1 << kIsEmpty)
228 #define METHOD_IS_THROW_FREE    (1 << kIsThrowFree)
229 #define METHOD_IS_GETTER        (1 << kIsGetter)
230 #define METHOD_IS_SETTER        (1 << kIsSetter)
231
232 /* Vectors to provide optimization hints */
233 typedef enum JitOptimizationHints {
234     kJitOptNoLoop = 0,          // Disable loop formation/optimization
235 } JitOptimizationHints;
236
237 #define JIT_OPT_NO_LOOP         (1 << kJitOptNoLoop)
238
239 typedef struct CompilerMethodStats {
240     const Method *method;       // Used as hash entry signature
241     int dalvikSize;             // # of bytes for dalvik bytecodes
242     int compiledDalvikSize;     // # of compiled dalvik bytecodes
243     int nativeSize;             // # of bytes for produced native code
244     int attributes;             // attribute vector
245 } CompilerMethodStats;
246
247 struct CompilationUnit;
248 struct BasicBlock;
249 struct SSARepresentation;
250 struct GrowableList;
251 struct JitEntry;
252 struct MIR;
253
254 bool dvmCompilerSetupCodeCache(void);
255 bool dvmCompilerArchInit(void);
256 void dvmCompilerArchDump(void);
257 bool dvmCompilerStartup(void);
258 void dvmCompilerShutdown(void);
259 bool dvmCompilerWorkEnqueue(const u2* pc, WorkOrderKind kind, void* info);
260 void *dvmCheckCodeCache(void *method);
261 CompilerMethodStats *dvmCompilerAnalyzeMethodBody(const Method *method,
262                                                   bool isCallee);
263 bool dvmCompilerCanIncludeThisInstruction(const Method *method,
264                                           const DecodedInstruction *insn);
265 bool dvmCompileMethod(struct CompilationUnit *cUnit, const Method *method,
266                       JitTranslationInfo *info);
267 bool dvmCompileTrace(JitTraceDescription *trace, int numMaxInsts,
268                      JitTranslationInfo *info, jmp_buf *bailPtr, int optHints);
269 void dvmCompilerDumpStats(void);
270 void dvmCompilerDrainQueue(void);
271 void dvmJitUnchainAll(void);
272 void dvmCompilerSortAndPrintTraceProfiles(void);
273 void dvmCompilerPerformSafePointChecks(void);
274 void dvmCompilerInlineMIR(struct CompilationUnit *cUnit);
275 void dvmInitializeSSAConversion(struct CompilationUnit *cUnit);
276 int dvmConvertSSARegToDalvik(struct CompilationUnit *cUnit, int ssaReg);
277 bool dvmCompilerLoopOpt(struct CompilationUnit *cUnit);
278 void dvmCompilerNonLoopAnalysis(struct CompilationUnit *cUnit);
279 void dvmCompilerFindLiveIn(struct CompilationUnit *cUnit,
280                            struct BasicBlock *bb);
281 void dvmCompilerDoSSAConversion(struct CompilationUnit *cUnit,
282                                 struct BasicBlock *bb);
283 void dvmCompilerDoConstantPropagation(struct CompilationUnit *cUnit,
284                                       struct BasicBlock *bb);
285 void dvmCompilerFindInductionVariables(struct CompilationUnit *cUnit,
286                                        struct BasicBlock *bb);
287 char *dvmCompilerGetDalvikDisassembly(DecodedInstruction *insn, char *note);
288 char *dvmCompilerGetSSAString(struct CompilationUnit *cUnit,
289                               struct SSARepresentation *ssaRep);
290 void dvmCompilerDataFlowAnalysisDispatcher(struct CompilationUnit *cUnit,
291                 void (*func)(struct CompilationUnit *, struct BasicBlock *));
292 void dvmCompilerStateRefresh(void);
293 JitTraceDescription *dvmCopyTraceDescriptor(const u2 *pc,
294                                             const struct JitEntry *desc);
295 void *dvmCompilerGetInterpretTemplate();
296 #endif /* _DALVIK_VM_COMPILER */