OSDN Git Service

9c1e1cb9fd70d4855c13d8feef373aa8c812292c
[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.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 }