Home | History | Annotate | Download | only in interp
      1 /*
      2  * Copyright (C) 2011 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  * Dalvik interpreter definitions.  These are internal to the interpreter.
     18  *
     19  * This includes defines, types, function declarations, and inline functions
     20  * that are common to all interpreter implementations.
     21  *
     22  * Functions and globals declared here are defined in Interp.c.
     23  */
     24 #ifndef DALVIK_INTERP_STATE_H_
     25 #define DALVIK_INTERP_STATE_H_
     26 
     27 /*
     28  * For x86 JIT. In the lowered code sequences for bytecodes, at most 10
     29  * temporary variables may be live at the same time. Therefore, at most
     30  * 10 temporary variables can be spilled at the same time.
     31 */
     32 #define MAX_SPILL_JIT_IA 10
     33 
     34 /*
     35  * Execution mode, e.g. interpreter vs. JIT.
     36  */
     37 enum ExecutionMode {
     38     kExecutionModeUnknown = 0,
     39     kExecutionModeInterpPortable,
     40     kExecutionModeInterpFast,
     41 #if defined(WITH_JIT)
     42     kExecutionModeJit,
     43 #endif
     44 #if defined(WITH_JIT)  /* IA only */
     45     kExecutionModeNcgO0,
     46     kExecutionModeNcgO1,
     47 #endif
     48 };
     49 
     50 /*
     51  * Execution sub modes, e.g. debugging, profiling, etc.
     52  * Treated as bit flags for fast access.  These values are used directly
     53  * by assembly code in the mterp interpeter and may also be used by
     54  * code generated by the JIT.  Take care when changing.
     55  */
     56 enum ExecutionSubModes {
     57     kSubModeNormal            = 0x0000,   /* No active subMode */
     58     kSubModeMethodTrace       = 0x0001,
     59     kSubModeEmulatorTrace     = 0x0002,
     60     kSubModeInstCounting      = 0x0004,
     61     kSubModeDebuggerActive    = 0x0008,
     62     kSubModeSuspendPending    = 0x0010,
     63     kSubModeCallbackPending   = 0x0020,
     64     kSubModeCountedStep       = 0x0040,
     65     kSubModeCheckAlways       = 0x0080,
     66     kSubModeJitTraceBuild     = 0x4000,
     67     kSubModeJitSV             = 0x8000,
     68     kSubModeDebugProfile   = (kSubModeMethodTrace |
     69                               kSubModeEmulatorTrace |
     70                               kSubModeInstCounting |
     71                               kSubModeDebuggerActive)
     72 };
     73 
     74 /*
     75  * Interpreter break flags.  When set, causes the interpreter to
     76  * break from normal execution and invoke the associated callback
     77  * handler.
     78  */
     79 
     80 enum InterpBreakFlags {
     81     kInterpNoBreak            = 0x00,    /* Don't check */
     82     kInterpSingleStep         = 0x01,    /* Check between each inst */
     83     kInterpSafePoint          = 0x02,    /* Check at safe points */
     84 };
     85 
     86 /*
     87  * Mapping between subModes and required check intervals.  Note: in
     88  * the future we might want to make this mapping target-dependent.
     89  */
     90 #define SINGLESTEP_BREAK_MASK ( kSubModeInstCounting | \
     91                                 kSubModeDebuggerActive | \
     92                                 kSubModeCountedStep | \
     93                                 kSubModeCheckAlways | \
     94                                 kSubModeJitSV | \
     95                                 kSubModeJitTraceBuild )
     96 
     97 #define SAFEPOINT_BREAK_MASK  ( kSubModeSuspendPending | \
     98                                 kSubModeCallbackPending )
     99 
    100 typedef bool (*SafePointCallback)(struct Thread* thread, void* arg);
    101 
    102 /*
    103  * Identify which break and submode flags should be local
    104  * to an interpreter activation.
    105  */
    106 #define LOCAL_SUBMODE (kSubModeJitTraceBuild)
    107 
    108 struct InterpSaveState {
    109     const u2*       pc;         // Dalvik PC
    110     u4*             curFrame;   // Dalvik frame pointer
    111     const Method    *method;    // Method being executed
    112     DvmDex*         methodClassDex;
    113     JValue          retval;
    114     void*           bailPtr;
    115 #if defined(WITH_TRACKREF_CHECKS)
    116     int             debugTrackedRefStart;
    117 #else
    118     int             unused;        // Keep struct size constant
    119 #endif
    120     struct InterpSaveState* prev;  // To follow nested activations
    121 } __attribute__ ((__packed__));
    122 
    123 #ifdef WITH_JIT
    124 /*
    125  * NOTE: Only entry points dispatched via [self + #offset] are put
    126  * in this struct, and there are six of them:
    127  * 1) dvmJitToInterpNormal: find if there is a corresponding compilation for
    128  *    the new dalvik PC. If so, chain the originating compilation with the
    129  *    target then jump to it. If the destination trace doesn't exist, update
    130  *    the profile count for that Dalvik PC.
    131  * 2) dvmJitToInterpNoChain: similar to dvmJitToInterpNormal but chaining is
    132  *    not performed.
    133  * 3) dvmJitToInterpPunt: use the fast interpreter to execute the next
    134  *    instruction(s) and stay there as long as it is appropriate to return
    135  *    to the compiled land. This is used when the jit'ed code is about to
    136  *    throw an exception.
    137  * 4) dvmJitToInterpSingleStep: use the portable interpreter to execute the
    138  *    next instruction only and return to pre-specified location in the
    139  *    compiled code to resume execution. This is mainly used as debugging
    140  *    feature to bypass problematic opcode implementations without
    141  *    disturbing the trace formation.
    142  * 5) dvmJitToTraceSelect: Similar to dvmJitToInterpNormal except for the
    143  *    profiling operation. If the new Dalvik PC is dominated by an already
    144  *    translated trace, directly request a new translation if the destinaion
    145  *    trace doesn't exist.
    146  * 6) dvmJitToBackwardBranch: special case for SELF_VERIFICATION when the
    147  *    destination Dalvik PC is included by the trace itself.
    148  */
    149 struct JitToInterpEntries {
    150     void (*dvmJitToInterpNormal)(void);
    151     void (*dvmJitToInterpNoChain)(void);
    152     void (*dvmJitToInterpPunt)(void);
    153     void (*dvmJitToInterpSingleStep)(void);
    154     void (*dvmJitToInterpTraceSelect)(void);
    155 #if defined(WITH_SELF_VERIFICATION)
    156     void (*dvmJitToInterpBackwardBranch)(void);
    157 #else
    158     void (*unused)(void);  // Keep structure size constant
    159 #endif
    160 };
    161 
    162 /* States of the interpreter when serving a JIT-related request */
    163 enum JitState {
    164     /* Entering states in the debug interpreter */
    165     kJitNot = 0,               // Non-JIT related reasons */
    166     kJitTSelectRequest = 1,    // Request a trace (subject to filtering)
    167     kJitTSelectRequestHot = 2, // Request a hot trace (bypass the filter)
    168     kJitSelfVerification = 3,  // Self Verification Mode
    169 
    170     /* Operational states in the debug interpreter */
    171     kJitTSelect = 4,           // Actively selecting a trace
    172     kJitTSelectEnd = 5,        // Done with the trace - wrap it up
    173     kJitDone = 6,              // No further JIT actions for interpBreak
    174 };
    175 
    176 #if defined(WITH_SELF_VERIFICATION)
    177 enum SelfVerificationState {
    178     kSVSIdle = 0,           // Idle
    179     kSVSStart = 1,          // Shadow space set up, running compiled code
    180     kSVSPunt = 2,           // Exiting compiled code by punting
    181     kSVSSingleStep = 3,     // Exiting compiled code by single stepping
    182     kSVSNoProfile = 4,      // Exiting compiled code and don't collect profiles
    183     kSVSTraceSelect = 5,    // Exiting compiled code and compile the next pc
    184     kSVSNormal = 6,         // Exiting compiled code normally
    185     kSVSNoChain = 7,        // Exiting compiled code by no chain
    186     kSVSBackwardBranch = 8, // Exiting compiled code with backward branch trace
    187     kSVSDebugInterp = 9,    // Normal state restored, running debug interpreter
    188 };
    189 #endif
    190 
    191 /* Number of entries in the 2nd level JIT profiler filter cache */
    192 #define JIT_TRACE_THRESH_FILTER_SIZE 32
    193 /* Number of low dalvik pc address bits to include in 2nd level filter key */
    194 #define JIT_TRACE_THRESH_FILTER_PC_BITS 4
    195 #define MAX_JIT_RUN_LEN 64
    196 
    197 enum JitHint {
    198    kJitHintNone = 0,
    199    kJitHintTaken = 1,         // Last inst in run was taken branch
    200    kJitHintNotTaken = 2,      // Last inst in run was not taken branch
    201    kJitHintNoBias = 3,        // Last inst in run was unbiased branch
    202 };
    203 
    204 /*
    205  * Element of a Jit trace description. If the isCode bit is set, it describes
    206  * a contiguous sequence of Dalvik byte codes.
    207  */
    208 struct JitCodeDesc {
    209     unsigned numInsts:8;     // Number of Byte codes in run
    210     unsigned runEnd:1;       // Run ends with last byte code
    211     JitHint hint:7;          // Hint to apply to final code of run
    212     u2 startOffset;          // Starting offset for trace run
    213 };
    214 
    215 /*
    216  * A complete list of trace runs passed to the compiler looks like the
    217  * following:
    218  *   frag1
    219  *   frag2
    220  *   frag3
    221  *   meta1
    222  *     :
    223  *   metan
    224  *   frag4
    225  *
    226  * frags 1-4 have the "isCode" field set and describe the location/length of
    227  * real code traces, while metas 1-n are misc information.
    228  * The meaning of the meta content is loosely defined. It is usually the code
    229  * fragment right before the first meta field (frag3 in this case) to
    230  * understand and parse them. Frag4 could be a dummy one with 0 "numInsts" but
    231  * the "runEnd" field set.
    232  *
    233  * For example, if a trace run contains a method inlining target, the class
    234  * descriptor/loader of "this" and the currently resolved method pointer are
    235  * three instances of meta information stored there.
    236  */
    237 struct JitTraceRun {
    238     union {
    239         JitCodeDesc frag;
    240         void*       meta;
    241     } info;
    242     u4 isCode:1;
    243     u4 unused:31;
    244 };
    245 
    246 #if defined(ARCH_IA32)
    247 /*
    248  * JIT code genarator optimization level
    249  */
    250 enum JitOptLevel {
    251     kJitOptLevelO0 = 0,
    252     kJitOptLevelO1 = 1,
    253 };
    254 #endif  // #if defined(ARCH_IA32)
    255 #endif
    256 
    257 #endif  // DALVIK_INTERP_STATE_H_
    258