Compiler.h revision a8b91c52fd8a90b784835dfe1f8898035266c4dd
1/* 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_H_ 18#define DALVIK_VM_COMPILER_H_ 19 20#include <setjmp.h> 21#include "Thread.h" 22 23/* 24 * Uncomment the following to enable JIT signature breakpoint 25 * #define SIGNATURE_BREAKPOINT 26 */ 27 28#define COMPILER_WORK_QUEUE_SIZE 100 29#define COMPILER_IC_PATCH_QUEUE_SIZE 64 30 31/* 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 42#define COMPILER_TRACED(X) 43#define COMPILER_TRACEE(X) 44#define COMPILER_TRACE_CHAINING(X) 45 46/* Macro to change the permissions applied to a chunk of the code cache */ 47#define PROTECT_CODE_CACHE_ATTRS (PROT_READ | PROT_EXEC) 48#define UNPROTECT_CODE_CACHE_ATTRS (PROT_READ | PROT_EXEC | PROT_WRITE) 49 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 68#define SINGLE_STEP_OP(opcode) \ 69 (gDvmJit.includeSelectedOp != \ 70 ((gDvmJit.opList[opcode >> 3] & (1 << (opcode & 0x7))) != 0)) 71 72typedef enum JitInstructionSetType { 73 DALVIK_JIT_NONE = 0, 74 DALVIK_JIT_ARM, 75 DALVIK_JIT_THUMB, 76 DALVIK_JIT_THUMB2, 77 DALVIK_JIT_IA32, 78 DALVIK_JIT_MIPS 79} JitInstructionSetType; 80 81/* Description of a compiled trace. */ 82typedef struct JitTranslationInfo { 83 void *codeAddress; 84 JitInstructionSetType instructionSet; 85 int profileCodeSize; 86 bool discardResult; // Used for debugging divergence and IC patching 87 bool methodCompilationAborted; // Cannot compile the whole method 88 Thread *requestingThread; // For debugging purpose 89 int cacheVersion; // Used to identify stale trace requests 90} JitTranslationInfo; 91 92typedef enum WorkOrderKind { 93 kWorkOrderInvalid = 0, // Should never see by the backend 94 kWorkOrderMethod = 1, // Work is to compile a whole method 95 kWorkOrderTrace = 2, // Work is to compile code fragment(s) 96 kWorkOrderTraceDebug = 3, // Work is to compile/debug code fragment(s) 97 kWorkOrderProfileMode = 4, // Change profiling mode 98} WorkOrderKind; 99 100typedef struct CompilerWorkOrder { 101 const u2* pc; 102 WorkOrderKind kind; 103 void* info; 104 JitTranslationInfo result; 105 jmp_buf *bailPtr; 106} CompilerWorkOrder; 107 108/* Chain cell for predicted method invocation */ 109typedef struct PredictedChainingCell { 110 u4 branch; /* Branch to chained destination */ 111#ifdef __mips__ 112 u4 delay_slot; /* nop goes here */ 113#endif 114 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 */ 117} 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 */ 123 const char *classDescriptor; /* Descriptor of the class object */ 124 Object *classLoader; /* Class loader */ 125 u4 serialNumber; /* Serial # (for verification only) */ 126} ICPatchWorkOrder; 127 128/* 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; 136 JitTraceRun trace[0]; // Variable-length trace descriptors 137} JitTraceDescription; 138 139typedef 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 */ 147 kCannotCompile, /* Method cannot be compiled */ 148} 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) 157#define METHOD_CANNOT_COMPILE (1 << kCannotCompile) 158 159/* 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 166/* 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 175typedef 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 180 int attributes; // attribute vector 181} CompilerMethodStats; 182 183struct CompilationUnit; 184struct BasicBlock; 185struct SSARepresentation; 186struct GrowableList; 187struct JitEntry; 188struct MIR; 189 190bool dvmCompilerSetupCodeCache(void); 191bool dvmCompilerArchInit(void); 192void dvmCompilerArchDump(void); 193bool dvmCompilerStartup(void); 194void dvmCompilerShutdown(void); 195void dvmCompilerForceWorkEnqueue(const u2* pc, WorkOrderKind kind, void* info); 196bool dvmCompilerWorkEnqueue(const u2* pc, WorkOrderKind kind, void* info); 197void *dvmCheckCodeCache(void *method); 198CompilerMethodStats *dvmCompilerAnalyzeMethodBody(const Method *method, 199 bool isCallee); 200bool dvmCompilerCanIncludeThisInstruction(const Method *method, 201 const DecodedInstruction *insn); 202bool dvmCompileMethod(const Method *method, JitTranslationInfo *info); 203bool dvmCompileTrace(JitTraceDescription *trace, int numMaxInsts, 204 JitTranslationInfo *info, jmp_buf *bailPtr, int optHints); 205void dvmCompilerDumpStats(void); 206void dvmCompilerDrainQueue(void); 207void dvmJitUnchainAll(void); 208void dvmJitScanAllClassPointers(void (*callback)(void *ptr)); 209void dvmCompilerSortAndPrintTraceProfiles(void); 210void dvmCompilerPerformSafePointChecks(void); 211void dvmCompilerInlineMIR(struct CompilationUnit *cUnit, 212 JitTranslationInfo *info); 213void dvmInitializeSSAConversion(struct CompilationUnit *cUnit); 214int dvmConvertSSARegToDalvik(const struct CompilationUnit *cUnit, int ssaReg); 215bool dvmCompilerLoopOpt(struct CompilationUnit *cUnit); 216void dvmCompilerInsertBackwardChaining(struct CompilationUnit *cUnit); 217void dvmCompilerNonLoopAnalysis(struct CompilationUnit *cUnit); 218bool dvmCompilerFindLocalLiveIn(struct CompilationUnit *cUnit, 219 struct BasicBlock *bb); 220bool dvmCompilerDoSSAConversion(struct CompilationUnit *cUnit, 221 struct BasicBlock *bb); 222bool dvmCompilerDoConstantPropagation(struct CompilationUnit *cUnit, 223 struct BasicBlock *bb); 224bool dvmCompilerFindInductionVariables(struct CompilationUnit *cUnit, 225 struct BasicBlock *bb); 226/* Clear the visited flag for each BB */ 227bool dvmCompilerClearVisitedFlag(struct CompilationUnit *cUnit, 228 struct BasicBlock *bb); 229char *dvmCompilerGetDalvikDisassembly(const DecodedInstruction *insn, 230 const char *note); 231char *dvmCompilerFullDisassembler(const struct CompilationUnit *cUnit, 232 const struct MIR *mir); 233char *dvmCompilerGetSSAString(struct CompilationUnit *cUnit, 234 struct SSARepresentation *ssaRep); 235void dvmCompilerDataFlowAnalysisDispatcher(struct CompilationUnit *cUnit, 236 bool (*func)(struct CompilationUnit *, struct BasicBlock *), 237 DataFlowAnalysisMode dfaMode, 238 bool isIterative); 239void dvmCompilerMethodSSATransformation(struct CompilationUnit *cUnit); 240bool dvmCompilerBuildLoop(struct CompilationUnit *cUnit); 241void dvmCompilerUpdateGlobalState(void); 242JitTraceDescription *dvmCopyTraceDescriptor(const u2 *pc, 243 const struct JitEntry *desc); 244extern "C" void *dvmCompilerGetInterpretTemplate(); 245JitInstructionSetType dvmCompilerGetInterpretTemplateSet(); 246u8 dvmGetRegResourceMask(int reg); 247void dvmDumpCFG(struct CompilationUnit *cUnit, const char *dirPrefix); 248 249#endif // DALVIK_VM_COMPILER_H_ 250