| /* |
| * 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 |
| #define _DALVIK_GLOBALS |
| |
| #include <cutils/array.h> |
| #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 |
| }; |
| |
| /* |
| * All fields are initialized to zero. |
| * |
| * Storage allocated here must be freed by a subsystem shutdown function or |
| * from within freeGlobals(). |
| */ |
| struct DvmGlobals { |
| /* |
| * Some options from the command line or environment. |
| */ |
| char* bootClassPathStr; |
| char* classPathStr; |
| |
| size_t heapStartingSize; |
| size_t heapMaximumSize; |
| size_t heapGrowthLimit; |
| size_t stackSize; |
| |
| 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; |
| |
| /* use wall clock as method profiler clock source? */ |
| bool profilerWallClock; |
| |
| /* |
| * 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); |
| |
| int jniGrefLimit; // 0 means no limit |
| 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; |
| |
| /* |
| * 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. |
| */ |
| Array* 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* classJavaNioReadWriteDirectByteBuffer; |
| ClassObject* classOrgApacheHarmonyLangAnnotationAnnotationFactory; |
| ClassObject* classOrgApacheHarmonyLangAnnotationAnnotationMember; |
| ClassObject* classOrgApacheHarmonyLangAnnotationAnnotationMemberArray; |
| 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; |
| |
| /* 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* methJavaNioReadWriteDirectByteBuffer_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; |
| int jniGlobalRefHiMark; |
| int jniGlobalRefLoMark; |
| |
| /* |
| * 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 */ |
| |
| /* |
| * 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; |
| |
| /* |
| * 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 |
| }; |
| |
| extern struct DvmGlobals gDvm; |
| |
| #if defined(WITH_JIT) |
| |
| /* 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; |
| |
| /* Bytes allocated for the code cache */ |
| 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; |
| |
| /* Disable JIT for selected opcodes - one bit for each opcode */ |
| char opList[(kNumPackedOpcodes+7)/8]; |
| |
| /* Disable JIT for selected methods */ |
| HashTable *methodTable; |
| |
| /* Flag to dump all compiled code */ |
| bool printMe; |
| |
| /* 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 |
| |
| /* 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; |
| |
| /** |
| * The JNI JavaVM object. Dalvik only supports a single VM per process. |
| */ |
| JavaVM* jniVm; |
| }; |
| |
| extern struct DvmJniGlobals gDvmJni; |
| |
| #endif /*_DALVIK_GLOBALS*/ |