blob: b0ad7b4a542f3921297cbdd8fa31fd9a6183fd19 [file] [log] [blame]
Ben Chengba4fc8b2009-06-01 13:00:29 -07001/*
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
Ben Cheng33672452010-01-12 14:59:30 -080017#include <Thread.h>
Bill Buzbeefc519dc2010-03-06 23:30:57 -080018#include <setjmp.h>
Ben Cheng33672452010-01-12 14:59:30 -080019
Ben Chengba4fc8b2009-06-01 13:00:29 -070020#ifndef _DALVIK_VM_COMPILER
21#define _DALVIK_VM_COMPILER
22
Ben Chengdca71432010-03-16 16:04:11 -070023/*
24 * Uncomment the following to enable JIT signature breakpoint
25 * #define SIGNATURE_BREAKPOINT
26 */
27
Ben Chengba4fc8b2009-06-01 13:00:29 -070028#define MAX_JIT_RUN_LEN 64
29#define COMPILER_WORK_QUEUE_SIZE 100
Ben Chengc3b92b22010-01-26 16:46:15 -080030#define COMPILER_IC_PATCH_QUEUE_SIZE 64
Ben Chengba4fc8b2009-06-01 13:00:29 -070031
Ben Chengb88ec3c2010-05-17 12:50:33 -070032/* 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
Ben Chengba4fc8b2009-06-01 13:00:29 -070043#define COMPILER_TRACED(X)
44#define COMPILER_TRACEE(X)
45#define COMPILER_TRACE_CHAINING(X)
46
Ben Chengb88ec3c2010-05-17 12:50:33 -070047/* Macro to change the permissions applied to a chunk of the code cache */
Ben Chengb88ec3c2010-05-17 12:50:33 -070048#define PROTECT_CODE_CACHE_ATTRS (PROT_READ | PROT_EXEC)
49#define UNPROTECT_CODE_CACHE_ATTRS (PROT_READ | PROT_EXEC | PROT_WRITE)
Ben Chengb88ec3c2010-05-17 12:50:33 -070050
51/* Acquire the lock before removing PROT_WRITE from the specified mem region */
52#define UNPROTECT_CODE_CACHE(addr, size) \
53 { \
54 dvmLockMutex(&gDvmJit.codeCacheProtectionLock); \
55 mprotect((void *) (((intptr_t) (addr)) & ~gDvmJit.pageSizeMask), \
56 (size) + (((intptr_t) (addr)) & gDvmJit.pageSizeMask), \
57 (UNPROTECT_CODE_CACHE_ATTRS)); \
58 }
59
60/* Add the PROT_WRITE to the specified memory region then release the lock */
61#define PROTECT_CODE_CACHE(addr, size) \
62 { \
63 mprotect((void *) (((intptr_t) (addr)) & ~gDvmJit.pageSizeMask), \
64 (size) + (((intptr_t) (addr)) & gDvmJit.pageSizeMask), \
65 (PROTECT_CODE_CACHE_ATTRS)); \
66 dvmUnlockMutex(&gDvmJit.codeCacheProtectionLock); \
67 }
68
Ben Cheng34dc7962010-08-26 14:56:31 -070069#define SINGLE_STEP_OP(opcode) \
70 (gDvmJit.includeSelectedOp != \
71 ((gDvmJit.opList[opcode >> 3] & (1 << (opcode & 0x7))) != 0))
72
Bill Buzbee716f1202009-07-23 13:22:09 -070073typedef enum JitInstructionSetType {
74 DALVIK_JIT_NONE = 0,
75 DALVIK_JIT_ARM,
76 DALVIK_JIT_THUMB,
77 DALVIK_JIT_THUMB2,
Bill Buzbee9bc3df32009-07-30 10:52:29 -070078 DALVIK_JIT_THUMB2EE,
buzbee7520ee72010-09-17 16:01:49 -070079 DALVIK_JIT_IA32
Bill Buzbee716f1202009-07-23 13:22:09 -070080} JitInstructionSetType;
81
82/* Description of a compiled trace. */
83typedef struct JitTranslationInfo {
Ben Chengccd6c012009-10-15 14:52:45 -070084 void *codeAddress;
Bill Buzbee716f1202009-07-23 13:22:09 -070085 JitInstructionSetType instructionSet;
buzbee2e152ba2010-12-15 16:32:35 -080086 int profileCodeSize;
Ben Cheng60c24f42010-01-04 12:29:56 -080087 bool discardResult; // Used for debugging divergence and IC patching
Ben Cheng7a2697d2010-06-07 13:44:23 -070088 bool methodCompilationAborted; // Cannot compile the whole method
Ben Cheng33672452010-01-12 14:59:30 -080089 Thread *requestingThread; // For debugging purpose
buzbee18fba342011-01-19 15:31:15 -080090 int cacheVersion; // Used to identify stale trace requests
Bill Buzbee716f1202009-07-23 13:22:09 -070091} JitTranslationInfo;
92
Ben Chengba4fc8b2009-06-01 13:00:29 -070093typedef enum WorkOrderKind {
94 kWorkOrderInvalid = 0, // Should never see by the backend
95 kWorkOrderMethod = 1, // Work is to compile a whole method
96 kWorkOrderTrace = 2, // Work is to compile code fragment(s)
Ben Chengccd6c012009-10-15 14:52:45 -070097 kWorkOrderTraceDebug = 3, // Work is to compile/debug code fragment(s)
buzbee2e152ba2010-12-15 16:32:35 -080098 kWorkOrderProfileMode = 4, // Change profiling mode
Ben Chengba4fc8b2009-06-01 13:00:29 -070099} WorkOrderKind;
100
101typedef struct CompilerWorkOrder {
102 const u2* pc;
103 WorkOrderKind kind;
104 void* info;
Bill Buzbee716f1202009-07-23 13:22:09 -0700105 JitTranslationInfo result;
Bill Buzbeefc519dc2010-03-06 23:30:57 -0800106 jmp_buf *bailPtr;
Ben Chengba4fc8b2009-06-01 13:00:29 -0700107} CompilerWorkOrder;
108
Ben Chengc3b92b22010-01-26 16:46:15 -0800109/* Chain cell for predicted method invocation */
110typedef struct PredictedChainingCell {
111 u4 branch; /* Branch to chained destination */
Ben Chengb88ec3c2010-05-17 12:50:33 -0700112 const ClassObject *clazz; /* key for prediction */
113 const Method *method; /* to lookup native PC from dalvik PC */
114 const ClassObject *stagedClazz; /* possible next key for prediction */
Ben Chengc3b92b22010-01-26 16:46:15 -0800115} PredictedChainingCell;
116
117/* Work order for inline cache patching */
118typedef struct ICPatchWorkOrder {
119 PredictedChainingCell *cellAddr; /* Address to be patched */
120 PredictedChainingCell cellContent; /* content of the new cell */
121} ICPatchWorkOrder;
122
Ben Chenga4973592010-03-31 11:59:18 -0700123/* States of the dbg interpreter when serving a JIT-related request */
Ben Chengba4fc8b2009-06-01 13:00:29 -0700124typedef enum JitState {
Ben Chenga4973592010-03-31 11:59:18 -0700125 /* Entering states in the debug interpreter */
126 kJitNot = 0, // Non-JIT related reasons */
127 kJitTSelectRequest = 1, // Request a trace (subject to filtering)
128 kJitTSelectRequestHot = 2, // Request a hot trace (bypass the filter)
129 kJitSelfVerification = 3, // Self Verification Mode
130
131 /* Operational states in the debug interpreter */
132 kJitTSelect = 4, // Actively selecting a trace
133 kJitTSelectEnd = 5, // Done with the trace - wrap it up
134 kJitSingleStep = 6, // Single step interpretation
135 kJitSingleStepEnd = 7, // Done with single step, ready return to mterp
136 kJitDone = 8, // Ready to leave the debug interpreter
Ben Chengba4fc8b2009-06-01 13:00:29 -0700137} JitState;
138
Jeff Hao97319a82009-08-12 16:57:15 -0700139#if defined(WITH_SELF_VERIFICATION)
140typedef enum SelfVerificationState {
141 kSVSIdle = 0, // Idle
142 kSVSStart = 1, // Shadow space set up, running compiled code
143 kSVSPunt = 2, // Exiting compiled code by punting
144 kSVSSingleStep = 3, // Exiting compiled code by single stepping
Ben Cheng7a2697d2010-06-07 13:44:23 -0700145 kSVSNoProfile = 4, // Exiting compiled code and don't collect profiles
146 kSVSTraceSelect = 5, // Exiting compiled code and compile the next pc
Ben Cheng40094c12010-02-24 20:58:44 -0800147 kSVSNormal = 6, // Exiting compiled code normally
148 kSVSNoChain = 7, // Exiting compiled code by no chain
149 kSVSBackwardBranch = 8, // Exiting compiled code with backward branch trace
150 kSVSDebugInterp = 9, // Normal state restored, running debug interpreter
Jeff Hao97319a82009-08-12 16:57:15 -0700151} SelfVerificationState;
152#endif
153
Ben Chengba4fc8b2009-06-01 13:00:29 -0700154typedef enum JitHint {
155 kJitHintNone = 0,
156 kJitHintTaken = 1, // Last inst in run was taken branch
157 kJitHintNotTaken = 2, // Last inst in run was not taken branch
158 kJitHintNoBias = 3, // Last inst in run was unbiased branch
159} jitHint;
160
161/*
Ben Cheng7a2697d2010-06-07 13:44:23 -0700162 * Element of a Jit trace description. If the isCode bit is set, it describes
163 * a contiguous sequence of Dalvik byte codes.
Ben Chengba4fc8b2009-06-01 13:00:29 -0700164 */
165typedef struct {
Ben Cheng7a2697d2010-06-07 13:44:23 -0700166 unsigned isCode:1; // If set denotes code fragments
Ben Chengba4fc8b2009-06-01 13:00:29 -0700167 unsigned numInsts:8; // Number of Byte codes in run
168 unsigned runEnd:1; // Run ends with last byte code
Ben Cheng7a2697d2010-06-07 13:44:23 -0700169 jitHint hint:6; // Hint to apply to final code of run
170 u2 startOffset; // Starting offset for trace run
Ben Chengba4fc8b2009-06-01 13:00:29 -0700171} JitCodeDesc;
172
Ben Cheng7a2697d2010-06-07 13:44:23 -0700173/*
174 * A complete list of trace runs passed to the compiler looks like the
175 * following:
176 * frag1
177 * frag2
178 * frag3
179 * meta1
180 * meta2
181 * frag4
182 *
183 * frags 1-4 have the "isCode" field set, and metas 1-2 are plain pointers or
184 * pointers to auxiliary data structures as long as the LSB is null.
185 * The meaning of the meta content is loosely defined. It is usually the code
186 * fragment right before the first meta field (frag3 in this case) to
187 * understand and parse them. Frag4 could be a dummy one with 0 "numInsts" but
188 * the "runEnd" field set.
189 *
190 * For example, if a trace run contains a method inlining target, the class
191 * type of "this" and the currently resolved method pointer are two instances
192 * of meta information stored there.
193 */
Ben Chengba4fc8b2009-06-01 13:00:29 -0700194typedef union {
195 JitCodeDesc frag;
Ben Cheng7a2697d2010-06-07 13:44:23 -0700196 void* meta;
Ben Chengba4fc8b2009-06-01 13:00:29 -0700197} JitTraceRun;
198
199/*
200 * Trace description as will appear in the translation cache. Note
201 * flexible array at end, as these will be of variable size. To
202 * conserve space in the translation cache, total length of JitTraceRun
203 * array must be recomputed via seqential scan if needed.
204 */
205typedef struct {
206 const Method* method;
Ben Cheng7a2697d2010-06-07 13:44:23 -0700207 JitTraceRun trace[0]; // Variable-length trace descriptors
Ben Chengba4fc8b2009-06-01 13:00:29 -0700208} JitTraceDescription;
209
Ben Cheng7a2697d2010-06-07 13:44:23 -0700210typedef enum JitMethodAttributes {
211 kIsCallee = 0, /* Code is part of a callee (invoked by a hot trace) */
212 kIsHot, /* Code is part of a hot trace */
213 kIsLeaf, /* Method is leaf */
214 kIsEmpty, /* Method is empty */
215 kIsThrowFree, /* Method doesn't throw */
216 kIsGetter, /* Method fits the getter pattern */
217 kIsSetter, /* Method fits the setter pattern */
Ben Chengcfdeca32011-01-14 11:36:46 -0800218 kCannotCompile, /* Method cannot be compiled */
Ben Cheng7a2697d2010-06-07 13:44:23 -0700219} JitMethodAttributes;
220
221#define METHOD_IS_CALLEE (1 << kIsCallee)
222#define METHOD_IS_HOT (1 << kIsHot)
223#define METHOD_IS_LEAF (1 << kIsLeaf)
224#define METHOD_IS_EMPTY (1 << kIsEmpty)
225#define METHOD_IS_THROW_FREE (1 << kIsThrowFree)
226#define METHOD_IS_GETTER (1 << kIsGetter)
227#define METHOD_IS_SETTER (1 << kIsSetter)
Ben Chengcfdeca32011-01-14 11:36:46 -0800228#define METHOD_CANNOT_COMPILE (1 << kCannotCompile)
Ben Cheng7a2697d2010-06-07 13:44:23 -0700229
Ben Cheng4a419582010-08-04 13:23:09 -0700230/* Vectors to provide optimization hints */
231typedef enum JitOptimizationHints {
232 kJitOptNoLoop = 0, // Disable loop formation/optimization
233} JitOptimizationHints;
234
235#define JIT_OPT_NO_LOOP (1 << kJitOptNoLoop)
236
Ben Cheng00603072010-10-28 11:13:58 -0700237/* Customized node traversal orders for different needs */
238typedef enum DataFlowAnalysisMode {
239 kAllNodes = 0, // All nodes
240 kReachableNodes, // All reachable nodes
241 kPreOrderDFSTraversal, // Depth-First-Search / Pre-Order
242 kPostOrderDFSTraversal, // Depth-First-Search / Post-Order
243 kPostOrderDOMTraversal, // Dominator tree / Post-Order
244} DataFlowAnalysisMode;
245
Ben Cheng8b258bf2009-06-24 17:27:07 -0700246typedef struct CompilerMethodStats {
247 const Method *method; // Used as hash entry signature
248 int dalvikSize; // # of bytes for dalvik bytecodes
249 int compiledDalvikSize; // # of compiled dalvik bytecodes
250 int nativeSize; // # of bytes for produced native code
Ben Cheng7a2697d2010-06-07 13:44:23 -0700251 int attributes; // attribute vector
Ben Cheng8b258bf2009-06-24 17:27:07 -0700252} CompilerMethodStats;
253
Ben Cheng7a2697d2010-06-07 13:44:23 -0700254struct CompilationUnit;
255struct BasicBlock;
256struct SSARepresentation;
257struct GrowableList;
258struct JitEntry;
259struct MIR;
260
Ben Chengba4fc8b2009-06-01 13:00:29 -0700261bool dvmCompilerSetupCodeCache(void);
262bool dvmCompilerArchInit(void);
263void dvmCompilerArchDump(void);
264bool dvmCompilerStartup(void);
265void dvmCompilerShutdown(void);
266bool dvmCompilerWorkEnqueue(const u2* pc, WorkOrderKind kind, void* info);
267void *dvmCheckCodeCache(void *method);
Ben Cheng7a2697d2010-06-07 13:44:23 -0700268CompilerMethodStats *dvmCompilerAnalyzeMethodBody(const Method *method,
269 bool isCallee);
270bool dvmCompilerCanIncludeThisInstruction(const Method *method,
271 const DecodedInstruction *insn);
Ben Chengcfdeca32011-01-14 11:36:46 -0800272bool dvmCompileMethod(const Method *method, JitTranslationInfo *info);
Bill Buzbee716f1202009-07-23 13:22:09 -0700273bool dvmCompileTrace(JitTraceDescription *trace, int numMaxInsts,
Ben Cheng4a419582010-08-04 13:23:09 -0700274 JitTranslationInfo *info, jmp_buf *bailPtr, int optHints);
Ben Chengba4fc8b2009-06-01 13:00:29 -0700275void dvmCompilerDumpStats(void);
276void dvmCompilerDrainQueue(void);
Bill Buzbee46cd5b62009-06-05 15:36:06 -0700277void dvmJitUnchainAll(void);
Bill Buzbee716f1202009-07-23 13:22:09 -0700278void dvmCompilerSortAndPrintTraceProfiles(void);
Carl Shapiro3f349af2010-02-25 15:47:08 -0800279void dvmCompilerPerformSafePointChecks(void);
Ben Chengcfdeca32011-01-14 11:36:46 -0800280void dvmCompilerInlineMIR(struct CompilationUnit *cUnit,
281 JitTranslationInfo *info);
Ben Cheng4238ec22009-08-24 16:32:22 -0700282void dvmInitializeSSAConversion(struct CompilationUnit *cUnit);
Ben Cheng00603072010-10-28 11:13:58 -0700283int dvmConvertSSARegToDalvik(const struct CompilationUnit *cUnit, int ssaReg);
Ben Cheng4a419582010-08-04 13:23:09 -0700284bool dvmCompilerLoopOpt(struct CompilationUnit *cUnit);
Ben Cheng4238ec22009-08-24 16:32:22 -0700285void dvmCompilerNonLoopAnalysis(struct CompilationUnit *cUnit);
Ben Cheng00603072010-10-28 11:13:58 -0700286bool dvmCompilerFindLocalLiveIn(struct CompilationUnit *cUnit,
Ben Cheng4238ec22009-08-24 16:32:22 -0700287 struct BasicBlock *bb);
Ben Cheng00603072010-10-28 11:13:58 -0700288bool dvmCompilerDoSSAConversion(struct CompilationUnit *cUnit,
289 struct BasicBlock *bb);
290bool dvmCompilerDoConstantPropagation(struct CompilationUnit *cUnit,
Ben Cheng4238ec22009-08-24 16:32:22 -0700291 struct BasicBlock *bb);
Ben Cheng00603072010-10-28 11:13:58 -0700292bool dvmCompilerFindInductionVariables(struct CompilationUnit *cUnit,
Ben Cheng4238ec22009-08-24 16:32:22 -0700293 struct BasicBlock *bb);
Ben Cheng00603072010-10-28 11:13:58 -0700294/* Clear the visited flag for each BB */
295bool dvmCompilerClearVisitedFlag(struct CompilationUnit *cUnit,
296 struct BasicBlock *bb);
297char *dvmCompilerGetDalvikDisassembly(const DecodedInstruction *insn,
298 char *note);
299char *dvmCompilerFullDisassembler(const struct CompilationUnit *cUnit,
300 const struct MIR *mir);
Ben Cheng4238ec22009-08-24 16:32:22 -0700301char *dvmCompilerGetSSAString(struct CompilationUnit *cUnit,
302 struct SSARepresentation *ssaRep);
303void dvmCompilerDataFlowAnalysisDispatcher(struct CompilationUnit *cUnit,
Ben Cheng00603072010-10-28 11:13:58 -0700304 bool (*func)(struct CompilationUnit *, struct BasicBlock *),
305 DataFlowAnalysisMode dfaMode,
306 bool isIterative);
307void dvmCompilerMethodSSATransformation(struct CompilationUnit *cUnit);
Bill Buzbee06bb8392010-01-31 18:53:15 -0800308void dvmCompilerStateRefresh(void);
Ben Cheng88a0f972010-02-24 15:00:40 -0800309JitTraceDescription *dvmCopyTraceDescriptor(const u2 *pc,
310 const struct JitEntry *desc);
Bill Buzbeebd047242010-05-13 13:02:53 -0700311void *dvmCompilerGetInterpretTemplate();
Ben Chengba4fc8b2009-06-01 13:00:29 -0700312#endif /* _DALVIK_VM_COMPILER */