dalvikコアデータ構造
42774 ワード
JavaVM,JNIEnv
typedef const struct JNINativeInterface* JNIEnv;
typedef const struct JNIInvokeInterface* JavaVM;
JNINativeInterfacestruct JNINativeInterface {
void* reserved0;
void* reserved1;
void* reserved2;
void* reserved3;
jint (*GetVersion)(JNIEnv *);
jclass (*DefineClass)(JNIEnv*, const char*, jobject, const jbyte*,
jsize);
jclass (*FindClass)(JNIEnv*, const char*);
......//
/* added in JNI 1.6 */
jobjectRefType (*GetObjectRefType)(JNIEnv*, jobject);
};
JNI Invoke Interface/*
* JNI invocation interface.
*/
struct JNIInvokeInterface {
void* reserved0;
void* reserved1;
void* reserved2;
jint (*DestroyJavaVM)(JavaVM*);
jint (*AttachCurrentThread)(JavaVM*, JNIEnv**, void*);
jint (*DetachCurrentThread)(JavaVM*);
jint (*GetEnv)(JavaVM*, void**, jint);
jint (*AttachCurrentThreadAsDaemon)(JavaVM*, JNIEnv**, void*);
};
JavaVMExtstruct JavaVMExt {
const struct JNIInvokeInterface* funcTable; /* must be first */
const struct JNIInvokeInterface* baseFuncTable;
/* head of list of JNIEnvs associated with this VM */
JNIEnvExt* envList;
pthread_mutex_t envListLock;
};
JNIEnvExtstruct JNIEnvExt {
const struct JNINativeInterface* funcTable; /* must be first */
const struct JNINativeInterface* baseFuncTable;
u4 envThreadId;
Thread* self;
/* if nonzero, we are in a "critical" JNI call */
int critical;
struct JNIEnvExt* prev;
struct JNIEnvExt* next;
};
DvmGlobals,gDvm/*
* 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;
};
DvmJniGlobals,gDvmJnistruct 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;
};