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