/*
* Copyright (C) 2008 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.
*/
/*
* Variables with library scope.
*
* Prefer this over scattered static and global variables -- it's easier to
* view the state in a debugger, it makes clean shutdown simpler, we can
* trivially dump the state into a crash log, and it dodges most naming
* collisions that will arise when we are embedded in a larger program.
*
* If we want multiple VMs per process, this can get stuffed into TLS (or
* accessed through a Thread field). May need to pass it around for some
* of the early initialization functions.
*/
#ifndef DALVIK_GLOBALS_H_
#define DALVIK_GLOBALS_H_
#include <string>
#include <vector>
#include <stdarg.h>
#include <pthread.h>
/* private structures */
struct GcHeap;
struct BreakpointSet;
struct InlineSub;
/*
* One of these for each -ea/-da/-esa/-dsa on the command line.
*/
struct AssertionControl {
char* pkgOrClass; /* package/class string, or NULL for esa/dsa */
int pkgOrClassLen; /* string length, for quick compare */
bool enable; /* enable or disable */
bool isPackage; /* string ended with "..."? */
};
/*
* Register map generation mode. Only applicable when generateRegisterMaps
* is enabled. (The "disabled" state is not folded into this because
* there are callers like dexopt that want to enable/disable without
* specifying the configuration details.)
*
* "TypePrecise" is slower and requires additional storage for the register
* maps, but allows type-precise GC. "LivePrecise" is even slower and
* requires additional heap during processing, but allows live-precise GC.
*/
enum RegisterMapMode {
kRegisterMapModeUnknown = 0,
kRegisterMapModeTypePrecise,
kRegisterMapModeLivePrecise
};
/*
* Profiler clock source.
*/
enum ProfilerClockSource {
kProfilerClockSourceThreadCpu,
kProfilerClockSourceWall,
kProfilerClockSourceDual,
};
/*
* All fields are initialized to zero.
*
* Storage allocated here must be freed by a subsystem shutdown function.
*/
struct DvmGlobals {
/*
* Some options from the command line or environment.
*/
char* bootClassPathStr;
char* classPathStr;
size_t heapStartingSize;
size_t heapMaximumSize;
size_t heapGrowthLimit;
bool lowMemoryMode;
double heapTargetUtilization;
size_t heapMinFree;
size_t heapMaxFree;
size_t stackSize;
size_t mainThreadStackSize;
bool verboseGc;
bool verboseJni;
bool verboseClass;
bool verboseShutdown;
bool jdwpAllowed; // debugging allowed for this process?
bool jdwpConfigured; // has debugging info been provided?
JdwpTransportType jdwpTransport;
bool jdwpServer;
char* jdwpHost;
int jdwpPort;
bool jdwpSuspend;
ProfilerClockSource profilerClockSource;
/*
* Lock profiling threshold value in milliseconds. Acquires that
* exceed threshold are logged. Acquires within the threshold are
* logged with a probability of $\frac{time}{threshold}$ . If the
* threshold is unset no additional logging occurs.
*/
u4 lockProfThreshold;
int (*vfprintfHook)(FILE*, const char*, va_list);
void (*exitHook)(int);
void (*abortHook)(void);
bool (*isSensitiveThreadHook)(void);
char* jniTrace;
bool reduceSignals;
bool noQuitHandler;
bool verifyDexChecksum;
char* stackTraceFile; // for SIGQUIT-inspired output
bool logStdio;
DexOptimizerMode dexOptMode;
DexClassVerifyMode classVerifyMode;
bool generateRegisterMaps;
RegisterMapMode registerMapMode;
bool monitorVerification;
bool dexOptForSmp;
/*
* GC option flags.
*/
bool preciseGc;
bool preVerify;
bool postVerify;
bool concurrentMarkSweep;
bool verifyCardTable;
bool disableExplicitGc;
int assertionCtrlCount;
AssertionControl* assertionCtrl;
ExecutionMode executionMode;
bool commonInit; /* whether common stubs are generated */
bool constInit; /* whether global constants are initialized */
/*
* VM init management.
*/
bool initializing;
bool optimizing;
/*
* java.lang.System properties set from the command line with -D.
* This is effectively a set, where later entries override earlier
* ones.
*/
std::vector<std::string>* properties;
/*
* Where the VM goes to find system classes.
*/
ClassPathEntry* bootClassPath;
/* used by the DEX optimizer to load classes from an unfinished DEX */
DvmDex* bootClassPathOptExtra;
bool optimizingBootstrapClass;
/*
* Loaded classes, hashed by class name. Each entry is a ClassObject*,
* allocated in GC space.
*/
HashTable* loadedClasses;
/*
* Value for the next class serial number to be assigned. This is
* incremented as we load classes. Failed loads and races may result
* in some numbers being skipped, and the serial number is not
* guaranteed to start at 1, so the current value should not be used
* as a count of loaded classes.
*/
volatile int classSerialNumber;
/*
* Classes with a low classSerialNumber are probably in the zygote, and
* their InitiatingLoaderList is not used, to promote sharing. The list is
* kept here instead.
*/
InitiatingLoaderList* initiatingLoaderList;
/*
* Interned strings.
*/
/* A mutex that guards access to the interned string tables. */
pthread_mutex_t internLock;
/* Hash table of strings interned by the user. */
HashTable* internedStrings;
/* Hash table of strings interned by the class loader. */
HashTable* literalStrings;
/*
* Classes constructed directly by the vm.
*/
/* the class Class */
ClassObject* classJavaLangClass;
/* synthetic classes representing primitive types */
ClassObject* typeVoid;
ClassObject* typeBoolean;
ClassObject* typeByte;
ClassObject* typeShort;
ClassObject* typeChar;
ClassObject* typeInt;
ClassObject* typeLong;
ClassObject* typeFloat;
ClassObject* typeDouble;
/* synthetic classes for arrays of primitives */
ClassObject* classArrayBoolean;
ClassObject* classArrayByte;
ClassObject* classArrayShort;
ClassObject* classArrayChar;
ClassObject* classArrayInt;
ClassObject* classArrayLong;
ClassObject* classArrayFloat;
ClassObject* classArrayDouble;
/*
* Quick lookups for popular classes used internally.
*/
ClassObject* classJavaLangClassArray;
ClassObject* classJavaLangClassLoader;
ClassObject* classJavaLangObject;
ClassObject* classJavaLangObjectArray;
ClassObject* classJavaLangString;
ClassObject* classJavaLangThread;
ClassObject* classJavaLangVMThread;
ClassObject* classJavaLangThreadGroup;
ClassObject* classJavaLangStackTraceElement;
ClassObject* classJavaLangStackTraceElementArray;
ClassObject* classJavaLangAnnotationAnnotationArray;
ClassObject* classJavaLangAnnotationAnnotationArrayArray;
ClassObject* classJavaLangReflectAccessibleObject;
ClassObject* classJavaLangReflectConstructor;
ClassObject* classJavaLangReflectConstructorArray;
ClassObject* classJavaLangReflectField;
ClassObject* classJavaLangReflectFieldArray;
ClassObject* classJavaLangReflectMethod;
ClassObject* classJavaLangReflectMethodArray;
ClassObject* classJavaLangReflectProxy;
ClassObject* classJavaLangSystem;
ClassObject* classJavaNioDirectByteBuffer;
ClassObject* classLibcoreReflectAnnotationFactory;
ClassObject* classLibcoreReflectAnnotationMember;
ClassObject* classLibcoreReflectAnnotationMemberArray;
ClassObject* classOrgApacheHarmonyDalvikDdmcChunk;
ClassObject* classOrgApacheHarmonyDalvikDdmcDdmServer;
ClassObject* classJavaLangRefFinalizerReference;
/*
* classes representing exception types. The names here don't include
* packages, just to keep the use sites a bit less verbose. All are
* in java.lang, except where noted.
*/
ClassObject* exAbstractMethodError;
ClassObject* exArithmeticException;
ClassObject* exArrayIndexOutOfBoundsException;
ClassObject* exArrayStoreException;
ClassObject* exClassCastException;
ClassObject* exClassCircularityError;
ClassObject* exClassFormatError;
ClassObject* exClassNotFoundException;
ClassObject* exError;
ClassObject* exExceptionInInitializerError;
ClassObject* exFileNotFoundException; /* in java.io */
ClassObject* exIOException; /* in java.io */
ClassObject* exIllegalAccessError;
ClassObject* exIllegalAccessException;
ClassObject* exIllegalArgumentException;
ClassObject* exIllegalMonitorStateException;
ClassObject* exIllegalStateException;
ClassObject* exIllegalThreadStateException;
ClassObject* exIncompatibleClassChangeError;
ClassObject* exInstantiationError;
ClassObject* exInstantiationException;
ClassObject* exInternalError;
ClassObject* exInterruptedException;
ClassObject* exLinkageError;
ClassObject* exNegativeArraySizeException;
ClassObject* exNoClassDefFoundError;
ClassObject* exNoSuchFieldError;
ClassObject* exNoSuchFieldException;
ClassObject* exNoSuchMethodError;
ClassObject* exNullPointerException;
ClassObject* exOutOfMemoryError;
ClassObject* exRuntimeException;
ClassObject* exStackOverflowError;
ClassObject* exStaleDexCacheError; /* in dalvik.system */
ClassObject* exStringIndexOutOfBoundsException;
ClassObject* exThrowable;
ClassObject* exTypeNotPresentException;
ClassObject* exUnsatisfiedLinkError;
ClassObject* exUnsupportedOperationException;
ClassObject* exVerifyError;
ClassObject* exVirtualMachineError;
/* method offsets - Object */
int voffJavaLangObject_equals;
int voffJavaLangObject_hashCode;
int voffJavaLangObject_toString;
/* field offsets - String */
int offJavaLangString_value;
int offJavaLangString_count;
int offJavaLangString_offset;
int offJavaLangString_hashCode;
/* field offsets - Thread */
int offJavaLangThread_vmThread;
int offJavaLangThread_group;
int offJavaLangThread_daemon;
int offJavaLangThread_name;
int offJavaLangThread_priority;
int offJavaLangThread_uncaughtHandler;
int offJavaLangThread_contextClassLoader;
/* method offsets - Thread */
int voffJavaLangThread_run;
/* field offsets - ThreadGroup */
int offJavaLangThreadGroup_name;
int offJavaLangThreadGroup_parent;
/* field offsets - VMThread */
int offJavaLangVMThread_thread;
int offJavaLangVMThread_vmData;
/* method offsets - ThreadGroup */
int voffJavaLangThreadGroup_removeThread;
/* field offsets - Throwable */
int offJavaLangThrowable_stackState;
int offJavaLangThrowable_cause;
/* method offsets - ClassLoader */
int voffJavaLangClassLoader_loadClass;
/* direct method pointers - ClassLoader */
Method* methJavaLangClassLoader_getSystemClassLoader;
/* field offsets - java.lang.reflect.* */
int offJavaLangReflectConstructor_slot;
int offJavaLangReflectConstructor_declClass;
int offJavaLangReflectField_slot;
int offJavaLangReflectField_declClass;
int offJavaLangReflectMethod_slot;
int offJavaLangReflectMethod_declClass;
/* field offsets - java.lang.ref.Reference */
int offJavaLangRefReference_referent;
int offJavaLangRefReference_queue;
int offJavaLangRefReference_queueNext;
int offJavaLangRefReference_pendingNext;
/* field offsets - java.lang.ref.FinalizerReference */
int offJavaLangRefFinalizerReference_zombie;
/* method pointers - java.lang.ref.ReferenceQueue */
Method* methJavaLangRefReferenceQueueAdd;
/* method pointers - java.lang.ref.FinalizerReference */
Method* methJavaLangRefFinalizerReferenceAdd;
/* constructor method pointers; no vtable involved, so use Method* */
Method* methJavaLangStackTraceElement_init;
Method* methJavaLangReflectConstructor_init;
Method* methJavaLangReflectField_init;
Method* methJavaLangReflectMethod_init;
Method* methOrgApacheHarmonyLangAnnotationAnnotationMember_init;
/* static method pointers - android.lang.annotation.* */
Method*
methOrgApacheHarmonyLangAnnotationAnnotationFactory_createAnnotation;
/* direct method pointers - java.lang.reflect.Proxy */
Method* methJavaLangReflectProxy_constructorPrototype;
/* field offsets - java.lang.reflect.Proxy */
int offJavaLangReflectProxy_h;
/* direct method pointer - java.lang.System.runFinalization */
Method* methJavaLangSystem_runFinalization;
/* field offsets - java.io.FileDescriptor */
int offJavaIoFileDescriptor_descriptor;
/* direct method pointers - dalvik.system.NativeStart */
Method* methDalvikSystemNativeStart_main;
Method* methDalvikSystemNativeStart_run;
/* assorted direct buffer helpers */
Method* methJavaNioDirectByteBuffer_init;
int offJavaNioBuffer_capacity;
int offJavaNioBuffer_effectiveDirectAddress;
/* direct method pointers - org.apache.harmony.dalvik.ddmc.DdmServer */
Method* methDalvikDdmcServer_dispatch;
Method* methDalvikDdmcServer_broadcast;
/* field offsets - org.apache.harmony.dalvik.ddmc.Chunk */
int offDalvikDdmcChunk_type;
int offDalvikDdmcChunk_data;
int offDalvikDdmcChunk_offset;
int offDalvikDdmcChunk_length;
/*
* Thread list. This always has at least one element in it (main),
* and main is always the first entry.
*
* The threadListLock is used for several things, including the thread
* start condition variable. Generally speaking, you must hold the
* threadListLock when:
* - adding/removing items from the list
* - waiting on or signaling threadStartCond
* - examining the Thread struct for another thread (this is to avoid
* one thread freeing the Thread struct while another thread is
* perusing it)
*/
Thread* threadList;
pthread_mutex_t threadListLock;
pthread_cond_t threadStartCond;
/*
* The thread code grabs this before suspending all threads. There
* are a few things that can cause a "suspend all":
* (1) the GC is starting;
* (2) the debugger has sent a "suspend all" request;
* (3) a thread has hit a breakpoint or exception that the debugger
* has marked as a "suspend all" event;
* (4) the SignalCatcher caught a signal that requires suspension.
* (5) (if implemented) the JIT needs to perform a heavyweight
* rearrangement of the translation cache or JitTable.
*
* Because we use "safe point" self-suspension, it is never safe to
* do a blocking "lock" call on this mutex -- if it has been acquired,
* somebody is probably trying to put you to sleep. The leading '_' is
* intended as a reminder that this lock is special.
*/
pthread_mutex_t _threadSuspendLock;
/*
* Guards Thread->suspendCount for all threads, and
* provides the lock for the condition variable that all suspended threads
* sleep on (threadSuspendCountCond).
*
* This has to be separate from threadListLock because of the way
* threads put themselves to sleep.
*/
pthread_mutex_t threadSuspendCountLock;
/*
* Suspended threads sleep on this. They should sleep on the condition
* variable until their "suspend count" is zero.
*
* Paired with "threadSuspendCountLock".
*/
pthread_cond_t threadSuspendCountCond;
/*
* Sum of all threads' suspendCount fields. Guarded by
* threadSuspendCountLock.
*/
int sumThreadSuspendCount;
/*
* MUTEX ORDERING: when locking multiple mutexes, always grab them in
* this order to avoid deadlock:
*
* (1) _threadSuspendLock (use lockThreadSuspend())
* (2) threadListLock (use dvmLockThreadList())
* (3) threadSuspendCountLock (use lockThreadSuspendCount())
*/
/*
* Thread ID bitmap. We want threads to have small integer IDs so
* we can use them in "thin locks".
*/
BitVector* threadIdMap;
/*
* Manage exit conditions. The VM exits when all non-daemon threads
* have exited. If the main thread returns early, we need to sleep
* on a condition variable.
*/
int nonDaemonThreadCount; /* must hold threadListLock to access */
pthread_cond_t vmExitCond;
/*
* The set of DEX files loaded by custom class loaders.
*/
HashTable* userDexFiles;
/*
* JNI global reference table.
*/
IndirectRefTable jniGlobalRefTable;
IndirectRefTable jniWeakGlobalRefTable;
pthread_mutex_t jniGlobalRefLock;
pthread_mutex_t jniWeakGlobalRefLock;
/*
* JNI pinned object table (used for primitive arrays).
*/
ReferenceTable jniPinRefTable;
pthread_mutex_t jniPinRefLock;
/*
* Native shared library table.
*/
HashTable* nativeLibs;
/*
* GC heap lock. Functions like gcMalloc() acquire this before making
* any changes to the heap. It is held throughout garbage collection.
*/
pthread_mutex_t gcHeapLock;
/*
* Condition variable to queue threads waiting to retry an
* allocation. Signaled after a concurrent GC is completed.
*/
pthread_cond_t gcHeapCond;
/* Opaque pointer representing the heap. */
GcHeap* gcHeap;
/* The card table base, modified as needed for marking cards. */
u1* biasedCardTableBase;
/*
* Pre-allocated throwables.
*/
Object* outOfMemoryObj;
Object* internalErrorObj;
Object* noClassDefFoundErrorObj;
/* Monitor list, so we can free them */
/*volatile*/ Monitor* monitorList;
/* Monitor for Thread.sleep() implementation */
Monitor* threadSleepMon;
/* set when we create a second heap inside the zygote */
bool newZygoteHeapAllocated;
/*
* TLS keys.
*/
pthread_key_t pthreadKeySelf; /* Thread*, for dvmThreadSelf */
/*
* Cache results of "A instanceof B".
*/
AtomicCache* instanceofCache;
/* inline substitution table, used during optimization */
InlineSub* inlineSubs;
/*
* Bootstrap class loader linear allocator.
*/
LinearAllocHdr* pBootLoaderAlloc;
/*
* Compute some stats on loaded classes.
*/
int numLoadedClasses;
int numDeclaredMethods;
int numDeclaredInstFields;
int numDeclaredStaticFields;
/* when using a native debugger, set this to suppress watchdog timers */
bool nativeDebuggerActive;
/*
* JDWP debugger support.
*
* Note: Each thread will normally determine whether the debugger is active
* for it by referring to its subMode flags. "debuggerActive" here should be
* seen as "debugger is making requests of 1 or more threads".
*/
bool debuggerConnected; /* debugger or DDMS is connected */
bool debuggerActive; /* debugger is making requests */
JdwpState* jdwpState;
/*
* Registry of objects known to the debugger.
*/
HashTable* dbgRegistry;
/*
* Debugger breakpoint table.
*/
BreakpointSet* breakpointSet;
/*
* Single-step control struct. We currently only allow one thread to
* be single-stepping at a time, which is all that really makes sense,
* but it's possible we may need to expand this to be per-thread.
*/
StepControl stepControl;
/*
* DDM features embedded in the VM.
*/
bool ddmThreadNotification;
/*
* Zygote (partially-started process) support
*/
bool zygote;
/*
* Used for tracking allocations that we report to DDMS. When the feature
* is enabled (through a DDMS request) the "allocRecords" pointer becomes
* non-NULL.
*/
pthread_mutex_t allocTrackerLock;
AllocRecord* allocRecords;
int allocRecordHead; /* most-recently-added entry */
int allocRecordCount; /* #of valid entries */
int allocRecordMax; /* Number of allocated entries. */
/*
* When a profiler is enabled, this is incremented. Distinct profilers
* include "dmtrace" method tracing, emulator method tracing, and
* possibly instruction counting.
*
* The purpose of this is to have a single value that shows whether any
* profiling is going on. Individual thread will normally check their
* thread-private subMode flags to take any profiling action.
*/
volatile int activeProfilers;
/*
* State for method-trace profiling.
*/
MethodTraceState methodTrace;
Method* methodTraceGcMethod;
Method* methodTraceClassPrepMethod;
/*
* State for emulator tracing.
*/
void* emulatorTracePage;
int emulatorTraceEnableCount;
/*
* Global state for memory allocation profiling.
*/
AllocProfState allocProf;
/*
* Pointers to the original methods for things that have been inlined.
* This makes it easy for us to output method entry/exit records for
* the method calls we're not actually making. (Used by method
* profiling.)
*/
Method** inlinedMethods;
/*
* Dalvik instruction counts (kNumPackedOpcodes entries).
*/
int* executedInstrCounts;
int instructionCountEnableCount;
/*
* Signal catcher thread (for SIGQUIT).
*/
pthread_t signalCatcherHandle;
bool haltSignalCatcher;
/*
* Stdout/stderr conversion thread.
*/
bool haltStdioConverter;
bool stdioConverterReady;
pthread_t stdioConverterHandle;
pthread_mutex_t stdioConverterLock;
pthread_cond_t stdioConverterCond;
int stdoutPipe[2];
int stderrPipe[2];
/*
* pid of the system_server process. We track it so that when system server
* crashes the Zygote process will be killed and restarted.
*/
pid_t systemServerPid;
int kernelGroupScheduling;
//#define COUNT_PRECISE_METHODS
#ifdef COUNT_PRECISE_METHODS
PointerSet* preciseMethods;
#endif
/* some RegisterMap statistics, useful during development */
void* registerMapStats;
#ifdef VERIFIER_STATS
VerifierStats verifierStats;
#endif
/* String pointed here will be deposited on the stack frame of dvmAbort */
const char *lastMessage;
};
extern struct DvmGlobals gDvm;
#if defined(WITH_JIT)
#define DEFAULT_CODE_CACHE_SIZE 0xffffffff
/* Trace profiling modes. Ordering matters - off states before on states */
enum TraceProfilingModes {
kTraceProfilingDisabled = 0, // Not profiling
kTraceProfilingPeriodicOff = 1, // Periodic profiling, off phase
kTraceProfilingContinuous = 2, // Always profiling
kTraceProfilingPeriodicOn = 3 // Periodic profiling, on phase
};
/*
* Exiting the compiled code w/o chaining will incur overhead to look up the
* target in the code cache which is extra work only when JIT is enabled. So
* we want to monitor it closely to make sure we don't have performance bugs.
*/
enum NoChainExits {
kInlineCacheMiss = 0,
kCallsiteInterpreted,
kSwitchOverflow,
kHeavyweightMonitor,
kNoChainExitLast,
};
/*
* JIT-specific global state
*/
struct DvmJitGlobals {
/*
* Guards writes to Dalvik PC (dPC), translated code address (codeAddr) and
* chain fields within the JIT hash table. Note carefully the access
* mechanism.
* Only writes are guarded, and the guarded fields must be updated in a
* specific order using atomic operations. Further, once a field is
* written it cannot be changed without halting all threads.
*
* The write order is:
* 1) codeAddr
* 2) dPC
* 3) chain [if necessary]
*
* This mutex also guards both read and write of curJitTableEntries.
*/
pthread_mutex_t tableLock;
/* The JIT hash table. Note that for access speed, copies of this pointer
* are stored in each thread. */
struct JitEntry *pJitEntryTable;
/* Array of compilation trigger threshold counters */
unsigned char *pProfTable;
/* Trace profiling counters */
struct JitTraceProfCounters *pJitTraceProfCounters;
/* Copy of pProfTable used for temporarily disabling the Jit */
unsigned char *pProfTableCopy;
/* Size of JIT hash table in entries. Must be a power of 2 */
unsigned int jitTableSize;
/* Mask used in hash function for JitTable. Should be jitTableSize-1 */
unsigned int jitTableMask;
/* How many entries in the JitEntryTable are in use */
unsigned int jitTableEntriesUsed;
/* Max bytes allocated for the code cache. Rough rule of thumb: 1K per 1M of system RAM */
unsigned int codeCacheSize;
/* Trigger for trace selection */
unsigned short threshold;
/* JIT Compiler Control */
bool haltCompilerThread;
bool blockingMode;
bool methodTraceSupport;
bool genSuspendPoll;
Thread* compilerThread;
pthread_t compilerHandle;
pthread_mutex_t compilerLock;
pthread_mutex_t compilerICPatchLock;
pthread_cond_t compilerQueueActivity;
pthread_cond_t compilerQueueEmpty;
volatile int compilerQueueLength;
int compilerHighWater;
int compilerWorkEnqueueIndex;
int compilerWorkDequeueIndex;
int compilerICPatchIndex;
/* JIT internal stats */
int compilerMaxQueued;
int translationChains;
/* Compiled code cache */
void* codeCache;
/*
* This is used to store the base address of an in-flight compilation whose
* class object pointers have been calculated to populate literal pool.
* Once the compiler thread has changed its status to VM_WAIT, we cannot
* guarantee whether GC has happened before the code address has been
* installed to the JIT table. Because of that, this field can only
* been cleared/overwritten by the compiler thread if it is in the
* THREAD_RUNNING state or in a safe point.
*/
void *inflightBaseAddr;
/* Translation cache version (protected by compilerLock */
int cacheVersion;
/* Bytes used by the code templates */
unsigned int templateSize;
/* Bytes already used in the code cache */
unsigned int codeCacheByteUsed;
/* Number of installed compilations in the cache */
unsigned int numCompilations;
/* Flag to indicate that the code cache is full */
bool codeCacheFull;
/* Page size - 1 */
unsigned int pageSizeMask;
/* Lock to change the protection type of the code cache */
pthread_mutex_t codeCacheProtectionLock;
/* Number of times that the code cache has been reset */
int numCodeCacheReset;
/* Number of times that the code cache reset request has been delayed */
int numCodeCacheResetDelayed;
/* true/false: compile/reject opcodes specified in the -Xjitop list */
bool includeSelectedOp;
/* true/false: compile/reject methods specified in the -Xjitmethod list */
bool includeSelectedMethod;
/* true/false: compile/reject traces with offset specified in the -Xjitoffset list */
bool includeSelectedOffset;
/* Disable JIT for selected opcodes - one bit for each opcode */
char opList[(kNumPackedOpcodes+7)/8];
/* Disable JIT for selected methods */
HashTable *methodTable;
/* Disable JIT for selected classes */
HashTable *classTable;
/* Disable JIT for selected offsets */
unsigned int pcTable[COMPILER_PC_OFFSET_SIZE];
int num_entries_pcTable;
/* Flag to dump all compiled code */
bool printMe;
/* Flag to dump compiled binary code in bytes */
bool printBinary;
/* Per-process debug flag toggled when receiving a SIGUSR2 */
bool receivedSIGUSR2;
/* Trace profiling mode */
TraceProfilingModes profileMode;
/* Periodic trace profiling countdown timer */
int profileCountdown;
/* Vector to disable selected optimizations */
int disableOpt;
/* Table to track the overall and trace statistics of hot methods */
HashTable* methodStatsTable;
/* Filter method compilation blacklist with call-graph information */
bool checkCallGraph;
/* New translation chain has been set up */
volatile bool hasNewChain;
#if defined(WITH_SELF_VERIFICATION)
/* Spin when error is detected, volatile so GDB can reset it */
volatile bool selfVerificationSpin;
#endif
/* Framework or stand-alone? */
bool runningInAndroidFramework;
/* Framework callback happened? */
bool alreadyEnabledViaFramework;
/* Framework requests to disable the JIT for good */
bool disableJit;
#if defined(SIGNATURE_BREAKPOINT)
/* Signature breakpoint */
u4 signatureBreakpointSize; // # of words
u4 *signatureBreakpoint; // Signature content
#endif
#if defined(WITH_JIT_TUNING)
/* Performance tuning counters */
int addrLookupsFound;
int addrLookupsNotFound;
int noChainExit[kNoChainExitLast];
int normalExit;
int puntExit;
int invokeMonomorphic;
int invokePolymorphic;
int invokeNative;
int invokeMonoGetterInlined;
int invokeMonoSetterInlined;
int invokePolyGetterInlined;
int invokePolySetterInlined;
int returnOp;
int icPatchInit;
int icPatchLockFree;
int icPatchQueued;
int icPatchRejected;
int icPatchDropped;
int codeCachePatches;
int numCompilerThreadBlockGC;
u8 jitTime;
u8 compilerThreadBlockGCStart;
u8 compilerThreadBlockGCTime;
u8 maxCompilerThreadBlockGCTime;
#endif
#if defined(ARCH_IA32)
JitOptLevel optLevel;
#endif
/* Place arrays at the end to ease the display in gdb sessions */
/* Work order queue for compilations */
CompilerWorkOrder compilerWorkQueue[COMPILER_WORK_QUEUE_SIZE];
/* Work order queue for predicted chain patching */
ICPatchWorkOrder compilerICPatchQueue[COMPILER_IC_PATCH_QUEUE_SIZE];
};
extern struct DvmJitGlobals gDvmJit;
#if defined(WITH_JIT_TUNING)
extern int gDvmICHitCount;
#endif
#endif
struct DvmJniGlobals {
bool useCheckJni;
bool warnOnly;
bool forceCopy;
// Provide backwards compatibility for pre-ICS apps on ICS.
bool workAroundAppJniBugs;
// Debugging help for third-party developers. Similar to -Xjnitrace.
bool logThirdPartyJni;
// We only support a single JavaVM per process.
JavaVM* jniVm;
};
extern struct DvmJniGlobals gDvmJni;
#endif // DALVIK_GLOBALS_H_