2 * Copyright (C) 2009 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 #ifndef DALVIK_VM_COMPILER_H_
18 #define DALVIK_VM_COMPILER_H_
24 * Uncomment the following to enable JIT signature breakpoint
25 * #define SIGNATURE_BREAKPOINT
28 #define COMPILER_WORK_QUEUE_SIZE 100
29 #define COMPILER_IC_PATCH_QUEUE_SIZE 64
31 /* Architectural-independent parameters for predicted chains */
32 #define PREDICTED_CHAIN_CLAZZ_INIT 0
33 #define PREDICTED_CHAIN_METHOD_INIT 0
34 #define PREDICTED_CHAIN_COUNTER_INIT 0
35 /* A fake value which will avoid initialization and won't match any class */
36 #define PREDICTED_CHAIN_FAKE_CLAZZ 0xdeadc001
37 /* Has to be positive */
38 #define PREDICTED_CHAIN_COUNTER_AVOID 0x7fffffff
39 /* Rechain after this many misses - shared globally and has to be positive */
40 #define PREDICTED_CHAIN_COUNTER_RECHAIN 8192
42 #define COMPILER_TRACED(X)
43 #define COMPILER_TRACEE(X)
44 #define COMPILER_TRACE_CHAINING(X)
46 /* Macro to change the permissions applied to a chunk of the code cache */
47 #define PROTECT_CODE_CACHE_ATTRS (PROT_READ | PROT_EXEC)
48 #define UNPROTECT_CODE_CACHE_ATTRS (PROT_READ | PROT_EXEC | PROT_WRITE)
50 /* Acquire the lock before removing PROT_WRITE from the specified mem region */
51 #define UNPROTECT_CODE_CACHE(addr, size) \
53 dvmLockMutex(&gDvmJit.codeCacheProtectionLock); \
54 mprotect((void *) (((intptr_t) (addr)) & ~gDvmJit.pageSizeMask), \
55 (size) + (((intptr_t) (addr)) & gDvmJit.pageSizeMask), \
56 (UNPROTECT_CODE_CACHE_ATTRS)); \
59 /* Add the PROT_WRITE to the specified memory region then release the lock */
60 #define PROTECT_CODE_CACHE(addr, size) \
62 mprotect((void *) (((intptr_t) (addr)) & ~gDvmJit.pageSizeMask), \
63 (size) + (((intptr_t) (addr)) & gDvmJit.pageSizeMask), \
64 (PROTECT_CODE_CACHE_ATTRS)); \
65 dvmUnlockMutex(&gDvmJit.codeCacheProtectionLock); \
68 #define SINGLE_STEP_OP(opcode) \
69 (gDvmJit.includeSelectedOp != \
70 ((gDvmJit.opList[opcode >> 3] & (1 << (opcode & 0x7))) != 0))
72 typedef enum JitInstructionSetType {
79 } JitInstructionSetType;
81 /* Description of a compiled trace. */
82 typedef struct JitTranslationInfo {
84 JitInstructionSetType instructionSet;
86 bool discardResult; // Used for debugging divergence and IC patching
87 bool methodCompilationAborted; // Cannot compile the whole method
88 Thread *requestingThread; // For debugging purpose
89 int cacheVersion; // Used to identify stale trace requests
92 typedef enum WorkOrderKind {
93 kWorkOrderInvalid = 0, // Should never see by the backend
94 kWorkOrderMethod = 1, // Work is to compile a whole method
95 kWorkOrderTrace = 2, // Work is to compile code fragment(s)
96 kWorkOrderTraceDebug = 3, // Work is to compile/debug code fragment(s)
97 kWorkOrderProfileMode = 4, // Change profiling mode
100 typedef struct CompilerWorkOrder {
104 JitTranslationInfo result;
108 /* Chain cell for predicted method invocation */
109 typedef struct PredictedChainingCell {
110 u4 branch; /* Branch to chained destination */
112 u4 delay_slot; /* nop goes here */
114 const ClassObject *clazz; /* key for prediction */
115 const Method *method; /* to lookup native PC from dalvik PC */
116 const ClassObject *stagedClazz; /* possible next key for prediction */
117 } PredictedChainingCell;
119 /* Work order for inline cache patching */
120 typedef struct ICPatchWorkOrder {
121 PredictedChainingCell *cellAddr; /* Address to be patched */
122 PredictedChainingCell cellContent; /* content of the new cell */
123 const char *classDescriptor; /* Descriptor of the class object */
124 Object *classLoader; /* Class loader */
125 u4 serialNumber; /* Serial # (for verification only) */
129 * Trace description as will appear in the translation cache. Note
130 * flexible array at end, as these will be of variable size. To
131 * conserve space in the translation cache, total length of JitTraceRun
132 * array must be recomputed via seqential scan if needed.
135 const Method* method;
136 JitTraceRun trace[0]; // Variable-length trace descriptors
137 } JitTraceDescription;
139 typedef enum JitMethodAttributes {
140 kIsCallee = 0, /* Code is part of a callee (invoked by a hot trace) */
141 kIsHot, /* Code is part of a hot trace */
142 kIsLeaf, /* Method is leaf */
143 kIsEmpty, /* Method is empty */
144 kIsThrowFree, /* Method doesn't throw */
145 kIsGetter, /* Method fits the getter pattern */
146 kIsSetter, /* Method fits the setter pattern */
147 kCannotCompile, /* Method cannot be compiled */
148 } JitMethodAttributes;
150 #define METHOD_IS_CALLEE (1 << kIsCallee)
151 #define METHOD_IS_HOT (1 << kIsHot)
152 #define METHOD_IS_LEAF (1 << kIsLeaf)
153 #define METHOD_IS_EMPTY (1 << kIsEmpty)
154 #define METHOD_IS_THROW_FREE (1 << kIsThrowFree)
155 #define METHOD_IS_GETTER (1 << kIsGetter)
156 #define METHOD_IS_SETTER (1 << kIsSetter)
157 #define METHOD_CANNOT_COMPILE (1 << kCannotCompile)
159 /* Vectors to provide optimization hints */
160 typedef enum JitOptimizationHints {
161 kJitOptNoLoop = 0, // Disable loop formation/optimization
162 } JitOptimizationHints;
164 #define JIT_OPT_NO_LOOP (1 << kJitOptNoLoop)
166 /* Customized node traversal orders for different needs */
167 typedef enum DataFlowAnalysisMode {
168 kAllNodes = 0, // All nodes
169 kReachableNodes, // All reachable nodes
170 kPreOrderDFSTraversal, // Depth-First-Search / Pre-Order
171 kPostOrderDFSTraversal, // Depth-First-Search / Post-Order
172 kPostOrderDOMTraversal, // Dominator tree / Post-Order
173 } DataFlowAnalysisMode;
175 typedef struct CompilerMethodStats {
176 const Method *method; // Used as hash entry signature
177 int dalvikSize; // # of bytes for dalvik bytecodes
178 int compiledDalvikSize; // # of compiled dalvik bytecodes
179 int nativeSize; // # of bytes for produced native code
180 int attributes; // attribute vector
181 } CompilerMethodStats;
183 struct CompilationUnit;
185 struct SSARepresentation;
190 bool dvmCompilerSetupCodeCache(void);
191 bool dvmCompilerArchInit(void);
192 void dvmCompilerArchDump(void);
193 bool dvmCompilerStartup(void);
194 void dvmCompilerShutdown(void);
195 void dvmCompilerForceWorkEnqueue(const u2* pc, WorkOrderKind kind, void* info);
196 bool dvmCompilerWorkEnqueue(const u2* pc, WorkOrderKind kind, void* info);
197 void *dvmCheckCodeCache(void *method);
198 CompilerMethodStats *dvmCompilerAnalyzeMethodBody(const Method *method,
200 bool dvmCompilerCanIncludeThisInstruction(const Method *method,
201 const DecodedInstruction *insn);
202 bool dvmCompileMethod(const Method *method, JitTranslationInfo *info);
203 bool dvmCompileTrace(JitTraceDescription *trace, int numMaxInsts,
204 JitTranslationInfo *info, jmp_buf *bailPtr, int optHints);
205 void dvmCompilerDumpStats(void);
206 void dvmCompilerDrainQueue(void);
207 void dvmJitUnchainAll(void);
208 void dvmJitScanAllClassPointers(void (*callback)(void *ptr));
209 void dvmCompilerSortAndPrintTraceProfiles(void);
210 void dvmCompilerPerformSafePointChecks(void);
211 void dvmCompilerInlineMIR(struct CompilationUnit *cUnit,
212 JitTranslationInfo *info);
213 void dvmInitializeSSAConversion(struct CompilationUnit *cUnit);
214 int dvmConvertSSARegToDalvik(const struct CompilationUnit *cUnit, int ssaReg);
215 bool dvmCompilerLoopOpt(struct CompilationUnit *cUnit);
216 void dvmCompilerInsertBackwardChaining(struct CompilationUnit *cUnit);
217 void dvmCompilerNonLoopAnalysis(struct CompilationUnit *cUnit);
218 bool dvmCompilerFindLocalLiveIn(struct CompilationUnit *cUnit,
219 struct BasicBlock *bb);
220 bool dvmCompilerDoSSAConversion(struct CompilationUnit *cUnit,
221 struct BasicBlock *bb);
222 bool dvmCompilerDoConstantPropagation(struct CompilationUnit *cUnit,
223 struct BasicBlock *bb);
224 bool dvmCompilerFindInductionVariables(struct CompilationUnit *cUnit,
225 struct BasicBlock *bb);
226 /* Clear the visited flag for each BB */
227 bool dvmCompilerClearVisitedFlag(struct CompilationUnit *cUnit,
228 struct BasicBlock *bb);
229 char *dvmCompilerGetDalvikDisassembly(const DecodedInstruction *insn,
231 char *dvmCompilerFullDisassembler(const struct CompilationUnit *cUnit,
232 const struct MIR *mir);
233 char *dvmCompilerGetSSAString(struct CompilationUnit *cUnit,
234 struct SSARepresentation *ssaRep);
235 void dvmCompilerDataFlowAnalysisDispatcher(struct CompilationUnit *cUnit,
236 bool (*func)(struct CompilationUnit *, struct BasicBlock *),
237 DataFlowAnalysisMode dfaMode,
239 void dvmCompilerMethodSSATransformation(struct CompilationUnit *cUnit);
240 bool dvmCompilerBuildLoop(struct CompilationUnit *cUnit);
241 void dvmCompilerUpdateGlobalState(void);
242 JitTraceDescription *dvmCopyTraceDescriptor(const u2 *pc,
243 const struct JitEntry *desc);
244 extern "C" void *dvmCompilerGetInterpretTemplate();
245 JitInstructionSetType dvmCompilerGetInterpretTemplateSet();
246 u8 dvmGetRegResourceMask(int reg);
247 void dvmDumpCFG(struct CompilationUnit *cUnit, const char *dirPrefix);
249 #endif // DALVIK_VM_COMPILER_H_