1 /* 2 * Copyright (C) 2011 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 /* 18 * Code to initialize references to classes and members for use by 19 * lower-level VM facilities 20 */ 21 22 #include "Dalvik.h" 23 24 static bool initClassReference(ClassObject** pClass, const char* name) { 25 ClassObject* result; 26 27 assert(*pClass == NULL); 28 29 if (name[0] == '[') { 30 result = dvmFindArrayClass(name, NULL); 31 } else { 32 result = dvmFindSystemClassNoInit(name); 33 } 34 35 if (result == NULL) { 36 ALOGE("Could not find essential class %s", name); 37 return false; 38 } 39 40 *pClass = result; 41 return true; 42 } 43 44 static bool initClassReferences() { 45 static struct { ClassObject** ref; const char* name; } classes[] = { 46 /* 47 * Note: The class Class gets special treatment during initial 48 * VM startup, so there is no need to list it here. 49 */ 50 51 /* The corest of the core classes */ 52 { &gDvm.classJavaLangObject, "Ljava/lang/Object;" }, 53 { &gDvm.exThrowable, "Ljava/lang/Throwable;" }, 54 55 /* Slightly less core, but still down there, classes */ 56 { &gDvm.classJavaLangClassArray, "[Ljava/lang/Class;" }, 57 { &gDvm.classJavaLangClassLoader, "Ljava/lang/ClassLoader;" }, 58 { &gDvm.classJavaLangObjectArray, "[Ljava/lang/Object;"}, 59 { &gDvm.classJavaLangStackTraceElement, "Ljava/lang/StackTraceElement;" }, 60 { &gDvm.classJavaLangStackTraceElementArray, "[Ljava/lang/StackTraceElement;" }, 61 { &gDvm.classJavaLangString, "Ljava/lang/String;" }, 62 { &gDvm.classJavaLangThread, "Ljava/lang/Thread;" }, 63 { &gDvm.classJavaLangThreadGroup, "Ljava/lang/ThreadGroup;" }, 64 { &gDvm.classJavaLangVMThread, "Ljava/lang/VMThread;" }, 65 66 /* Arrays of primitive types */ 67 { &gDvm.classArrayBoolean, "[Z" }, 68 { &gDvm.classArrayByte, "[B" }, 69 { &gDvm.classArrayShort, "[S" }, 70 { &gDvm.classArrayChar, "[C" }, 71 { &gDvm.classArrayInt, "[I" }, 72 { &gDvm.classArrayLong, "[J" }, 73 { &gDvm.classArrayFloat, "[F" }, 74 { &gDvm.classArrayDouble, "[D" }, 75 76 /* Exception classes */ 77 { &gDvm.exAbstractMethodError, "Ljava/lang/AbstractMethodError;" }, 78 { &gDvm.exArithmeticException, "Ljava/lang/ArithmeticException;" }, 79 { &gDvm.exArrayIndexOutOfBoundsException, "Ljava/lang/ArrayIndexOutOfBoundsException;" }, 80 { &gDvm.exArrayStoreException, "Ljava/lang/ArrayStoreException;" }, 81 { &gDvm.exClassCastException, "Ljava/lang/ClassCastException;" }, 82 { &gDvm.exClassCircularityError, "Ljava/lang/ClassCircularityError;" }, 83 { &gDvm.exClassNotFoundException, "Ljava/lang/ClassNotFoundException;" }, 84 { &gDvm.exClassFormatError, "Ljava/lang/ClassFormatError;" }, 85 { &gDvm.exError, "Ljava/lang/Error;" }, 86 { &gDvm.exExceptionInInitializerError, "Ljava/lang/ExceptionInInitializerError;" }, 87 { &gDvm.exFileNotFoundException, "Ljava/io/FileNotFoundException;" }, 88 { &gDvm.exIOException, "Ljava/io/IOException;" }, 89 { &gDvm.exIllegalAccessError, "Ljava/lang/IllegalAccessError;" }, 90 { &gDvm.exIllegalAccessException, "Ljava/lang/IllegalAccessException;" }, 91 { &gDvm.exIllegalArgumentException, "Ljava/lang/IllegalArgumentException;" }, 92 { &gDvm.exIllegalMonitorStateException, "Ljava/lang/IllegalMonitorStateException;" }, 93 { &gDvm.exIllegalStateException, "Ljava/lang/IllegalStateException;" }, 94 { &gDvm.exIllegalThreadStateException, "Ljava/lang/IllegalThreadStateException;" }, 95 { &gDvm.exIncompatibleClassChangeError, "Ljava/lang/IncompatibleClassChangeError;" }, 96 { &gDvm.exInstantiationError, "Ljava/lang/InstantiationError;" }, 97 { &gDvm.exInstantiationException, "Ljava/lang/InstantiationException;" }, 98 { &gDvm.exInternalError, "Ljava/lang/InternalError;" }, 99 { &gDvm.exInterruptedException, "Ljava/lang/InterruptedException;" }, 100 { &gDvm.exLinkageError, "Ljava/lang/LinkageError;" }, 101 { &gDvm.exNegativeArraySizeException, "Ljava/lang/NegativeArraySizeException;" }, 102 { &gDvm.exNoClassDefFoundError, "Ljava/lang/NoClassDefFoundError;" }, 103 { &gDvm.exNoSuchFieldError, "Ljava/lang/NoSuchFieldError;" }, 104 { &gDvm.exNoSuchFieldException, "Ljava/lang/NoSuchFieldException;" }, 105 { &gDvm.exNoSuchMethodError, "Ljava/lang/NoSuchMethodError;" }, 106 { &gDvm.exNullPointerException, "Ljava/lang/NullPointerException;" }, 107 { &gDvm.exOutOfMemoryError, "Ljava/lang/OutOfMemoryError;" }, 108 { &gDvm.exRuntimeException, "Ljava/lang/RuntimeException;" }, 109 { &gDvm.exStackOverflowError, "Ljava/lang/StackOverflowError;" }, 110 { &gDvm.exStaleDexCacheError, "Ldalvik/system/StaleDexCacheError;" }, 111 { &gDvm.exStringIndexOutOfBoundsException, "Ljava/lang/StringIndexOutOfBoundsException;" }, 112 { &gDvm.exTypeNotPresentException, "Ljava/lang/TypeNotPresentException;" }, 113 { &gDvm.exUnsatisfiedLinkError, "Ljava/lang/UnsatisfiedLinkError;" }, 114 { &gDvm.exUnsupportedOperationException, "Ljava/lang/UnsupportedOperationException;" }, 115 { &gDvm.exVerifyError, "Ljava/lang/VerifyError;" }, 116 { &gDvm.exVirtualMachineError, "Ljava/lang/VirtualMachineError;" }, 117 118 /* Other classes */ 119 { &gDvm.classJavaLangAnnotationAnnotationArray, "[Ljava/lang/annotation/Annotation;" }, 120 { &gDvm.classJavaLangAnnotationAnnotationArrayArray, 121 "[[Ljava/lang/annotation/Annotation;" }, 122 { &gDvm.classJavaLangReflectAccessibleObject, "Ljava/lang/reflect/AccessibleObject;" }, 123 { &gDvm.classJavaLangReflectConstructor, "Ljava/lang/reflect/Constructor;" }, 124 { &gDvm.classJavaLangReflectConstructorArray, "[Ljava/lang/reflect/Constructor;" }, 125 { &gDvm.classJavaLangReflectField, "Ljava/lang/reflect/Field;" }, 126 { &gDvm.classJavaLangReflectFieldArray, "[Ljava/lang/reflect/Field;" }, 127 { &gDvm.classJavaLangReflectMethod, "Ljava/lang/reflect/Method;" }, 128 { &gDvm.classJavaLangReflectMethodArray, "[Ljava/lang/reflect/Method;"}, 129 { &gDvm.classJavaLangReflectProxy, "Ljava/lang/reflect/Proxy;" }, 130 { &gDvm.classJavaLangSystem, "Ljava/lang/System;" }, 131 { &gDvm.classJavaNioDirectByteBuffer, "Ljava/nio/DirectByteBuffer;" }, 132 { &gDvm.classOrgApacheHarmonyDalvikDdmcChunk, "Lorg/apache/harmony/dalvik/ddmc/Chunk;" }, 133 { &gDvm.classOrgApacheHarmonyDalvikDdmcDdmServer, 134 "Lorg/apache/harmony/dalvik/ddmc/DdmServer;" }, 135 { &gDvm.classLibcoreReflectAnnotationFactory, "Llibcore/reflect/AnnotationFactory;" }, 136 { &gDvm.classLibcoreReflectAnnotationMember, "Llibcore/reflect/AnnotationMember;" }, 137 { &gDvm.classLibcoreReflectAnnotationMemberArray, "[Llibcore/reflect/AnnotationMember;" }, 138 139 { NULL, NULL } 140 }; 141 142 int i; 143 for (i = 0; classes[i].ref != NULL; i++) { 144 if (!initClassReference(classes[i].ref, classes[i].name)) { 145 return false; 146 } 147 } 148 149 return true; 150 } 151 152 static bool initFieldOffset(ClassObject* clazz, int *pOffset, 153 const char* name, const char* type) { 154 int offset = dvmFindFieldOffset(clazz, name, type); 155 if (offset < 0) { 156 ALOGE("Could not find essential field %s.%s of type %s", clazz->descriptor, name, type); 157 return false; 158 } 159 160 *pOffset = offset; 161 return true; 162 } 163 164 static bool initFieldOffsets() { 165 struct FieldInfo { 166 int* offset; 167 const char* name; 168 const char* type; 169 }; 170 171 static struct FieldInfo infoDdmcChunk[] = { 172 { &gDvm.offDalvikDdmcChunk_type, "type", "I" }, 173 { &gDvm.offDalvikDdmcChunk_data, "data", "[B" }, 174 { &gDvm.offDalvikDdmcChunk_offset, "offset", "I" }, 175 { &gDvm.offDalvikDdmcChunk_length, "length", "I" }, 176 { NULL, NULL, NULL } 177 }; 178 179 static struct FieldInfo infoFileDescriptor[] = { 180 { &gDvm.offJavaIoFileDescriptor_descriptor, "descriptor", "I" }, 181 { NULL, NULL, NULL } 182 }; 183 184 static struct FieldInfo infoString[] = { 185 { &gDvm.offJavaLangString_value, "value", "[C" }, 186 { &gDvm.offJavaLangString_count, "count", "I" }, 187 { &gDvm.offJavaLangString_offset, "offset", "I" }, 188 { &gDvm.offJavaLangString_hashCode, "hashCode", "I" }, 189 { NULL, NULL, NULL } 190 }; 191 192 static struct FieldInfo infoThread[] = { 193 { &gDvm.offJavaLangThread_vmThread, "vmThread", "Ljava/lang/VMThread;" }, 194 { &gDvm.offJavaLangThread_group, "group", "Ljava/lang/ThreadGroup;" }, 195 { &gDvm.offJavaLangThread_daemon, "daemon", "Z" }, 196 { &gDvm.offJavaLangThread_name, "name", "Ljava/lang/String;" }, 197 { &gDvm.offJavaLangThread_priority, "priority", "I" }, 198 { &gDvm.offJavaLangThread_uncaughtHandler, "uncaughtHandler", "Ljava/lang/Thread$UncaughtExceptionHandler;" }, 199 { &gDvm.offJavaLangThread_contextClassLoader, "contextClassLoader", "Ljava/lang/ClassLoader;" }, 200 { NULL, NULL, NULL } 201 }; 202 203 static struct FieldInfo infoThreadGroup[] = { 204 { &gDvm.offJavaLangThreadGroup_name, "name", "Ljava/lang/String;" }, 205 { &gDvm.offJavaLangThreadGroup_parent, "parent", "Ljava/lang/ThreadGroup;" }, 206 { NULL, NULL, NULL } 207 }; 208 209 static struct FieldInfo infoThrowable[] = { 210 { &gDvm.offJavaLangThrowable_stackState, "stackState", "Ljava/lang/Object;" }, 211 { &gDvm.offJavaLangThrowable_cause, "cause", "Ljava/lang/Throwable;" }, 212 { NULL, NULL, NULL } 213 }; 214 215 static struct FieldInfo infoVMThread[] = { 216 { &gDvm.offJavaLangVMThread_thread, "thread", "Ljava/lang/Thread;" }, 217 { &gDvm.offJavaLangVMThread_vmData, "vmData", "I" }, 218 { NULL, NULL, NULL } 219 }; 220 221 static struct FieldInfo infoFinalizerReference[] = { 222 { &gDvm.offJavaLangRefFinalizerReference_zombie, "zombie", "Ljava/lang/Object;" }, 223 { NULL, NULL, NULL } 224 }; 225 226 static struct FieldInfo infoConstructor[] = { 227 { &gDvm.offJavaLangReflectConstructor_slot, "slot", "I" }, 228 { &gDvm.offJavaLangReflectConstructor_declClass, "declaringClass", "Ljava/lang/Class;" }, 229 { NULL, NULL, NULL } 230 }; 231 232 static struct FieldInfo infoField[] = { 233 { &gDvm.offJavaLangReflectField_slot, "slot", "I" }, 234 { &gDvm.offJavaLangReflectField_declClass, "declaringClass", "Ljava/lang/Class;" }, 235 { NULL, NULL, NULL } 236 }; 237 238 static struct FieldInfo infoMethod[] = { 239 { &gDvm.offJavaLangReflectMethod_slot, "slot", "I" }, 240 { &gDvm.offJavaLangReflectMethod_declClass, "declaringClass", "Ljava/lang/Class;" }, 241 { NULL, NULL, NULL } 242 }; 243 244 static struct FieldInfo infoProxy[] = { 245 { &gDvm.offJavaLangReflectProxy_h, "h", "Ljava/lang/reflect/InvocationHandler;" }, 246 { NULL, NULL, NULL } 247 }; 248 249 static struct FieldInfo infoBuffer[] = { 250 { &gDvm.offJavaNioBuffer_capacity, "capacity", "I" }, 251 { &gDvm.offJavaNioBuffer_effectiveDirectAddress, "effectiveDirectAddress", "J" }, 252 { NULL, NULL, NULL } 253 }; 254 255 static struct { const char* name; const struct FieldInfo* fields; } classes[] = { 256 { "Lorg/apache/harmony/dalvik/ddmc/Chunk;", infoDdmcChunk }, 257 { "Ljava/io/FileDescriptor;", infoFileDescriptor }, 258 { "Ljava/lang/String;", infoString }, 259 { "Ljava/lang/Thread;", infoThread }, 260 { "Ljava/lang/ThreadGroup;", infoThreadGroup }, 261 { "Ljava/lang/Throwable;", infoThrowable }, 262 { "Ljava/lang/VMThread;", infoVMThread }, 263 { "Ljava/lang/ref/FinalizerReference;", infoFinalizerReference }, 264 { "Ljava/lang/reflect/Constructor;", infoConstructor }, 265 { "Ljava/lang/reflect/Field;", infoField }, 266 { "Ljava/lang/reflect/Method;", infoMethod }, 267 { "Ljava/lang/reflect/Proxy;", infoProxy }, 268 { "Ljava/nio/Buffer;", infoBuffer }, 269 { NULL, NULL } 270 }; 271 272 int i; 273 for (i = 0; classes[i].name != NULL; i++) { 274 const char* className = classes[i].name; 275 ClassObject* clazz = dvmFindSystemClassNoInit(className); 276 const struct FieldInfo* fields = classes[i].fields; 277 278 if (clazz == NULL) { 279 ALOGE("Could not find essential class %s for field lookup", className); 280 return false; 281 } 282 283 int j; 284 for (j = 0; fields[j].offset != NULL; j++) { 285 if (!initFieldOffset(clazz, fields[j].offset, fields[j].name, fields[j].type)) { 286 return false; 287 } 288 } 289 } 290 291 return true; 292 } 293 294 static bool initDirectMethodReferenceByClass(Method** pMethod, ClassObject* clazz, 295 const char* name, const char* descriptor) { 296 Method* method = dvmFindDirectMethodByDescriptor(clazz, name, descriptor); 297 298 if (method == NULL) { 299 ALOGE("Could not find essential direct method %s.%s with descriptor %s", 300 clazz->descriptor, name, descriptor); 301 return false; 302 } 303 304 *pMethod = method; 305 return true; 306 } 307 308 static bool initDirectMethodReference(Method** pMethod, const char* className, 309 const char* name, const char* descriptor) { 310 ClassObject* clazz = dvmFindSystemClassNoInit(className); 311 312 if (clazz == NULL) { 313 ALOGE("Could not find essential class %s for direct method lookup", className); 314 return false; 315 } 316 317 return initDirectMethodReferenceByClass(pMethod, clazz, name, descriptor); 318 } 319 320 static bool initConstructorReferences() { 321 static struct { Method** method; const char* name; const char* descriptor; } constructors[] = { 322 { &gDvm.methJavaLangStackTraceElement_init, "Ljava/lang/StackTraceElement;", 323 "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;I)V" }, 324 { &gDvm.methJavaLangReflectConstructor_init, "Ljava/lang/reflect/Constructor;", 325 "(Ljava/lang/Class;[Ljava/lang/Class;[Ljava/lang/Class;II)V" }, 326 { &gDvm.methJavaLangReflectField_init, "Ljava/lang/reflect/Field;", 327 "(Ljava/lang/Class;Ljava/lang/Class;Ljava/lang/String;II)V" }, 328 { &gDvm.methJavaLangReflectMethod_init, "Ljava/lang/reflect/Method;", 329 "(Ljava/lang/Class;[Ljava/lang/Class;[Ljava/lang/Class;Ljava/lang/Class;" 330 "Ljava/lang/String;II)V" }, 331 { &gDvm.methJavaNioDirectByteBuffer_init, "Ljava/nio/DirectByteBuffer;", 332 "(JI)V" }, 333 { &gDvm.methOrgApacheHarmonyLangAnnotationAnnotationMember_init, 334 "Llibcore/reflect/AnnotationMember;", 335 "(Ljava/lang/String;Ljava/lang/Object;Ljava/lang/Class;Ljava/lang/reflect/Method;)V" }, 336 { NULL, NULL, NULL } 337 }; 338 339 int i; 340 for (i = 0; constructors[i].method != NULL; i++) { 341 if (!initDirectMethodReference(constructors[i].method, constructors[i].name, 342 "<init>", constructors[i].descriptor)) { 343 return false; 344 } 345 } 346 347 return true; 348 } 349 350 static bool initDirectMethodReferences() { 351 static struct { 352 Method** method; 353 const char* className; 354 const char* name; 355 const char* descriptor; 356 } methods[] = { 357 { &gDvm.methJavaLangClassLoader_getSystemClassLoader, "Ljava/lang/ClassLoader;", 358 "getSystemClassLoader", "()Ljava/lang/ClassLoader;" }, 359 { &gDvm.methJavaLangReflectProxy_constructorPrototype, "Ljava/lang/reflect/Proxy;", 360 "constructorPrototype", "(Ljava/lang/reflect/InvocationHandler;)V" }, 361 { &gDvm.methJavaLangSystem_runFinalization, "Ljava/lang/System;", 362 "runFinalization", "()V" }, 363 364 { &gDvm.methodTraceGcMethod, "Ldalvik/system/VMDebug;", "startGC", "()V" }, 365 { &gDvm.methodTraceClassPrepMethod, "Ldalvik/system/VMDebug;", "startClassPrep", "()V" }, 366 { &gDvm.methOrgApacheHarmonyLangAnnotationAnnotationFactory_createAnnotation, 367 "Llibcore/reflect/AnnotationFactory;", "createAnnotation", 368 "(Ljava/lang/Class;[Llibcore/reflect/AnnotationMember;)" 369 "Ljava/lang/annotation/Annotation;" }, 370 { &gDvm.methDalvikSystemNativeStart_main, "Ldalvik/system/NativeStart;", "main", "([Ljava/lang/String;)V" }, 371 { &gDvm.methDalvikSystemNativeStart_run, "Ldalvik/system/NativeStart;", "run", "()V" }, 372 { &gDvm.methJavaLangRefFinalizerReferenceAdd, 373 "Ljava/lang/ref/FinalizerReference;", "add", "(Ljava/lang/Object;)V" }, 374 { &gDvm.methDalvikDdmcServer_dispatch, 375 "Lorg/apache/harmony/dalvik/ddmc/DdmServer;", "dispatch", "(I[BII)Lorg/apache/harmony/dalvik/ddmc/Chunk;" }, 376 { &gDvm.methDalvikDdmcServer_broadcast, 377 "Lorg/apache/harmony/dalvik/ddmc/DdmServer;", "broadcast", "(I)V" }, 378 { &gDvm.methJavaLangRefReferenceQueueAdd, 379 "Ljava/lang/ref/ReferenceQueue;", "add", "(Ljava/lang/ref/Reference;)V" }, 380 { NULL, NULL, NULL, NULL } 381 }; 382 383 int i; 384 for (i = 0; methods[i].method != NULL; i++) { 385 if (!initDirectMethodReference(methods[i].method, methods[i].className, 386 methods[i].name, methods[i].descriptor)) { 387 return false; 388 } 389 } 390 391 return true; 392 } 393 394 static bool initVirtualMethodOffset(int* pOffset, const char* className, 395 const char* name, const char* descriptor) { 396 ClassObject* clazz = dvmFindSystemClassNoInit(className); 397 398 if (clazz == NULL) { 399 ALOGE("Could not find essential class %s for virtual method lookup", className); 400 return false; 401 } 402 403 Method* method = dvmFindVirtualMethodByDescriptor(clazz, name, descriptor); 404 405 if (method == NULL) { 406 ALOGE("Could not find essential virtual method %s.%s with descriptor %s", 407 clazz->descriptor, name, descriptor); 408 return false; 409 } 410 411 *pOffset = method->methodIndex; 412 return true; 413 } 414 415 static bool initVirtualMethodOffsets() { 416 static struct { 417 int* offset; 418 const char* className; 419 const char* name; 420 const char* descriptor; 421 } methods[] = { 422 { &gDvm.voffJavaLangClassLoader_loadClass, "Ljava/lang/ClassLoader;", "loadClass", 423 "(Ljava/lang/String;)Ljava/lang/Class;" }, 424 { &gDvm.voffJavaLangObject_equals, "Ljava/lang/Object;", "equals", 425 "(Ljava/lang/Object;)Z" }, 426 { &gDvm.voffJavaLangObject_hashCode, "Ljava/lang/Object;", "hashCode", "()I" }, 427 { &gDvm.voffJavaLangObject_toString, "Ljava/lang/Object;", "toString", 428 "()Ljava/lang/String;" }, 429 { &gDvm.voffJavaLangThread_run, "Ljava/lang/Thread;", "run", "()V" }, 430 { &gDvm.voffJavaLangThreadGroup_removeThread, "Ljava/lang/ThreadGroup;", 431 "removeThread", "(Ljava/lang/Thread;)V" }, 432 { NULL, NULL, NULL, NULL } 433 }; 434 435 int i; 436 for (i = 0; methods[i].offset != NULL; i++) { 437 if (!initVirtualMethodOffset(methods[i].offset, methods[i].className, 438 methods[i].name, methods[i].descriptor)) { 439 return false; 440 } 441 } 442 443 return true; 444 } 445 446 static bool initFinalizerReference() 447 { 448 gDvm.classJavaLangRefFinalizerReference = 449 dvmFindSystemClass("Ljava/lang/ref/FinalizerReference;"); 450 return gDvm.classJavaLangRefFinalizerReference != NULL; 451 } 452 453 static bool verifyStringOffset(const char* name, int actual, int expected) { 454 if (actual != expected) { 455 ALOGE("InitRefs: String.%s offset = %d; expected %d", name, actual, expected); 456 return false; 457 } 458 459 return true; 460 } 461 462 static bool verifyStringOffsets() { 463 /* 464 * Various parts of the system use predefined constants for the 465 * offsets to a few fields of the class String. This code verifies 466 * that the predefined offsets match what is actually defined by 467 * the class. 468 */ 469 470 bool ok = true; 471 ok &= verifyStringOffset("value", gDvm.offJavaLangString_value, STRING_FIELDOFF_VALUE); 472 ok &= verifyStringOffset("count", gDvm.offJavaLangString_count, STRING_FIELDOFF_COUNT); 473 ok &= verifyStringOffset("offset", gDvm.offJavaLangString_offset, STRING_FIELDOFF_OFFSET); 474 ok &= verifyStringOffset("hashCode", gDvm.offJavaLangString_hashCode, 475 STRING_FIELDOFF_HASHCODE); 476 477 return ok; 478 } 479 480 /* (documented in header) */ 481 bool dvmFindRequiredClassesAndMembers() { 482 /* 483 * Note: Under normal VM use, this is called by dvmStartup() 484 * in Init.c. For dex optimization, this is called as well, but in 485 * that case, the call is made from DexPrepare.c. 486 */ 487 488 return initClassReferences() 489 && initFieldOffsets() 490 && initConstructorReferences() 491 && initDirectMethodReferences() 492 && initVirtualMethodOffsets() 493 && initFinalizerReference() 494 && verifyStringOffsets(); 495 } 496 497 /* (documented in header) */ 498 bool dvmFindReferenceMembers(ClassObject* classReference) { 499 if (strcmp(classReference->descriptor, "Ljava/lang/ref/Reference;") != 0) { 500 ALOGE("Attempt to set up the wrong class as Reference"); 501 return false; 502 } 503 return initFieldOffset(classReference, &gDvm.offJavaLangRefReference_pendingNext, 504 "pendingNext", "Ljava/lang/ref/Reference;") 505 && initFieldOffset(classReference, &gDvm.offJavaLangRefReference_queue, 506 "queue", "Ljava/lang/ref/ReferenceQueue;") 507 && initFieldOffset(classReference, &gDvm.offJavaLangRefReference_queueNext, 508 "queueNext", "Ljava/lang/ref/Reference;") 509 && initFieldOffset(classReference, &gDvm.offJavaLangRefReference_referent, 510 "referent", "Ljava/lang/Object;"); 511 } 512