blob: 384cb141415280d639439586582b27a9b432c485 [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
17#ifndef _DALVIK_VM_COMPILER
18#define _DALVIK_VM_COMPILER
19
Carl Shapiroae188c62011-04-08 13:11:58 -070020#include <setjmp.h>
21#include "Thread.h"
22
23#ifdef __cplusplus
24extern "C" {
25#endif
26
Ben Chengdca71432010-03-16 16:04:11 -070027/*
28 * Uncomment the following to enable JIT signature breakpoint
29 * #define SIGNATURE_BREAKPOINT
30 */
31
Ben Chengba4fc8b2009-06-01 13:00:29 -070032#define COMPILER_WORK_QUEUE_SIZE 100
Ben Chengc3b92b22010-01-26 16:46:15 -080033#define COMPILER_IC_PATCH_QUEUE_SIZE 64
Ben Chengba4fc8b2009-06-01 13:00:29 -070034
Ben Chengb88ec3c2010-05-17 12:50:33 -070035/* Architectural-independent parameters for predicted chains */
36#define PREDICTED_CHAIN_CLAZZ_INIT 0
37#define PREDICTED_CHAIN_METHOD_INIT 0
38#define PREDICTED_CHAIN_COUNTER_INIT 0
39/* A fake value which will avoid initialization and won't match any class */
40#define PREDICTED_CHAIN_FAKE_CLAZZ 0xdeadc001
41/* Has to be positive */
42#define PREDICTED_CHAIN_COUNTER_AVOID 0x7fffffff
43/* Rechain after this many misses - shared globally and has to be positive */
44#define PREDICTED_CHAIN_COUNTER_RECHAIN 8192
45
Ben Chengba4fc8b2009-06-01 13:00:29 -070046#define COMPILER_TRACED(X)
47#define COMPILER_TRACEE(X)
48#define COMPILER_TRACE_CHAINING(X)
49
Ben Chengb88ec3c2010-05-17 12:50:33 -070050/* Macro to change the permissions applied to a chunk of the code cache */
Ben Chengb88ec3c2010-05-17 12:50:33 -070051#define PROTECT_CODE_CACHE_ATTRS (PROT_READ | PROT_EXEC)
52#define UNPROTECT_CODE_CACHE_ATTRS (PROT_READ | PROT_EXEC | PROT_WRITE)
Ben Chengb88ec3c2010-05-17 12:50:33 -070053
54/* Acquire the lock before removing PROT_WRITE from the specified mem region */
55#define UNPROTECT_CODE_CACHE(addr, size) \
56 { \
57 dvmLockMutex(&gDvmJit.codeCacheProtectionLock); \
58 mprotect((void *) (((intptr_t) (addr)) & ~gDvmJit.pageSizeMask), \
59 (size) + (((intptr_t) (addr)) & gDvmJit.pageSizeMask), \
60 (UNPROTECT_CODE_CACHE_ATTRS)); \
61 }
62
63/* Add the PROT_WRITE to the specified memory region then release the lock */
64#define PROTECT_CODE_CACHE(addr, size) \
65 { \
66 mprotect((void *) (((intptr_t) (addr)) & ~gDvmJit.pageSizeMask), \
67 (size) + (((intptr_t) (addr)) & gDvmJit.pageSizeMask), \
68 (PROTECT_CODE_CACHE_ATTRS)); \
69 dvmUnlockMutex(&gDvmJit.codeCacheProtectionLock); \
70 }
71
Ben Cheng34dc7962010-08-26 14:56:31 -070072#define SINGLE_STEP_OP(opcode) \
73 (gDvmJit.includeSelectedOp != \
74 ((gDvmJit.opList[opcode >> 3] & (1 << (opcode & 0x7))) != 0))
75
Bill Buzbee716f1202009-07-23 13:22:09 -070076typedef enum JitInstructionSetType {
77 DALVIK_JIT_NONE = 0,
78 DALVIK_JIT_ARM,
79 DALVIK_JIT_THUMB,
80 DALVIK_JIT_THUMB2,
buzbee7520ee72010-09-17 16:01:49 -070081 DALVIK_JIT_IA32
Bill Buzbee716f1202009-07-23 13:22:09 -070082} JitInstructionSetType;
83
84/* Description of a compiled trace. */
85typedef struct JitTranslationInfo {
Ben Chengccd6c012009-10-15 14:52:45 -070086 void *codeAddress;
Bill Buzbee716f1202009-07-23 13:22:09 -070087 JitInstructionSetType instructionSet;
buzbee2e152ba2010-12-15 16:32:35 -080088 int profileCodeSize;
Ben Cheng60c24f42010-01-04 12:29:56 -080089 bool discardResult; // Used for debugging divergence and IC patching
Ben Cheng7a2697d2010-06-07 13:44:23 -070090 bool methodCompilationAborted; // Cannot compile the whole method
Ben Cheng33672452010-01-12 14:59:30 -080091 Thread *requestingThread; // For debugging purpose
buzbee18fba342011-01-19 15:31:15 -080092 int cacheVersion; // Used to identify stale trace requests
Bill Buzbee716f1202009-07-23 13:22:09 -070093} JitTranslationInfo;
94
Ben Chengba4fc8b2009-06-01 13:00:29 -070095typedef enum WorkOrderKind {
96 kWorkOrderInvalid = 0, // Should never see by the backend
97 kWorkOrderMethod = 1, // Work is to compile a whole method
98 kWorkOrderTrace = 2, // Work is to compile code fragment(s)
Ben Chengccd6c012009-10-15 14:52:45 -070099 kWorkOrderTraceDebug = 3, // Work is to compile/debug code fragment(s)
buzbee2e152ba2010-12-15 16:32:35 -0800100 kWorkOrderProfileMode = 4, // Change profiling mode
Ben Chengba4fc8b2009-06-01 13:00:29 -0700101} WorkOrderKind;
102
103typedef struct CompilerWorkOrder {
104 const u2* pc;
105 WorkOrderKind kind;
106 void* info;
Bill Buzbee716f1202009-07-23 13:22:09 -0700107 JitTranslationInfo result;
Bill Buzbeefc519dc2010-03-06 23:30:57 -0800108 jmp_buf *bailPtr;
Ben Chengba4fc8b2009-06-01 13:00:29 -0700109} CompilerWorkOrder;
110
Ben Chengc3b92b22010-01-26 16:46:15 -0800111/* Chain cell for predicted method invocation */
112typedef struct PredictedChainingCell {
113 u4 branch; /* Branch to chained destination */
Ben Chengb88ec3c2010-05-17 12:50:33 -0700114 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 */
Ben Chengc3b92b22010-01-26 16:46:15 -0800117} PredictedChainingCell;
118
119/* Work order for inline cache patching */
120typedef struct ICPatchWorkOrder {
121 PredictedChainingCell *cellAddr; /* Address to be patched */
122 PredictedChainingCell cellContent; /* content of the new cell */
Ben Cheng385828e2011-03-04 16:48:33 -0800123 const char *classDescriptor; /* Descriptor of the class object */
124 Object *classLoader; /* Class loader */
125 u4 serialNumber; /* Serial # (for verification only) */
Ben Chengc3b92b22010-01-26 16:46:15 -0800126} ICPatchWorkOrder;
127
Ben Chengba4fc8b2009-06-01 13:00:29 -0700128/*
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.
133 */
134typedef struct {
135 const Method* method;
Ben Cheng7a2697d2010-06-07 13:44:23 -0700136 JitTraceRun trace[0]; // Variable-length trace descriptors
Ben Chengba4fc8b2009-06-01 13:00:29 -0700137} JitTraceDescription;
138
Ben Cheng7a2697d2010-06-07 13:44:23 -0700139typedef 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 */
Ben Chengcfdeca32011-01-14 11:36:46 -0800147 kCannotCompile, /* Method cannot be compiled */
Ben Cheng7a2697d2010-06-07 13:44:23 -0700148} JitMethodAttributes;
149
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)
Ben Chengcfdeca32011-01-14 11:36:46 -0800157#define METHOD_CANNOT_COMPILE (1 << kCannotCompile)
Ben Cheng7a2697d2010-06-07 13:44:23 -0700158
Ben Cheng4a419582010-08-04 13:23:09 -0700159/* Vectors to provide optimization hints */
160typedef enum JitOptimizationHints {
161 kJitOptNoLoop = 0, // Disable loop formation/optimization
162} JitOptimizationHints;
163
164#define JIT_OPT_NO_LOOP (1 << kJitOptNoLoop)
165
Ben Cheng00603072010-10-28 11:13:58 -0700166/* Customized node traversal orders for different needs */
167typedef 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;
174
Ben Cheng8b258bf2009-06-24 17:27:07 -0700175typedef 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
Ben Cheng7a2697d2010-06-07 13:44:23 -0700180 int attributes; // attribute vector
Ben Cheng8b258bf2009-06-24 17:27:07 -0700181} CompilerMethodStats;
182
Ben Cheng7a2697d2010-06-07 13:44:23 -0700183struct CompilationUnit;
184struct BasicBlock;
185struct SSARepresentation;
186struct GrowableList;
187struct JitEntry;
188struct MIR;
189
Ben Chengba4fc8b2009-06-01 13:00:29 -0700190bool dvmCompilerSetupCodeCache(void);
191bool dvmCompilerArchInit(void);
192void dvmCompilerArchDump(void);
193bool dvmCompilerStartup(void);
194void dvmCompilerShutdown(void);
Bill Buzbee1b3da592011-02-03 07:38:22 -0800195void dvmCompilerForceWorkEnqueue(const u2* pc, WorkOrderKind kind, void* info);
Ben Chengba4fc8b2009-06-01 13:00:29 -0700196bool dvmCompilerWorkEnqueue(const u2* pc, WorkOrderKind kind, void* info);
197void *dvmCheckCodeCache(void *method);
Ben Cheng7a2697d2010-06-07 13:44:23 -0700198CompilerMethodStats *dvmCompilerAnalyzeMethodBody(const Method *method,
199 bool isCallee);
200bool dvmCompilerCanIncludeThisInstruction(const Method *method,
201 const DecodedInstruction *insn);
Ben Chengcfdeca32011-01-14 11:36:46 -0800202bool dvmCompileMethod(const Method *method, JitTranslationInfo *info);
Bill Buzbee716f1202009-07-23 13:22:09 -0700203bool dvmCompileTrace(JitTraceDescription *trace, int numMaxInsts,
Ben Cheng4a419582010-08-04 13:23:09 -0700204 JitTranslationInfo *info, jmp_buf *bailPtr, int optHints);
Ben Chengba4fc8b2009-06-01 13:00:29 -0700205void dvmCompilerDumpStats(void);
206void dvmCompilerDrainQueue(void);
Bill Buzbee46cd5b62009-06-05 15:36:06 -0700207void dvmJitUnchainAll(void);
Ben Cheng385828e2011-03-04 16:48:33 -0800208void dvmJitScanAllClassPointers(void (*callback)(void *ptr));
Bill Buzbee716f1202009-07-23 13:22:09 -0700209void dvmCompilerSortAndPrintTraceProfiles(void);
Carl Shapiro3f349af2010-02-25 15:47:08 -0800210void dvmCompilerPerformSafePointChecks(void);
Ben Chengcfdeca32011-01-14 11:36:46 -0800211void dvmCompilerInlineMIR(struct CompilationUnit *cUnit,
212 JitTranslationInfo *info);
Ben Cheng4238ec22009-08-24 16:32:22 -0700213void dvmInitializeSSAConversion(struct CompilationUnit *cUnit);
Ben Cheng00603072010-10-28 11:13:58 -0700214int dvmConvertSSARegToDalvik(const struct CompilationUnit *cUnit, int ssaReg);
Ben Cheng4a419582010-08-04 13:23:09 -0700215bool dvmCompilerLoopOpt(struct CompilationUnit *cUnit);
Ben Cheng32115a92011-03-22 14:09:09 -0700216void dvmCompilerInsertBackwardChaining(struct CompilationUnit *cUnit);
Ben Cheng4238ec22009-08-24 16:32:22 -0700217void dvmCompilerNonLoopAnalysis(struct CompilationUnit *cUnit);
Ben Cheng00603072010-10-28 11:13:58 -0700218bool dvmCompilerFindLocalLiveIn(struct CompilationUnit *cUnit,
Ben Cheng4238ec22009-08-24 16:32:22 -0700219 struct BasicBlock *bb);
Ben Cheng00603072010-10-28 11:13:58 -0700220bool dvmCompilerDoSSAConversion(struct CompilationUnit *cUnit,
221 struct BasicBlock *bb);
222bool dvmCompilerDoConstantPropagation(struct CompilationUnit *cUnit,
Ben Cheng4238ec22009-08-24 16:32:22 -0700223 struct BasicBlock *bb);
Ben Cheng00603072010-10-28 11:13:58 -0700224bool dvmCompilerFindInductionVariables(struct CompilationUnit *cUnit,
Ben Cheng4238ec22009-08-24 16:32:22 -0700225 struct BasicBlock *bb);
Ben Cheng00603072010-10-28 11:13:58 -0700226/* Clear the visited flag for each BB */
227bool dvmCompilerClearVisitedFlag(struct CompilationUnit *cUnit,
228 struct BasicBlock *bb);
229char *dvmCompilerGetDalvikDisassembly(const DecodedInstruction *insn,
230 char *note);
231char *dvmCompilerFullDisassembler(const struct CompilationUnit *cUnit,
232 const struct MIR *mir);
Ben Cheng4238ec22009-08-24 16:32:22 -0700233char *dvmCompilerGetSSAString(struct CompilationUnit *cUnit,
234 struct SSARepresentation *ssaRep);
235void dvmCompilerDataFlowAnalysisDispatcher(struct CompilationUnit *cUnit,
Ben Cheng00603072010-10-28 11:13:58 -0700236 bool (*func)(struct CompilationUnit *, struct BasicBlock *),
237 DataFlowAnalysisMode dfaMode,
238 bool isIterative);
239void dvmCompilerMethodSSATransformation(struct CompilationUnit *cUnit);
Ben Cheng46cd4fb2011-03-16 17:19:06 -0700240bool dvmCompilerBuildLoop(struct CompilationUnit *cUnit);
buzbee99e3e6e2011-03-29 10:26:07 -0700241void dvmCompilerUpdateGlobalState(void);
Ben Cheng88a0f972010-02-24 15:00:40 -0800242JitTraceDescription *dvmCopyTraceDescriptor(const u2 *pc,
243 const struct JitEntry *desc);
Bill Buzbeebd047242010-05-13 13:02:53 -0700244void *dvmCompilerGetInterpretTemplate();
Bill Buzbee1b3da592011-02-03 07:38:22 -0800245JitInstructionSetType dvmCompilerGetInterpretTemplateSet();
Ben Chengd72564c2011-02-08 17:09:25 -0800246u8 dvmGetRegResourceMask(int reg);
Ben Cheng32115a92011-03-22 14:09:09 -0700247void dvmDumpCFG(struct CompilationUnit *cUnit, const char *dirPrefix);
Carl Shapiroae188c62011-04-08 13:11:58 -0700248
249#ifdef __cplusplus
250}
251#endif
252
Ben Chengba4fc8b2009-06-01 13:00:29 -0700253#endif /* _DALVIK_VM_COMPILER */