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 } 512