| /* |
| * 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. |
| */ |
| |
| /* |
| * Code to initialize references to classes and members for use by |
| * lower-level VM facilities |
| */ |
| |
| #include "Dalvik.h" |
| |
| static bool initClassReference(ClassObject** pClass, const char* name) { |
| ClassObject* result; |
| |
| assert(*pClass == NULL); |
| |
| if (name[0] == '[') { |
| result = dvmFindArrayClass(name, NULL); |
| } else { |
| result = dvmFindSystemClassNoInit(name); |
| } |
| |
| if (result == NULL) { |
| LOGE("Could not find essential class %s", name); |
| return false; |
| } |
| |
| *pClass = result; |
| return true; |
| } |
| |
| static bool initClassReferences() { |
| static struct { ClassObject** ref; const char* name; } classes[] = { |
| /* |
| * Note: The class Class gets special treatment during initial |
| * VM startup, so there is no need to list it here. |
| */ |
| |
| /* The corest of the core classes */ |
| { &gDvm.classJavaLangObject, "Ljava/lang/Object;" }, |
| { &gDvm.exThrowable, "Ljava/lang/Throwable;" }, |
| |
| /* Slightly less core, but still down there, classes */ |
| { &gDvm.classJavaLangClassArray, "[Ljava/lang/Class;" }, |
| { &gDvm.classJavaLangClassLoader, "Ljava/lang/ClassLoader;" }, |
| { &gDvm.classJavaLangObjectArray, "[Ljava/lang/Object;"}, |
| { &gDvm.classJavaLangStackTraceElement, "Ljava/lang/StackTraceElement;" }, |
| { &gDvm.classJavaLangStackTraceElementArray, "[Ljava/lang/StackTraceElement;" }, |
| { &gDvm.classJavaLangString, "Ljava/lang/String;" }, |
| { &gDvm.classJavaLangThread, "Ljava/lang/Thread;" }, |
| { &gDvm.classJavaLangThreadGroup, "Ljava/lang/ThreadGroup;" }, |
| { &gDvm.classJavaLangVMThread, "Ljava/lang/VMThread;" }, |
| |
| /* Arrays of primitive types */ |
| { &gDvm.classArrayBoolean, "[Z" }, |
| { &gDvm.classArrayByte, "[B" }, |
| { &gDvm.classArrayShort, "[S" }, |
| { &gDvm.classArrayChar, "[C" }, |
| { &gDvm.classArrayInt, "[I" }, |
| { &gDvm.classArrayLong, "[J" }, |
| { &gDvm.classArrayFloat, "[F" }, |
| { &gDvm.classArrayDouble, "[D" }, |
| |
| /* Exception classes */ |
| { &gDvm.exAbstractMethodError, "Ljava/lang/AbstractMethodError;" }, |
| { &gDvm.exArithmeticException, "Ljava/lang/ArithmeticException;" }, |
| { &gDvm.exArrayIndexOutOfBoundsException, "Ljava/lang/ArrayIndexOutOfBoundsException;" }, |
| { &gDvm.exArrayStoreException, "Ljava/lang/ArrayStoreException;" }, |
| { &gDvm.exClassCastException, "Ljava/lang/ClassCastException;" }, |
| { &gDvm.exClassCircularityError, "Ljava/lang/ClassCircularityError;" }, |
| { &gDvm.exClassNotFoundException, "Ljava/lang/ClassNotFoundException;" }, |
| { &gDvm.exClassFormatError, "Ljava/lang/ClassFormatError;" }, |
| { &gDvm.exError, "Ljava/lang/Error;" }, |
| { &gDvm.exExceptionInInitializerError, "Ljava/lang/ExceptionInInitializerError;" }, |
| { &gDvm.exFileNotFoundException, "Ljava/io/FileNotFoundException;" }, |
| { &gDvm.exIOException, "Ljava/io/IOException;" }, |
| { &gDvm.exIllegalAccessError, "Ljava/lang/IllegalAccessError;" }, |
| { &gDvm.exIllegalAccessException, "Ljava/lang/IllegalAccessException;" }, |
| { &gDvm.exIllegalArgumentException, "Ljava/lang/IllegalArgumentException;" }, |
| { &gDvm.exIllegalMonitorStateException, "Ljava/lang/IllegalMonitorStateException;" }, |
| { &gDvm.exIllegalStateException, "Ljava/lang/IllegalStateException;" }, |
| { &gDvm.exIllegalThreadStateException, "Ljava/lang/IllegalThreadStateException;" }, |
| { &gDvm.exIncompatibleClassChangeError, "Ljava/lang/IncompatibleClassChangeError;" }, |
| { &gDvm.exInstantiationError, "Ljava/lang/InstantiationError;" }, |
| { &gDvm.exInstantiationException, "Ljava/lang/InstantiationException;" }, |
| { &gDvm.exInternalError, "Ljava/lang/InternalError;" }, |
| { &gDvm.exInterruptedException, "Ljava/lang/InterruptedException;" }, |
| { &gDvm.exLinkageError, "Ljava/lang/LinkageError;" }, |
| { &gDvm.exNegativeArraySizeException, "Ljava/lang/NegativeArraySizeException;" }, |
| { &gDvm.exNoClassDefFoundError, "Ljava/lang/NoClassDefFoundError;" }, |
| { &gDvm.exNoSuchFieldError, "Ljava/lang/NoSuchFieldError;" }, |
| { &gDvm.exNoSuchFieldException, "Ljava/lang/NoSuchFieldException;" }, |
| { &gDvm.exNoSuchMethodError, "Ljava/lang/NoSuchMethodError;" }, |
| { &gDvm.exNullPointerException, "Ljava/lang/NullPointerException;" }, |
| { &gDvm.exOutOfMemoryError, "Ljava/lang/OutOfMemoryError;" }, |
| { &gDvm.exRuntimeException, "Ljava/lang/RuntimeException;" }, |
| { &gDvm.exStackOverflowError, "Ljava/lang/StackOverflowError;" }, |
| { &gDvm.exStaleDexCacheError, "Ldalvik/system/StaleDexCacheError;" }, |
| { &gDvm.exStringIndexOutOfBoundsException, "Ljava/lang/StringIndexOutOfBoundsException;" }, |
| { &gDvm.exTypeNotPresentException, "Ljava/lang/TypeNotPresentException;" }, |
| { &gDvm.exUnsatisfiedLinkError, "Ljava/lang/UnsatisfiedLinkError;" }, |
| { &gDvm.exUnsupportedOperationException, "Ljava/lang/UnsupportedOperationException;" }, |
| { &gDvm.exVerifyError, "Ljava/lang/VerifyError;" }, |
| { &gDvm.exVirtualMachineError, "Ljava/lang/VirtualMachineError;" }, |
| |
| /* Other classes */ |
| { &gDvm.classJavaLangAnnotationAnnotationArray, "[Ljava/lang/annotation/Annotation;" }, |
| { &gDvm.classJavaLangAnnotationAnnotationArrayArray, |
| "[[Ljava/lang/annotation/Annotation;" }, |
| { &gDvm.classJavaLangReflectAccessibleObject, "Ljava/lang/reflect/AccessibleObject;" }, |
| { &gDvm.classJavaLangReflectConstructor, "Ljava/lang/reflect/Constructor;" }, |
| { &gDvm.classJavaLangReflectConstructorArray, "[Ljava/lang/reflect/Constructor;" }, |
| { &gDvm.classJavaLangReflectField, "Ljava/lang/reflect/Field;" }, |
| { &gDvm.classJavaLangReflectFieldArray, "[Ljava/lang/reflect/Field;" }, |
| { &gDvm.classJavaLangReflectMethod, "Ljava/lang/reflect/Method;" }, |
| { &gDvm.classJavaLangReflectMethodArray, "[Ljava/lang/reflect/Method;"}, |
| { &gDvm.classJavaLangReflectProxy, "Ljava/lang/reflect/Proxy;" }, |
| { &gDvm.classJavaNioReadWriteDirectByteBuffer, "Ljava/nio/ReadWriteDirectByteBuffer;" }, |
| { &gDvm.classOrgApacheHarmonyDalvikDdmcChunk, |
| "Lorg/apache/harmony/dalvik/ddmc/Chunk;" }, |
| { &gDvm.classOrgApacheHarmonyDalvikDdmcDdmServer, |
| "Lorg/apache/harmony/dalvik/ddmc/DdmServer;" }, |
| { &gDvm.classOrgApacheHarmonyLangAnnotationAnnotationFactory, |
| "Lorg/apache/harmony/lang/annotation/AnnotationFactory;" }, |
| { &gDvm.classOrgApacheHarmonyLangAnnotationAnnotationMember, |
| "Lorg/apache/harmony/lang/annotation/AnnotationMember;" }, |
| { &gDvm.classOrgApacheHarmonyLangAnnotationAnnotationMemberArray, |
| "[Lorg/apache/harmony/lang/annotation/AnnotationMember;" }, |
| |
| { NULL, NULL } |
| }; |
| |
| int i; |
| for (i = 0; classes[i].ref != NULL; i++) { |
| if (!initClassReference(classes[i].ref, classes[i].name)) { |
| return false; |
| } |
| } |
| |
| return true; |
| } |
| |
| static bool initFieldOffset(ClassObject* clazz, int *pOffset, |
| const char* name, const char* type) { |
| int offset = dvmFindFieldOffset(clazz, name, type); |
| if (offset < 0) { |
| LOGE("Could not find essential field %s.%s of type %s", clazz->descriptor, name, type); |
| return false; |
| } |
| |
| *pOffset = offset; |
| return true; |
| } |
| |
| static bool initFieldOffsets() { |
| struct FieldInfo { |
| int* offset; |
| const char* name; |
| const char* type; |
| }; |
| |
| static struct FieldInfo infoDdmcChunk[] = { |
| { &gDvm.offDalvikDdmcChunk_type, "type", "I" }, |
| { &gDvm.offDalvikDdmcChunk_data, "data", "[B" }, |
| { &gDvm.offDalvikDdmcChunk_offset, "offset", "I" }, |
| { &gDvm.offDalvikDdmcChunk_length, "length", "I" }, |
| { NULL, NULL, NULL } |
| }; |
| |
| static struct FieldInfo infoFileDescriptor[] = { |
| { &gDvm.offJavaIoFileDescriptor_descriptor, "descriptor", "I" }, |
| { NULL, NULL, NULL } |
| }; |
| |
| static struct FieldInfo infoString[] = { |
| { &gDvm.offJavaLangString_value, "value", "[C" }, |
| { &gDvm.offJavaLangString_count, "count", "I" }, |
| { &gDvm.offJavaLangString_offset, "offset", "I" }, |
| { &gDvm.offJavaLangString_hashCode, "hashCode", "I" }, |
| { NULL, NULL, NULL } |
| }; |
| |
| static struct FieldInfo infoThread[] = { |
| { &gDvm.offJavaLangThread_vmThread, "vmThread", "Ljava/lang/VMThread;" }, |
| { &gDvm.offJavaLangThread_group, "group", "Ljava/lang/ThreadGroup;" }, |
| { &gDvm.offJavaLangThread_daemon, "daemon", "Z" }, |
| { &gDvm.offJavaLangThread_name, "name", "Ljava/lang/String;" }, |
| { &gDvm.offJavaLangThread_priority, "priority", "I" }, |
| { &gDvm.offJavaLangThread_uncaughtHandler, "uncaughtHandler", "Ljava/lang/Thread$UncaughtExceptionHandler;" }, |
| { &gDvm.offJavaLangThread_contextClassLoader, "contextClassLoader", "Ljava/lang/ClassLoader;" }, |
| { NULL, NULL, NULL } |
| }; |
| |
| static struct FieldInfo infoThreadGroup[] = { |
| { &gDvm.offJavaLangThreadGroup_name, "name", "Ljava/lang/String;" }, |
| { &gDvm.offJavaLangThreadGroup_parent, "parent", "Ljava/lang/ThreadGroup;" }, |
| { NULL, NULL, NULL } |
| }; |
| |
| static struct FieldInfo infoThrowable[] = { |
| { &gDvm.offJavaLangThrowable_stackState, "stackState", "Ljava/lang/Object;" }, |
| { &gDvm.offJavaLangThrowable_cause, "cause", "Ljava/lang/Throwable;" }, |
| { NULL, NULL, NULL } |
| }; |
| |
| static struct FieldInfo infoVMThread[] = { |
| { &gDvm.offJavaLangVMThread_thread, "thread", "Ljava/lang/Thread;" }, |
| { &gDvm.offJavaLangVMThread_vmData, "vmData", "I" }, |
| { NULL, NULL, NULL } |
| }; |
| |
| static struct FieldInfo infoFinalizerReference[] = { |
| { &gDvm.offJavaLangRefFinalizerReference_zombie, "zombie", "Ljava/lang/Object;" }, |
| { NULL, NULL, NULL } |
| }; |
| |
| static struct FieldInfo infoConstructor[] = { |
| { &gDvm.offJavaLangReflectConstructor_slot, "slot", "I" }, |
| { &gDvm.offJavaLangReflectConstructor_declClass, "declaringClass", "Ljava/lang/Class;" }, |
| { NULL, NULL, NULL } |
| }; |
| |
| static struct FieldInfo infoField[] = { |
| { &gDvm.offJavaLangReflectField_slot, "slot", "I" }, |
| { &gDvm.offJavaLangReflectField_declClass, "declaringClass", "Ljava/lang/Class;" }, |
| { NULL, NULL, NULL } |
| }; |
| |
| static struct FieldInfo infoMethod[] = { |
| { &gDvm.offJavaLangReflectMethod_slot, "slot", "I" }, |
| { &gDvm.offJavaLangReflectMethod_declClass, "declaringClass", "Ljava/lang/Class;" }, |
| { NULL, NULL, NULL } |
| }; |
| |
| static struct FieldInfo infoProxy[] = { |
| { &gDvm.offJavaLangReflectProxy_h, "h", "Ljava/lang/reflect/InvocationHandler;" }, |
| { NULL, NULL, NULL } |
| }; |
| |
| static struct FieldInfo infoBuffer[] = { |
| { &gDvm.offJavaNioBuffer_capacity, "capacity", "I" }, |
| { &gDvm.offJavaNioBuffer_effectiveDirectAddress, "effectiveDirectAddress", "I" }, |
| { NULL, NULL, NULL } |
| }; |
| |
| static struct { const char* name; const struct FieldInfo* fields; } classes[] = { |
| { "Lorg/apache/harmony/dalvik/ddmc/Chunk;", infoDdmcChunk }, |
| { "Ljava/io/FileDescriptor;", infoFileDescriptor }, |
| { "Ljava/lang/String;", infoString }, |
| { "Ljava/lang/Thread;", infoThread }, |
| { "Ljava/lang/ThreadGroup;", infoThreadGroup }, |
| { "Ljava/lang/Throwable;", infoThrowable }, |
| { "Ljava/lang/VMThread;", infoVMThread }, |
| { "Ljava/lang/ref/FinalizerReference;", infoFinalizerReference }, |
| { "Ljava/lang/reflect/Constructor;", infoConstructor }, |
| { "Ljava/lang/reflect/Field;", infoField }, |
| { "Ljava/lang/reflect/Method;", infoMethod }, |
| { "Ljava/lang/reflect/Proxy;", infoProxy }, |
| { "Ljava/nio/Buffer;", infoBuffer }, |
| { NULL, NULL } |
| }; |
| |
| int i; |
| for (i = 0; classes[i].name != NULL; i++) { |
| const char* className = classes[i].name; |
| ClassObject* clazz = dvmFindSystemClassNoInit(className); |
| const struct FieldInfo* fields = classes[i].fields; |
| |
| if (clazz == NULL) { |
| LOGE("Could not find essential class %s for field lookup", className); |
| return false; |
| } |
| |
| int j; |
| for (j = 0; fields[j].offset != NULL; j++) { |
| if (!initFieldOffset(clazz, fields[j].offset, fields[j].name, fields[j].type)) { |
| return false; |
| } |
| } |
| } |
| |
| return true; |
| } |
| |
| static bool initDirectMethodReferenceByClass(Method** pMethod, ClassObject* clazz, |
| const char* name, const char* descriptor) { |
| Method* method = dvmFindDirectMethodByDescriptor(clazz, name, descriptor); |
| |
| if (method == NULL) { |
| LOGE("Could not find essential direct method %s.%s with descriptor %s", |
| clazz->descriptor, name, descriptor); |
| return false; |
| } |
| |
| *pMethod = method; |
| return true; |
| } |
| |
| static bool initDirectMethodReference(Method** pMethod, const char* className, |
| const char* name, const char* descriptor) { |
| ClassObject* clazz = dvmFindSystemClassNoInit(className); |
| |
| if (clazz == NULL) { |
| LOGE("Could not find essential class %s for direct method lookup", className); |
| return false; |
| } |
| |
| return initDirectMethodReferenceByClass(pMethod, clazz, name, descriptor); |
| } |
| |
| static bool initConstructorReferences() { |
| static struct { Method** method; const char* name; const char* descriptor; } constructors[] = { |
| { &gDvm.methJavaLangStackTraceElement_init, "Ljava/lang/StackTraceElement;", |
| "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;I)V" }, |
| { &gDvm.methJavaLangReflectConstructor_init, "Ljava/lang/reflect/Constructor;", |
| "(Ljava/lang/Class;[Ljava/lang/Class;[Ljava/lang/Class;I)V" }, |
| { &gDvm.methJavaLangReflectField_init, "Ljava/lang/reflect/Field;", |
| "(Ljava/lang/Class;Ljava/lang/Class;Ljava/lang/String;I)V" }, |
| { &gDvm.methJavaLangReflectMethod_init, "Ljava/lang/reflect/Method;", |
| "(Ljava/lang/Class;[Ljava/lang/Class;[Ljava/lang/Class;Ljava/lang/Class;" |
| "Ljava/lang/String;I)V" }, |
| { &gDvm.methJavaNioReadWriteDirectByteBuffer_init, "Ljava/nio/ReadWriteDirectByteBuffer;", |
| "(II)V" }, |
| { &gDvm.methOrgApacheHarmonyLangAnnotationAnnotationMember_init, |
| "Lorg/apache/harmony/lang/annotation/AnnotationMember;", |
| "(Ljava/lang/String;Ljava/lang/Object;Ljava/lang/Class;Ljava/lang/reflect/Method;)V" }, |
| { NULL, NULL, NULL } |
| }; |
| |
| int i; |
| for (i = 0; constructors[i].method != NULL; i++) { |
| if (!initDirectMethodReference(constructors[i].method, constructors[i].name, |
| "<init>", constructors[i].descriptor)) { |
| return false; |
| } |
| } |
| |
| return true; |
| } |
| |
| static bool initDirectMethodReferences() { |
| static struct { |
| Method** method; |
| const char* className; |
| const char* name; |
| const char* descriptor; |
| } methods[] = { |
| { &gDvm.methJavaLangClassLoader_getSystemClassLoader, "Ljava/lang/ClassLoader;", |
| "getSystemClassLoader", "()Ljava/lang/ClassLoader;" }, |
| { &gDvm.methJavaLangReflectProxy_constructorPrototype, "Ljava/lang/reflect/Proxy;", |
| "constructorPrototype", "(Ljava/lang/reflect/InvocationHandler;)V" }, |
| { &gDvm.methodTraceGcMethod, "Ldalvik/system/VMDebug;", "startGC", "()V" }, |
| { &gDvm.methodTraceClassPrepMethod, "Ldalvik/system/VMDebug;", "startClassPrep", "()V" }, |
| { &gDvm.methOrgApacheHarmonyLangAnnotationAnnotationFactory_createAnnotation, |
| "Lorg/apache/harmony/lang/annotation/AnnotationFactory;", "createAnnotation", |
| "(Ljava/lang/Class;[Lorg/apache/harmony/lang/annotation/AnnotationMember;)" |
| "Ljava/lang/annotation/Annotation;" }, |
| { &gDvm.methDalvikSystemNativeStart_main, "Ldalvik/system/NativeStart;", "main", "([Ljava/lang/String;)V" }, |
| { &gDvm.methDalvikSystemNativeStart_run, "Ldalvik/system/NativeStart;", "run", "()V" }, |
| { &gDvm.methJavaLangRefFinalizerReferenceAdd, |
| "Ljava/lang/ref/FinalizerReference;", "add", "(Ljava/lang/Object;)V" }, |
| { &gDvm.methDalvikDdmcServer_dispatch, |
| "Lorg/apache/harmony/dalvik/ddmc/DdmServer;", "dispatch", "(I[BII)Lorg/apache/harmony/dalvik/ddmc/Chunk;" }, |
| { &gDvm.methDalvikDdmcServer_broadcast, |
| "Lorg/apache/harmony/dalvik/ddmc/DdmServer;", "broadcast", "(I)V" }, |
| { &gDvm.methJavaLangRefReferenceQueueAdd, |
| "Ljava/lang/ref/ReferenceQueue;", "add", "(Ljava/lang/ref/Reference;)V" }, |
| { NULL, NULL, NULL, NULL } |
| }; |
| |
| int i; |
| for (i = 0; methods[i].method != NULL; i++) { |
| if (!initDirectMethodReference(methods[i].method, methods[i].className, |
| methods[i].name, methods[i].descriptor)) { |
| return false; |
| } |
| } |
| |
| return true; |
| } |
| |
| static bool initVirtualMethodOffset(int* pOffset, const char* className, |
| const char* name, const char* descriptor) { |
| ClassObject* clazz = dvmFindSystemClassNoInit(className); |
| |
| if (clazz == NULL) { |
| LOGE("Could not find essential class %s for virtual method lookup", className); |
| return false; |
| } |
| |
| Method* method = dvmFindVirtualMethodByDescriptor(clazz, name, descriptor); |
| |
| if (method == NULL) { |
| LOGE("Could not find essential virtual method %s.%s with descriptor %s", |
| clazz->descriptor, name, descriptor); |
| return false; |
| } |
| |
| *pOffset = method->methodIndex; |
| return true; |
| } |
| |
| static bool initVirtualMethodOffsets() { |
| static struct { |
| int* offset; |
| const char* className; |
| const char* name; |
| const char* descriptor; |
| } methods[] = { |
| { &gDvm.voffJavaLangClassLoader_loadClass, "Ljava/lang/ClassLoader;", "loadClass", |
| "(Ljava/lang/String;)Ljava/lang/Class;" }, |
| { &gDvm.voffJavaLangObject_equals, "Ljava/lang/Object;", "equals", |
| "(Ljava/lang/Object;)Z" }, |
| { &gDvm.voffJavaLangObject_hashCode, "Ljava/lang/Object;", "hashCode", "()I" }, |
| { &gDvm.voffJavaLangObject_toString, "Ljava/lang/Object;", "toString", |
| "()Ljava/lang/String;" }, |
| { &gDvm.voffJavaLangThread_run, "Ljava/lang/Thread;", "run", "()V" }, |
| { &gDvm.voffJavaLangThreadGroup_removeThread, "Ljava/lang/ThreadGroup;", |
| "removeThread", "(Ljava/lang/Thread;)V" }, |
| { NULL, NULL, NULL, NULL } |
| }; |
| |
| int i; |
| for (i = 0; methods[i].offset != NULL; i++) { |
| if (!initVirtualMethodOffset(methods[i].offset, methods[i].className, |
| methods[i].name, methods[i].descriptor)) { |
| return false; |
| } |
| } |
| |
| return true; |
| } |
| |
| static bool initFinalizerReference() |
| { |
| gDvm.classJavaLangRefFinalizerReference = |
| dvmFindSystemClass("Ljava/lang/ref/FinalizerReference;"); |
| return gDvm.classJavaLangRefFinalizerReference != NULL; |
| } |
| |
| static bool verifyStringOffset(const char* name, int actual, int expected) { |
| if (actual != expected) { |
| LOGE("InitRefs: String.%s offset = %d; expected %d", name, actual, expected); |
| return false; |
| } |
| |
| return true; |
| } |
| |
| static bool verifyStringOffsets() { |
| /* |
| * Various parts of the system use predefined constants for the |
| * offsets to a few fields of the class String. This code verifies |
| * that the predefined offsets match what is actually defined by |
| * the class. |
| */ |
| |
| bool ok = true; |
| ok &= verifyStringOffset("value", gDvm.offJavaLangString_value, STRING_FIELDOFF_VALUE); |
| ok &= verifyStringOffset("count", gDvm.offJavaLangString_count, STRING_FIELDOFF_COUNT); |
| ok &= verifyStringOffset("offset", gDvm.offJavaLangString_offset, STRING_FIELDOFF_OFFSET); |
| ok &= verifyStringOffset("hashCode", gDvm.offJavaLangString_hashCode, |
| STRING_FIELDOFF_HASHCODE); |
| |
| return ok; |
| } |
| |
| /* (documented in header) */ |
| bool dvmFindRequiredClassesAndMembers() { |
| /* |
| * Note: Under normal VM use, this is called by dvmStartup() |
| * in Init.c. For dex optimization, this is called as well, but in |
| * that case, the call is made from DexPrepare.c. |
| */ |
| |
| return initClassReferences() |
| && initFieldOffsets() |
| && initConstructorReferences() |
| && initDirectMethodReferences() |
| && initVirtualMethodOffsets() |
| && initFinalizerReference() |
| && verifyStringOffsets(); |
| } |
| |
| /* (documented in header) */ |
| bool dvmFindReferenceMembers(ClassObject* classReference) { |
| if (strcmp(classReference->descriptor, "Ljava/lang/ref/Reference;") != 0) { |
| LOGE("Attempt to set up the wrong class as Reference"); |
| return false; |
| } |
| return initFieldOffset(classReference, &gDvm.offJavaLangRefReference_pendingNext, |
| "pendingNext", "Ljava/lang/ref/Reference;") |
| && initFieldOffset(classReference, &gDvm.offJavaLangRefReference_queue, |
| "queue", "Ljava/lang/ref/ReferenceQueue;") |
| && initFieldOffset(classReference, &gDvm.offJavaLangRefReference_queueNext, |
| "queueNext", "Ljava/lang/ref/Reference;") |
| && initFieldOffset(classReference, &gDvm.offJavaLangRefReference_referent, |
| "referent", "Ljava/lang/Object;"); |
| } |