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