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.classJavaLangSystem,                    "Ljava/lang/System;" },
    131         { &gDvm.classJavaNioDirectByteBuffer,           "Ljava/nio/DirectByteBuffer;" },
    132         { &gDvm.classOrgApacheHarmonyDalvikDdmcChunk,   "Lorg/apache/harmony/dalvik/ddmc/Chunk;" },
    133         { &gDvm.classOrgApacheHarmonyDalvikDdmcDdmServer,
    134           "Lorg/apache/harmony/dalvik/ddmc/DdmServer;" },
    135         { &gDvm.classLibcoreReflectAnnotationFactory,     "Llibcore/reflect/AnnotationFactory;" },
    136         { &gDvm.classLibcoreReflectAnnotationMember,      "Llibcore/reflect/AnnotationMember;" },
    137         { &gDvm.classLibcoreReflectAnnotationMemberArray, "[Llibcore/reflect/AnnotationMember;" },
    138 
    139         { NULL, NULL }
    140     };
    141 
    142     int i;
    143     for (i = 0; classes[i].ref != NULL; i++) {
    144         if (!initClassReference(classes[i].ref, classes[i].name)) {
    145             return false;
    146         }
    147     }
    148 
    149     return true;
    150 }
    151 
    152 static bool initFieldOffset(ClassObject* clazz, int *pOffset,
    153         const char* name, const char* type) {
    154     int offset = dvmFindFieldOffset(clazz, name, type);
    155     if (offset < 0) {
    156         ALOGE("Could not find essential field %s.%s of type %s", clazz->descriptor, name, type);
    157         return false;
    158     }
    159 
    160     *pOffset = offset;
    161     return true;
    162 }
    163 
    164 static bool initFieldOffsets() {
    165     struct FieldInfo {
    166         int* offset;
    167         const char* name;
    168         const char* type;
    169     };
    170 
    171     static struct FieldInfo infoDdmcChunk[] = {
    172         { &gDvm.offDalvikDdmcChunk_type,   "type",   "I" },
    173         { &gDvm.offDalvikDdmcChunk_data,   "data",   "[B" },
    174         { &gDvm.offDalvikDdmcChunk_offset, "offset", "I" },
    175         { &gDvm.offDalvikDdmcChunk_length, "length", "I" },
    176         { NULL, NULL, NULL }
    177     };
    178 
    179     static struct FieldInfo infoFileDescriptor[] = {
    180         { &gDvm.offJavaIoFileDescriptor_descriptor, "descriptor", "I" },
    181         { NULL, NULL, NULL }
    182     };
    183 
    184     static struct FieldInfo infoString[] = {
    185         { &gDvm.offJavaLangString_value,    "value",    "[C" },
    186         { &gDvm.offJavaLangString_count,    "count",    "I" },
    187         { &gDvm.offJavaLangString_offset,   "offset",   "I" },
    188         { &gDvm.offJavaLangString_hashCode, "hashCode", "I" },
    189         { NULL, NULL, NULL }
    190     };
    191 
    192     static struct FieldInfo infoThread[] = {
    193         { &gDvm.offJavaLangThread_vmThread,           "vmThread",           "Ljava/lang/VMThread;" },
    194         { &gDvm.offJavaLangThread_group,              "group",              "Ljava/lang/ThreadGroup;" },
    195         { &gDvm.offJavaLangThread_daemon,             "daemon",             "Z" },
    196         { &gDvm.offJavaLangThread_name,               "name",               "Ljava/lang/String;" },
    197         { &gDvm.offJavaLangThread_priority,           "priority",           "I" },
    198         { &gDvm.offJavaLangThread_uncaughtHandler,    "uncaughtHandler",    "Ljava/lang/Thread$UncaughtExceptionHandler;" },
    199         { &gDvm.offJavaLangThread_contextClassLoader, "contextClassLoader", "Ljava/lang/ClassLoader;" },
    200         { NULL, NULL, NULL }
    201     };
    202 
    203     static struct FieldInfo infoThreadGroup[] = {
    204         { &gDvm.offJavaLangThreadGroup_name,   "name",   "Ljava/lang/String;" },
    205         { &gDvm.offJavaLangThreadGroup_parent, "parent", "Ljava/lang/ThreadGroup;" },
    206         { NULL, NULL, NULL }
    207     };
    208 
    209     static struct FieldInfo infoThrowable[] = {
    210         { &gDvm.offJavaLangThrowable_stackState, "stackState", "Ljava/lang/Object;" },
    211         { &gDvm.offJavaLangThrowable_cause,      "cause",      "Ljava/lang/Throwable;" },
    212         { NULL, NULL, NULL }
    213     };
    214 
    215     static struct FieldInfo infoVMThread[] = {
    216         { &gDvm.offJavaLangVMThread_thread, "thread", "Ljava/lang/Thread;" },
    217         { &gDvm.offJavaLangVMThread_vmData, "vmData", "I" },
    218         { NULL, NULL, NULL }
    219     };
    220 
    221     static struct FieldInfo infoFinalizerReference[] = {
    222         { &gDvm.offJavaLangRefFinalizerReference_zombie, "zombie", "Ljava/lang/Object;" },
    223         { NULL, NULL, NULL }
    224     };
    225 
    226     static struct FieldInfo infoConstructor[] = {
    227         { &gDvm.offJavaLangReflectConstructor_slot,      "slot",           "I" },
    228         { &gDvm.offJavaLangReflectConstructor_declClass, "declaringClass", "Ljava/lang/Class;" },
    229         { NULL, NULL, NULL }
    230     };
    231 
    232     static struct FieldInfo infoField[] = {
    233         { &gDvm.offJavaLangReflectField_slot,      "slot",           "I" },
    234         { &gDvm.offJavaLangReflectField_declClass, "declaringClass", "Ljava/lang/Class;" },
    235         { NULL, NULL, NULL }
    236     };
    237 
    238     static struct FieldInfo infoMethod[] = {
    239         { &gDvm.offJavaLangReflectMethod_slot,      "slot",           "I" },
    240         { &gDvm.offJavaLangReflectMethod_declClass, "declaringClass", "Ljava/lang/Class;" },
    241         { NULL, NULL, NULL }
    242     };
    243 
    244     static struct FieldInfo infoProxy[] = {
    245         { &gDvm.offJavaLangReflectProxy_h, "h", "Ljava/lang/reflect/InvocationHandler;" },
    246         { NULL, NULL, NULL }
    247     };
    248 
    249     static struct FieldInfo infoBuffer[] = {
    250         { &gDvm.offJavaNioBuffer_capacity,               "capacity",               "I" },
    251         { &gDvm.offJavaNioBuffer_effectiveDirectAddress, "effectiveDirectAddress", "J" },
    252         { NULL, NULL, NULL }
    253     };
    254 
    255     static struct { const char* name; const struct FieldInfo* fields; } classes[] = {
    256         { "Lorg/apache/harmony/dalvik/ddmc/Chunk;", infoDdmcChunk },
    257         { "Ljava/io/FileDescriptor;",               infoFileDescriptor },
    258         { "Ljava/lang/String;",                     infoString },
    259         { "Ljava/lang/Thread;",                     infoThread },
    260         { "Ljava/lang/ThreadGroup;",                infoThreadGroup },
    261         { "Ljava/lang/Throwable;",                  infoThrowable },
    262         { "Ljava/lang/VMThread;",                   infoVMThread },
    263         { "Ljava/lang/ref/FinalizerReference;", infoFinalizerReference },
    264         { "Ljava/lang/reflect/Constructor;",        infoConstructor },
    265         { "Ljava/lang/reflect/Field;",              infoField },
    266         { "Ljava/lang/reflect/Method;",             infoMethod },
    267         { "Ljava/lang/reflect/Proxy;",              infoProxy },
    268         { "Ljava/nio/Buffer;",                      infoBuffer },
    269         { NULL, NULL }
    270     };
    271 
    272     int i;
    273     for (i = 0; classes[i].name != NULL; i++) {
    274         const char* className = classes[i].name;
    275         ClassObject* clazz = dvmFindSystemClassNoInit(className);
    276         const struct FieldInfo* fields = classes[i].fields;
    277 
    278         if (clazz == NULL) {
    279             ALOGE("Could not find essential class %s for field lookup", className);
    280             return false;
    281         }
    282 
    283         int j;
    284         for (j = 0; fields[j].offset != NULL; j++) {
    285             if (!initFieldOffset(clazz, fields[j].offset, fields[j].name, fields[j].type)) {
    286                 return false;
    287             }
    288         }
    289     }
    290 
    291     return true;
    292 }
    293 
    294 static bool initDirectMethodReferenceByClass(Method** pMethod, ClassObject* clazz,
    295         const char* name, const char* descriptor) {
    296     Method* method = dvmFindDirectMethodByDescriptor(clazz, name, descriptor);
    297 
    298     if (method == NULL) {
    299         ALOGE("Could not find essential direct method %s.%s with descriptor %s",
    300                 clazz->descriptor, name, descriptor);
    301         return false;
    302     }
    303 
    304     *pMethod = method;
    305     return true;
    306 }
    307 
    308 static bool initDirectMethodReference(Method** pMethod, const char* className,
    309         const char* name, const char* descriptor) {
    310     ClassObject* clazz = dvmFindSystemClassNoInit(className);
    311 
    312     if (clazz == NULL) {
    313         ALOGE("Could not find essential class %s for direct method lookup", className);
    314         return false;
    315     }
    316 
    317     return initDirectMethodReferenceByClass(pMethod, clazz, name, descriptor);
    318 }
    319 
    320 static bool initConstructorReferences() {
    321     static struct { Method** method; const char* name; const char* descriptor; } constructors[] = {
    322         { &gDvm.methJavaLangStackTraceElement_init, "Ljava/lang/StackTraceElement;",
    323           "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;I)V" },
    324         { &gDvm.methJavaLangReflectConstructor_init, "Ljava/lang/reflect/Constructor;",
    325           "(Ljava/lang/Class;[Ljava/lang/Class;[Ljava/lang/Class;II)V" },
    326         { &gDvm.methJavaLangReflectField_init, "Ljava/lang/reflect/Field;",
    327           "(Ljava/lang/Class;Ljava/lang/Class;Ljava/lang/String;II)V" },
    328         { &gDvm.methJavaLangReflectMethod_init, "Ljava/lang/reflect/Method;",
    329           "(Ljava/lang/Class;[Ljava/lang/Class;[Ljava/lang/Class;Ljava/lang/Class;"
    330           "Ljava/lang/String;II)V" },
    331         { &gDvm.methJavaNioDirectByteBuffer_init, "Ljava/nio/DirectByteBuffer;",
    332           "(JI)V" },
    333         { &gDvm.methOrgApacheHarmonyLangAnnotationAnnotationMember_init,
    334           "Llibcore/reflect/AnnotationMember;",
    335           "(Ljava/lang/String;Ljava/lang/Object;Ljava/lang/Class;Ljava/lang/reflect/Method;)V" },
    336         { NULL, NULL, NULL }
    337     };
    338 
    339     int i;
    340     for (i = 0; constructors[i].method != NULL; i++) {
    341         if (!initDirectMethodReference(constructors[i].method, constructors[i].name,
    342                 "<init>", constructors[i].descriptor)) {
    343             return false;
    344         }
    345     }
    346 
    347     return true;
    348 }
    349 
    350 static bool initDirectMethodReferences() {
    351     static struct {
    352         Method** method;
    353         const char* className;
    354         const char* name;
    355         const char* descriptor;
    356     } methods[] = {
    357         { &gDvm.methJavaLangClassLoader_getSystemClassLoader, "Ljava/lang/ClassLoader;",
    358           "getSystemClassLoader", "()Ljava/lang/ClassLoader;" },
    359         { &gDvm.methJavaLangReflectProxy_constructorPrototype, "Ljava/lang/reflect/Proxy;",
    360           "constructorPrototype", "(Ljava/lang/reflect/InvocationHandler;)V" },
    361         { &gDvm.methJavaLangSystem_runFinalization, "Ljava/lang/System;",
    362           "runFinalization", "()V" },
    363 
    364         { &gDvm.methodTraceGcMethod, "Ldalvik/system/VMDebug;", "startGC", "()V" },
    365         { &gDvm.methodTraceClassPrepMethod, "Ldalvik/system/VMDebug;", "startClassPrep", "()V" },
    366         { &gDvm.methOrgApacheHarmonyLangAnnotationAnnotationFactory_createAnnotation,
    367           "Llibcore/reflect/AnnotationFactory;", "createAnnotation",
    368           "(Ljava/lang/Class;[Llibcore/reflect/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