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
initClassReference(ClassObject ** pClass,const char * name)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
initClassReferences()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.classJavaNioReadWriteDirectByteBuffer, "Ljava/nio/ReadWriteDirectByteBuffer;" },
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
initFieldOffset(ClassObject * clazz,int * pOffset,const char * name,const char * type)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
initFieldOffsets()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", "I" },
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
initDirectMethodReferenceByClass(Method ** pMethod,ClassObject * clazz,const char * name,const char * descriptor)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
initDirectMethodReference(Method ** pMethod,const char * className,const char * name,const char * descriptor)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
initConstructorReferences()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.methJavaNioReadWriteDirectByteBuffer_init, "Ljava/nio/ReadWriteDirectByteBuffer;",
335 "(II)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
initDirectMethodReferences()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
initVirtualMethodOffset(int * pOffset,const char * className,const char * name,const char * descriptor)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
initVirtualMethodOffsets()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
initFinalizerReference()446 static bool initFinalizerReference()
447 {
448 gDvm.classJavaLangRefFinalizerReference =
449 dvmFindSystemClass("Ljava/lang/ref/FinalizerReference;");
450 return gDvm.classJavaLangRefFinalizerReference != NULL;
451 }
452
verifyStringOffset(const char * name,int actual,int expected)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
verifyStringOffsets()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) */
dvmFindRequiredClassesAndMembers()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) */
dvmFindReferenceMembers(ClassObject * classReference)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