diff options
Diffstat (limited to 'vm/interp/InterpState.h')
-rw-r--r-- | vm/interp/InterpState.h | 237 |
1 files changed, 237 insertions, 0 deletions
diff --git a/vm/interp/InterpState.h b/vm/interp/InterpState.h new file mode 100644 index 0000000..37b7fdd --- /dev/null +++ b/vm/interp/InterpState.h @@ -0,0 +1,237 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * Dalvik interpreter definitions. These are internal to the interpreter. + * + * This includes defines, types, function declarations, and inline functions + * that are common to all interpreter implementations. + * + * Functions and globals declared here are defined in Interp.c. + */ +#ifndef DALVIK_INTERP_STATE_H_ +#define DALVIK_INTERP_STATE_H_ + +/* + * Execution mode, e.g. interpreter vs. JIT. + */ +enum ExecutionMode { + kExecutionModeUnknown = 0, + kExecutionModeInterpPortable, + kExecutionModeInterpFast, +#if defined(WITH_JIT) + kExecutionModeJit, +#endif +}; + +/* + * Execution sub modes, e.g. debugging, profiling, etc. + * Treated as bit flags for fast access. These values are used directly + * by assembly code in the mterp interpeter and may also be used by + * code generated by the JIT. Take care when changing. + */ +enum ExecutionSubModes { + kSubModeNormal = 0x0000, /* No active subMode */ + kSubModeMethodTrace = 0x0001, + kSubModeEmulatorTrace = 0x0002, + kSubModeInstCounting = 0x0004, + kSubModeDebuggerActive = 0x0008, + kSubModeSuspendPending = 0x0010, + kSubModeCallbackPending = 0x0020, + kSubModeCountedStep = 0x0040, + kSubModeCheckAlways = 0x0080, + kSubModeJitTraceBuild = 0x4000, + kSubModeJitSV = 0x8000, + kSubModeDebugProfile = (kSubModeMethodTrace | + kSubModeEmulatorTrace | + kSubModeInstCounting | + kSubModeDebuggerActive) +}; + +/* + * Interpreter break flags. When set, causes the interpreter to + * break from normal execution and invoke the associated callback + * handler. + */ + +enum InterpBreakFlags { + kInterpNoBreak = 0x00, /* Don't check */ + kInterpSingleStep = 0x01, /* Check between each inst */ + kInterpSafePoint = 0x02, /* Check at safe points */ +}; + +/* + * Mapping between subModes and required check intervals. Note: in + * the future we might want to make this mapping target-dependent. + */ +#define SINGLESTEP_BREAK_MASK ( kSubModeInstCounting | \ + kSubModeDebuggerActive | \ + kSubModeCountedStep | \ + kSubModeCheckAlways | \ + kSubModeJitSV | \ + kSubModeJitTraceBuild ) + +#define SAFEPOINT_BREAK_MASK ( kSubModeSuspendPending | \ + kSubModeCallbackPending ) + +typedef bool (*SafePointCallback)(struct Thread* thread, void* arg); + +/* + * Identify which break and submode flags should be local + * to an interpreter activation. + */ +#define LOCAL_SUBMODE (kSubModeJitTraceBuild) + +struct InterpSaveState { + const u2* pc; // Dalvik PC + u4* curFrame; // Dalvik frame pointer + const Method *method; // Method being executed + DvmDex* methodClassDex; + JValue retval; + void* bailPtr; +#if defined(WITH_TRACKREF_CHECKS) + int debugTrackedRefStart; +#else + int unused; // Keep struct size constant +#endif + struct InterpSaveState* prev; // To follow nested activations +} __attribute__ ((__packed__)); + +#ifdef WITH_JIT +/* + * NOTE: Only entry points dispatched via [self + #offset] are put + * in this struct, and there are six of them: + * 1) dvmJitToInterpNormal: find if there is a corresponding compilation for + * the new dalvik PC. If so, chain the originating compilation with the + * target then jump to it. If the destination trace doesn't exist, update + * the profile count for that Dalvik PC. + * 2) dvmJitToInterpNoChain: similar to dvmJitToInterpNormal but chaining is + * not performed. + * 3) dvmJitToInterpPunt: use the fast interpreter to execute the next + * instruction(s) and stay there as long as it is appropriate to return + * to the compiled land. This is used when the jit'ed code is about to + * throw an exception. + * 4) dvmJitToInterpSingleStep: use the portable interpreter to execute the + * next instruction only and return to pre-specified location in the + * compiled code to resume execution. This is mainly used as debugging + * feature to bypass problematic opcode implementations without + * disturbing the trace formation. + * 5) dvmJitToTraceSelect: Similar to dvmJitToInterpNormal except for the + * profiling operation. If the new Dalvik PC is dominated by an already + * translated trace, directly request a new translation if the destinaion + * trace doesn't exist. + * 6) dvmJitToBackwardBranch: special case for SELF_VERIFICATION when the + * destination Dalvik PC is included by the trace itself. + */ +struct JitToInterpEntries { + void (*dvmJitToInterpNormal)(void); + void (*dvmJitToInterpNoChain)(void); + void (*dvmJitToInterpPunt)(void); + void (*dvmJitToInterpSingleStep)(void); + void (*dvmJitToInterpTraceSelect)(void); +#if defined(WITH_SELF_VERIFICATION) + void (*dvmJitToInterpBackwardBranch)(void); +#else + void (*unused)(void); // Keep structure size constant +#endif +}; + +/* States of the interpreter when serving a JIT-related request */ +enum JitState { + /* Entering states in the debug interpreter */ + kJitNot = 0, // Non-JIT related reasons */ + kJitTSelectRequest = 1, // Request a trace (subject to filtering) + kJitTSelectRequestHot = 2, // Request a hot trace (bypass the filter) + kJitSelfVerification = 3, // Self Verification Mode + + /* Operational states in the debug interpreter */ + kJitTSelect = 4, // Actively selecting a trace + kJitTSelectEnd = 5, // Done with the trace - wrap it up + kJitDone = 6, // No further JIT actions for interpBreak +}; + +#if defined(WITH_SELF_VERIFICATION) +enum SelfVerificationState { + kSVSIdle = 0, // Idle + kSVSStart = 1, // Shadow space set up, running compiled code + kSVSPunt = 2, // Exiting compiled code by punting + kSVSSingleStep = 3, // Exiting compiled code by single stepping + kSVSNoProfile = 4, // Exiting compiled code and don't collect profiles + kSVSTraceSelect = 5, // Exiting compiled code and compile the next pc + kSVSNormal = 6, // Exiting compiled code normally + kSVSNoChain = 7, // Exiting compiled code by no chain + kSVSBackwardBranch = 8, // Exiting compiled code with backward branch trace + kSVSDebugInterp = 9, // Normal state restored, running debug interpreter +}; +#endif + +/* Number of entries in the 2nd level JIT profiler filter cache */ +#define JIT_TRACE_THRESH_FILTER_SIZE 32 +/* Number of low dalvik pc address bits to include in 2nd level filter key */ +#define JIT_TRACE_THRESH_FILTER_PC_BITS 4 +#define MAX_JIT_RUN_LEN 64 + +enum JitHint { + kJitHintNone = 0, + kJitHintTaken = 1, // Last inst in run was taken branch + kJitHintNotTaken = 2, // Last inst in run was not taken branch + kJitHintNoBias = 3, // Last inst in run was unbiased branch +}; + +/* + * Element of a Jit trace description. If the isCode bit is set, it describes + * a contiguous sequence of Dalvik byte codes. + */ +struct JitCodeDesc { + unsigned numInsts:8; // Number of Byte codes in run + unsigned runEnd:1; // Run ends with last byte code + JitHint hint:7; // Hint to apply to final code of run + u2 startOffset; // Starting offset for trace run +}; + +/* + * A complete list of trace runs passed to the compiler looks like the + * following: + * frag1 + * frag2 + * frag3 + * meta1 + * : + * metan + * frag4 + * + * frags 1-4 have the "isCode" field set and describe the location/length of + * real code traces, while metas 1-n are misc information. + * The meaning of the meta content is loosely defined. It is usually the code + * fragment right before the first meta field (frag3 in this case) to + * understand and parse them. Frag4 could be a dummy one with 0 "numInsts" but + * the "runEnd" field set. + * + * For example, if a trace run contains a method inlining target, the class + * descriptor/loader of "this" and the currently resolved method pointer are + * three instances of meta information stored there. + */ +struct JitTraceRun { + union { + JitCodeDesc frag; + void* meta; + } info; + u4 isCode:1; + u4 unused:31; +}; + +#endif + +#endif // DALVIK_INTERP_STATE_H_ |