blob: 2a0eef46e012543951dd48558d3dc91704ac656e [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 COMPILER_WORK_QUEUE_SIZE 100
Ben Chengc3b92b22010-01-26 16:46:15 -080029#define COMPILER_IC_PATCH_QUEUE_SIZE 64
Ben Chengba4fc8b2009-06-01 13:00:29 -070030
Ben Chengb88ec3c2010-05-17 12:50:33 -070031/* 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
41
Ben Chengba4fc8b2009-06-01 13:00:29 -070042#define COMPILER_TRACED(X)
43#define COMPILER_TRACEE(X)
44#define COMPILER_TRACE_CHAINING(X)
45
Ben Chengb88ec3c2010-05-17 12:50:33 -070046/* Macro to change the permissions applied to a chunk of the code cache */
Ben Chengb88ec3c2010-05-17 12:50:33 -070047#define PROTECT_CODE_CACHE_ATTRS (PROT_READ | PROT_EXEC)
48#define UNPROTECT_CODE_CACHE_ATTRS (PROT_READ | PROT_EXEC | PROT_WRITE)
Ben Chengb88ec3c2010-05-17 12:50:33 -070049
50/* Acquire the lock before removing PROT_WRITE from the specified mem region */
51#define UNPROTECT_CODE_CACHE(addr, size) \
52 { \
53 dvmLockMutex(&gDvmJit.codeCacheProtectionLock); \
54 mprotect((void *) (((intptr_t) (addr)) & ~gDvmJit.pageSizeMask), \
55 (size) + (((intptr_t) (addr)) & gDvmJit.pageSizeMask), \
56 (UNPROTECT_CODE_CACHE_ATTRS)); \
57 }
58
59/* Add the PROT_WRITE to the specified memory region then release the lock */
60#define PROTECT_CODE_CACHE(addr, size) \
61 { \
62 mprotect((void *) (((intptr_t) (addr)) & ~gDvmJit.pageSizeMask), \
63 (size) + (((intptr_t) (addr)) & gDvmJit.pageSizeMask), \
64 (PROTECT_CODE_CACHE_ATTRS)); \
65 dvmUnlockMutex(&gDvmJit.codeCacheProtectionLock); \
66 }
67
Ben Cheng34dc7962010-08-26 14:56:31 -070068#define SINGLE_STEP_OP(opcode) \
69 (gDvmJit.includeSelectedOp != \
70 ((gDvmJit.opList[opcode >> 3] & (1 << (opcode & 0x7))) != 0))
71
Bill Buzbee716f1202009-07-23 13:22:09 -070072typedef enum JitInstructionSetType {
73 DALVIK_JIT_NONE = 0,
74 DALVIK_JIT_ARM,
75 DALVIK_JIT_THUMB,
76 DALVIK_JIT_THUMB2,
buzbee7520ee72010-09-17 16:01:49 -070077 DALVIK_JIT_IA32
Bill Buzbee716f1202009-07-23 13:22:09 -070078} JitInstructionSetType;
79
80/* Description of a compiled trace. */
81typedef struct JitTranslationInfo {
Ben Chengccd6c012009-10-15 14:52:45 -070082 void *codeAddress;
Bill Buzbee716f1202009-07-23 13:22:09 -070083 JitInstructionSetType instructionSet;
buzbee2e152ba2010-12-15 16:32:35 -080084 int profileCodeSize;
Ben Cheng60c24f42010-01-04 12:29:56 -080085 bool discardResult; // Used for debugging divergence and IC patching
Ben Cheng7a2697d2010-06-07 13:44:23 -070086 bool methodCompilationAborted; // Cannot compile the whole method
Ben Cheng33672452010-01-12 14:59:30 -080087 Thread *requestingThread; // For debugging purpose
buzbee18fba342011-01-19 15:31:15 -080088 int cacheVersion; // Used to identify stale trace requests
Bill Buzbee716f1202009-07-23 13:22:09 -070089} JitTranslationInfo;
90
Ben Chengba4fc8b2009-06-01 13:00:29 -070091typedef enum WorkOrderKind {
92 kWorkOrderInvalid = 0, // Should never see by the backend
93 kWorkOrderMethod = 1, // Work is to compile a whole method
94 kWorkOrderTrace = 2, // Work is to compile code fragment(s)
Ben Chengccd6c012009-10-15 14:52:45 -070095 kWorkOrderTraceDebug = 3, // Work is to compile/debug code fragment(s)
buzbee2e152ba2010-12-15 16:32:35 -080096 kWorkOrderProfileMode = 4, // Change profiling mode
Ben Chengba4fc8b2009-06-01 13:00:29 -070097} WorkOrderKind;
98
99typedef struct CompilerWorkOrder {
100 const u2* pc;
101 WorkOrderKind kind;
102 void* info;
Bill Buzbee716f1202009-07-23 13:22:09 -0700103 JitTranslationInfo result;
Bill Buzbeefc519dc2010-03-06 23:30:57 -0800104 jmp_buf *bailPtr;
Ben Chengba4fc8b2009-06-01 13:00:29 -0700105} CompilerWorkOrder;
106
Ben Chengc3b92b22010-01-26 16:46:15 -0800107/* Chain cell for predicted method invocation */
108typedef struct PredictedChainingCell {
109 u4 branch; /* Branch to chained destination */
Ben Chengb88ec3c2010-05-17 12:50:33 -0700110 const ClassObject *clazz; /* key for prediction */
111 const Method *method; /* to lookup native PC from dalvik PC */
112 const ClassObject *stagedClazz; /* possible next key for prediction */
Ben Chengc3b92b22010-01-26 16:46:15 -0800113} PredictedChainingCell;
114
115/* Work order for inline cache patching */
116typedef struct ICPatchWorkOrder {
117 PredictedChainingCell *cellAddr; /* Address to be patched */
118 PredictedChainingCell cellContent; /* content of the new cell */
Ben Cheng385828e2011-03-04 16:48:33 -0800119 const char *classDescriptor; /* Descriptor of the class object */
120 Object *classLoader; /* Class loader */
121 u4 serialNumber; /* Serial # (for verification only) */
Ben Chengc3b92b22010-01-26 16:46:15 -0800122} ICPatchWorkOrder;
123
Ben Chengba4fc8b2009-06-01 13:00:29 -0700124/*
125 * Trace description as will appear in the translation cache. Note
126 * flexible array at end, as these will be of variable size. To
127 * conserve space in the translation cache, total length of JitTraceRun
128 * array must be recomputed via seqential scan if needed.
129 */
130typedef struct {
131 const Method* method;
Ben Cheng7a2697d2010-06-07 13:44:23 -0700132 JitTraceRun trace[0]; // Variable-length trace descriptors
Ben Chengba4fc8b2009-06-01 13:00:29 -0700133} JitTraceDescription;
134
Ben Cheng7a2697d2010-06-07 13:44:23 -0700135typedef enum JitMethodAttributes {
136 kIsCallee = 0, /* Code is part of a callee (invoked by a hot trace) */
137 kIsHot, /* Code is part of a hot trace */
138 kIsLeaf, /* Method is leaf */
139 kIsEmpty, /* Method is empty */
140 kIsThrowFree, /* Method doesn't throw */
141 kIsGetter, /* Method fits the getter pattern */
142 kIsSetter, /* Method fits the setter pattern */
Ben Chengcfdeca32011-01-14 11:36:46 -0800143 kCannotCompile, /* Method cannot be compiled */
Ben Cheng7a2697d2010-06-07 13:44:23 -0700144} JitMethodAttributes;
145
146#define METHOD_IS_CALLEE (1 << kIsCallee)
147#define METHOD_IS_HOT (1 << kIsHot)
148#define METHOD_IS_LEAF (1 << kIsLeaf)
149#define METHOD_IS_EMPTY (1 << kIsEmpty)
150#define METHOD_IS_THROW_FREE (1 << kIsThrowFree)
151#define METHOD_IS_GETTER (1 << kIsGetter)
152#define METHOD_IS_SETTER (1 << kIsSetter)
Ben Chengcfdeca32011-01-14 11:36:46 -0800153#define METHOD_CANNOT_COMPILE (1 << kCannotCompile)
Ben Cheng7a2697d2010-06-07 13:44:23 -0700154
Ben Cheng4a419582010-08-04 13:23:09 -0700155/* Vectors to provide optimization hints */
156typedef enum JitOptimizationHints {
157 kJitOptNoLoop = 0, // Disable loop formation/optimization
158} JitOptimizationHints;
159
160#define JIT_OPT_NO_LOOP (1 << kJitOptNoLoop)
161
Ben Cheng00603072010-10-28 11:13:58 -0700162/* Customized node traversal orders for different needs */
163typedef enum DataFlowAnalysisMode {
164 kAllNodes = 0, // All nodes
165 kReachableNodes, // All reachable nodes
166 kPreOrderDFSTraversal, // Depth-First-Search / Pre-Order
167 kPostOrderDFSTraversal, // Depth-First-Search / Post-Order
168 kPostOrderDOMTraversal, // Dominator tree / Post-Order
169} DataFlowAnalysisMode;
170
Ben Cheng8b258bf2009-06-24 17:27:07 -0700171typedef struct CompilerMethodStats {
172 const Method *method; // Used as hash entry signature
173 int dalvikSize; // # of bytes for dalvik bytecodes
174 int compiledDalvikSize; // # of compiled dalvik bytecodes
175 int nativeSize; // # of bytes for produced native code
Ben Cheng7a2697d2010-06-07 13:44:23 -0700176 int attributes; // attribute vector
Ben Cheng8b258bf2009-06-24 17:27:07 -0700177} CompilerMethodStats;
178
Ben Cheng7a2697d2010-06-07 13:44:23 -0700179struct CompilationUnit;
180struct BasicBlock;
181struct SSARepresentation;
182struct GrowableList;
183struct JitEntry;
184struct MIR;
185
Ben Chengba4fc8b2009-06-01 13:00:29 -0700186bool dvmCompilerSetupCodeCache(void);
187bool dvmCompilerArchInit(void);
188void dvmCompilerArchDump(void);
189bool dvmCompilerStartup(void);
190void dvmCompilerShutdown(void);
Bill Buzbee1b3da592011-02-03 07:38:22 -0800191void dvmCompilerForceWorkEnqueue(const u2* pc, WorkOrderKind kind, void* info);
Ben Chengba4fc8b2009-06-01 13:00:29 -0700192bool dvmCompilerWorkEnqueue(const u2* pc, WorkOrderKind kind, void* info);
193void *dvmCheckCodeCache(void *method);
Ben Cheng7a2697d2010-06-07 13:44:23 -0700194CompilerMethodStats *dvmCompilerAnalyzeMethodBody(const Method *method,
195 bool isCallee);
196bool dvmCompilerCanIncludeThisInstruction(const Method *method,
197 const DecodedInstruction *insn);
Ben Chengcfdeca32011-01-14 11:36:46 -0800198bool dvmCompileMethod(const Method *method, JitTranslationInfo *info);
Bill Buzbee716f1202009-07-23 13:22:09 -0700199bool dvmCompileTrace(JitTraceDescription *trace, int numMaxInsts,
Ben Cheng4a419582010-08-04 13:23:09 -0700200 JitTranslationInfo *info, jmp_buf *bailPtr, int optHints);
Ben Chengba4fc8b2009-06-01 13:00:29 -0700201void dvmCompilerDumpStats(void);
202void dvmCompilerDrainQueue(void);
Bill Buzbee46cd5b62009-06-05 15:36:06 -0700203void dvmJitUnchainAll(void);
Ben Cheng385828e2011-03-04 16:48:33 -0800204void dvmJitScanAllClassPointers(void (*callback)(void *ptr));
Bill Buzbee716f1202009-07-23 13:22:09 -0700205void dvmCompilerSortAndPrintTraceProfiles(void);
Carl Shapiro3f349af2010-02-25 15:47:08 -0800206void dvmCompilerPerformSafePointChecks(void);
Ben Chengcfdeca32011-01-14 11:36:46 -0800207void dvmCompilerInlineMIR(struct CompilationUnit *cUnit,
208 JitTranslationInfo *info);
Ben Cheng4238ec22009-08-24 16:32:22 -0700209void dvmInitializeSSAConversion(struct CompilationUnit *cUnit);
Ben Cheng00603072010-10-28 11:13:58 -0700210int dvmConvertSSARegToDalvik(const struct CompilationUnit *cUnit, int ssaReg);
Ben Cheng4a419582010-08-04 13:23:09 -0700211bool dvmCompilerLoopOpt(struct CompilationUnit *cUnit);
Ben Cheng4238ec22009-08-24 16:32:22 -0700212void dvmCompilerNonLoopAnalysis(struct CompilationUnit *cUnit);
Ben Cheng00603072010-10-28 11:13:58 -0700213bool dvmCompilerFindLocalLiveIn(struct CompilationUnit *cUnit,
Ben Cheng4238ec22009-08-24 16:32:22 -0700214 struct BasicBlock *bb);
Ben Cheng00603072010-10-28 11:13:58 -0700215bool dvmCompilerDoSSAConversion(struct CompilationUnit *cUnit,
216 struct BasicBlock *bb);
217bool dvmCompilerDoConstantPropagation(struct CompilationUnit *cUnit,
Ben Cheng4238ec22009-08-24 16:32:22 -0700218 struct BasicBlock *bb);
Ben Cheng00603072010-10-28 11:13:58 -0700219bool dvmCompilerFindInductionVariables(struct CompilationUnit *cUnit,
Ben Cheng4238ec22009-08-24 16:32:22 -0700220 struct BasicBlock *bb);
Ben Cheng00603072010-10-28 11:13:58 -0700221/* Clear the visited flag for each BB */
222bool dvmCompilerClearVisitedFlag(struct CompilationUnit *cUnit,
223 struct BasicBlock *bb);
224char *dvmCompilerGetDalvikDisassembly(const DecodedInstruction *insn,
225 char *note);
226char *dvmCompilerFullDisassembler(const struct CompilationUnit *cUnit,
227 const struct MIR *mir);
Ben Cheng4238ec22009-08-24 16:32:22 -0700228char *dvmCompilerGetSSAString(struct CompilationUnit *cUnit,
229 struct SSARepresentation *ssaRep);
230void dvmCompilerDataFlowAnalysisDispatcher(struct CompilationUnit *cUnit,
Ben Cheng00603072010-10-28 11:13:58 -0700231 bool (*func)(struct CompilationUnit *, struct BasicBlock *),
232 DataFlowAnalysisMode dfaMode,
233 bool isIterative);
234void dvmCompilerMethodSSATransformation(struct CompilationUnit *cUnit);
Bill Buzbee06bb8392010-01-31 18:53:15 -0800235void dvmCompilerStateRefresh(void);
Ben Cheng88a0f972010-02-24 15:00:40 -0800236JitTraceDescription *dvmCopyTraceDescriptor(const u2 *pc,
237 const struct JitEntry *desc);
Bill Buzbeebd047242010-05-13 13:02:53 -0700238void *dvmCompilerGetInterpretTemplate();
Bill Buzbee1b3da592011-02-03 07:38:22 -0800239JitInstructionSetType dvmCompilerGetInterpretTemplateSet();
Ben Chengd72564c2011-02-08 17:09:25 -0800240u8 dvmGetRegResourceMask(int reg);
Ben Chengba4fc8b2009-06-01 13:00:29 -0700241#endif /* _DALVIK_VM_COMPILER */