Compiler.h revision fbdcfb9ea9e2a78f295834424c3f24986ea45dac
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#include <Thread.h> 18#include <setjmp.h> 19 20#ifndef _DALVIK_VM_COMPILER 21#define _DALVIK_VM_COMPILER 22 23/* 24 * Uncomment the following to enable JIT signature breakpoint 25 * #define SIGNATURE_BREAKPOINT 26 */ 27 28#define MAX_JIT_RUN_LEN 64 29#define COMPILER_WORK_QUEUE_SIZE 100 30#define COMPILER_IC_PATCH_QUEUE_SIZE 64 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#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 76typedef enum JitInstructionSetType { 77 DALVIK_JIT_NONE = 0, 78 DALVIK_JIT_ARM, 79 DALVIK_JIT_THUMB, 80 DALVIK_JIT_THUMB2, 81 DALVIK_JIT_THUMB2EE, 82 DALVIK_JIT_X86 83} JitInstructionSetType; 84 85/* Description of a compiled trace. */ 86typedef struct JitTranslationInfo { 87 void *codeAddress; 88 JitInstructionSetType instructionSet; 89 bool discardResult; // Used for debugging divergence and IC patching 90 Thread *requestingThread; // For debugging purpose 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} 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 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 */ 114} 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 122/* States of the dbg interpreter when serving a JIT-related request */ 123typedef enum JitState { 124 /* 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 136} JitState; 137 138#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 144 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 150} SelfVerificationState; 151#endif 152 153typedef 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 189typedef 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 196bool 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); 203bool dvmCompileMethod(const Method *method, JitTranslationInfo *info); 204bool dvmCompileTrace(JitTraceDescription *trace, int numMaxInsts, 205 JitTranslationInfo *info, jmp_buf *bailPtr); 206void dvmCompilerDumpStats(void); 207void dvmCompilerDrainQueue(void); 208void dvmJitUnchainAll(void); 209void dvmCompilerSortAndPrintTraceProfiles(void); 210void dvmCompilerPerformSafePointChecks(void); 211 212struct CompilationUnit; 213struct BasicBlock; 214struct SSARepresentation; 215struct GrowableList; 216struct JitEntry; 217 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); 230char *dvmCompilerGetDalvikDisassembly(DecodedInstruction *insn); 231char *dvmCompilerGetSSAString(struct CompilationUnit *cUnit, 232 struct SSARepresentation *ssaRep); 233void dvmCompilerDataFlowAnalysisDispatcher(struct CompilationUnit *cUnit, 234 void (*func)(struct CompilationUnit *, struct BasicBlock *)); 235void dvmCompilerStateRefresh(void); 236JitTraceDescription *dvmCopyTraceDescriptor(const u2 *pc, 237 const struct JitEntry *desc); 238void *dvmCompilerGetInterpretTemplate(); 239#endif /* _DALVIK_VM_COMPILER */ 240