Home | History | Annotate | Download | only in compiler
      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