blob: c566aa6c48e4df8a13199f0955472bae6bcada62 [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 */
119} ICPatchWorkOrder;
120
Ben Chengba4fc8b2009-06-01 13:00:29 -0700121/*
122 * Trace description as will appear in the translation cache. Note
123 * flexible array at end, as these will be of variable size. To
124 * conserve space in the translation cache, total length of JitTraceRun
125 * array must be recomputed via seqential scan if needed.
126 */
127typedef struct {
128 const Method* method;
Ben Cheng7a2697d2010-06-07 13:44:23 -0700129 JitTraceRun trace[0]; // Variable-length trace descriptors
Ben Chengba4fc8b2009-06-01 13:00:29 -0700130} JitTraceDescription;
131
Ben Cheng7a2697d2010-06-07 13:44:23 -0700132typedef enum JitMethodAttributes {
133 kIsCallee = 0, /* Code is part of a callee (invoked by a hot trace) */
134 kIsHot, /* Code is part of a hot trace */
135 kIsLeaf, /* Method is leaf */
136 kIsEmpty, /* Method is empty */
137 kIsThrowFree, /* Method doesn't throw */
138 kIsGetter, /* Method fits the getter pattern */
139 kIsSetter, /* Method fits the setter pattern */
Ben Chengcfdeca32011-01-14 11:36:46 -0800140 kCannotCompile, /* Method cannot be compiled */
Ben Cheng7a2697d2010-06-07 13:44:23 -0700141} JitMethodAttributes;
142
143#define METHOD_IS_CALLEE (1 << kIsCallee)
144#define METHOD_IS_HOT (1 << kIsHot)
145#define METHOD_IS_LEAF (1 << kIsLeaf)
146#define METHOD_IS_EMPTY (1 << kIsEmpty)
147#define METHOD_IS_THROW_FREE (1 << kIsThrowFree)
148#define METHOD_IS_GETTER (1 << kIsGetter)
149#define METHOD_IS_SETTER (1 << kIsSetter)
Ben Chengcfdeca32011-01-14 11:36:46 -0800150#define METHOD_CANNOT_COMPILE (1 << kCannotCompile)
Ben Cheng7a2697d2010-06-07 13:44:23 -0700151
Ben Cheng4a419582010-08-04 13:23:09 -0700152/* Vectors to provide optimization hints */
153typedef enum JitOptimizationHints {
154 kJitOptNoLoop = 0, // Disable loop formation/optimization
155} JitOptimizationHints;
156
157#define JIT_OPT_NO_LOOP (1 << kJitOptNoLoop)
158
Ben Cheng00603072010-10-28 11:13:58 -0700159/* Customized node traversal orders for different needs */
160typedef enum DataFlowAnalysisMode {
161 kAllNodes = 0, // All nodes
162 kReachableNodes, // All reachable nodes
163 kPreOrderDFSTraversal, // Depth-First-Search / Pre-Order
164 kPostOrderDFSTraversal, // Depth-First-Search / Post-Order
165 kPostOrderDOMTraversal, // Dominator tree / Post-Order
166} DataFlowAnalysisMode;
167
Ben Cheng8b258bf2009-06-24 17:27:07 -0700168typedef struct CompilerMethodStats {
169 const Method *method; // Used as hash entry signature
170 int dalvikSize; // # of bytes for dalvik bytecodes
171 int compiledDalvikSize; // # of compiled dalvik bytecodes
172 int nativeSize; // # of bytes for produced native code
Ben Cheng7a2697d2010-06-07 13:44:23 -0700173 int attributes; // attribute vector
Ben Cheng8b258bf2009-06-24 17:27:07 -0700174} CompilerMethodStats;
175
Ben Cheng7a2697d2010-06-07 13:44:23 -0700176struct CompilationUnit;
177struct BasicBlock;
178struct SSARepresentation;
179struct GrowableList;
180struct JitEntry;
181struct MIR;
182
Ben Chengba4fc8b2009-06-01 13:00:29 -0700183bool dvmCompilerSetupCodeCache(void);
184bool dvmCompilerArchInit(void);
185void dvmCompilerArchDump(void);
186bool dvmCompilerStartup(void);
187void dvmCompilerShutdown(void);
Bill Buzbee1b3da592011-02-03 07:38:22 -0800188void dvmCompilerForceWorkEnqueue(const u2* pc, WorkOrderKind kind, void* info);
Ben Chengba4fc8b2009-06-01 13:00:29 -0700189bool dvmCompilerWorkEnqueue(const u2* pc, WorkOrderKind kind, void* info);
190void *dvmCheckCodeCache(void *method);
Ben Cheng7a2697d2010-06-07 13:44:23 -0700191CompilerMethodStats *dvmCompilerAnalyzeMethodBody(const Method *method,
192 bool isCallee);
193bool dvmCompilerCanIncludeThisInstruction(const Method *method,
194 const DecodedInstruction *insn);
Ben Chengcfdeca32011-01-14 11:36:46 -0800195bool dvmCompileMethod(const Method *method, JitTranslationInfo *info);
Bill Buzbee716f1202009-07-23 13:22:09 -0700196bool dvmCompileTrace(JitTraceDescription *trace, int numMaxInsts,
Ben Cheng4a419582010-08-04 13:23:09 -0700197 JitTranslationInfo *info, jmp_buf *bailPtr, int optHints);
Ben Chengba4fc8b2009-06-01 13:00:29 -0700198void dvmCompilerDumpStats(void);
199void dvmCompilerDrainQueue(void);
Bill Buzbee46cd5b62009-06-05 15:36:06 -0700200void dvmJitUnchainAll(void);
Bill Buzbee716f1202009-07-23 13:22:09 -0700201void dvmCompilerSortAndPrintTraceProfiles(void);
Carl Shapiro3f349af2010-02-25 15:47:08 -0800202void dvmCompilerPerformSafePointChecks(void);
Ben Chengcfdeca32011-01-14 11:36:46 -0800203void dvmCompilerInlineMIR(struct CompilationUnit *cUnit,
204 JitTranslationInfo *info);
Ben Cheng4238ec22009-08-24 16:32:22 -0700205void dvmInitializeSSAConversion(struct CompilationUnit *cUnit);
Ben Cheng00603072010-10-28 11:13:58 -0700206int dvmConvertSSARegToDalvik(const struct CompilationUnit *cUnit, int ssaReg);
Ben Cheng4a419582010-08-04 13:23:09 -0700207bool dvmCompilerLoopOpt(struct CompilationUnit *cUnit);
Ben Cheng4238ec22009-08-24 16:32:22 -0700208void dvmCompilerNonLoopAnalysis(struct CompilationUnit *cUnit);
Ben Cheng00603072010-10-28 11:13:58 -0700209bool dvmCompilerFindLocalLiveIn(struct CompilationUnit *cUnit,
Ben Cheng4238ec22009-08-24 16:32:22 -0700210 struct BasicBlock *bb);
Ben Cheng00603072010-10-28 11:13:58 -0700211bool dvmCompilerDoSSAConversion(struct CompilationUnit *cUnit,
212 struct BasicBlock *bb);
213bool dvmCompilerDoConstantPropagation(struct CompilationUnit *cUnit,
Ben Cheng4238ec22009-08-24 16:32:22 -0700214 struct BasicBlock *bb);
Ben Cheng00603072010-10-28 11:13:58 -0700215bool dvmCompilerFindInductionVariables(struct CompilationUnit *cUnit,
Ben Cheng4238ec22009-08-24 16:32:22 -0700216 struct BasicBlock *bb);
Ben Cheng00603072010-10-28 11:13:58 -0700217/* Clear the visited flag for each BB */
218bool dvmCompilerClearVisitedFlag(struct CompilationUnit *cUnit,
219 struct BasicBlock *bb);
220char *dvmCompilerGetDalvikDisassembly(const DecodedInstruction *insn,
221 char *note);
222char *dvmCompilerFullDisassembler(const struct CompilationUnit *cUnit,
223 const struct MIR *mir);
Ben Cheng4238ec22009-08-24 16:32:22 -0700224char *dvmCompilerGetSSAString(struct CompilationUnit *cUnit,
225 struct SSARepresentation *ssaRep);
226void dvmCompilerDataFlowAnalysisDispatcher(struct CompilationUnit *cUnit,
Ben Cheng00603072010-10-28 11:13:58 -0700227 bool (*func)(struct CompilationUnit *, struct BasicBlock *),
228 DataFlowAnalysisMode dfaMode,
229 bool isIterative);
230void dvmCompilerMethodSSATransformation(struct CompilationUnit *cUnit);
Bill Buzbee06bb8392010-01-31 18:53:15 -0800231void dvmCompilerStateRefresh(void);
Ben Cheng88a0f972010-02-24 15:00:40 -0800232JitTraceDescription *dvmCopyTraceDescriptor(const u2 *pc,
233 const struct JitEntry *desc);
Bill Buzbeebd047242010-05-13 13:02:53 -0700234void *dvmCompilerGetInterpretTemplate();
Bill Buzbee1b3da592011-02-03 07:38:22 -0800235JitInstructionSetType dvmCompilerGetInterpretTemplateSet();
Ben Chengd72564c2011-02-08 17:09:25 -0800236u8 dvmGetRegResourceMask(int reg);
Ben Chengba4fc8b2009-06-01 13:00:29 -0700237#endif /* _DALVIK_VM_COMPILER */