OSDN Git Service

am 813a3a2d: Merge "If dalvik wants ASCII casing, it needs to ask for it."
[android-x86/dalvik.git] / vm / InitRefs.cpp
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 }