OSDN Git Service

Simplify merges of the annotation code.
[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,   "Lorg/apache/harmony/dalvik/ddmc/Chunk;" },
132         { &gDvm.classOrgApacheHarmonyDalvikDdmcDdmServer,
133           "Lorg/apache/harmony/dalvik/ddmc/DdmServer;" },
134         { &gDvm.classLibcoreReflectAnnotationFactory,     "Llibcore/reflect/AnnotationFactory;" },
135         { &gDvm.classLibcoreReflectAnnotationMember,      "Llibcore/reflect/AnnotationMember;" },
136         { &gDvm.classLibcoreReflectAnnotationMemberArray, "[Llibcore/reflect/AnnotationMember;" },
137
138         { NULL, NULL }
139     };
140
141     int i;
142     for (i = 0; classes[i].ref != NULL; i++) {
143         if (!initClassReference(classes[i].ref, classes[i].name)) {
144             return false;
145         }
146     }
147
148     return true;
149 }
150
151 static bool initFieldOffset(ClassObject* clazz, int *pOffset,
152         const char* name, const char* type) {
153     int offset = dvmFindFieldOffset(clazz, name, type);
154     if (offset < 0) {
155         ALOGE("Could not find essential field %s.%s of type %s", clazz->descriptor, name, type);
156         return false;
157     }
158
159     *pOffset = offset;
160     return true;
161 }
162
163 static bool initFieldOffsets() {
164     struct FieldInfo {
165         int* offset;
166         const char* name;
167         const char* type;
168     };
169
170     static struct FieldInfo infoDdmcChunk[] = {
171         { &gDvm.offDalvikDdmcChunk_type,   "type",   "I" },
172         { &gDvm.offDalvikDdmcChunk_data,   "data",   "[B" },
173         { &gDvm.offDalvikDdmcChunk_offset, "offset", "I" },
174         { &gDvm.offDalvikDdmcChunk_length, "length", "I" },
175         { NULL, NULL, NULL }
176     };
177
178     static struct FieldInfo infoFileDescriptor[] = {
179         { &gDvm.offJavaIoFileDescriptor_descriptor, "descriptor", "I" },
180         { NULL, NULL, NULL }
181     };
182
183     static struct FieldInfo infoString[] = {
184         { &gDvm.offJavaLangString_value,    "value",    "[C" },
185         { &gDvm.offJavaLangString_count,    "count",    "I" },
186         { &gDvm.offJavaLangString_offset,   "offset",   "I" },
187         { &gDvm.offJavaLangString_hashCode, "hashCode", "I" },
188         { NULL, NULL, NULL }
189     };
190
191     static struct FieldInfo infoThread[] = {
192         { &gDvm.offJavaLangThread_vmThread,           "vmThread",           "Ljava/lang/VMThread;" },
193         { &gDvm.offJavaLangThread_group,              "group",              "Ljava/lang/ThreadGroup;" },
194         { &gDvm.offJavaLangThread_daemon,             "daemon",             "Z" },
195         { &gDvm.offJavaLangThread_name,               "name",               "Ljava/lang/String;" },
196         { &gDvm.offJavaLangThread_priority,           "priority",           "I" },
197         { &gDvm.offJavaLangThread_uncaughtHandler,    "uncaughtHandler",    "Ljava/lang/Thread$UncaughtExceptionHandler;" },
198         { &gDvm.offJavaLangThread_contextClassLoader, "contextClassLoader", "Ljava/lang/ClassLoader;" },
199         { NULL, NULL, NULL }
200     };
201
202     static struct FieldInfo infoThreadGroup[] = {
203         { &gDvm.offJavaLangThreadGroup_name,   "name",   "Ljava/lang/String;" },
204         { &gDvm.offJavaLangThreadGroup_parent, "parent", "Ljava/lang/ThreadGroup;" },
205         { NULL, NULL, NULL }
206     };
207
208     static struct FieldInfo infoThrowable[] = {
209         { &gDvm.offJavaLangThrowable_stackState, "stackState", "Ljava/lang/Object;" },
210         { &gDvm.offJavaLangThrowable_cause,      "cause",      "Ljava/lang/Throwable;" },
211         { NULL, NULL, NULL }
212     };
213
214     static struct FieldInfo infoVMThread[] = {
215         { &gDvm.offJavaLangVMThread_thread, "thread", "Ljava/lang/Thread;" },
216         { &gDvm.offJavaLangVMThread_vmData, "vmData", "I" },
217         { NULL, NULL, NULL }
218     };
219
220     static struct FieldInfo infoFinalizerReference[] = {
221         { &gDvm.offJavaLangRefFinalizerReference_zombie, "zombie", "Ljava/lang/Object;" },
222         { NULL, NULL, NULL }
223     };
224
225     static struct FieldInfo infoConstructor[] = {
226         { &gDvm.offJavaLangReflectConstructor_slot,      "slot",           "I" },
227         { &gDvm.offJavaLangReflectConstructor_declClass, "declaringClass", "Ljava/lang/Class;" },
228         { NULL, NULL, NULL }
229     };
230
231     static struct FieldInfo infoField[] = {
232         { &gDvm.offJavaLangReflectField_slot,      "slot",           "I" },
233         { &gDvm.offJavaLangReflectField_declClass, "declaringClass", "Ljava/lang/Class;" },
234         { NULL, NULL, NULL }
235     };
236
237     static struct FieldInfo infoMethod[] = {
238         { &gDvm.offJavaLangReflectMethod_slot,      "slot",           "I" },
239         { &gDvm.offJavaLangReflectMethod_declClass, "declaringClass", "Ljava/lang/Class;" },
240         { NULL, NULL, NULL }
241     };
242
243     static struct FieldInfo infoProxy[] = {
244         { &gDvm.offJavaLangReflectProxy_h, "h", "Ljava/lang/reflect/InvocationHandler;" },
245         { NULL, NULL, NULL }
246     };
247
248     static struct FieldInfo infoBuffer[] = {
249         { &gDvm.offJavaNioBuffer_capacity,               "capacity",               "I" },
250         { &gDvm.offJavaNioBuffer_effectiveDirectAddress, "effectiveDirectAddress", "J" },
251         { NULL, NULL, NULL }
252     };
253
254     static struct { const char* name; const struct FieldInfo* fields; } classes[] = {
255         { "Lorg/apache/harmony/dalvik/ddmc/Chunk;", infoDdmcChunk },
256         { "Ljava/io/FileDescriptor;",               infoFileDescriptor },
257         { "Ljava/lang/String;",                     infoString },
258         { "Ljava/lang/Thread;",                     infoThread },
259         { "Ljava/lang/ThreadGroup;",                infoThreadGroup },
260         { "Ljava/lang/Throwable;",                  infoThrowable },
261         { "Ljava/lang/VMThread;",                   infoVMThread },
262         { "Ljava/lang/ref/FinalizerReference;", infoFinalizerReference },
263         { "Ljava/lang/reflect/Constructor;",        infoConstructor },
264         { "Ljava/lang/reflect/Field;",              infoField },
265         { "Ljava/lang/reflect/Method;",             infoMethod },
266         { "Ljava/lang/reflect/Proxy;",              infoProxy },
267         { "Ljava/nio/Buffer;",                      infoBuffer },
268         { NULL, NULL }
269     };
270
271     int i;
272     for (i = 0; classes[i].name != NULL; i++) {
273         const char* className = classes[i].name;
274         ClassObject* clazz = dvmFindSystemClassNoInit(className);
275         const struct FieldInfo* fields = classes[i].fields;
276
277         if (clazz == NULL) {
278             ALOGE("Could not find essential class %s for field lookup", className);
279             return false;
280         }
281
282         int j;
283         for (j = 0; fields[j].offset != NULL; j++) {
284             if (!initFieldOffset(clazz, fields[j].offset, fields[j].name, fields[j].type)) {
285                 return false;
286             }
287         }
288     }
289
290     return true;
291 }
292
293 static bool initDirectMethodReferenceByClass(Method** pMethod, ClassObject* clazz,
294         const char* name, const char* descriptor) {
295     Method* method = dvmFindDirectMethodByDescriptor(clazz, name, descriptor);
296
297     if (method == NULL) {
298         ALOGE("Could not find essential direct method %s.%s with descriptor %s",
299                 clazz->descriptor, name, descriptor);
300         return false;
301     }
302
303     *pMethod = method;
304     return true;
305 }
306
307 static bool initDirectMethodReference(Method** pMethod, const char* className,
308         const char* name, const char* descriptor) {
309     ClassObject* clazz = dvmFindSystemClassNoInit(className);
310
311     if (clazz == NULL) {
312         ALOGE("Could not find essential class %s for direct method lookup", className);
313         return false;
314     }
315
316     return initDirectMethodReferenceByClass(pMethod, clazz, name, descriptor);
317 }
318
319 static bool initConstructorReferences() {
320     static struct { Method** method; const char* name; const char* descriptor; } constructors[] = {
321         { &gDvm.methJavaLangStackTraceElement_init, "Ljava/lang/StackTraceElement;",
322           "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;I)V" },
323         { &gDvm.methJavaLangReflectConstructor_init, "Ljava/lang/reflect/Constructor;",
324           "(Ljava/lang/Class;[Ljava/lang/Class;[Ljava/lang/Class;I)V" },
325         { &gDvm.methJavaLangReflectField_init, "Ljava/lang/reflect/Field;",
326           "(Ljava/lang/Class;Ljava/lang/Class;Ljava/lang/String;I)V" },
327         { &gDvm.methJavaLangReflectMethod_init, "Ljava/lang/reflect/Method;",
328           "(Ljava/lang/Class;[Ljava/lang/Class;[Ljava/lang/Class;Ljava/lang/Class;"
329           "Ljava/lang/String;I)V" },
330         { &gDvm.methJavaNioDirectByteBuffer_init, "Ljava/nio/DirectByteBuffer;",
331           "(JI)V" },
332         { &gDvm.methOrgApacheHarmonyLangAnnotationAnnotationMember_init,
333           "Llibcore/reflect/AnnotationMember;",
334           "(Ljava/lang/String;Ljava/lang/Object;Ljava/lang/Class;Ljava/lang/reflect/Method;)V" },
335         { NULL, NULL, NULL }
336     };
337
338     int i;
339     for (i = 0; constructors[i].method != NULL; i++) {
340         if (!initDirectMethodReference(constructors[i].method, constructors[i].name,
341                 "<init>", constructors[i].descriptor)) {
342             return false;
343         }
344     }
345
346     return true;
347 }
348
349 static bool initDirectMethodReferences() {
350     static struct {
351         Method** method;
352         const char* className;
353         const char* name;
354         const char* descriptor;
355     } methods[] = {
356         { &gDvm.methJavaLangClassLoader_getSystemClassLoader, "Ljava/lang/ClassLoader;",
357           "getSystemClassLoader", "()Ljava/lang/ClassLoader;" },
358         { &gDvm.methJavaLangReflectProxy_constructorPrototype, "Ljava/lang/reflect/Proxy;",
359           "constructorPrototype", "(Ljava/lang/reflect/InvocationHandler;)V" },
360         { &gDvm.methodTraceGcMethod, "Ldalvik/system/VMDebug;", "startGC", "()V" },
361         { &gDvm.methodTraceClassPrepMethod, "Ldalvik/system/VMDebug;", "startClassPrep", "()V" },
362         { &gDvm.methOrgApacheHarmonyLangAnnotationAnnotationFactory_createAnnotation,
363           "Llibcore/reflect/AnnotationFactory;", "createAnnotation",
364           "(Ljava/lang/Class;[Llibcore/reflect/AnnotationMember;)"
365           "Ljava/lang/annotation/Annotation;" },
366         { &gDvm.methDalvikSystemNativeStart_main, "Ldalvik/system/NativeStart;", "main", "([Ljava/lang/String;)V" },
367         { &gDvm.methDalvikSystemNativeStart_run, "Ldalvik/system/NativeStart;", "run", "()V" },
368         { &gDvm.methJavaLangRefFinalizerReferenceAdd,
369           "Ljava/lang/ref/FinalizerReference;", "add", "(Ljava/lang/Object;)V" },
370         { &gDvm.methDalvikDdmcServer_dispatch,
371           "Lorg/apache/harmony/dalvik/ddmc/DdmServer;", "dispatch", "(I[BII)Lorg/apache/harmony/dalvik/ddmc/Chunk;" },
372         { &gDvm.methDalvikDdmcServer_broadcast,
373           "Lorg/apache/harmony/dalvik/ddmc/DdmServer;", "broadcast", "(I)V" },
374         { &gDvm.methJavaLangRefReferenceQueueAdd,
375           "Ljava/lang/ref/ReferenceQueue;", "add", "(Ljava/lang/ref/Reference;)V" },
376         { NULL, NULL, NULL, NULL }
377     };
378
379     int i;
380     for (i = 0; methods[i].method != NULL; i++) {
381         if (!initDirectMethodReference(methods[i].method, methods[i].className,
382                 methods[i].name, methods[i].descriptor)) {
383             return false;
384         }
385     }
386
387     return true;
388 }
389
390 static bool initVirtualMethodOffset(int* pOffset, const char* className,
391         const char* name, const char* descriptor) {
392     ClassObject* clazz = dvmFindSystemClassNoInit(className);
393
394     if (clazz == NULL) {
395         ALOGE("Could not find essential class %s for virtual method lookup", className);
396         return false;
397     }
398
399     Method* method = dvmFindVirtualMethodByDescriptor(clazz, name, descriptor);
400
401     if (method == NULL) {
402         ALOGE("Could not find essential virtual method %s.%s with descriptor %s",
403                 clazz->descriptor, name, descriptor);
404         return false;
405     }
406
407     *pOffset = method->methodIndex;
408     return true;
409 }
410
411 static bool initVirtualMethodOffsets() {
412     static struct {
413         int* offset;
414         const char* className;
415         const char* name;
416         const char* descriptor;
417     } methods[] = {
418         { &gDvm.voffJavaLangClassLoader_loadClass, "Ljava/lang/ClassLoader;", "loadClass",
419           "(Ljava/lang/String;)Ljava/lang/Class;" },
420         { &gDvm.voffJavaLangObject_equals, "Ljava/lang/Object;", "equals",
421           "(Ljava/lang/Object;)Z" },
422         { &gDvm.voffJavaLangObject_hashCode, "Ljava/lang/Object;", "hashCode", "()I" },
423         { &gDvm.voffJavaLangObject_toString, "Ljava/lang/Object;", "toString",
424           "()Ljava/lang/String;" },
425         { &gDvm.voffJavaLangThread_run, "Ljava/lang/Thread;", "run", "()V" },
426         { &gDvm.voffJavaLangThreadGroup_removeThread, "Ljava/lang/ThreadGroup;",
427           "removeThread", "(Ljava/lang/Thread;)V" },
428         { NULL, NULL, NULL, NULL }
429     };
430
431     int i;
432     for (i = 0; methods[i].offset != NULL; i++) {
433         if (!initVirtualMethodOffset(methods[i].offset, methods[i].className,
434                 methods[i].name, methods[i].descriptor)) {
435             return false;
436         }
437     }
438
439     return true;
440 }
441
442 static bool initFinalizerReference()
443 {
444     gDvm.classJavaLangRefFinalizerReference =
445         dvmFindSystemClass("Ljava/lang/ref/FinalizerReference;");
446     return gDvm.classJavaLangRefFinalizerReference != NULL;
447 }
448
449 static bool verifyStringOffset(const char* name, int actual, int expected) {
450     if (actual != expected) {
451         ALOGE("InitRefs: String.%s offset = %d; expected %d", name, actual, expected);
452         return false;
453     }
454
455     return true;
456 }
457
458 static bool verifyStringOffsets() {
459     /*
460      * Various parts of the system use predefined constants for the
461      * offsets to a few fields of the class String. This code verifies
462      * that the predefined offsets match what is actually defined by
463      * the class.
464      */
465
466     bool ok = true;
467     ok &= verifyStringOffset("value",    gDvm.offJavaLangString_value,  STRING_FIELDOFF_VALUE);
468     ok &= verifyStringOffset("count",    gDvm.offJavaLangString_count,  STRING_FIELDOFF_COUNT);
469     ok &= verifyStringOffset("offset",   gDvm.offJavaLangString_offset, STRING_FIELDOFF_OFFSET);
470     ok &= verifyStringOffset("hashCode", gDvm.offJavaLangString_hashCode,
471             STRING_FIELDOFF_HASHCODE);
472
473     return ok;
474 }
475
476 /* (documented in header) */
477 bool dvmFindRequiredClassesAndMembers() {
478     /*
479      * Note: Under normal VM use, this is called by dvmStartup()
480      * in Init.c. For dex optimization, this is called as well, but in
481      * that case, the call is made from DexPrepare.c.
482      */
483
484     return initClassReferences()
485         && initFieldOffsets()
486         && initConstructorReferences()
487         && initDirectMethodReferences()
488         && initVirtualMethodOffsets()
489         && initFinalizerReference()
490         && verifyStringOffsets();
491 }
492
493 /* (documented in header) */
494 bool dvmFindReferenceMembers(ClassObject* classReference) {
495     if (strcmp(classReference->descriptor, "Ljava/lang/ref/Reference;") != 0) {
496         ALOGE("Attempt to set up the wrong class as Reference");
497         return false;
498     }
499     return initFieldOffset(classReference, &gDvm.offJavaLangRefReference_pendingNext,
500                 "pendingNext", "Ljava/lang/ref/Reference;")
501         && initFieldOffset(classReference, &gDvm.offJavaLangRefReference_queue,
502                 "queue", "Ljava/lang/ref/ReferenceQueue;")
503         && initFieldOffset(classReference, &gDvm.offJavaLangRefReference_queueNext,
504                 "queueNext", "Ljava/lang/ref/Reference;")
505         && initFieldOffset(classReference, &gDvm.offJavaLangRefReference_referent,
506                 "referent", "Ljava/lang/Object;");
507 }