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 #define COMPILER_TRACED(X) 33 #define COMPILER_TRACEE(X) 34 #define COMPILER_TRACE_CHAINING(X) 35 36 typedef enum JitInstructionSetType { 37 DALVIK_JIT_NONE = 0, 38 DALVIK_JIT_ARM, 39 DALVIK_JIT_THUMB, 40 DALVIK_JIT_THUMB2, 41 DALVIK_JIT_THUMB2EE, 42 DALVIK_JIT_X86 43 } JitInstructionSetType; 44 45 /* Description of a compiled trace. */ 46 typedef struct JitTranslationInfo { 47 void *codeAddress; 48 JitInstructionSetType instructionSet; 49 bool discardResult; // Used for debugging divergence and IC patching 50 Thread *requestingThread; // For debugging purpose 51 } JitTranslationInfo; 52 53 typedef enum WorkOrderKind { 54 kWorkOrderInvalid = 0, // Should never see by the backend 55 kWorkOrderMethod = 1, // Work is to compile a whole method 56 kWorkOrderTrace = 2, // Work is to compile code fragment(s) 57 kWorkOrderTraceDebug = 3, // Work is to compile/debug code fragment(s) 58 } WorkOrderKind; 59 60 typedef struct CompilerWorkOrder { 61 const u2* pc; 62 WorkOrderKind kind; 63 void* info; 64 JitTranslationInfo result; 65 jmp_buf *bailPtr; 66 } CompilerWorkOrder; 67 68 /* Chain cell for predicted method invocation */ 69 typedef struct PredictedChainingCell { 70 u4 branch; /* Branch to chained destination */ 71 const ClassObject *clazz; /* key #1 for prediction */ 72 const Method *method; /* key #2 to lookup native PC from dalvik PC */ 73 u4 counter; /* counter to patch the chaining cell */ 74 } PredictedChainingCell; 75 76 /* Work order for inline cache patching */ 77 typedef struct ICPatchWorkOrder { 78 PredictedChainingCell *cellAddr; /* Address to be patched */ 79 PredictedChainingCell cellContent; /* content of the new cell */ 80 } ICPatchWorkOrder; 81 82 /* States of the dbg interpreter when serving a JIT-related request */ 83 typedef enum JitState { 84 /* Entering states in the debug interpreter */ 85 kJitNot = 0, // Non-JIT related reasons */ 86 kJitTSelectRequest = 1, // Request a trace (subject to filtering) 87 kJitTSelectRequestHot = 2, // Request a hot trace (bypass the filter) 88 kJitSelfVerification = 3, // Self Verification Mode 89 90 /* Operational states in the debug interpreter */ 91 kJitTSelect = 4, // Actively selecting a trace 92 kJitTSelectEnd = 5, // Done with the trace - wrap it up 93 kJitSingleStep = 6, // Single step interpretation 94 kJitSingleStepEnd = 7, // Done with single step, ready return to mterp 95 kJitDone = 8, // Ready to leave the debug interpreter 96 } JitState; 97 98 #if defined(WITH_SELF_VERIFICATION) 99 typedef enum SelfVerificationState { 100 kSVSIdle = 0, // Idle 101 kSVSStart = 1, // Shadow space set up, running compiled code 102 kSVSPunt = 2, // Exiting compiled code by punting 103 kSVSSingleStep = 3, // Exiting compiled code by single stepping 104 kSVSTraceSelectNoChain = 4,// Exiting compiled code by trace select no chain 105 kSVSTraceSelect = 5, // Exiting compiled code by trace select 106 kSVSNormal = 6, // Exiting compiled code normally 107 kSVSNoChain = 7, // Exiting compiled code by no chain 108 kSVSBackwardBranch = 8, // Exiting compiled code with backward branch trace 109 kSVSDebugInterp = 9, // Normal state restored, running debug interpreter 110 } SelfVerificationState; 111 #endif 112 113 typedef enum JitHint { 114 kJitHintNone = 0, 115 kJitHintTaken = 1, // Last inst in run was taken branch 116 kJitHintNotTaken = 2, // Last inst in run was not taken branch 117 kJitHintNoBias = 3, // Last inst in run was unbiased branch 118 } jitHint; 119 120 /* 121 * Element of a Jit trace description. Describes a contiguous 122 * sequence of Dalvik byte codes, the last of which can be 123 * associated with a hint. 124 * Dalvik byte code 125 */ 126 typedef struct { 127 u2 startOffset; // Starting offset for trace run 128 unsigned numInsts:8; // Number of Byte codes in run 129 unsigned runEnd:1; // Run ends with last byte code 130 jitHint hint:7; // Hint to apply to final code of run 131 } JitCodeDesc; 132 133 typedef union { 134 JitCodeDesc frag; 135 void* hint; 136 } JitTraceRun; 137 138 /* 139 * Trace description as will appear in the translation cache. Note 140 * flexible array at end, as these will be of variable size. To 141 * conserve space in the translation cache, total length of JitTraceRun 142 * array must be recomputed via seqential scan if needed. 143 */ 144 typedef struct { 145 const Method* method; 146 JitTraceRun trace[]; 147 } JitTraceDescription; 148 149 typedef struct CompilerMethodStats { 150 const Method *method; // Used as hash entry signature 151 int dalvikSize; // # of bytes for dalvik bytecodes 152 int compiledDalvikSize; // # of compiled dalvik bytecodes 153 int nativeSize; // # of bytes for produced native code 154 } CompilerMethodStats; 155 156 bool dvmCompilerSetupCodeCache(void); 157 bool dvmCompilerArchInit(void); 158 void dvmCompilerArchDump(void); 159 bool dvmCompilerStartup(void); 160 void dvmCompilerShutdown(void); 161 bool dvmCompilerWorkEnqueue(const u2* pc, WorkOrderKind kind, void* info); 162 void *dvmCheckCodeCache(void *method); 163 bool dvmCompileMethod(const Method *method, JitTranslationInfo *info); 164 bool dvmCompileTrace(JitTraceDescription *trace, int numMaxInsts, 165 JitTranslationInfo *info, jmp_buf *bailPtr); 166 void dvmCompilerDumpStats(void); 167 void dvmCompilerDrainQueue(void); 168 void dvmJitUnchainAll(void); 169 void dvmCompilerSortAndPrintTraceProfiles(void); 170 171 struct CompilationUnit; 172 struct BasicBlock; 173 struct SSARepresentation; 174 struct GrowableList; 175 struct JitEntry; 176 177 void dvmInitializeSSAConversion(struct CompilationUnit *cUnit); 178 int dvmConvertSSARegToDalvik(struct CompilationUnit *cUnit, int ssaReg); 179 void dvmCompilerLoopOpt(struct CompilationUnit *cUnit); 180 void dvmCompilerNonLoopAnalysis(struct CompilationUnit *cUnit); 181 void dvmCompilerFindLiveIn(struct CompilationUnit *cUnit, 182 struct BasicBlock *bb); 183 void dvmCompilerDoSSAConversion(struct CompilationUnit *cUnit, 184 struct BasicBlock *bb); 185 void dvmCompilerDoConstantPropagation(struct CompilationUnit *cUnit, 186 struct BasicBlock *bb); 187 void dvmCompilerFindInductionVariables(struct CompilationUnit *cUnit, 188 struct BasicBlock *bb); 189 char *dvmCompilerGetDalvikDisassembly(DecodedInstruction *insn); 190 char *dvmCompilerGetSSAString(struct CompilationUnit *cUnit, 191 struct SSARepresentation *ssaRep); 192 void dvmCompilerDataFlowAnalysisDispatcher(struct CompilationUnit *cUnit, 193 void (*func)(struct CompilationUnit *, struct BasicBlock *)); 194 void dvmCompilerStateRefresh(void); 195 JitTraceDescription *dvmCopyTraceDescriptor(const u2 *pc, 196 const struct JitEntry *desc); 197 #endif /* _DALVIK_VM_COMPILER */ 198