Compiler.h revision 0c2dc522d0e120f346cf0a40c8cf0c93346131c2
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#define COMPILER_PC_OFFSET_SIZE 100 31 32/* 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 43#define COMPILER_TRACED(X) 44#define COMPILER_TRACEE(X) 45#define COMPILER_TRACE_CHAINING(X) 46 47/* Macro to change the permissions applied to a chunk of the code cache */ 48#define PROTECT_CODE_CACHE_ATTRS (PROT_READ | PROT_EXEC) 49#define UNPROTECT_CODE_CACHE_ATTRS (PROT_READ | PROT_EXEC | PROT_WRITE) 50 51/* Acquire the lock before removing PROT_WRITE from the specified mem region */ 52#define UNPROTECT_CODE_CACHE(addr, size) \ 53 { \ 54 dvmLockMutex(&gDvmJit.codeCacheProtectionLock); \ 55 mprotect((void *) (((intptr_t) (addr)) & ~gDvmJit.pageSizeMask), \ 56 (size) + (((intptr_t) (addr)) & gDvmJit.pageSizeMask), \ 57 (UNPROTECT_CODE_CACHE_ATTRS)); \ 58 } 59 60/* Add the PROT_WRITE to the specified memory region then release the lock */ 61#define PROTECT_CODE_CACHE(addr, size) \ 62 { \ 63 mprotect((void *) (((intptr_t) (addr)) & ~gDvmJit.pageSizeMask), \ 64 (size) + (((intptr_t) (addr)) & gDvmJit.pageSizeMask), \ 65 (PROTECT_CODE_CACHE_ATTRS)); \ 66 dvmUnlockMutex(&gDvmJit.codeCacheProtectionLock); \ 67 } 68 69#define SINGLE_STEP_OP(opcode) \ 70 (gDvmJit.includeSelectedOp != \ 71 ((gDvmJit.opList[opcode >> 3] & (1 << (opcode & 0x7))) != 0)) 72 73typedef enum JitInstructionSetType { 74 DALVIK_JIT_NONE = 0, 75 DALVIK_JIT_ARM, 76 DALVIK_JIT_THUMB, 77 DALVIK_JIT_THUMB2, 78 DALVIK_JIT_IA32, 79 DALVIK_JIT_MIPS 80} JitInstructionSetType; 81 82/* Description of a compiled trace. */ 83typedef struct JitTranslationInfo { 84 void *codeAddress; 85 JitInstructionSetType instructionSet; 86 int profileCodeSize; 87 bool discardResult; // Used for debugging divergence and IC patching 88 bool methodCompilationAborted; // Cannot compile the whole method 89 Thread *requestingThread; // For debugging purpose 90 int cacheVersion; // Used to identify stale trace requests 91} JitTranslationInfo; 92 93typedef 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) 97 kWorkOrderTraceDebug = 3, // Work is to compile/debug code fragment(s) 98 kWorkOrderProfileMode = 4, // Change profiling mode 99} WorkOrderKind; 100 101typedef struct CompilerWorkOrder { 102 const u2* pc; 103 WorkOrderKind kind; 104 void* info; 105 JitTranslationInfo result; 106 jmp_buf *bailPtr; 107} CompilerWorkOrder; 108 109/* Chain cell for predicted method invocation */ 110typedef struct PredictedChainingCell { 111 u4 branch; /* Branch to chained destination */ 112#ifdef __mips__ 113 u4 delay_slot; /* nop goes here */ 114#elif defined(ARCH_IA32) 115 u4 branch2; /* IA32 branch instr may be > 32 bits */ 116#endif 117 const ClassObject *clazz; /* key for prediction */ 118 const Method *method; /* to lookup native PC from dalvik PC */ 119 const ClassObject *stagedClazz; /* possible next key for prediction */ 120} PredictedChainingCell; 121 122/* Work order for inline cache patching */ 123typedef struct ICPatchWorkOrder { 124 PredictedChainingCell *cellAddr; /* Address to be patched */ 125 PredictedChainingCell cellContent; /* content of the new cell */ 126 const char *classDescriptor; /* Descriptor of the class object */ 127 Object *classLoader; /* Class loader */ 128 u4 serialNumber; /* Serial # (for verification only) */ 129} ICPatchWorkOrder; 130 131/* 132 * Trace description as will appear in the translation cache. Note 133 * flexible array at end, as these will be of variable size. To 134 * conserve space in the translation cache, total length of JitTraceRun 135 * array must be recomputed via seqential scan if needed. 136 */ 137typedef struct { 138 const Method* method; 139 JitTraceRun trace[0]; // Variable-length trace descriptors 140} JitTraceDescription; 141 142typedef enum JitMethodAttributes { 143 kIsCallee = 0, /* Code is part of a callee (invoked by a hot trace) */ 144 kIsHot, /* Code is part of a hot trace */ 145 kIsLeaf, /* Method is leaf */ 146 kIsEmpty, /* Method is empty */ 147 kIsThrowFree, /* Method doesn't throw */ 148 kIsGetter, /* Method fits the getter pattern */ 149 kIsSetter, /* Method fits the setter pattern */ 150 kCannotCompile, /* Method cannot be compiled */ 151} JitMethodAttributes; 152 153#define METHOD_IS_CALLEE (1 << kIsCallee) 154#define METHOD_IS_HOT (1 << kIsHot) 155#define METHOD_IS_LEAF (1 << kIsLeaf) 156#define METHOD_IS_EMPTY (1 << kIsEmpty) 157#define METHOD_IS_THROW_FREE (1 << kIsThrowFree) 158#define METHOD_IS_GETTER (1 << kIsGetter) 159#define METHOD_IS_SETTER (1 << kIsSetter) 160#define METHOD_CANNOT_COMPILE (1 << kCannotCompile) 161 162/* Vectors to provide optimization hints */ 163typedef enum JitOptimizationHints { 164 kJitOptNoLoop = 0, // Disable loop formation/optimization 165} JitOptimizationHints; 166 167#define JIT_OPT_NO_LOOP (1 << kJitOptNoLoop) 168 169/* Customized node traversal orders for different needs */ 170typedef enum DataFlowAnalysisMode { 171 kAllNodes = 0, // All nodes 172 kReachableNodes, // All reachable nodes 173 kPreOrderDFSTraversal, // Depth-First-Search / Pre-Order 174 kPostOrderDFSTraversal, // Depth-First-Search / Post-Order 175 kPostOrderDOMTraversal, // Dominator tree / Post-Order 176} DataFlowAnalysisMode; 177 178typedef struct CompilerMethodStats { 179 const Method *method; // Used as hash entry signature 180 int dalvikSize; // # of bytes for dalvik bytecodes 181 int compiledDalvikSize; // # of compiled dalvik bytecodes 182 int nativeSize; // # of bytes for produced native code 183 int attributes; // attribute vector 184} CompilerMethodStats; 185 186struct CompilationUnit; 187struct BasicBlock; 188struct SSARepresentation; 189struct GrowableList; 190struct JitEntry; 191struct MIR; 192 193bool dvmCompilerSetupCodeCache(void); 194bool dvmCompilerArchInit(void); 195void dvmCompilerArchDump(void); 196bool dvmCompilerStartup(void); 197void dvmCompilerShutdown(void); 198void dvmCompilerForceWorkEnqueue(const u2* pc, WorkOrderKind kind, void* info); 199bool dvmCompilerWorkEnqueue(const u2* pc, WorkOrderKind kind, void* info); 200void *dvmCheckCodeCache(void *method); 201CompilerMethodStats *dvmCompilerAnalyzeMethodBody(const Method *method, 202 bool isCallee); 203bool dvmCompilerCanIncludeThisInstruction(const Method *method, 204 const DecodedInstruction *insn); 205bool dvmCompileMethod(const Method *method, JitTranslationInfo *info); 206bool dvmCompileTrace(JitTraceDescription *trace, int numMaxInsts, 207 JitTranslationInfo *info, jmp_buf *bailPtr, int optHints); 208void dvmCompilerDumpStats(void); 209void dvmCompilerDrainQueue(void); 210void dvmJitUnchainAll(void); 211void dvmJitScanAllClassPointers(void (*callback)(void *ptr)); 212void dvmCompilerSortAndPrintTraceProfiles(void); 213void dvmCompilerPerformSafePointChecks(void); 214void dvmCompilerInlineMIR(struct CompilationUnit *cUnit, 215 JitTranslationInfo *info); 216void dvmInitializeSSAConversion(struct CompilationUnit *cUnit); 217int dvmConvertSSARegToDalvik(const struct CompilationUnit *cUnit, int ssaReg); 218bool dvmCompilerLoopOpt(struct CompilationUnit *cUnit); 219void dvmCompilerInsertBackwardChaining(struct CompilationUnit *cUnit); 220void dvmCompilerNonLoopAnalysis(struct CompilationUnit *cUnit); 221bool dvmCompilerFindLocalLiveIn(struct CompilationUnit *cUnit, 222 struct BasicBlock *bb); 223bool dvmCompilerDoSSAConversion(struct CompilationUnit *cUnit, 224 struct BasicBlock *bb); 225bool dvmCompilerDoConstantPropagation(struct CompilationUnit *cUnit, 226 struct BasicBlock *bb); 227bool dvmCompilerFindInductionVariables(struct CompilationUnit *cUnit, 228 struct BasicBlock *bb); 229/* Clear the visited flag for each BB */ 230bool dvmCompilerClearVisitedFlag(struct CompilationUnit *cUnit, 231 struct BasicBlock *bb); 232char *dvmCompilerGetDalvikDisassembly(const DecodedInstruction *insn, 233 const char *note); 234char *dvmCompilerFullDisassembler(const struct CompilationUnit *cUnit, 235 const struct MIR *mir); 236char *dvmCompilerGetSSAString(struct CompilationUnit *cUnit, 237 struct SSARepresentation *ssaRep); 238void dvmCompilerDataFlowAnalysisDispatcher(struct CompilationUnit *cUnit, 239 bool (*func)(struct CompilationUnit *, struct BasicBlock *), 240 DataFlowAnalysisMode dfaMode, 241 bool isIterative); 242void dvmCompilerMethodSSATransformation(struct CompilationUnit *cUnit); 243bool dvmCompilerBuildLoop(struct CompilationUnit *cUnit); 244void dvmCompilerUpdateGlobalState(void); 245JitTraceDescription *dvmCopyTraceDescriptor(const u2 *pc, 246 const struct JitEntry *desc); 247extern "C" void *dvmCompilerGetInterpretTemplate(); 248JitInstructionSetType dvmCompilerGetInterpretTemplateSet(); 249u8 dvmGetRegResourceMask(int reg); 250void dvmDumpCFG(struct CompilationUnit *cUnit, const char *dirPrefix); 251bool dvmIsOpcodeSupportedByJit(Opcode opcode); 252 253#endif // DALVIK_VM_COMPILER_H_ 254