blob: dae46fc8883cfa85ebb54d11eca69d0aa454effc [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 */
48#if !defined(WITH_JIT_TUNING)
49#define PROTECT_CODE_CACHE_ATTRS (PROT_READ | PROT_EXEC)
50#define UNPROTECT_CODE_CACHE_ATTRS (PROT_READ | PROT_EXEC | PROT_WRITE)
51#else
52/* When doing JIT profiling always grant the write permission */
53#define PROTECT_CODE_CACHE_ATTRS (PROT_READ | PROT_EXEC | \
54 (gDvmJit.profile ? PROT_WRITE : 0))
55#define UNPROTECT_CODE_CACHE_ATTRS (PROT_READ | PROT_EXEC | PROT_WRITE)
56#endif
57
58/* Acquire the lock before removing PROT_WRITE from the specified mem region */
59#define UNPROTECT_CODE_CACHE(addr, size) \
60 { \
61 dvmLockMutex(&gDvmJit.codeCacheProtectionLock); \
62 mprotect((void *) (((intptr_t) (addr)) & ~gDvmJit.pageSizeMask), \
63 (size) + (((intptr_t) (addr)) & gDvmJit.pageSizeMask), \
64 (UNPROTECT_CODE_CACHE_ATTRS)); \
65 }
66
67/* Add the PROT_WRITE to the specified memory region then release the lock */
68#define PROTECT_CODE_CACHE(addr, size) \
69 { \
70 mprotect((void *) (((intptr_t) (addr)) & ~gDvmJit.pageSizeMask), \
71 (size) + (((intptr_t) (addr)) & gDvmJit.pageSizeMask), \
72 (PROTECT_CODE_CACHE_ATTRS)); \
73 dvmUnlockMutex(&gDvmJit.codeCacheProtectionLock); \
74 }
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,
Bill Buzbee9bc3df32009-07-30 10:52:29 -070081 DALVIK_JIT_THUMB2EE,
Bill Buzbee716f1202009-07-23 13:22:09 -070082 DALVIK_JIT_X86
83} JitInstructionSetType;
84
85/* Description of a compiled trace. */
86typedef struct JitTranslationInfo {
Ben Chengccd6c012009-10-15 14:52:45 -070087 void *codeAddress;
Bill Buzbee716f1202009-07-23 13:22:09 -070088 JitInstructionSetType instructionSet;
Ben Cheng60c24f42010-01-04 12:29:56 -080089 bool discardResult; // Used for debugging divergence and IC patching
Ben Cheng33672452010-01-12 14:59:30 -080090 Thread *requestingThread; // For debugging purpose
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)
Ben Chengba4fc8b2009-06-01 13:00:29 -070098} WorkOrderKind;
99
100typedef struct CompilerWorkOrder {
101 const u2* pc;
102 WorkOrderKind kind;
103 void* info;
Bill Buzbee716f1202009-07-23 13:22:09 -0700104 JitTranslationInfo result;
Bill Buzbeefc519dc2010-03-06 23:30:57 -0800105 jmp_buf *bailPtr;
Ben Chengba4fc8b2009-06-01 13:00:29 -0700106} CompilerWorkOrder;
107
Ben Chengc3b92b22010-01-26 16:46:15 -0800108/* Chain cell for predicted method invocation */
109typedef struct PredictedChainingCell {
110 u4 branch; /* Branch to chained destination */
Ben Chengb88ec3c2010-05-17 12:50:33 -0700111 const ClassObject *clazz; /* key for prediction */
112 const Method *method; /* to lookup native PC from dalvik PC */
113 const ClassObject *stagedClazz; /* possible next key for prediction */
Ben Chengc3b92b22010-01-26 16:46:15 -0800114} PredictedChainingCell;
115
116/* Work order for inline cache patching */
117typedef struct ICPatchWorkOrder {
118 PredictedChainingCell *cellAddr; /* Address to be patched */
119 PredictedChainingCell cellContent; /* content of the new cell */
120} ICPatchWorkOrder;
121
Ben Chenga4973592010-03-31 11:59:18 -0700122/* States of the dbg interpreter when serving a JIT-related request */
Ben Chengba4fc8b2009-06-01 13:00:29 -0700123typedef enum JitState {
Ben Chenga4973592010-03-31 11:59:18 -0700124 /* Entering states in the debug interpreter */
125 kJitNot = 0, // Non-JIT related reasons */
126 kJitTSelectRequest = 1, // Request a trace (subject to filtering)
127 kJitTSelectRequestHot = 2, // Request a hot trace (bypass the filter)
128 kJitSelfVerification = 3, // Self Verification Mode
129
130 /* Operational states in the debug interpreter */
131 kJitTSelect = 4, // Actively selecting a trace
132 kJitTSelectEnd = 5, // Done with the trace - wrap it up
133 kJitSingleStep = 6, // Single step interpretation
134 kJitSingleStepEnd = 7, // Done with single step, ready return to mterp
135 kJitDone = 8, // Ready to leave the debug interpreter
Ben Chengba4fc8b2009-06-01 13:00:29 -0700136} JitState;
137
Jeff Hao97319a82009-08-12 16:57:15 -0700138#if defined(WITH_SELF_VERIFICATION)
139typedef enum SelfVerificationState {
140 kSVSIdle = 0, // Idle
141 kSVSStart = 1, // Shadow space set up, running compiled code
142 kSVSPunt = 2, // Exiting compiled code by punting
143 kSVSSingleStep = 3, // Exiting compiled code by single stepping
Ben Cheng40094c12010-02-24 20:58:44 -0800144 kSVSTraceSelectNoChain = 4,// Exiting compiled code by trace select no chain
145 kSVSTraceSelect = 5, // Exiting compiled code by trace select
146 kSVSNormal = 6, // Exiting compiled code normally
147 kSVSNoChain = 7, // Exiting compiled code by no chain
148 kSVSBackwardBranch = 8, // Exiting compiled code with backward branch trace
149 kSVSDebugInterp = 9, // Normal state restored, running debug interpreter
Jeff Hao97319a82009-08-12 16:57:15 -0700150} SelfVerificationState;
151#endif
152
Ben Chengba4fc8b2009-06-01 13:00:29 -0700153typedef enum JitHint {
154 kJitHintNone = 0,
155 kJitHintTaken = 1, // Last inst in run was taken branch
156 kJitHintNotTaken = 2, // Last inst in run was not taken branch
157 kJitHintNoBias = 3, // Last inst in run was unbiased branch
158} jitHint;
159
160/*
161 * Element of a Jit trace description. Describes a contiguous
162 * sequence of Dalvik byte codes, the last of which can be
163 * associated with a hint.
164 * Dalvik byte code
165 */
166typedef struct {
167 u2 startOffset; // Starting offset for trace run
168 unsigned numInsts:8; // Number of Byte codes in run
169 unsigned runEnd:1; // Run ends with last byte code
170 jitHint hint:7; // Hint to apply to final code of run
171} JitCodeDesc;
172
173typedef union {
174 JitCodeDesc frag;
175 void* hint;
176} JitTraceRun;
177
178/*
179 * Trace description as will appear in the translation cache. Note
180 * flexible array at end, as these will be of variable size. To
181 * conserve space in the translation cache, total length of JitTraceRun
182 * array must be recomputed via seqential scan if needed.
183 */
184typedef struct {
185 const Method* method;
186 JitTraceRun trace[];
187} JitTraceDescription;
188
Ben Cheng8b258bf2009-06-24 17:27:07 -0700189typedef struct CompilerMethodStats {
190 const Method *method; // Used as hash entry signature
191 int dalvikSize; // # of bytes for dalvik bytecodes
192 int compiledDalvikSize; // # of compiled dalvik bytecodes
193 int nativeSize; // # of bytes for produced native code
194} CompilerMethodStats;
195
Ben Chengba4fc8b2009-06-01 13:00:29 -0700196bool dvmCompilerSetupCodeCache(void);
197bool dvmCompilerArchInit(void);
198void dvmCompilerArchDump(void);
199bool dvmCompilerStartup(void);
200void dvmCompilerShutdown(void);
201bool dvmCompilerWorkEnqueue(const u2* pc, WorkOrderKind kind, void* info);
202void *dvmCheckCodeCache(void *method);
Bill Buzbee716f1202009-07-23 13:22:09 -0700203bool dvmCompileMethod(const Method *method, JitTranslationInfo *info);
204bool dvmCompileTrace(JitTraceDescription *trace, int numMaxInsts,
Bill Buzbeefc519dc2010-03-06 23:30:57 -0800205 JitTranslationInfo *info, jmp_buf *bailPtr);
Ben Chengba4fc8b2009-06-01 13:00:29 -0700206void dvmCompilerDumpStats(void);
207void dvmCompilerDrainQueue(void);
Bill Buzbee46cd5b62009-06-05 15:36:06 -0700208void dvmJitUnchainAll(void);
Bill Buzbee716f1202009-07-23 13:22:09 -0700209void dvmCompilerSortAndPrintTraceProfiles(void);
Carl Shapiro3f349af2010-02-25 15:47:08 -0800210void dvmCompilerPerformSafePointChecks(void);
Ben Chengba4fc8b2009-06-01 13:00:29 -0700211
Ben Cheng4238ec22009-08-24 16:32:22 -0700212struct CompilationUnit;
213struct BasicBlock;
214struct SSARepresentation;
215struct GrowableList;
Ben Cheng88a0f972010-02-24 15:00:40 -0800216struct JitEntry;
Ben Cheng4238ec22009-08-24 16:32:22 -0700217
218void dvmInitializeSSAConversion(struct CompilationUnit *cUnit);
219int dvmConvertSSARegToDalvik(struct CompilationUnit *cUnit, int ssaReg);
220void dvmCompilerLoopOpt(struct CompilationUnit *cUnit);
221void dvmCompilerNonLoopAnalysis(struct CompilationUnit *cUnit);
222void dvmCompilerFindLiveIn(struct CompilationUnit *cUnit,
223 struct BasicBlock *bb);
224void dvmCompilerDoSSAConversion(struct CompilationUnit *cUnit,
225 struct BasicBlock *bb);
226void dvmCompilerDoConstantPropagation(struct CompilationUnit *cUnit,
227 struct BasicBlock *bb);
228void dvmCompilerFindInductionVariables(struct CompilationUnit *cUnit,
229 struct BasicBlock *bb);
Ben Chengccd6c012009-10-15 14:52:45 -0700230char *dvmCompilerGetDalvikDisassembly(DecodedInstruction *insn);
Ben Cheng4238ec22009-08-24 16:32:22 -0700231char *dvmCompilerGetSSAString(struct CompilationUnit *cUnit,
232 struct SSARepresentation *ssaRep);
233void dvmCompilerDataFlowAnalysisDispatcher(struct CompilationUnit *cUnit,
234 void (*func)(struct CompilationUnit *, struct BasicBlock *));
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();
Ben Chengba4fc8b2009-06-01 13:00:29 -0700239#endif /* _DALVIK_VM_COMPILER */