Home | History | Annotate | Download | only in vm
      1 /*
      2  * Copyright (C) 2011 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 /*
     18  * Code to initialize references to classes and members for use by
     19  * lower-level VM facilities
     20  */
     21 
     22 #include "Dalvik.h"
     23 
     24 static bool initClassReference(ClassObject** pClass, const char* name) {
     25     ClassObject* result;
     26 
     27     assert(*pClass == NULL);
     28 
     29     if (name[0] == '[') {
     30         result = dvmFindArrayClass(name, NULL);
     31     } else {
     32         result = dvmFindSystemClassNoInit(name);
     33     }
     34 
     35     if (result == NULL) {
     36         ALOGE("Could not find essential class %s", name);
     37         return false;
     38     }
     39 
     40     *pClass = result;
     41     return true;
     42 }
     43 
     44 static bool initClassReferences() {
     45     static struct { ClassObject** ref; const char* name; } classes[] = {
     46         /*
     47          * Note: The class Class gets special treatment during initial
     48          * VM startup, so there is no need to list it here.
     49          */
     50 
     51         /* The corest of the core classes */
     52         { &gDvm.classJavaLangObject, "Ljava/lang/Object;" },
     53         { &gDvm.exThrowable,         "Ljava/lang/Throwable;" },
     54 
     55         /* Slightly less core, but still down there, classes */
     56         { &gDvm.classJavaLangClassArray,             "[Ljava/lang/Class;" },
     57         { &gDvm.classJavaLangClassLoader,            "Ljava/lang/ClassLoader;" },
     58         { &gDvm.classJavaLangObjectArray,            "[Ljava/lang/Object;"},
     59         { &gDvm.classJavaLangStackTraceElement,      "Ljava/lang/StackTraceElement;" },
     60         { &gDvm.classJavaLangStackTraceElementArray, "[Ljava/lang/StackTraceElement;" },
     61         { &gDvm.classJavaLangString,                 "Ljava/lang/String;" },
     62         { &gDvm.classJavaLangThread,                 "Ljava/lang/Thread;" },
     63         { &gDvm.classJavaLangThreadGroup,            "Ljava/lang/ThreadGroup;" },
     64         { &gDvm.classJavaLangVMThread,               "Ljava/lang/VMThread;" },
     65 
     66         /* Arrays of primitive types */
     67         { &gDvm.classArrayBoolean, "[Z" },
     68         { &gDvm.classArrayByte,    "[B" },
     69         { &gDvm.classArrayShort,   "[S" },
     70         { &gDvm.classArrayChar,    "[C" },
     71         { &gDvm.classArrayInt,     "[I" },
     72         { &gDvm.classArrayLong,    "[J" },
     73         { &gDvm.classArrayFloat,   "[F" },
     74         { &gDvm.classArrayDouble,  "[D" },
     75 
     76         /* Exception classes */
     77         { &gDvm.exAbstractMethodError,             "Ljava/lang/AbstractMethodError;" },
     78         { &gDvm.exArithmeticException,             "Ljava/lang/ArithmeticException;" },
     79         { &gDvm.exArrayIndexOutOfBoundsException,  "Ljava/lang/ArrayIndexOutOfBoundsException;" },
     80         { &gDvm.exArrayStoreException,             "Ljava/lang/ArrayStoreException;" },
     81         { &gDvm.exClassCastException,              "Ljava/lang/ClassCastException;" },
     82         { &gDvm.exClassCircularityError,           "Ljava/lang/ClassCircularityError;" },
     83         { &gDvm.exClassNotFoundException,          "Ljava/lang/ClassNotFoundException;" },
     84         { &gDvm.exClassFormatError,                "Ljava/lang/ClassFormatError;" },
     85         { &gDvm.exError,                           "Ljava/lang/Error;" },
     86         { &gDvm.exExceptionInInitializerError,     "Ljava/lang/ExceptionInInitializerError;" },
     87         { &gDvm.exFileNotFoundException,           "Ljava/io/FileNotFoundException;" },
     88         { &gDvm.exIOException,                     "Ljava/io/IOException;" },
     89         { &gDvm.exIllegalAccessError,              "Ljava/lang/IllegalAccessError;" },
     90         { &gDvm.exIllegalAccessException,          "Ljava/lang/IllegalAccessException;" },
     91         { &gDvm.exIllegalArgumentException,        "Ljava/lang/IllegalArgumentException;" },
     92         { &gDvm.exIllegalMonitorStateException,    "Ljava/lang/IllegalMonitorStateException;" },
     93         { &gDvm.exIllegalStateException,           "Ljava/lang/IllegalStateException;" },
     94         { &gDvm.exIllegalThreadStateException,     "Ljava/lang/IllegalThreadStateException;" },
     95         { &gDvm.exIncompatibleClassChangeError,    "Ljava/lang/IncompatibleClassChangeError;" },
     96         { &gDvm.exInstantiationError,              "Ljava/lang/InstantiationError;" },
     97         { &gDvm.exInstantiationException,          "Ljava/lang/InstantiationException;" },
     98         { &gDvm.exInternalError,                   "Ljava/lang/InternalError;" },
     99         { &gDvm.exInterruptedException,            "Ljava/lang/InterruptedException;" },
    100         { &gDvm.exLinkageError,                    "Ljava/lang/LinkageError;" },
    101         { &gDvm.exNegativeArraySizeException,      "Ljava/lang/NegativeArraySizeException;" },
    102         { &gDvm.exNoClassDefFoundError,            "Ljava/lang/NoClassDefFoundError;" },
    103         { &gDvm.exNoSuchFieldError,                "Ljava/lang/NoSuchFieldError;" },
    104         { &gDvm.exNoSuchFieldException,            "Ljava/lang/NoSuchFieldException;" },
    105         { &gDvm.exNoSuchMethodError,               "Ljava/lang/NoSuchMethodError;" },
    106         { &gDvm.exNullPointerException,            "Ljava/lang/NullPointerException;" },
    107         { &gDvm.exOutOfMemoryError,                "Ljava/lang/OutOfMemoryError;" },
    108         { &gDvm.exRuntimeException,                "Ljava/lang/RuntimeException;" },
    109         { &gDvm.exStackOverflowError,              "Ljava/lang/StackOverflowError;" },
    110         { &gDvm.exStaleDexCacheError,              "Ldalvik/system/StaleDexCacheError;" },
    111         { &gDvm.exStringIndexOutOfBoundsException, "Ljava/lang/StringIndexOutOfBoundsException;" },
    112         { &gDvm.exTypeNotPresentException,         "Ljava/lang/TypeNotPresentException;" },
    113         { &gDvm.exUnsatisfiedLinkError,            "Ljava/lang/UnsatisfiedLinkError;" },
    114         { &gDvm.exUnsupportedOperationException,   "Ljava/lang/UnsupportedOperationException;" },
    115         { &gDvm.exVerifyError,                     "Ljava/lang/VerifyError;" },
    116         { &gDvm.exVirtualMachineError,             "Ljava/lang/VirtualMachineError;" },
    117 
    118         /* Other classes */
    119         { &gDvm.classJavaLangAnnotationAnnotationArray, "[Ljava/lang/annotation/Annotation;" },
    120         { &gDvm.classJavaLangAnnotationAnnotationArrayArray,
    121           "[[Ljava/lang/annotation/Annotation;" },
    122         { &gDvm.classJavaLangReflectAccessibleObject,   "Ljava/lang/reflect/AccessibleObject;" },
    123         { &gDvm.classJavaLangReflectConstructor,        "Ljava/lang/reflect/Constructor;" },
    124         { &gDvm.classJavaLangReflectConstructorArray,   "[Ljava/lang/reflect/Constructor;" },
    125         { &gDvm.classJavaLangReflectField,              "Ljava/lang/reflect/Field;" },
    126         { &gDvm.classJavaLangReflectFieldArray,         "[Ljava/lang/reflect/Field;" },
    127         { &gDvm.classJavaLangReflectMethod,             "Ljava/lang/reflect/Method;" },
    128         { &gDvm.classJavaLangReflectMethodArray,        "[Ljava/lang/reflect/Method;"},
    129         { &gDvm.classJavaLangReflectProxy,              "Ljava/lang/reflect/Proxy;" },
    130         { &gDvm.classJavaNioDirectByteBuffer,           "Ljava/nio/DirectByteBuffer;" },
    131         { &gDvm.classOrgApacheHarmonyDalvikDdmcChunk,
    132           "Lorg/apache/harmony/dalvik/ddmc/Chunk;" },
    133         { &gDvm.classOrgApacheHarmonyDalvikDdmcDdmServer,
    134           "Lorg/apache/harmony/dalvik/ddmc/DdmServer;" },
    135         { &gDvm.classOrgApacheHarmonyLangAnnotationAnnotationFactory,
    136           "Lorg/apache/harmony/lang/annotation/AnnotationFactory;" },
    137         { &gDvm.classOrgApacheHarmonyLangAnnotationAnnotationMember,
    138           "Lorg/apache/harmony/lang/annotation/AnnotationMember;" },
    139         { &gDvm.classOrgApacheHarmonyLangAnnotationAnnotationMemberArray,
    140           "[Lorg/apache/harmony/lang/annotation/AnnotationMember;" },
    141 
    142         { NULL, NULL }
    143     };
    144 
    145     int i;
    146     for (i = 0; classes[i].ref != NULL; i++) {
    147         if (!initClassReference(classes[i].ref, classes[i].name)) {
    148             return false;
    149         }
    150     }
    151 
    152     return true;
    153 }
    154 
    155 static bool initFieldOffset(ClassObject* clazz, int *pOffset,
    156         const char* name, const char* type) {
    157     int offset = dvmFindFieldOffset(clazz, name, type);
    158     if (offset < 0) {
    159         ALOGE("Could not find essential field %s.%s of type %s", clazz->descriptor, name, type);
    160         return false;
    161     }
    162 
    163     *pOffset = offset;
    164     return true;
    165 }
    166 
    167 static bool initFieldOffsets() {
    168     struct FieldInfo {
    169         int* offset;
    170         const char* name;
    171         const char* type;
    172     };
    173 
    174     static struct FieldInfo infoDdmcChunk[] = {
    175         { &gDvm.offDalvikDdmcChunk_type,   "type",   "I" },
    176         { &gDvm.offDalvikDdmcChunk_data,   "data",   "[B" },
    177         { &gDvm.offDalvikDdmcChunk_offset, "offset", "I" },
    178         { &gDvm.offDalvikDdmcChunk_length, "length", "I" },
    179         { NULL, NULL, NULL }
    180     };
    181 
    182     static struct FieldInfo infoFileDescriptor[] = {
    183         { &gDvm.offJavaIoFileDescriptor_descriptor, "descriptor", "I" },
    184         { NULL, NULL, NULL }
    185     };
    186 
    187     static struct FieldInfo infoString[] = {
    188         { &gDvm.offJavaLangString_value,    "value",    "[C" },
    189         { &gDvm.offJavaLangString_count,    "count",    "I" },
    190         { &gDvm.offJavaLangString_offset,   "offset",   "I" },
    191         { &gDvm.offJavaLangString_hashCode, "hashCode", "I" },
    192         { NULL, NULL, NULL }
    193     };
    194 
    195     static struct FieldInfo infoThread[] = {
    196         { &gDvm.offJavaLangThread_vmThread,           "vmThread",           "Ljava/lang/VMThread;" },
    197         { &gDvm.offJavaLangThread_group,              "group",              "Ljava/lang/ThreadGroup;" },
    198         { &gDvm.offJavaLangThread_daemon,             "daemon",             "Z" },
    199         { &gDvm.offJavaLangThread_name,               "name",               "Ljava/lang/String;" },
    200         { &gDvm.offJavaLangThread_priority,           "priority",           "I" },
    201         { &gDvm.offJavaLangThread_uncaughtHandler,    "uncaughtHandler",    "Ljava/lang/Thread$UncaughtExceptionHandler;" },
    202         { &gDvm.offJavaLangThread_contextClassLoader, "contextClassLoader", "Ljava/lang/ClassLoader;" },
    203         { NULL, NULL, NULL }
    204     };
    205 
    206     static struct FieldInfo infoThreadGroup[] = {
    207         { &gDvm.offJavaLangThreadGroup_name,   "name",   "Ljava/lang/String;" },
    208         { &gDvm.offJavaLangThreadGroup_parent, "parent", "Ljava/lang/ThreadGroup;" },
    209         { NULL, NULL, NULL }
    210     };
    211 
    212     static struct FieldInfo infoThrowable[] = {
    213         { &gDvm.offJavaLangThrowable_stackState, "stackState", "Ljava/lang/Object;" },
    214         { &gDvm.offJavaLangThrowable_cause,      "cause",      "Ljava/lang/Throwable;" },
    215         { NULL, NULL, NULL }
    216     };
    217 
    218     static struct FieldInfo infoVMThread[] = {
    219         { &gDvm.offJavaLangVMThread_thread, "thread", "Ljava/lang/Thread;" },
    220         { &gDvm.offJavaLangVMThread_vmData, "vmData", "I" },
    221         { NULL, NULL, NULL }
    222     };
    223 
    224     static struct FieldInfo infoFinalizerReference[] = {
    225         { &gDvm.offJavaLangRefFinalizerReference_zombie, "zombie", "Ljava/lang/Object;" },
    226         { NULL, NULL, NULL }
    227     };
    228 
    229     static struct FieldInfo infoConstructor[] = {
    230         { &gDvm.offJavaLangReflectConstructor_slot,      "slot",           "I" },
    231         { &gDvm.offJavaLangReflectConstructor_declClass, "declaringClass", "Ljava/lang/Class;" },
    232         { NULL, NULL, NULL }
    233     };
    234 
    235     static struct FieldInfo infoField[] = {
    236         { &gDvm.offJavaLangReflectField_slot,      "slot",           "I" },
    237         { &gDvm.offJavaLangReflectField_declClass, "declaringClass", "Ljava/lang/Class;" },
    238         { NULL, NULL, NULL }
    239     };
    240 
    241     static struct FieldInfo infoMethod[] = {
    242         { &gDvm.offJavaLangReflectMethod_slot,      "slot",           "I" },
    243         { &gDvm.offJavaLangReflectMethod_declClass, "declaringClass", "Ljava/lang/Class;" },
    244         { NULL, NULL, NULL }
    245     };
    246 
    247     static struct FieldInfo infoProxy[] = {
    248         { &gDvm.offJavaLangReflectProxy_h, "h", "Ljava/lang/reflect/InvocationHandler;" },
    249         { NULL, NULL, NULL }
    250     };
    251 
    252     static struct FieldInfo infoBuffer[] = {
    253         { &gDvm.offJavaNioBuffer_capacity,               "capacity",               "I" },
    254         { &gDvm.offJavaNioBuffer_effectiveDirectAddress, "effectiveDirectAddress", "J" },
    255         { NULL, NULL, NULL }
    256     };
    257 
    258     static struct { const char* name; const struct FieldInfo* fields; } classes[] = {
    259         { "Lorg/apache/harmony/dalvik/ddmc/Chunk;", infoDdmcChunk },
    260         { "Ljava/io/FileDescriptor;",               infoFileDescriptor },
    261         { "Ljava/lang/String;",                     infoString },
    262         { "Ljava/lang/Thread;",                     infoThread },
    263         { "Ljava/lang/ThreadGroup;",                infoThreadGroup },
    264         { "Ljava/lang/Throwable;",                  infoThrowable },
    265         { "Ljava/lang/VMThread;",                   infoVMThread },
    266         { "Ljava/lang/ref/FinalizerReference;", infoFinalizerReference },
    267         { "Ljava/lang/reflect/Constructor;",        infoConstructor },
    268         { "Ljava/lang/reflect/Field;",              infoField },
    269         { "Ljava/lang/reflect/Method;",             infoMethod },
    270         { "Ljava/lang/reflect/Proxy;",              infoProxy },
    271         { "Ljava/nio/Buffer;",                      infoBuffer },
    272         { NULL, NULL }
    273     };
    274 
    275     int i;
    276     for (i = 0; classes[i].name != NULL; i++) {
    277         const char* className = classes[i].name;
    278         ClassObject* clazz = dvmFindSystemClassNoInit(className);
    279         const struct FieldInfo* fields = classes[i].fields;
    280 
    281         if (clazz == NULL) {
    282             ALOGE("Could not find essential class %s for field lookup", className);
    283             return false;
    284         }
    285 
    286         int j;
    287         for (j = 0; fields[j].offset != NULL; j++) {
    288             if (!initFieldOffset(clazz, fields[j].offset, fields[j].name, fields[j].type)) {
    289                 return false;
    290             }
    291         }
    292     }
    293 
    294     return true;
    295 }
    296 
    297 static bool initDirectMethodReferenceByClass(Method** pMethod, ClassObject* clazz,
    298         const char* name, const char* descriptor) {
    299     Method* method = dvmFindDirectMethodByDescriptor(clazz, name, descriptor);
    300 
    301     if (method == NULL) {
    302         ALOGE("Could not find essential direct method %s.%s with descriptor %s",
    303                 clazz->descriptor, name, descriptor);
    304         return false;
    305     }
    306 
    307     *pMethod = method;
    308     return true;
    309 }
    310 
    311 static bool initDirectMethodReference(Method** pMethod, const char* className,
    312         const char* name, const char* descriptor) {
    313     ClassObject* clazz = dvmFindSystemClassNoInit(className);
    314 
    315     if (clazz == NULL) {
    316         ALOGE("Could not find essential class %s for direct method lookup", className);
    317         return false;
    318     }
    319 
    320     return initDirectMethodReferenceByClass(pMethod, clazz, name, descriptor);
    321 }
    322 
    323 static bool initConstructorReferences() {
    324     static struct { Method** method; const char* name; const char* descriptor; } constructors[] = {
    325         { &gDvm.methJavaLangStackTraceElement_init, "Ljava/lang/StackTraceElement;",
    326           "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;I)V" },
    327         { &gDvm.methJavaLangReflectConstructor_init, "Ljava/lang/reflect/Constructor;",
    328           "(Ljava/lang/Class;[Ljava/lang/Class;[Ljava/lang/Class;I)V" },
    329         { &gDvm.methJavaLangReflectField_init, "Ljava/lang/reflect/Field;",
    330           "(Ljava/lang/Class;Ljava/lang/Class;Ljava/lang/String;I)V" },
    331         { &gDvm.methJavaLangReflectMethod_init, "Ljava/lang/reflect/Method;",
    332           "(Ljava/lang/Class;[Ljava/lang/Class;[Ljava/lang/Class;Ljava/lang/Class;"
    333           "Ljava/lang/String;I)V" },
    334         { &gDvm.methJavaNioDirectByteBuffer_init, "Ljava/nio/DirectByteBuffer;",
    335           "(JI)V" },
    336         { &gDvm.methOrgApacheHarmonyLangAnnotationAnnotationMember_init,
    337           "Lorg/apache/harmony/lang/annotation/AnnotationMember;",
    338           "(Ljava/lang/String;Ljava/lang/Object;Ljava/lang/Class;Ljava/lang/reflect/Method;)V" },
    339         { NULL, NULL, NULL }
    340     };
    341 
    342     int i;
    343     for (i = 0; constructors[i].method != NULL; i++) {
    344         if (!initDirectMethodReference(constructors[i].method, constructors[i].name,
    345                 "<init>", constructors[i].descriptor)) {
    346             return false;
    347         }
    348     }
    349 
    350     return true;
    351 }
    352 
    353 static bool initDirectMethodReferences() {
    354     static struct {
    355         Method** method;
    356         const char* className;
    357         const char* name;
    358         const char* descriptor;
    359     } methods[] = {
    360         { &gDvm.methJavaLangClassLoader_getSystemClassLoader, "Ljava/lang/ClassLoader;",
    361           "getSystemClassLoader", "()Ljava/lang/ClassLoader;" },
    362         { &gDvm.methJavaLangReflectProxy_constructorPrototype, "Ljava/lang/reflect/Proxy;",
    363           "constructorPrototype", "(Ljava/lang/reflect/InvocationHandler;)V" },
    364         { &gDvm.methodTraceGcMethod, "Ldalvik/system/VMDebug;", "startGC", "()V" },
    365         { &gDvm.methodTraceClassPrepMethod, "Ldalvik/system/VMDebug;", "startClassPrep", "()V" },
    366         { &gDvm.methOrgApacheHarmonyLangAnnotationAnnotationFactory_createAnnotation,
    367           "Lorg/apache/harmony/lang/annotation/AnnotationFactory;", "createAnnotation",
    368           "(Ljava/lang/Class;[Lorg/apache/harmony/lang/annotation/AnnotationMember;)"
    369           "Ljava/lang/annotation/Annotation;" },
    370         { &gDvm.methDalvikSystemNativeStart_main, "Ldalvik/system/NativeStart;", "main", "([Ljava/lang/String;)V" },
    371         { &gDvm.methDalvikSystemNativeStart_run, "Ldalvik/system/NativeStart;", "run", "()V" },
    372         { &gDvm.methJavaLangRefFinalizerReferenceAdd,
    373           "Ljava/lang/ref/FinalizerReference;", "add", "(Ljava/lang/Object;)V" },
    374         { &gDvm.methDalvikDdmcServer_dispatch,
    375           "Lorg/apache/harmony/dalvik/ddmc/DdmServer;", "dispatch", "(I[BII)Lorg/apache/harmony/dalvik/ddmc/Chunk;" },
    376         { &gDvm.methDalvikDdmcServer_broadcast,
    377           "Lorg/apache/harmony/dalvik/ddmc/DdmServer;", "broadcast", "(I)V" },
    378         { &gDvm.methJavaLangRefReferenceQueueAdd,
    379           "Ljava/lang/ref/ReferenceQueue;", "add", "(Ljava/lang/ref/Reference;)V" },
    380         { NULL, NULL, NULL, NULL }
    381     };
    382 
    383     int i;
    384     for (i = 0; methods[i].method != NULL; i++) {
    385         if (!initDirectMethodReference(methods[i].method, methods[i].className,
    386                 methods[i].name, methods[i].descriptor)) {
    387             return false;
    388         }
    389     }
    390 
    391     return true;
    392 }
    393 
    394 static bool initVirtualMethodOffset(int* pOffset, const char* className,
    395         const char* name, const char* descriptor) {
    396     ClassObject* clazz = dvmFindSystemClassNoInit(className);
    397 
    398     if (clazz == NULL) {
    399         ALOGE("Could not find essential class %s for virtual method lookup", className);
    400         return false;
    401     }
    402 
    403     Method* method = dvmFindVirtualMethodByDescriptor(clazz, name, descriptor);
    404 
    405     if (method == NULL) {
    406         ALOGE("Could not find essential virtual method %s.%s with descriptor %s",
    407                 clazz->descriptor, name, descriptor);
    408         return false;
    409     }
    410 
    411     *pOffset = method->methodIndex;
    412     return true;
    413 }
    414 
    415 static bool initVirtualMethodOffsets() {
    416     static struct {
    417         int* offset;
    418         const char* className;
    419         const char* name;
    420         const char* descriptor;
    421     } methods[] = {
    422         { &gDvm.voffJavaLangClassLoader_loadClass, "Ljava/lang/ClassLoader;", "loadClass",
    423           "(Ljava/lang/String;)Ljava/lang/Class;" },
    424         { &gDvm.voffJavaLangObject_equals, "Ljava/lang/Object;", "equals",
    425           "(Ljava/lang/Object;)Z" },
    426         { &gDvm.voffJavaLangObject_hashCode, "Ljava/lang/Object;", "hashCode", "()I" },
    427         { &gDvm.voffJavaLangObject_toString, "Ljava/lang/Object;", "toString",
    428           "()Ljava/lang/String;" },
    429         { &gDvm.voffJavaLangThread_run, "Ljava/lang/Thread;", "run", "()V" },
    430         { &gDvm.voffJavaLangThreadGroup_removeThread, "Ljava/lang/ThreadGroup;",
    431           "removeThread", "(Ljava/lang/Thread;)V" },
    432         { NULL, NULL, NULL, NULL }
    433     };
    434 
    435     int i;
    436     for (i = 0; methods[i].offset != NULL; i++) {
    437         if (!initVirtualMethodOffset(methods[i].offset, methods[i].className,
    438                 methods[i].name, methods[i].descriptor)) {
    439             return false;
    440         }
    441     }
    442 
    443     return true;
    444 }
    445 
    446 static bool initFinalizerReference()
    447 {
    448     gDvm.classJavaLangRefFinalizerReference =
    449         dvmFindSystemClass("Ljava/lang/ref/FinalizerReference;");
    450     return gDvm.classJavaLangRefFinalizerReference != NULL;
    451 }
    452 
    453 static bool verifyStringOffset(const char* name, int actual, int expected) {
    454     if (actual != expected) {
    455         ALOGE("InitRefs: String.%s offset = %d; expected %d", name, actual, expected);
    456         return false;
    457     }
    458 
    459     return true;
    460 }
    461 
    462 static bool verifyStringOffsets() {
    463     /*
    464      * Various parts of the system use predefined constants for the
    465      * offsets to a few fields of the class String. This code verifies
    466      * that the predefined offsets match what is actually defined by
    467      * the class.
    468      */
    469 
    470     bool ok = true;
    471     ok &= verifyStringOffset("value",    gDvm.offJavaLangString_value,  STRING_FIELDOFF_VALUE);
    472     ok &= verifyStringOffset("count",    gDvm.offJavaLangString_count,  STRING_FIELDOFF_COUNT);
    473     ok &= verifyStringOffset("offset",   gDvm.offJavaLangString_offset, STRING_FIELDOFF_OFFSET);
    474     ok &= verifyStringOffset("hashCode", gDvm.offJavaLangString_hashCode,
    475             STRING_FIELDOFF_HASHCODE);
    476 
    477     return ok;
    478 }
    479 
    480 /* (documented in header) */
    481 bool dvmFindRequiredClassesAndMembers() {
    482     /*
    483      * Note: Under normal VM use, this is called by dvmStartup()
    484      * in Init.c. For dex optimization, this is called as well, but in
    485      * that case, the call is made from DexPrepare.c.
    486      */
    487 
    488     return initClassReferences()
    489         && initFieldOffsets()
    490         && initConstructorReferences()
    491         && initDirectMethodReferences()
    492         && initVirtualMethodOffsets()
    493         && initFinalizerReference()
    494         && verifyStringOffsets();
    495 }
    496 
    497 /* (documented in header) */
    498 bool dvmFindReferenceMembers(ClassObject* classReference) {
    499     if (strcmp(classReference->descriptor, "Ljava/lang/ref/Reference;") != 0) {
    500         ALOGE("Attempt to set up the wrong class as Reference");
    501         return false;
    502     }
    503     return initFieldOffset(classReference, &gDvm.offJavaLangRefReference_pendingNext,
    504                 "pendingNext", "Ljava/lang/ref/Reference;")
    505         && initFieldOffset(classReference, &gDvm.offJavaLangRefReference_queue,
    506                 "queue", "Ljava/lang/ref/ReferenceQueue;")
    507         && initFieldOffset(classReference, &gDvm.offJavaLangRefReference_queueNext,
    508                 "queueNext", "Ljava/lang/ref/Reference;")
    509         && initFieldOffset(classReference, &gDvm.offJavaLangRefReference_referent,
    510                 "referent", "Ljava/lang/Object;");
    511 }
    512