1 /* 2 * Copyright (C) 2008 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 * Class loading, including bootstrap class loader, linking, and 19 * initialization. 20 */ 21 22 #define LOG_CLASS_LOADING 0 23 24 #include "Dalvik.h" 25 #include "libdex/DexClass.h" 26 27 #include <stdlib.h> 28 #include <stddef.h> 29 #include <sys/stat.h> 30 31 #if LOG_CLASS_LOADING 32 #include <unistd.h> 33 #include <pthread.h> 34 #include <cutils/process_name.h> 35 #include <sys/types.h> 36 #endif 37 38 /* 39 Notes on Linking and Verification 40 41 The basic way to retrieve a class is to load it, make sure its superclass 42 and interfaces are available, prepare its fields, and return it. This gets 43 a little more complicated when multiple threads can be trying to retrieve 44 the class simultaneously, requiring that we use the class object's monitor 45 to keep things orderly. 46 47 The linking (preparing, resolving) of a class can cause us to recursively 48 load superclasses and interfaces. Barring circular references (e.g. two 49 classes that are superclasses of each other), this will complete without 50 the loader attempting to access the partially-linked class. 51 52 With verification, the situation is different. If we try to verify 53 every class as we load it, we quickly run into trouble. Even the lowly 54 java.lang.Object requires CloneNotSupportedException; follow the list 55 of referenced classes and you can head down quite a trail. The trail 56 eventually leads back to Object, which is officially not fully-formed yet. 57 58 The VM spec (specifically, v2 5.4.1) notes that classes pulled in during 59 verification do not need to be prepared or verified. This means that we 60 are allowed to have loaded but unverified classes. It further notes that 61 the class must be verified before it is initialized, which allows us to 62 defer verification for all classes until class init. You can't execute 63 code or access fields in an uninitialized class, so this is safe. 64 65 It also allows a more peaceful coexistence between verified and 66 unverifiable code. If class A refers to B, and B has a method that 67 refers to a bogus class C, should we allow class A to be verified? 68 If A only exercises parts of B that don't use class C, then there is 69 nothing wrong with running code in A. We can fully verify both A and B, 70 and allow execution to continue until B causes initialization of C. The 71 VerifyError is thrown close to the point of use. 72 73 This gets a little weird with java.lang.Class, which is the only class 74 that can be instantiated before it is initialized. We have to force 75 initialization right after the class is created, because by definition we 76 have instances of it on the heap, and somebody might get a class object and 77 start making virtual calls on it. We can end up going recursive during 78 verification of java.lang.Class, but we avoid that by checking to see if 79 verification is already in progress before we try to initialize it. 80 */ 81 82 /* 83 Notes on class loaders and interaction with optimization / verification 84 85 In what follows, "pre-verification" and "optimization" are the steps 86 performed by the dexopt command, which attempts to verify and optimize 87 classes as part of unpacking jar files and storing the DEX data in the 88 dalvik-cache directory. These steps are performed by loading the DEX 89 files directly, without any assistance from ClassLoader instances. 90 91 When we pre-verify and optimize a class in a DEX file, we make some 92 assumptions about where the class loader will go to look for classes. 93 If we can't guarantee those assumptions, e.g. because a class ("AppClass") 94 references something not defined in the bootstrap jars or the AppClass jar, 95 we can't pre-verify or optimize the class. 96 97 The VM doesn't define the behavior of user-defined class loaders. 98 For example, suppose application class AppClass, loaded by UserLoader, 99 has a method that creates a java.lang.String. The first time 100 AppClass.stringyMethod tries to do something with java.lang.String, it 101 asks UserLoader to find it. UserLoader is expected to defer to its parent 102 loader, but isn't required to. UserLoader might provide a replacement 103 for String. 104 105 We can run into trouble if we pre-verify AppClass with the assumption that 106 java.lang.String will come from core.jar, and don't verify this assumption 107 at runtime. There are two places that an alternate implementation of 108 java.lang.String can come from: the AppClass jar, or from some other jar 109 that UserLoader knows about. (Someday UserLoader will be able to generate 110 some bytecode and call DefineClass, but not yet.) 111 112 To handle the first situation, the pre-verifier will explicitly check for 113 conflicts between the class being optimized/verified and the bootstrap 114 classes. If an app jar contains a class that has the same package and 115 class name as a class in a bootstrap jar, the verification resolver refuses 116 to find either, which will block pre-verification and optimization on 117 classes that reference ambiguity. The VM will postpone verification of 118 the app class until first load. 119 120 For the second situation, we need to ensure that all references from a 121 pre-verified class are satisified by the class' jar or earlier bootstrap 122 jars. In concrete terms: when resolving a reference to NewClass, 123 which was caused by a reference in class AppClass, we check to see if 124 AppClass was pre-verified. If so, we require that NewClass comes out 125 of either the AppClass jar or one of the jars in the bootstrap path. 126 (We may not control the class loaders, but we do manage the DEX files. 127 We can verify that it's either (loader==null && dexFile==a_boot_dex) 128 or (loader==UserLoader && dexFile==AppClass.dexFile). Classes from 129 DefineClass can't be pre-verified, so this doesn't apply.) 130 131 This should ensure that you can't "fake out" the pre-verifier by creating 132 a user-defined class loader that replaces system classes. It should 133 also ensure that you can write such a loader and have it work in the 134 expected fashion; all you lose is some performance due to "just-in-time 135 verification" and the lack of DEX optimizations. 136 137 There is a "back door" of sorts in the class resolution check, due to 138 the fact that the "class ref" entries are shared between the bytecode 139 and meta-data references (e.g. annotations and exception handler lists). 140 The class references in annotations have no bearing on class verification, 141 so when a class does an annotation query that causes a class reference 142 index to be resolved, we don't want to fail just because the calling 143 class was pre-verified and the resolved class is in some random DEX file. 144 The successful resolution adds the class to the "resolved classes" table, 145 so when optimized bytecode references it we don't repeat the resolve-time 146 check. We can avoid this by not updating the "resolved classes" table 147 when the class reference doesn't come out of something that has been 148 checked by the verifier, but that has a nonzero performance impact. 149 Since the ultimate goal of this test is to catch an unusual situation 150 (user-defined class loaders redefining core classes), the added caution 151 may not be worth the performance hit. 152 */ 153 154 /* 155 * Class serial numbers start at this value. We use a nonzero initial 156 * value so they stand out in binary dumps (e.g. hprof output). 157 */ 158 #define INITIAL_CLASS_SERIAL_NUMBER 0x50000000 159 160 /* 161 * Constant used to size an auxillary class object data structure. 162 * For optimum memory use this should be equal to or slightly larger than 163 * the number of classes loaded when the zygote finishes initializing. 164 */ 165 #define ZYGOTE_CLASS_CUTOFF 2304 166 167 static ClassPathEntry* processClassPath(const char* pathStr, bool isBootstrap); 168 static void freeCpeArray(ClassPathEntry* cpe); 169 170 static ClassObject* findClassFromLoaderNoInit( 171 const char* descriptor, Object* loader); 172 static ClassObject* findClassNoInit(const char* descriptor, Object* loader,\ 173 DvmDex* pDvmDex); 174 static ClassObject* loadClassFromDex(DvmDex* pDvmDex, 175 const DexClassDef* pClassDef, Object* loader); 176 static void loadMethodFromDex(ClassObject* clazz, const DexMethod* pDexMethod,\ 177 Method* meth); 178 static int computeJniArgInfo(const DexProto* proto); 179 static void loadSFieldFromDex(ClassObject* clazz, 180 const DexField* pDexSField, StaticField* sfield); 181 static void loadIFieldFromDex(ClassObject* clazz, 182 const DexField* pDexIField, InstField* field); 183 static bool precacheReferenceOffsets(ClassObject* clazz); 184 static void computeRefOffsets(ClassObject* clazz); 185 static void freeMethodInnards(Method* meth); 186 static bool createVtable(ClassObject* clazz); 187 static bool createIftable(ClassObject* clazz); 188 static bool insertMethodStubs(ClassObject* clazz); 189 static bool computeFieldOffsets(ClassObject* clazz); 190 static void throwEarlierClassFailure(ClassObject* clazz); 191 192 #if LOG_CLASS_LOADING 193 /* 194 * Logs information about a class loading with given timestamp. 195 * 196 * TODO: In the case where we fail in dvmLinkClass() and log the class as closing (type='<'), 197 * it would probably be better to use a new type code to indicate the failure. This change would 198 * require a matching change in the parser and analysis code in frameworks/base/tools/preload. 199 */ 200 static void logClassLoadWithTime(char type, ClassObject* clazz, u8 time) { 201 pid_t ppid = getppid(); 202 pid_t pid = getpid(); 203 unsigned int tid = (unsigned int) pthread_self(); 204 205 LOG(LOG_INFO, "PRELOAD", "%c%d:%d:%d:%s:%d:%s:%lld\n", type, ppid, pid, tid, 206 get_process_name(), (int) clazz->classLoader, clazz->descriptor, 207 time); 208 } 209 210 /* 211 * Logs information about a class loading. 212 */ 213 static void logClassLoad(char type, ClassObject* clazz) { 214 logClassLoadWithTime(type, clazz, dvmGetThreadCpuTimeNsec()); 215 } 216 #endif 217 218 /* 219 * Some LinearAlloc unit tests. 220 */ 221 static void linearAllocTests() 222 { 223 char* fiddle; 224 int try = 1; 225 226 switch (try) { 227 case 0: 228 fiddle = dvmLinearAlloc(NULL, 3200-28); 229 dvmLinearReadOnly(NULL, fiddle); 230 break; 231 case 1: 232 fiddle = dvmLinearAlloc(NULL, 3200-24); 233 dvmLinearReadOnly(NULL, fiddle); 234 break; 235 case 2: 236 fiddle = dvmLinearAlloc(NULL, 3200-20); 237 dvmLinearReadOnly(NULL, fiddle); 238 break; 239 case 3: 240 fiddle = dvmLinearAlloc(NULL, 3200-16); 241 dvmLinearReadOnly(NULL, fiddle); 242 break; 243 case 4: 244 fiddle = dvmLinearAlloc(NULL, 3200-12); 245 dvmLinearReadOnly(NULL, fiddle); 246 break; 247 } 248 fiddle = dvmLinearAlloc(NULL, 896); 249 dvmLinearReadOnly(NULL, fiddle); 250 fiddle = dvmLinearAlloc(NULL, 20); // watch addr of this alloc 251 dvmLinearReadOnly(NULL, fiddle); 252 253 fiddle = dvmLinearAlloc(NULL, 1); 254 fiddle[0] = 'q'; 255 dvmLinearReadOnly(NULL, fiddle); 256 fiddle = dvmLinearAlloc(NULL, 4096); 257 fiddle[0] = 'x'; 258 fiddle[4095] = 'y'; 259 dvmLinearReadOnly(NULL, fiddle); 260 dvmLinearFree(NULL, fiddle); 261 fiddle = dvmLinearAlloc(NULL, 0); 262 dvmLinearReadOnly(NULL, fiddle); 263 fiddle = dvmLinearRealloc(NULL, fiddle, 12); 264 fiddle[11] = 'z'; 265 dvmLinearReadOnly(NULL, fiddle); 266 fiddle = dvmLinearRealloc(NULL, fiddle, 5); 267 dvmLinearReadOnly(NULL, fiddle); 268 fiddle = dvmLinearAlloc(NULL, 17001); 269 fiddle[0] = 'x'; 270 fiddle[17000] = 'y'; 271 dvmLinearReadOnly(NULL, fiddle); 272 273 char* str = dvmLinearStrdup(NULL, "This is a test!"); 274 LOGI("GOT: '%s'\n", str); 275 276 /* try to check the bounds; allocator may round allocation size up */ 277 fiddle = dvmLinearAlloc(NULL, 12); 278 LOGI("Should be 1: %d\n", dvmLinearAllocContains(fiddle, 12)); 279 LOGI("Should be 0: %d\n", dvmLinearAllocContains(fiddle, 13)); 280 LOGI("Should be 0: %d\n", dvmLinearAllocContains(fiddle - 128*1024, 1)); 281 282 dvmLinearAllocDump(NULL); 283 dvmLinearFree(NULL, str); 284 } 285 286 /* 287 * Initialize the bootstrap class loader. 288 * 289 * Call this after the bootclasspath string has been finalized. 290 */ 291 bool dvmClassStartup(void) 292 { 293 ClassObject* unlinkedClass; 294 295 /* make this a requirement -- don't currently support dirs in path */ 296 if (strcmp(gDvm.bootClassPathStr, ".") == 0) { 297 LOGE("ERROR: must specify non-'.' bootclasspath\n"); 298 return false; 299 } 300 301 gDvm.loadedClasses = 302 dvmHashTableCreate(256, (HashFreeFunc) dvmFreeClassInnards); 303 304 gDvm.pBootLoaderAlloc = dvmLinearAllocCreate(NULL); 305 if (gDvm.pBootLoaderAlloc == NULL) 306 return false; 307 308 if (false) { 309 linearAllocTests(); 310 exit(0); 311 } 312 313 /* 314 * Class serial number. We start with a high value to make it distinct 315 * in binary dumps (e.g. hprof). 316 */ 317 gDvm.classSerialNumber = INITIAL_CLASS_SERIAL_NUMBER; 318 319 /* Set up the table we'll use for tracking initiating loaders for 320 * early classes. 321 * If it's NULL, we just fall back to the InitiatingLoaderList in the 322 * ClassObject, so it's not fatal to fail this allocation. 323 */ 324 gDvm.initiatingLoaderList = 325 calloc(ZYGOTE_CLASS_CUTOFF, sizeof(InitiatingLoaderList)); 326 327 /* This placeholder class is used while a ClassObject is 328 * loading/linking so those not in the know can still say 329 * "obj->clazz->...". 330 */ 331 unlinkedClass = &gDvm.unlinkedJavaLangClassObject; 332 333 memset(unlinkedClass, 0, sizeof(*unlinkedClass)); 334 335 /* Set obj->clazz to NULL so anyone who gets too interested 336 * in the fake class will crash. 337 */ 338 DVM_OBJECT_INIT(&unlinkedClass->obj, NULL); 339 unlinkedClass->descriptor = "!unlinkedClass"; 340 dvmSetClassSerialNumber(unlinkedClass); 341 342 gDvm.unlinkedJavaLangClass = unlinkedClass; 343 344 /* 345 * Process the bootstrap class path. This means opening the specified 346 * DEX or Jar files and possibly running them through the optimizer. 347 */ 348 assert(gDvm.bootClassPath == NULL); 349 processClassPath(gDvm.bootClassPathStr, true); 350 351 if (gDvm.bootClassPath == NULL) 352 return false; 353 354 return true; 355 } 356 357 /* 358 * Clean up. 359 */ 360 void dvmClassShutdown(void) 361 { 362 int i; 363 364 /* discard all system-loaded classes */ 365 dvmHashTableFree(gDvm.loadedClasses); 366 gDvm.loadedClasses = NULL; 367 368 /* discard primitive classes created for arrays */ 369 for (i = 0; i < PRIM_MAX; i++) 370 dvmFreeClassInnards(gDvm.primitiveClass[i]); 371 372 /* this closes DEX files, JAR files, etc. */ 373 freeCpeArray(gDvm.bootClassPath); 374 gDvm.bootClassPath = NULL; 375 376 dvmLinearAllocDestroy(NULL); 377 378 free(gDvm.initiatingLoaderList); 379 } 380 381 382 /* 383 * =========================================================================== 384 * Bootstrap class loader 385 * =========================================================================== 386 */ 387 388 /* 389 * Dump the contents of a ClassPathEntry array. 390 */ 391 static void dumpClassPath(const ClassPathEntry* cpe) 392 { 393 int idx = 0; 394 395 while (cpe->kind != kCpeLastEntry) { 396 const char* kindStr; 397 398 switch (cpe->kind) { 399 case kCpeDir: kindStr = "dir"; break; 400 case kCpeJar: kindStr = "jar"; break; 401 case kCpeDex: kindStr = "dex"; break; 402 default: kindStr = "???"; break; 403 } 404 405 LOGI(" %2d: type=%s %s %p\n", idx, kindStr, cpe->fileName, cpe->ptr); 406 if (CALC_CACHE_STATS && cpe->kind == kCpeJar) { 407 JarFile* pJarFile = (JarFile*) cpe->ptr; 408 DvmDex* pDvmDex = dvmGetJarFileDex(pJarFile); 409 dvmDumpAtomicCacheStats(pDvmDex->pInterfaceCache); 410 } 411 412 cpe++; 413 idx++; 414 } 415 } 416 417 /* 418 * Dump the contents of the bootstrap class path. 419 */ 420 void dvmDumpBootClassPath(void) 421 { 422 dumpClassPath(gDvm.bootClassPath); 423 } 424 425 /* 426 * Returns "true" if the class path contains the specified path. 427 */ 428 bool dvmClassPathContains(const ClassPathEntry* cpe, const char* path) 429 { 430 while (cpe->kind != kCpeLastEntry) { 431 if (strcmp(cpe->fileName, path) == 0) 432 return true; 433 434 cpe++; 435 } 436 return false; 437 } 438 439 /* 440 * Free an array of ClassPathEntry structs. 441 * 442 * We release the contents of each entry, then free the array itself. 443 */ 444 static void freeCpeArray(ClassPathEntry* cpe) 445 { 446 ClassPathEntry* cpeStart = cpe; 447 448 if (cpe == NULL) 449 return; 450 451 while (cpe->kind != kCpeLastEntry) { 452 switch (cpe->kind) { 453 case kCpeJar: 454 /* free JarFile */ 455 dvmJarFileFree((JarFile*) cpe->ptr); 456 break; 457 case kCpeDex: 458 /* free RawDexFile */ 459 dvmRawDexFileFree((RawDexFile*) cpe->ptr); 460 break; 461 default: 462 /* e.g. kCpeDir */ 463 assert(cpe->ptr == NULL); 464 break; 465 } 466 467 free(cpe->fileName); 468 cpe++; 469 } 470 471 free(cpeStart); 472 } 473 474 /* 475 * Prepare a ClassPathEntry struct, which at this point only has a valid 476 * filename. We need to figure out what kind of file it is, and for 477 * everything other than directories we need to open it up and see 478 * what's inside. 479 */ 480 static bool prepareCpe(ClassPathEntry* cpe, bool isBootstrap) 481 { 482 JarFile* pJarFile = NULL; 483 RawDexFile* pRawDexFile = NULL; 484 struct stat sb; 485 int cc; 486 487 cc = stat(cpe->fileName, &sb); 488 if (cc < 0) { 489 LOGD("Unable to stat classpath element '%s'\n", cpe->fileName); 490 return false; 491 } 492 if (S_ISDIR(sb.st_mode)) { 493 /* 494 * The directory will usually have .class files in subdirectories, 495 * which may be a few levels down. Doing a recursive scan and 496 * caching the results would help us avoid hitting the filesystem 497 * on misses. Whether or not this is of measureable benefit 498 * depends on a number of factors, but most likely it is not 499 * worth the effort (especially since most of our stuff will be 500 * in DEX or JAR). 501 */ 502 cpe->kind = kCpeDir; 503 assert(cpe->ptr == NULL); 504 return true; 505 } 506 507 if (dvmJarFileOpen(cpe->fileName, NULL, &pJarFile, isBootstrap) == 0) { 508 cpe->kind = kCpeJar; 509 cpe->ptr = pJarFile; 510 return true; 511 } 512 513 // TODO: do we still want to support "raw" DEX files in the classpath? 514 if (dvmRawDexFileOpen(cpe->fileName, NULL, &pRawDexFile, isBootstrap) == 0) 515 { 516 cpe->kind = kCpeDex; 517 cpe->ptr = pRawDexFile; 518 return true; 519 } 520 521 LOGD("Unable to process classpath element '%s'\n", cpe->fileName); 522 return false; 523 } 524 525 /* 526 * Convert a colon-separated list of directories, Zip files, and DEX files 527 * into an array of ClassPathEntry structs. 528 * 529 * During normal startup we fail if there are no entries, because we won't 530 * get very far without the basic language support classes, but if we're 531 * optimizing a DEX file we allow it. 532 * 533 * If entries are added or removed from the bootstrap class path, the 534 * dependencies in the DEX files will break, and everything except the 535 * very first entry will need to be regenerated. 536 */ 537 static ClassPathEntry* processClassPath(const char* pathStr, bool isBootstrap) 538 { 539 ClassPathEntry* cpe = NULL; 540 char* mangle; 541 char* cp; 542 const char* end; 543 int idx, count; 544 545 assert(pathStr != NULL); 546 547 mangle = strdup(pathStr); 548 549 /* 550 * Run through and essentially strtok() the string. Get a count of 551 * the #of elements while we're at it. 552 * 553 * If the path was constructed strangely (e.g. ":foo::bar:") this will 554 * over-allocate, which isn't ideal but is mostly harmless. 555 */ 556 count = 1; 557 for (cp = mangle; *cp != '\0'; cp++) { 558 if (*cp == ':') { /* separates two entries */ 559 count++; 560 *cp = '\0'; 561 } 562 } 563 end = cp; 564 565 /* 566 * Allocate storage. We over-alloc by one so we can set an "end" marker. 567 */ 568 cpe = (ClassPathEntry*) calloc(count+1, sizeof(ClassPathEntry)); 569 570 /* 571 * Set the global pointer so the DEX file dependency stuff can find it. 572 */ 573 gDvm.bootClassPath = cpe; 574 575 /* 576 * Go through a second time, pulling stuff out. 577 */ 578 cp = mangle; 579 idx = 0; 580 while (cp < end) { 581 if (*cp == '\0') { 582 /* leading, trailing, or doubled ':'; ignore it */ 583 } else { 584 ClassPathEntry tmp; 585 tmp.kind = kCpeUnknown; 586 tmp.fileName = strdup(cp); 587 tmp.ptr = NULL; 588 589 /* drop an end marker here so DEX loader can walk unfinished list */ 590 cpe[idx].kind = kCpeLastEntry; 591 cpe[idx].fileName = NULL; 592 cpe[idx].ptr = NULL; 593 594 if (!prepareCpe(&tmp, isBootstrap)) { 595 /* drop from list and continue on */ 596 free(tmp.fileName); 597 } else { 598 /* copy over, pointers and all */ 599 if (tmp.fileName[0] != '/') 600 LOGW("Non-absolute bootclasspath entry '%s'\n", 601 tmp.fileName); 602 cpe[idx] = tmp; 603 idx++; 604 } 605 } 606 607 cp += strlen(cp) +1; 608 } 609 assert(idx <= count); 610 if (idx == 0 && !gDvm.optimizing) { 611 LOGE("ERROR: no valid entries found in bootclasspath '%s'\n", pathStr); 612 free(cpe); 613 cpe = NULL; 614 goto bail; 615 } 616 617 LOGVV(" (filled %d of %d slots)\n", idx, count); 618 619 /* put end marker in over-alloc slot */ 620 cpe[idx].kind = kCpeLastEntry; 621 cpe[idx].fileName = NULL; 622 cpe[idx].ptr = NULL; 623 624 //dumpClassPath(cpe); 625 626 bail: 627 free(mangle); 628 gDvm.bootClassPath = cpe; 629 return cpe; 630 } 631 632 /* 633 * Search the DEX files we loaded from the bootstrap class path for a DEX 634 * file that has the class with the matching descriptor. 635 * 636 * Returns the matching DEX file and DexClassDef entry if found, otherwise 637 * returns NULL. 638 */ 639 static DvmDex* searchBootPathForClass(const char* descriptor, 640 const DexClassDef** ppClassDef) 641 { 642 const ClassPathEntry* cpe = gDvm.bootClassPath; 643 const DexClassDef* pFoundDef = NULL; 644 DvmDex* pFoundFile = NULL; 645 646 LOGVV("+++ class '%s' not yet loaded, scanning bootclasspath...\n", 647 descriptor); 648 649 while (cpe->kind != kCpeLastEntry) { 650 //LOGV("+++ checking '%s' (%d)\n", cpe->fileName, cpe->kind); 651 652 switch (cpe->kind) { 653 case kCpeDir: 654 LOGW("Directory entries ('%s') not supported in bootclasspath\n", 655 cpe->fileName); 656 break; 657 case kCpeJar: 658 { 659 JarFile* pJarFile = (JarFile*) cpe->ptr; 660 const DexClassDef* pClassDef; 661 DvmDex* pDvmDex; 662 663 pDvmDex = dvmGetJarFileDex(pJarFile); 664 pClassDef = dexFindClass(pDvmDex->pDexFile, descriptor); 665 if (pClassDef != NULL) { 666 /* found */ 667 pFoundDef = pClassDef; 668 pFoundFile = pDvmDex; 669 goto found; 670 } 671 } 672 break; 673 case kCpeDex: 674 { 675 RawDexFile* pRawDexFile = (RawDexFile*) cpe->ptr; 676 const DexClassDef* pClassDef; 677 DvmDex* pDvmDex; 678 679 pDvmDex = dvmGetRawDexFileDex(pRawDexFile); 680 pClassDef = dexFindClass(pDvmDex->pDexFile, descriptor); 681 if (pClassDef != NULL) { 682 /* found */ 683 pFoundDef = pClassDef; 684 pFoundFile = pDvmDex; 685 goto found; 686 } 687 } 688 break; 689 default: 690 LOGE("Unknown kind %d\n", cpe->kind); 691 assert(false); 692 break; 693 } 694 695 cpe++; 696 } 697 698 /* 699 * Special handling during verification + optimization. 700 * 701 * The DEX optimizer needs to load classes from the DEX file it's working 702 * on. Rather than trying to insert it into the bootstrap class path 703 * or synthesizing a class loader to manage it, we just make it available 704 * here. It logically comes after all existing entries in the bootstrap 705 * class path. 706 */ 707 if (gDvm.bootClassPathOptExtra != NULL) { 708 const DexClassDef* pClassDef; 709 710 pClassDef = 711 dexFindClass(gDvm.bootClassPathOptExtra->pDexFile, descriptor); 712 if (pClassDef != NULL) { 713 /* found */ 714 pFoundDef = pClassDef; 715 pFoundFile = gDvm.bootClassPathOptExtra; 716 } 717 } 718 719 found: 720 *ppClassDef = pFoundDef; 721 return pFoundFile; 722 } 723 724 /* 725 * Set the "extra" DEX, which becomes a de facto member of the bootstrap 726 * class set. 727 */ 728 void dvmSetBootPathExtraDex(DvmDex* pDvmDex) 729 { 730 gDvm.bootClassPathOptExtra = pDvmDex; 731 } 732 733 734 /* 735 * Return the #of entries in the bootstrap class path. 736 * 737 * (Used for ClassLoader.getResources().) 738 */ 739 int dvmGetBootPathSize(void) 740 { 741 const ClassPathEntry* cpe = gDvm.bootClassPath; 742 743 while (cpe->kind != kCpeLastEntry) 744 cpe++; 745 746 return cpe - gDvm.bootClassPath; 747 } 748 749 /* 750 * Find a resource with the specified name in entry N of the boot class path. 751 * 752 * We return a newly-allocated String of one of these forms: 753 * file://path/name 754 * jar:file://path!/name 755 * Where "path" is the bootstrap class path entry and "name" is the string 756 * passed into this method. "path" needs to be an absolute path (starting 757 * with '/'); if it's not we'd need to "absolutify" it as part of forming 758 * the URL string. 759 */ 760 StringObject* dvmGetBootPathResource(const char* name, int idx) 761 { 762 const int kUrlOverhead = 13; // worst case for Jar URL 763 const ClassPathEntry* cpe = gDvm.bootClassPath; 764 StringObject* urlObj = NULL; 765 766 LOGV("+++ searching for resource '%s' in %d(%s)\n", 767 name, idx, cpe[idx].fileName); 768 769 /* we could use direct array index, but I don't entirely trust "idx" */ 770 while (idx-- && cpe->kind != kCpeLastEntry) 771 cpe++; 772 if (cpe->kind == kCpeLastEntry) { 773 assert(false); 774 return NULL; 775 } 776 777 char urlBuf[strlen(name) + strlen(cpe->fileName) + kUrlOverhead +1]; 778 779 switch (cpe->kind) { 780 case kCpeDir: 781 sprintf(urlBuf, "file://%s/%s", cpe->fileName, name); 782 if (access(urlBuf+7, F_OK) != 0) 783 goto bail; 784 break; 785 case kCpeJar: 786 { 787 JarFile* pJarFile = (JarFile*) cpe->ptr; 788 if (dexZipFindEntry(&pJarFile->archive, name) == NULL) 789 goto bail; 790 sprintf(urlBuf, "jar:file://%s!/%s", cpe->fileName, name); 791 } 792 break; 793 case kCpeDex: 794 LOGV("No resources in DEX files\n"); 795 goto bail; 796 default: 797 assert(false); 798 goto bail; 799 } 800 801 LOGV("+++ using URL='%s'\n", urlBuf); 802 urlObj = dvmCreateStringFromCstr(urlBuf, ALLOC_DEFAULT); 803 804 bail: 805 return urlObj; 806 } 807 808 809 /* 810 * =========================================================================== 811 * Class list management 812 * =========================================================================== 813 */ 814 815 /* search for these criteria in the Class hash table */ 816 typedef struct ClassMatchCriteria { 817 const char* descriptor; 818 Object* loader; 819 } ClassMatchCriteria; 820 821 #define kInitLoaderInc 4 /* must be power of 2 */ 822 823 static InitiatingLoaderList *dvmGetInitiatingLoaderList(ClassObject* clazz) 824 { 825 assert(clazz->serialNumber > INITIAL_CLASS_SERIAL_NUMBER); 826 int classIndex = clazz->serialNumber-INITIAL_CLASS_SERIAL_NUMBER; 827 if (gDvm.initiatingLoaderList != NULL && 828 classIndex < ZYGOTE_CLASS_CUTOFF) { 829 return &(gDvm.initiatingLoaderList[classIndex]); 830 } else { 831 return &(clazz->initiatingLoaderList); 832 } 833 } 834 835 /* 836 * Determine if "loader" appears in clazz' initiating loader list. 837 * 838 * The class hash table lock must be held when calling here, since 839 * it's also used when updating a class' initiating loader list. 840 * 841 * TODO: switch to some sort of lock-free data structure so we don't have 842 * to grab the lock to do a lookup. Among other things, this would improve 843 * the speed of compareDescriptorClasses(). 844 */ 845 bool dvmLoaderInInitiatingList(const ClassObject* clazz, const Object* loader) 846 { 847 /* 848 * The bootstrap class loader can't be just an initiating loader for 849 * anything (it's always the defining loader if the class is visible 850 * to it). We don't put defining loaders in the initiating list. 851 */ 852 if (loader == NULL) 853 return false; 854 855 /* 856 * Scan the list for a match. The list is expected to be short. 857 */ 858 /* Cast to remove the const from clazz, but use const loaderList */ 859 ClassObject* nonConstClazz = (ClassObject*) clazz; 860 const InitiatingLoaderList *loaderList = 861 dvmGetInitiatingLoaderList(nonConstClazz); 862 int i; 863 for (i = loaderList->initiatingLoaderCount-1; i >= 0; --i) { 864 if (loaderList->initiatingLoaders[i] == loader) { 865 //LOGI("+++ found initiating match %p in %s\n", 866 // loader, clazz->descriptor); 867 return true; 868 } 869 } 870 return false; 871 } 872 873 /* 874 * Add "loader" to clazz's initiating loader set, unless it's the defining 875 * class loader. 876 * 877 * In the common case this will be a short list, so we don't need to do 878 * anything too fancy here. 879 * 880 * This locks gDvm.loadedClasses for synchronization, so don't hold it 881 * when calling here. 882 */ 883 void dvmAddInitiatingLoader(ClassObject* clazz, Object* loader) 884 { 885 if (loader != clazz->classLoader) { 886 assert(loader != NULL); 887 888 LOGVV("Adding %p to '%s' init list\n", loader, clazz->descriptor); 889 dvmHashTableLock(gDvm.loadedClasses); 890 891 /* 892 * Make sure nobody snuck in. The penalty for adding twice is 893 * pretty minor, and probably outweighs the O(n^2) hit for 894 * checking before every add, so we may not want to do this. 895 */ 896 //if (dvmLoaderInInitiatingList(clazz, loader)) { 897 // LOGW("WOW: simultaneous add of initiating class loader\n"); 898 // goto bail_unlock; 899 //} 900 901 /* 902 * The list never shrinks, so we just keep a count of the 903 * number of elements in it, and reallocate the buffer when 904 * we run off the end. 905 * 906 * The pointer is initially NULL, so we *do* want to call realloc 907 * when count==0. 908 */ 909 InitiatingLoaderList *loaderList = dvmGetInitiatingLoaderList(clazz); 910 if ((loaderList->initiatingLoaderCount & (kInitLoaderInc-1)) == 0) { 911 Object** newList; 912 913 newList = (Object**) realloc(loaderList->initiatingLoaders, 914 (loaderList->initiatingLoaderCount + kInitLoaderInc) 915 * sizeof(Object*)); 916 if (newList == NULL) { 917 /* this is mainly a cache, so it's not the EotW */ 918 assert(false); 919 goto bail_unlock; 920 } 921 loaderList->initiatingLoaders = newList; 922 923 //LOGI("Expanded init list to %d (%s)\n", 924 // loaderList->initiatingLoaderCount+kInitLoaderInc, 925 // clazz->descriptor); 926 } 927 loaderList->initiatingLoaders[loaderList->initiatingLoaderCount++] = 928 loader; 929 930 bail_unlock: 931 dvmHashTableUnlock(gDvm.loadedClasses); 932 } 933 } 934 935 /* 936 * (This is a dvmHashTableLookup callback.) 937 * 938 * Entries in the class hash table are stored as { descriptor, d-loader } 939 * tuples. If the hashed class descriptor matches the requested descriptor, 940 * and the hashed defining class loader matches the requested class 941 * loader, we're good. If only the descriptor matches, we check to see if the 942 * loader is in the hashed class' initiating loader list. If so, we 943 * can return "true" immediately and skip some of the loadClass melodrama. 944 * 945 * The caller must lock the hash table before calling here. 946 * 947 * Returns 0 if a matching entry is found, nonzero otherwise. 948 */ 949 static int hashcmpClassByCrit(const void* vclazz, const void* vcrit) 950 { 951 const ClassObject* clazz = (const ClassObject*) vclazz; 952 const ClassMatchCriteria* pCrit = (const ClassMatchCriteria*) vcrit; 953 bool match; 954 955 match = (strcmp(clazz->descriptor, pCrit->descriptor) == 0 && 956 (clazz->classLoader == pCrit->loader || 957 (pCrit->loader != NULL && 958 dvmLoaderInInitiatingList(clazz, pCrit->loader)) )); 959 //if (match) 960 // LOGI("+++ %s %p matches existing %s %p\n", 961 // pCrit->descriptor, pCrit->loader, 962 // clazz->descriptor, clazz->classLoader); 963 return !match; 964 } 965 966 /* 967 * Like hashcmpClassByCrit, but passing in a fully-formed ClassObject 968 * instead of a ClassMatchCriteria. 969 */ 970 static int hashcmpClassByClass(const void* vclazz, const void* vaddclazz) 971 { 972 const ClassObject* clazz = (const ClassObject*) vclazz; 973 const ClassObject* addClazz = (const ClassObject*) vaddclazz; 974 bool match; 975 976 match = (strcmp(clazz->descriptor, addClazz->descriptor) == 0 && 977 (clazz->classLoader == addClazz->classLoader || 978 (addClazz->classLoader != NULL && 979 dvmLoaderInInitiatingList(clazz, addClazz->classLoader)) )); 980 return !match; 981 } 982 983 /* 984 * Search through the hash table to find an entry with a matching descriptor 985 * and an initiating class loader that matches "loader". 986 * 987 * The table entries are hashed on descriptor only, because they're unique 988 * on *defining* class loader, not *initiating* class loader. This isn't 989 * great, because it guarantees we will have to probe when multiple 990 * class loaders are used. 991 * 992 * Note this does NOT try to load a class; it just finds a class that 993 * has already been loaded. 994 * 995 * If "unprepOkay" is set, this will return classes that have been added 996 * to the hash table but are not yet fully loaded and linked. Otherwise, 997 * such classes are ignored. (The only place that should set "unprepOkay" 998 * is findClassNoInit(), which will wait for the prep to finish.) 999 * 1000 * Returns NULL if not found. 1001 */ 1002 ClassObject* dvmLookupClass(const char* descriptor, Object* loader, 1003 bool unprepOkay) 1004 { 1005 ClassMatchCriteria crit; 1006 void* found; 1007 u4 hash; 1008 1009 crit.descriptor = descriptor; 1010 crit.loader = loader; 1011 hash = dvmComputeUtf8Hash(descriptor); 1012 1013 LOGVV("threadid=%d: dvmLookupClass searching for '%s' %p\n", 1014 dvmThreadSelf()->threadId, descriptor, loader); 1015 1016 dvmHashTableLock(gDvm.loadedClasses); 1017 found = dvmHashTableLookup(gDvm.loadedClasses, hash, &crit, 1018 hashcmpClassByCrit, false); 1019 dvmHashTableUnlock(gDvm.loadedClasses); 1020 1021 /* 1022 * The class has been added to the hash table but isn't ready for use. 1023 * We're going to act like we didn't see it, so that the caller will 1024 * go through the full "find class" path, which includes locking the 1025 * object and waiting until it's ready. We could do that lock/wait 1026 * here, but this is an extremely rare case, and it's simpler to have 1027 * the wait-for-class code centralized. 1028 */ 1029 if (found != NULL && !unprepOkay && !dvmIsClassLinked(found)) { 1030 LOGV("Ignoring not-yet-ready %s, using slow path\n", 1031 ((ClassObject*)found)->descriptor); 1032 found = NULL; 1033 } 1034 1035 return (ClassObject*) found; 1036 } 1037 1038 /* 1039 * Add a new class to the hash table. 1040 * 1041 * The class is considered "new" if it doesn't match on both the class 1042 * descriptor and the defining class loader. 1043 * 1044 * TODO: we should probably have separate hash tables for each 1045 * ClassLoader. This could speed up dvmLookupClass and 1046 * other common operations. It does imply a VM-visible data structure 1047 * for each ClassLoader object with loaded classes, which we don't 1048 * have yet. 1049 */ 1050 bool dvmAddClassToHash(ClassObject* clazz) 1051 { 1052 void* found; 1053 u4 hash; 1054 1055 hash = dvmComputeUtf8Hash(clazz->descriptor); 1056 1057 dvmHashTableLock(gDvm.loadedClasses); 1058 found = dvmHashTableLookup(gDvm.loadedClasses, hash, clazz, 1059 hashcmpClassByClass, true); 1060 dvmHashTableUnlock(gDvm.loadedClasses); 1061 1062 LOGV("+++ dvmAddClassToHash '%s' %p (isnew=%d) --> %p\n", 1063 clazz->descriptor, clazz->classLoader, 1064 (found == (void*) clazz), clazz); 1065 1066 //dvmCheckClassTablePerf(); 1067 1068 /* can happen if two threads load the same class simultaneously */ 1069 return (found == (void*) clazz); 1070 } 1071 1072 #if 0 1073 /* 1074 * Compute hash value for a class. 1075 */ 1076 u4 hashcalcClass(const void* item) 1077 { 1078 return dvmComputeUtf8Hash(((const ClassObject*) item)->descriptor); 1079 } 1080 1081 /* 1082 * Check the performance of the "loadedClasses" hash table. 1083 */ 1084 void dvmCheckClassTablePerf(void) 1085 { 1086 dvmHashTableLock(gDvm.loadedClasses); 1087 dvmHashTableProbeCount(gDvm.loadedClasses, hashcalcClass, 1088 hashcmpClassByClass); 1089 dvmHashTableUnlock(gDvm.loadedClasses); 1090 } 1091 #endif 1092 1093 /* 1094 * Remove a class object from the hash table. 1095 */ 1096 static void removeClassFromHash(ClassObject* clazz) 1097 { 1098 LOGV("+++ removeClassFromHash '%s'\n", clazz->descriptor); 1099 1100 u4 hash = dvmComputeUtf8Hash(clazz->descriptor); 1101 1102 dvmHashTableLock(gDvm.loadedClasses); 1103 if (!dvmHashTableRemove(gDvm.loadedClasses, hash, clazz)) 1104 LOGW("Hash table remove failed on class '%s'\n", clazz->descriptor); 1105 dvmHashTableUnlock(gDvm.loadedClasses); 1106 } 1107 1108 1109 /* 1110 * =========================================================================== 1111 * Class creation 1112 * =========================================================================== 1113 */ 1114 1115 /* 1116 * Set clazz->serialNumber to the next available value. 1117 * 1118 * This usually happens *very* early in class creation, so don't expect 1119 * anything else in the class to be ready. 1120 */ 1121 void dvmSetClassSerialNumber(ClassObject* clazz) 1122 { 1123 u4 oldValue, newValue; 1124 1125 assert(clazz->serialNumber == 0); 1126 1127 do { 1128 oldValue = gDvm.classSerialNumber; 1129 newValue = oldValue + 1; 1130 } while (!ATOMIC_CMP_SWAP(&gDvm.classSerialNumber, oldValue, newValue)); 1131 1132 clazz->serialNumber = (u4) oldValue; 1133 } 1134 1135 1136 /* 1137 * Find the named class (by descriptor), using the specified 1138 * initiating ClassLoader. 1139 * 1140 * The class will be loaded and initialized if it has not already been. 1141 * If necessary, the superclass will be loaded. 1142 * 1143 * If the class can't be found, returns NULL with an appropriate exception 1144 * raised. 1145 */ 1146 ClassObject* dvmFindClass(const char* descriptor, Object* loader) 1147 { 1148 ClassObject* clazz; 1149 1150 clazz = dvmFindClassNoInit(descriptor, loader); 1151 if (clazz != NULL && clazz->status < CLASS_INITIALIZED) { 1152 /* initialize class */ 1153 if (!dvmInitClass(clazz)) { 1154 /* init failed; leave it in the list, marked as bad */ 1155 assert(dvmCheckException(dvmThreadSelf())); 1156 assert(clazz->status == CLASS_ERROR); 1157 return NULL; 1158 } 1159 } 1160 1161 return clazz; 1162 } 1163 1164 /* 1165 * Find the named class (by descriptor), using the specified 1166 * initiating ClassLoader. 1167 * 1168 * The class will be loaded if it has not already been, as will its 1169 * superclass. It will not be initialized. 1170 * 1171 * If the class can't be found, returns NULL with an appropriate exception 1172 * raised. 1173 */ 1174 ClassObject* dvmFindClassNoInit(const char* descriptor, 1175 Object* loader) 1176 { 1177 assert(descriptor != NULL); 1178 //assert(loader != NULL); 1179 1180 LOGVV("FindClassNoInit '%s' %p\n", descriptor, loader); 1181 1182 if (*descriptor == '[') { 1183 /* 1184 * Array class. Find in table, generate if not found. 1185 */ 1186 return dvmFindArrayClass(descriptor, loader); 1187 } else { 1188 /* 1189 * Regular class. Find in table, load if not found. 1190 */ 1191 if (loader != NULL) { 1192 return findClassFromLoaderNoInit(descriptor, loader); 1193 } else { 1194 return dvmFindSystemClassNoInit(descriptor); 1195 } 1196 } 1197 } 1198 1199 /* 1200 * Load the named class (by descriptor) from the specified class 1201 * loader. This calls out to let the ClassLoader object do its thing. 1202 * 1203 * Returns with NULL and an exception raised on error. 1204 */ 1205 static ClassObject* findClassFromLoaderNoInit(const char* descriptor, 1206 Object* loader) 1207 { 1208 //LOGI("##### findClassFromLoaderNoInit (%s,%p)\n", 1209 // descriptor, loader); 1210 1211 Thread* self = dvmThreadSelf(); 1212 ClassObject* clazz; 1213 1214 assert(loader != NULL); 1215 1216 /* 1217 * Do we already have it? 1218 * 1219 * The class loader code does the "is it already loaded" check as 1220 * well. However, this call is much faster than calling through 1221 * interpreted code. Doing this does mean that in the common case 1222 * (365 out of 420 calls booting the sim) we're doing the 1223 * lookup-by-descriptor twice. It appears this is still a win, so 1224 * I'm keeping it in. 1225 */ 1226 clazz = dvmLookupClass(descriptor, loader, false); 1227 if (clazz != NULL) { 1228 LOGVV("Already loaded: %s %p\n", descriptor, loader); 1229 return clazz; 1230 } else { 1231 LOGVV("Not already loaded: %s %p\n", descriptor, loader); 1232 } 1233 1234 char* dotName = NULL; 1235 StringObject* nameObj = NULL; 1236 Object* excep; 1237 Method* loadClass; 1238 1239 /* convert "Landroid/debug/Stuff;" to "android.debug.Stuff" */ 1240 dotName = dvmDescriptorToDot(descriptor); 1241 if (dotName == NULL) { 1242 dvmThrowException("Ljava/lang/OutOfMemoryError;", NULL); 1243 goto bail; 1244 } 1245 nameObj = dvmCreateStringFromCstr(dotName, ALLOC_DEFAULT); 1246 if (nameObj == NULL) { 1247 assert(dvmCheckException(self)); 1248 goto bail; 1249 } 1250 1251 // TODO: cache the vtable offset 1252 loadClass = dvmFindVirtualMethodHierByDescriptor(loader->clazz, "loadClass", 1253 "(Ljava/lang/String;)Ljava/lang/Class;"); 1254 if (loadClass == NULL) { 1255 LOGW("Couldn't find loadClass in ClassLoader\n"); 1256 goto bail; 1257 } 1258 1259 #ifdef WITH_PROFILER 1260 dvmMethodTraceClassPrepBegin(); 1261 #endif 1262 1263 /* 1264 * Invoke loadClass(). This will probably result in a couple of 1265 * exceptions being thrown, because the ClassLoader.loadClass() 1266 * implementation eventually calls VMClassLoader.loadClass to see if 1267 * the bootstrap class loader can find it before doing its own load. 1268 */ 1269 LOGVV("--- Invoking loadClass(%s, %p)\n", dotName, loader); 1270 JValue result; 1271 dvmCallMethod(self, loadClass, loader, &result, nameObj); 1272 clazz = (ClassObject*) result.l; 1273 1274 #ifdef WITH_PROFILER 1275 dvmMethodTraceClassPrepEnd(); 1276 #endif 1277 1278 excep = dvmGetException(self); 1279 if (excep != NULL) { 1280 #if DVM_SHOW_EXCEPTION >= 2 1281 LOGD("NOTE: loadClass '%s' %p threw exception %s\n", 1282 dotName, loader, excep->clazz->descriptor); 1283 #endif 1284 dvmAddTrackedAlloc(excep, self); 1285 dvmClearException(self); 1286 dvmThrowChainedExceptionWithClassMessage( 1287 "Ljava/lang/NoClassDefFoundError;", descriptor, excep); 1288 dvmReleaseTrackedAlloc(excep, self); 1289 clazz = NULL; 1290 goto bail; 1291 } else { 1292 assert(clazz != NULL); 1293 } 1294 1295 dvmAddInitiatingLoader(clazz, loader); 1296 1297 LOGVV("--- Successfully loaded %s %p (thisldr=%p clazz=%p)\n", 1298 descriptor, clazz->classLoader, loader, clazz); 1299 1300 bail: 1301 dvmReleaseTrackedAlloc((Object*)nameObj, NULL); 1302 free(dotName); 1303 return clazz; 1304 } 1305 1306 /* 1307 * Load the named class (by descriptor) from the specified DEX file. 1308 * Used by class loaders to instantiate a class object from a 1309 * VM-managed DEX. 1310 */ 1311 ClassObject* dvmDefineClass(DvmDex* pDvmDex, const char* descriptor, 1312 Object* classLoader) 1313 { 1314 assert(pDvmDex != NULL); 1315 1316 return findClassNoInit(descriptor, classLoader, pDvmDex); 1317 } 1318 1319 1320 /* 1321 * Find the named class (by descriptor), scanning through the 1322 * bootclasspath if it hasn't already been loaded. 1323 * 1324 * "descriptor" looks like "Landroid/debug/Stuff;". 1325 * 1326 * Uses NULL as the defining class loader. 1327 */ 1328 ClassObject* dvmFindSystemClass(const char* descriptor) 1329 { 1330 ClassObject* clazz; 1331 1332 clazz = dvmFindSystemClassNoInit(descriptor); 1333 if (clazz != NULL && clazz->status < CLASS_INITIALIZED) { 1334 /* initialize class */ 1335 if (!dvmInitClass(clazz)) { 1336 /* init failed; leave it in the list, marked as bad */ 1337 assert(dvmCheckException(dvmThreadSelf())); 1338 assert(clazz->status == CLASS_ERROR); 1339 return NULL; 1340 } 1341 } 1342 1343 return clazz; 1344 } 1345 1346 /* 1347 * Find the named class (by descriptor), searching for it in the 1348 * bootclasspath. 1349 * 1350 * On failure, this returns NULL with an exception raised. 1351 */ 1352 ClassObject* dvmFindSystemClassNoInit(const char* descriptor) 1353 { 1354 return findClassNoInit(descriptor, NULL, NULL); 1355 } 1356 1357 /* 1358 * Find the named class (by descriptor). If it's not already loaded, 1359 * we load it and link it, but don't execute <clinit>. (The VM has 1360 * specific limitations on which events can cause initialization.) 1361 * 1362 * If "pDexFile" is NULL, we will search the bootclasspath for an entry. 1363 * 1364 * On failure, this returns NULL with an exception raised. 1365 * 1366 * TODO: we need to return an indication of whether we loaded the class or 1367 * used an existing definition. If somebody deliberately tries to load a 1368 * class twice in the same class loader, they should get a LinkageError, 1369 * but inadvertent simultaneous class references should "just work". 1370 */ 1371 static ClassObject* findClassNoInit(const char* descriptor, Object* loader, 1372 DvmDex* pDvmDex) 1373 { 1374 Thread* self = dvmThreadSelf(); 1375 ClassObject* clazz; 1376 #ifdef WITH_PROFILER 1377 bool profilerNotified = false; 1378 #endif 1379 1380 if (loader != NULL) { 1381 LOGVV("#### findClassNoInit(%s,%p,%p)\n", descriptor, loader, 1382 pDvmDex->pDexFile); 1383 } 1384 1385 /* 1386 * We don't expect an exception to be raised at this point. The 1387 * exception handling code is good about managing this. This *can* 1388 * happen if a JNI lookup fails and the JNI code doesn't do any 1389 * error checking before doing another class lookup, so we may just 1390 * want to clear this and restore it on exit. If we don't, some kinds 1391 * of failures can't be detected without rearranging other stuff. 1392 * 1393 * Most often when we hit this situation it means that something is 1394 * broken in the VM or in JNI code, so I'm keeping it in place (and 1395 * making it an informative abort rather than an assert). 1396 */ 1397 if (dvmCheckException(self)) { 1398 LOGE("Class lookup %s attempted while exception %s pending\n", 1399 descriptor, dvmGetException(self)->clazz->descriptor); 1400 dvmDumpAllThreads(false); 1401 dvmAbort(); 1402 } 1403 1404 clazz = dvmLookupClass(descriptor, loader, true); 1405 if (clazz == NULL) { 1406 const DexClassDef* pClassDef; 1407 1408 #ifdef WITH_PROFILER 1409 dvmMethodTraceClassPrepBegin(); 1410 profilerNotified = true; 1411 #endif 1412 1413 #if LOG_CLASS_LOADING 1414 u8 startTime = dvmGetThreadCpuTimeNsec(); 1415 #endif 1416 1417 if (pDvmDex == NULL) { 1418 assert(loader == NULL); /* shouldn't be here otherwise */ 1419 pDvmDex = searchBootPathForClass(descriptor, &pClassDef); 1420 } else { 1421 pClassDef = dexFindClass(pDvmDex->pDexFile, descriptor); 1422 } 1423 1424 if (pDvmDex == NULL || pClassDef == NULL) { 1425 if (gDvm.noClassDefFoundErrorObj != NULL) { 1426 /* usual case -- use prefabricated object */ 1427 dvmSetException(self, gDvm.noClassDefFoundErrorObj); 1428 } else { 1429 /* dexopt case -- can't guarantee prefab (core.jar) */ 1430 dvmThrowExceptionWithClassMessage( 1431 "Ljava/lang/NoClassDefFoundError;", descriptor); 1432 } 1433 goto bail; 1434 } 1435 1436 /* found a match, try to load it */ 1437 clazz = loadClassFromDex(pDvmDex, pClassDef, loader); 1438 if (dvmCheckException(self)) { 1439 /* class was found but had issues */ 1440 dvmReleaseTrackedAlloc((Object*) clazz, NULL); 1441 goto bail; 1442 } 1443 1444 /* 1445 * Lock the class while we link it so other threads must wait for us 1446 * to finish. Set the "initThreadId" so we can identify recursive 1447 * invocation. 1448 */ 1449 dvmLockObject(self, (Object*) clazz); 1450 clazz->initThreadId = self->threadId; 1451 1452 /* 1453 * Add to hash table so lookups succeed. 1454 * 1455 * [Are circular references possible when linking a class?] 1456 */ 1457 assert(clazz->classLoader == loader); 1458 if (!dvmAddClassToHash(clazz)) { 1459 /* 1460 * Another thread must have loaded the class after we 1461 * started but before we finished. Discard what we've 1462 * done and leave some hints for the GC. 1463 * 1464 * (Yes, this happens.) 1465 */ 1466 //LOGW("WOW: somebody loaded %s simultaneously\n", descriptor); 1467 clazz->initThreadId = 0; 1468 dvmUnlockObject(self, (Object*) clazz); 1469 1470 /* Let the GC free the class. 1471 */ 1472 assert(clazz->obj.clazz == gDvm.unlinkedJavaLangClass); 1473 dvmReleaseTrackedAlloc((Object*) clazz, NULL); 1474 1475 /* Grab the winning class. 1476 */ 1477 clazz = dvmLookupClass(descriptor, loader, true); 1478 assert(clazz != NULL); 1479 goto got_class; 1480 } 1481 dvmReleaseTrackedAlloc((Object*) clazz, NULL); 1482 1483 #if LOG_CLASS_LOADING 1484 logClassLoadWithTime('>', clazz, startTime); 1485 #endif 1486 /* 1487 * Prepare and resolve. 1488 */ 1489 if (!dvmLinkClass(clazz, false)) { 1490 assert(dvmCheckException(self)); 1491 1492 /* Make note of the error and clean up the class. 1493 */ 1494 removeClassFromHash(clazz); 1495 clazz->status = CLASS_ERROR; 1496 dvmFreeClassInnards(clazz); 1497 1498 /* Let any waiters know. 1499 */ 1500 clazz->initThreadId = 0; 1501 dvmObjectNotifyAll(self, (Object*) clazz); 1502 dvmUnlockObject(self, (Object*) clazz); 1503 1504 #if LOG_CLASS_LOADING 1505 LOG(LOG_INFO, "DVMLINK FAILED FOR CLASS ", "%s in %s\n", 1506 clazz->descriptor, get_process_name()); 1507 1508 /* 1509 * TODO: It would probably be better to use a new type code here (instead of '<') to 1510 * indicate the failure. This change would require a matching change in the parser 1511 * and analysis code in frameworks/base/tools/preload. 1512 */ 1513 logClassLoad('<', clazz); 1514 #endif 1515 clazz = NULL; 1516 if (gDvm.optimizing) { 1517 /* happens with "external" libs */ 1518 LOGV("Link of class '%s' failed\n", descriptor); 1519 } else { 1520 LOGW("Link of class '%s' failed\n", descriptor); 1521 } 1522 goto bail; 1523 } 1524 dvmObjectNotifyAll(self, (Object*) clazz); 1525 dvmUnlockObject(self, (Object*) clazz); 1526 1527 /* 1528 * Add class stats to global counters. 1529 * 1530 * TODO: these should probably be atomic ops. 1531 */ 1532 gDvm.numLoadedClasses++; 1533 gDvm.numDeclaredMethods += 1534 clazz->virtualMethodCount + clazz->directMethodCount; 1535 gDvm.numDeclaredInstFields += clazz->ifieldCount; 1536 gDvm.numDeclaredStaticFields += clazz->sfieldCount; 1537 1538 /* 1539 * Cache pointers to basic classes. We want to use these in 1540 * various places, and it's easiest to initialize them on first 1541 * use rather than trying to force them to initialize (startup 1542 * ordering makes it weird). 1543 */ 1544 if (gDvm.classJavaLangObject == NULL && 1545 strcmp(descriptor, "Ljava/lang/Object;") == 0) 1546 { 1547 /* It should be impossible to get here with anything 1548 * but the bootclasspath loader. 1549 */ 1550 assert(loader == NULL); 1551 gDvm.classJavaLangObject = clazz; 1552 } 1553 1554 #if LOG_CLASS_LOADING 1555 logClassLoad('<', clazz); 1556 #endif 1557 1558 } else { 1559 got_class: 1560 if (!dvmIsClassLinked(clazz) && clazz->status != CLASS_ERROR) { 1561 /* 1562 * We can race with other threads for class linking. We should 1563 * never get here recursively; doing so indicates that two 1564 * classes have circular dependencies. 1565 * 1566 * One exception: we force discovery of java.lang.Class in 1567 * dvmLinkClass(), and Class has Object as its superclass. So 1568 * if the first thing we ever load is Object, we will init 1569 * Object->Class->Object. The easiest way to avoid this is to 1570 * ensure that Object is never the first thing we look up, so 1571 * we get Foo->Class->Object instead. 1572 */ 1573 dvmLockObject(self, (Object*) clazz); 1574 if (!dvmIsClassLinked(clazz) && 1575 clazz->initThreadId == self->threadId) 1576 { 1577 LOGW("Recursive link on class %s\n", clazz->descriptor); 1578 dvmUnlockObject(self, (Object*) clazz); 1579 dvmThrowExceptionWithClassMessage( 1580 "Ljava/lang/ClassCircularityError;", clazz->descriptor); 1581 clazz = NULL; 1582 goto bail; 1583 } 1584 //LOGI("WAITING for '%s' (owner=%d)\n", 1585 // clazz->descriptor, clazz->initThreadId); 1586 while (!dvmIsClassLinked(clazz) && clazz->status != CLASS_ERROR) { 1587 dvmObjectWait(self, (Object*) clazz, 0, 0, false); 1588 } 1589 dvmUnlockObject(self, (Object*) clazz); 1590 } 1591 if (clazz->status == CLASS_ERROR) { 1592 /* 1593 * Somebody else tried to load this and failed. We need to raise 1594 * an exception and report failure. 1595 */ 1596 throwEarlierClassFailure(clazz); 1597 clazz = NULL; 1598 goto bail; 1599 } 1600 } 1601 1602 /* check some invariants */ 1603 assert(dvmIsClassLinked(clazz)); 1604 assert(gDvm.classJavaLangClass != NULL); 1605 assert(clazz->obj.clazz == gDvm.classJavaLangClass); 1606 if (clazz != gDvm.classJavaLangObject) { 1607 if (clazz->super == NULL) { 1608 LOGE("Non-Object has no superclass (gDvm.classJavaLangObject=%p)\n", 1609 gDvm.classJavaLangObject); 1610 dvmAbort(); 1611 } 1612 } 1613 if (!dvmIsInterfaceClass(clazz)) { 1614 //LOGI("class=%s vtableCount=%d, virtualMeth=%d\n", 1615 // clazz->descriptor, clazz->vtableCount, 1616 // clazz->virtualMethodCount); 1617 assert(clazz->vtableCount >= clazz->virtualMethodCount); 1618 } 1619 1620 /* 1621 * Normally class objects are initialized before we instantiate them, 1622 * but we can't do that with java.lang.Class (chicken, meet egg). We 1623 * do it explicitly here. 1624 * 1625 * The verifier could call here to find Class while verifying Class, 1626 * so we need to check for CLASS_VERIFYING as well as !initialized. 1627 */ 1628 if (clazz == gDvm.classJavaLangClass && !dvmIsClassInitialized(clazz) && 1629 !(clazz->status == CLASS_VERIFYING)) 1630 { 1631 LOGV("+++ explicitly initializing %s\n", clazz->descriptor); 1632 dvmInitClass(clazz); 1633 } 1634 1635 bail: 1636 #ifdef WITH_PROFILER 1637 if (profilerNotified) 1638 dvmMethodTraceClassPrepEnd(); 1639 #endif 1640 assert(clazz != NULL || dvmCheckException(self)); 1641 return clazz; 1642 } 1643 1644 /* 1645 * Helper for loadClassFromDex, which takes a DexClassDataHeader and 1646 * encoded data pointer in addition to the other arguments. 1647 */ 1648 static ClassObject* loadClassFromDex0(DvmDex* pDvmDex, 1649 const DexClassDef* pClassDef, const DexClassDataHeader* pHeader, 1650 const u1* pEncodedData, Object* classLoader) 1651 { 1652 ClassObject* newClass = NULL; 1653 const DexFile* pDexFile; 1654 const char* descriptor; 1655 int i; 1656 1657 pDexFile = pDvmDex->pDexFile; 1658 descriptor = dexGetClassDescriptor(pDexFile, pClassDef); 1659 1660 /* 1661 * Make sure the aren't any "bonus" flags set, since we use them for 1662 * runtime state. 1663 */ 1664 if ((pClassDef->accessFlags & ~EXPECTED_FILE_FLAGS) != 0) { 1665 LOGW("Invalid file flags in class %s: %04x\n", 1666 descriptor, pClassDef->accessFlags); 1667 return NULL; 1668 } 1669 1670 /* 1671 * Allocate storage for the class object on the GC heap, so that other 1672 * objects can have references to it. We bypass the usual mechanism 1673 * (allocObject), because we don't have all the bits and pieces yet. 1674 * 1675 * Note that we assume that java.lang.Class does not override 1676 * finalize(). 1677 */ 1678 newClass = (ClassObject*) dvmMalloc(sizeof(*newClass), ALLOC_DEFAULT); 1679 if (newClass == NULL) 1680 return NULL; 1681 1682 /* Until the class is loaded and linked, use a placeholder 1683 * obj->clazz value as a hint to the GC. We don't want 1684 * the GC trying to scan the object while it's full of Idx 1685 * values. Also, the real java.lang.Class may not exist 1686 * yet. 1687 */ 1688 DVM_OBJECT_INIT(&newClass->obj, gDvm.unlinkedJavaLangClass); 1689 1690 dvmSetClassSerialNumber(newClass); 1691 newClass->descriptor = descriptor; 1692 assert(newClass->descriptorAlloc == NULL); 1693 newClass->accessFlags = pClassDef->accessFlags; 1694 newClass->classLoader = classLoader; 1695 newClass->pDvmDex = pDvmDex; 1696 newClass->primitiveType = PRIM_NOT; 1697 1698 /* 1699 * Stuff the superclass index into the object pointer field. The linker 1700 * pulls it out and replaces it with a resolved ClassObject pointer. 1701 * I'm doing it this way (rather than having a dedicated superclassIdx 1702 * field) to save a few bytes of overhead per class. 1703 * 1704 * newClass->super is not traversed or freed by dvmFreeClassInnards, so 1705 * this is safe. 1706 */ 1707 assert(sizeof(u4) == sizeof(ClassObject*)); 1708 newClass->super = (ClassObject*) pClassDef->superclassIdx; 1709 1710 /* 1711 * Stuff class reference indices into the pointer fields. 1712 * 1713 * The elements of newClass->interfaces are not traversed or freed by 1714 * dvmFreeClassInnards, so this is GC-safe. 1715 */ 1716 const DexTypeList* pInterfacesList; 1717 pInterfacesList = dexGetInterfacesList(pDexFile, pClassDef); 1718 if (pInterfacesList != NULL) { 1719 newClass->interfaceCount = pInterfacesList->size; 1720 newClass->interfaces = (ClassObject**) dvmLinearAlloc(classLoader, 1721 newClass->interfaceCount * sizeof(ClassObject*)); 1722 1723 for (i = 0; i < newClass->interfaceCount; i++) { 1724 const DexTypeItem* pType = dexGetTypeItem(pInterfacesList, i); 1725 newClass->interfaces[i] = (ClassObject*)(u4) pType->typeIdx; 1726 } 1727 dvmLinearReadOnly(classLoader, newClass->interfaces); 1728 } 1729 1730 /* load field definitions */ 1731 1732 /* 1733 * TODO: consider over-allocating the class object and appending the 1734 * static field info onto the end. It's fixed-size and known at alloc 1735 * time. This would save a couple of native heap allocations, but it 1736 * would also make heap compaction more difficult because we pass Field 1737 * pointers around internally. 1738 */ 1739 1740 if (pHeader->staticFieldsSize != 0) { 1741 /* static fields stay on system heap; field data isn't "write once" */ 1742 int count = (int) pHeader->staticFieldsSize; 1743 u4 lastIndex = 0; 1744 DexField field; 1745 1746 newClass->sfieldCount = count; 1747 newClass->sfields = 1748 (StaticField*) calloc(count, sizeof(StaticField)); 1749 for (i = 0; i < count; i++) { 1750 dexReadClassDataField(&pEncodedData, &field, &lastIndex); 1751 loadSFieldFromDex(newClass, &field, &newClass->sfields[i]); 1752 } 1753 } 1754 1755 if (pHeader->instanceFieldsSize != 0) { 1756 int count = (int) pHeader->instanceFieldsSize; 1757 u4 lastIndex = 0; 1758 DexField field; 1759 1760 newClass->ifieldCount = count; 1761 newClass->ifields = (InstField*) dvmLinearAlloc(classLoader, 1762 count * sizeof(InstField)); 1763 for (i = 0; i < count; i++) { 1764 dexReadClassDataField(&pEncodedData, &field, &lastIndex); 1765 loadIFieldFromDex(newClass, &field, &newClass->ifields[i]); 1766 } 1767 dvmLinearReadOnly(classLoader, newClass->ifields); 1768 } 1769 1770 /* 1771 * Load method definitions. We do this in two batches, direct then 1772 * virtual. 1773 * 1774 * If register maps have already been generated for this class, and 1775 * precise GC is enabled, we pull out pointers to them. We know that 1776 * they were streamed to the DEX file in the same order in which the 1777 * methods appear. 1778 * 1779 * If the class wasn't pre-verified, the maps will be generated when 1780 * the class is verified during class initialization. 1781 */ 1782 u4 classDefIdx = dexGetIndexForClassDef(pDexFile, pClassDef); 1783 const void* classMapData; 1784 u4 numMethods; 1785 1786 if (gDvm.preciseGc) { 1787 classMapData = 1788 dvmRegisterMapGetClassData(pDexFile, classDefIdx, &numMethods); 1789 1790 /* sanity check */ 1791 if (classMapData != NULL && 1792 pHeader->directMethodsSize + pHeader->virtualMethodsSize != numMethods) 1793 { 1794 LOGE("ERROR: in %s, direct=%d virtual=%d, maps have %d\n", 1795 newClass->descriptor, pHeader->directMethodsSize, 1796 pHeader->virtualMethodsSize, numMethods); 1797 assert(false); 1798 classMapData = NULL; /* abandon */ 1799 } 1800 } else { 1801 classMapData = NULL; 1802 } 1803 1804 if (pHeader->directMethodsSize != 0) { 1805 int count = (int) pHeader->directMethodsSize; 1806 u4 lastIndex = 0; 1807 DexMethod method; 1808 1809 newClass->directMethodCount = count; 1810 newClass->directMethods = (Method*) dvmLinearAlloc(classLoader, 1811 count * sizeof(Method)); 1812 for (i = 0; i < count; i++) { 1813 dexReadClassDataMethod(&pEncodedData, &method, &lastIndex); 1814 loadMethodFromDex(newClass, &method, &newClass->directMethods[i]); 1815 if (classMapData != NULL) { 1816 const RegisterMap* pMap = dvmRegisterMapGetNext(&classMapData); 1817 if (dvmRegisterMapGetFormat(pMap) != kRegMapFormatNone) { 1818 newClass->directMethods[i].registerMap = pMap; 1819 /* TODO: add rigorous checks */ 1820 assert((newClass->directMethods[i].registersSize+7) / 8 == 1821 newClass->directMethods[i].registerMap->regWidth); 1822 } 1823 } 1824 } 1825 dvmLinearReadOnly(classLoader, newClass->directMethods); 1826 } 1827 1828 if (pHeader->virtualMethodsSize != 0) { 1829 int count = (int) pHeader->virtualMethodsSize; 1830 u4 lastIndex = 0; 1831 DexMethod method; 1832 1833 newClass->virtualMethodCount = count; 1834 newClass->virtualMethods = (Method*) dvmLinearAlloc(classLoader, 1835 count * sizeof(Method)); 1836 for (i = 0; i < count; i++) { 1837 dexReadClassDataMethod(&pEncodedData, &method, &lastIndex); 1838 loadMethodFromDex(newClass, &method, &newClass->virtualMethods[i]); 1839 if (classMapData != NULL) { 1840 const RegisterMap* pMap = dvmRegisterMapGetNext(&classMapData); 1841 if (dvmRegisterMapGetFormat(pMap) != kRegMapFormatNone) { 1842 newClass->virtualMethods[i].registerMap = pMap; 1843 /* TODO: add rigorous checks */ 1844 assert((newClass->virtualMethods[i].registersSize+7) / 8 == 1845 newClass->virtualMethods[i].registerMap->regWidth); 1846 } 1847 } 1848 } 1849 dvmLinearReadOnly(classLoader, newClass->virtualMethods); 1850 } 1851 1852 newClass->sourceFile = dexGetSourceFile(pDexFile, pClassDef); 1853 newClass->status = CLASS_LOADED; 1854 1855 /* caller must call dvmReleaseTrackedAlloc */ 1856 return newClass; 1857 } 1858 1859 /* 1860 * Try to load the indicated class from the specified DEX file. 1861 * 1862 * This is effectively loadClass()+defineClass() for a DexClassDef. The 1863 * loading was largely done when we crunched through the DEX. 1864 * 1865 * Returns NULL on failure. If we locate the class but encounter an error 1866 * while processing it, an appropriate exception is thrown. 1867 */ 1868 static ClassObject* loadClassFromDex(DvmDex* pDvmDex, 1869 const DexClassDef* pClassDef, Object* classLoader) 1870 { 1871 ClassObject* result; 1872 DexClassDataHeader header; 1873 const u1* pEncodedData; 1874 const DexFile* pDexFile; 1875 1876 assert((pDvmDex != NULL) && (pClassDef != NULL)); 1877 pDexFile = pDvmDex->pDexFile; 1878 1879 if (gDvm.verboseClass) { 1880 LOGV("CLASS: loading '%s'...\n", 1881 dexGetClassDescriptor(pDexFile, pClassDef)); 1882 } 1883 1884 pEncodedData = dexGetClassData(pDexFile, pClassDef); 1885 1886 if (pEncodedData != NULL) { 1887 dexReadClassDataHeader(&pEncodedData, &header); 1888 } else { 1889 // Provide an all-zeroes header for the rest of the loading. 1890 memset(&header, 0, sizeof(header)); 1891 } 1892 1893 result = loadClassFromDex0(pDvmDex, pClassDef, &header, pEncodedData, 1894 classLoader); 1895 1896 if (gDvm.verboseClass && (result != NULL)) { 1897 LOGI("[Loaded %s from DEX %p (cl=%p)]\n", 1898 result->descriptor, pDvmDex, classLoader); 1899 } 1900 1901 return result; 1902 } 1903 1904 /* 1905 * Free anything in a ClassObject that was allocated on the system heap. 1906 * 1907 * The ClassObject itself is allocated on the GC heap, so we leave it for 1908 * the garbage collector. 1909 * 1910 * NOTE: this may be called with a partially-constructed object. 1911 * NOTE: there is no particular ordering imposed, so don't go poking at 1912 * superclasses. 1913 */ 1914 void dvmFreeClassInnards(ClassObject* clazz) 1915 { 1916 void *tp; 1917 int i; 1918 1919 if (clazz == NULL) 1920 return; 1921 1922 assert(clazz->obj.clazz == gDvm.classJavaLangClass || 1923 clazz->obj.clazz == gDvm.unlinkedJavaLangClass); 1924 1925 /* Guarantee that dvmFreeClassInnards can be called on a given 1926 * class multiple times by clearing things out as we free them. 1927 * We don't make any attempt at real atomicity here; higher 1928 * levels need to make sure that no two threads can free the 1929 * same ClassObject at the same time. 1930 * 1931 * TODO: maybe just make it so the GC will never free the 1932 * innards of an already-freed class. 1933 * 1934 * TODO: this #define isn't MT-safe -- the compiler could rearrange it. 1935 */ 1936 #define NULL_AND_FREE(p) \ 1937 do { \ 1938 if ((p) != NULL) { \ 1939 tp = (p); \ 1940 (p) = NULL; \ 1941 free(tp); \ 1942 } \ 1943 } while (0) 1944 #define NULL_AND_LINEAR_FREE(p) \ 1945 do { \ 1946 if ((p) != NULL) { \ 1947 tp = (p); \ 1948 (p) = NULL; \ 1949 dvmLinearFree(clazz->classLoader, tp); \ 1950 } \ 1951 } while (0) 1952 1953 /* arrays just point at Object's vtable; don't free vtable in this case. 1954 * dvmIsArrayClass() checks clazz->descriptor, so we have to do this check 1955 * before freeing the name. 1956 */ 1957 clazz->vtableCount = -1; 1958 if (dvmIsArrayClass(clazz)) { 1959 clazz->vtable = NULL; 1960 } else { 1961 NULL_AND_LINEAR_FREE(clazz->vtable); 1962 } 1963 1964 clazz->descriptor = NULL; 1965 NULL_AND_FREE(clazz->descriptorAlloc); 1966 1967 if (clazz->directMethods != NULL) { 1968 Method *directMethods = clazz->directMethods; 1969 int directMethodCount = clazz->directMethodCount; 1970 clazz->directMethods = NULL; 1971 clazz->directMethodCount = -1; 1972 dvmLinearReadWrite(clazz->classLoader, directMethods); 1973 for (i = 0; i < directMethodCount; i++) { 1974 freeMethodInnards(&directMethods[i]); 1975 } 1976 dvmLinearReadOnly(clazz->classLoader, directMethods); 1977 dvmLinearFree(clazz->classLoader, directMethods); 1978 } 1979 if (clazz->virtualMethods != NULL) { 1980 Method *virtualMethods = clazz->virtualMethods; 1981 int virtualMethodCount = clazz->virtualMethodCount; 1982 clazz->virtualMethodCount = -1; 1983 clazz->virtualMethods = NULL; 1984 dvmLinearReadWrite(clazz->classLoader, virtualMethods); 1985 for (i = 0; i < virtualMethodCount; i++) { 1986 freeMethodInnards(&virtualMethods[i]); 1987 } 1988 dvmLinearReadOnly(clazz->classLoader, virtualMethods); 1989 dvmLinearFree(clazz->classLoader, virtualMethods); 1990 } 1991 1992 InitiatingLoaderList *loaderList = dvmGetInitiatingLoaderList(clazz); 1993 loaderList->initiatingLoaderCount = -1; 1994 NULL_AND_FREE(loaderList->initiatingLoaders); 1995 1996 clazz->interfaceCount = -1; 1997 NULL_AND_LINEAR_FREE(clazz->interfaces); 1998 1999 clazz->iftableCount = -1; 2000 NULL_AND_LINEAR_FREE(clazz->iftable); 2001 2002 clazz->ifviPoolCount = -1; 2003 NULL_AND_LINEAR_FREE(clazz->ifviPool); 2004 2005 clazz->sfieldCount = -1; 2006 NULL_AND_FREE(clazz->sfields); 2007 2008 clazz->ifieldCount = -1; 2009 NULL_AND_LINEAR_FREE(clazz->ifields); 2010 2011 #undef NULL_AND_FREE 2012 #undef NULL_AND_LINEAR_FREE 2013 } 2014 2015 /* 2016 * Free anything in a Method that was allocated on the system heap. 2017 * 2018 * The containing class is largely torn down by this point. 2019 */ 2020 static void freeMethodInnards(Method* meth) 2021 { 2022 #if 0 2023 free(meth->exceptions); 2024 free(meth->lines); 2025 free(meth->locals); 2026 #endif 2027 2028 /* 2029 * Some register maps are allocated on the heap, either because of late 2030 * verification or because we're caching an uncompressed form. 2031 */ 2032 const RegisterMap* pMap = meth->registerMap; 2033 if (pMap != NULL && dvmRegisterMapGetOnHeap(pMap)) { 2034 dvmFreeRegisterMap((RegisterMap*) pMap); 2035 meth->registerMap = NULL; 2036 } 2037 2038 /* 2039 * We may have copied the instructions. 2040 */ 2041 if (IS_METHOD_FLAG_SET(meth, METHOD_ISWRITABLE)) { 2042 DexCode* methodDexCode = (DexCode*) dvmGetMethodCode(meth); 2043 dvmLinearFree(meth->clazz->classLoader, methodDexCode); 2044 } 2045 } 2046 2047 /* 2048 * Clone a Method, making new copies of anything that will be freed up 2049 * by freeMethodInnards(). This is used for "miranda" methods. 2050 */ 2051 static void cloneMethod(Method* dst, const Method* src) 2052 { 2053 if (src->registerMap != NULL) { 2054 LOGE("GLITCH: only expected abstract methods here\n"); 2055 LOGE(" cloning %s.%s\n", src->clazz->descriptor, src->name); 2056 dvmAbort(); 2057 } 2058 memcpy(dst, src, sizeof(Method)); 2059 } 2060 2061 /* 2062 * Pull the interesting pieces out of a DexMethod. 2063 * 2064 * The DEX file isn't going anywhere, so we don't need to make copies of 2065 * the code area. 2066 */ 2067 static void loadMethodFromDex(ClassObject* clazz, const DexMethod* pDexMethod, 2068 Method* meth) 2069 { 2070 DexFile* pDexFile = clazz->pDvmDex->pDexFile; 2071 const DexMethodId* pMethodId; 2072 const DexCode* pDexCode; 2073 2074 pMethodId = dexGetMethodId(pDexFile, pDexMethod->methodIdx); 2075 2076 meth->name = dexStringById(pDexFile, pMethodId->nameIdx); 2077 dexProtoSetFromMethodId(&meth->prototype, pDexFile, pMethodId); 2078 meth->shorty = dexProtoGetShorty(&meth->prototype); 2079 meth->accessFlags = pDexMethod->accessFlags; 2080 meth->clazz = clazz; 2081 meth->jniArgInfo = 0; 2082 2083 if (dvmCompareNameDescriptorAndMethod("finalize", "()V", meth) == 0) { 2084 SET_CLASS_FLAG(clazz, CLASS_ISFINALIZABLE); 2085 } 2086 2087 pDexCode = dexGetCode(pDexFile, pDexMethod); 2088 if (pDexCode != NULL) { 2089 /* integer constants, copy over for faster access */ 2090 meth->registersSize = pDexCode->registersSize; 2091 meth->insSize = pDexCode->insSize; 2092 meth->outsSize = pDexCode->outsSize; 2093 2094 /* pointer to code area */ 2095 meth->insns = pDexCode->insns; 2096 } else { 2097 /* 2098 * We don't have a DexCode block, but we still want to know how 2099 * much space is needed for the arguments (so we don't have to 2100 * compute it later). We also take this opportunity to compute 2101 * JNI argument info. 2102 * 2103 * We do this for abstract methods as well, because we want to 2104 * be able to substitute our exception-throwing "stub" in. 2105 */ 2106 int argsSize = dvmComputeMethodArgsSize(meth); 2107 if (!dvmIsStaticMethod(meth)) 2108 argsSize++; 2109 meth->registersSize = meth->insSize = argsSize; 2110 assert(meth->outsSize == 0); 2111 assert(meth->insns == NULL); 2112 2113 if (dvmIsNativeMethod(meth)) { 2114 meth->nativeFunc = dvmResolveNativeMethod; 2115 meth->jniArgInfo = computeJniArgInfo(&meth->prototype); 2116 } 2117 } 2118 } 2119 2120 #if 0 /* replaced with private/read-write mapping */ 2121 /* 2122 * We usually map bytecode directly out of the DEX file, which is mapped 2123 * shared read-only. If we want to be able to modify it, we have to make 2124 * a new copy. 2125 * 2126 * Once copied, the code will be in the LinearAlloc region, which may be 2127 * marked read-only. 2128 * 2129 * The bytecode instructions are embedded inside a DexCode structure, so we 2130 * need to copy all of that. (The dvmGetMethodCode function backs up the 2131 * instruction pointer to find the start of the DexCode.) 2132 */ 2133 void dvmMakeCodeReadWrite(Method* meth) 2134 { 2135 DexCode* methodDexCode = (DexCode*) dvmGetMethodCode(meth); 2136 2137 if (IS_METHOD_FLAG_SET(meth, METHOD_ISWRITABLE)) { 2138 dvmLinearReadWrite(meth->clazz->classLoader, methodDexCode); 2139 return; 2140 } 2141 2142 assert(!dvmIsNativeMethod(meth) && !dvmIsAbstractMethod(meth)); 2143 2144 size_t dexCodeSize = dexGetDexCodeSize(methodDexCode); 2145 LOGD("Making a copy of %s.%s code (%d bytes)\n", 2146 meth->clazz->descriptor, meth->name, dexCodeSize); 2147 2148 DexCode* newCode = 2149 (DexCode*) dvmLinearAlloc(meth->clazz->classLoader, dexCodeSize); 2150 memcpy(newCode, methodDexCode, dexCodeSize); 2151 2152 meth->insns = newCode->insns; 2153 SET_METHOD_FLAG(meth, METHOD_ISWRITABLE); 2154 } 2155 2156 /* 2157 * Mark the bytecode read-only. 2158 * 2159 * If the contents of the DexCode haven't actually changed, we could revert 2160 * to the original shared page. 2161 */ 2162 void dvmMakeCodeReadOnly(Method* meth) 2163 { 2164 DexCode* methodDexCode = (DexCode*) dvmGetMethodCode(meth); 2165 LOGV("+++ marking %p read-only\n", methodDexCode); 2166 dvmLinearReadOnly(meth->clazz->classLoader, methodDexCode); 2167 } 2168 #endif 2169 2170 2171 /* 2172 * jniArgInfo (32-bit int) layout: 2173 * SRRRHHHH HHHHHHHH HHHHHHHH HHHHHHHH 2174 * 2175 * S - if set, do things the hard way (scan the signature) 2176 * R - return-type enumeration 2177 * H - target-specific hints 2178 * 2179 * This info is used at invocation time by dvmPlatformInvoke. In most 2180 * cases, the target-specific hints allow dvmPlatformInvoke to avoid 2181 * having to fully parse the signature. 2182 * 2183 * The return-type bits are always set, even if target-specific hint bits 2184 * are unavailable. 2185 */ 2186 static int computeJniArgInfo(const DexProto* proto) 2187 { 2188 const char* sig = dexProtoGetShorty(proto); 2189 int returnType, padFlags, jniArgInfo; 2190 char sigByte; 2191 int stackOffset, padMask; 2192 u4 hints; 2193 2194 /* The first shorty character is the return type. */ 2195 switch (*(sig++)) { 2196 case 'V': 2197 returnType = DALVIK_JNI_RETURN_VOID; 2198 break; 2199 case 'F': 2200 returnType = DALVIK_JNI_RETURN_FLOAT; 2201 break; 2202 case 'D': 2203 returnType = DALVIK_JNI_RETURN_DOUBLE; 2204 break; 2205 case 'J': 2206 returnType = DALVIK_JNI_RETURN_S8; 2207 break; 2208 case 'Z': 2209 case 'B': 2210 returnType = DALVIK_JNI_RETURN_S1; 2211 break; 2212 case 'C': 2213 returnType = DALVIK_JNI_RETURN_U2; 2214 break; 2215 case 'S': 2216 returnType = DALVIK_JNI_RETURN_S2; 2217 break; 2218 default: 2219 returnType = DALVIK_JNI_RETURN_S4; 2220 break; 2221 } 2222 2223 jniArgInfo = returnType << DALVIK_JNI_RETURN_SHIFT; 2224 2225 hints = dvmPlatformInvokeHints(proto); 2226 2227 if (hints & DALVIK_JNI_NO_ARG_INFO) { 2228 jniArgInfo |= DALVIK_JNI_NO_ARG_INFO; 2229 } else { 2230 assert((hints & DALVIK_JNI_RETURN_MASK) == 0); 2231 jniArgInfo |= hints; 2232 } 2233 2234 return jniArgInfo; 2235 } 2236 2237 /* 2238 * Load information about a static field. 2239 * 2240 * This also "prepares" static fields by initializing them 2241 * to their "standard default values". 2242 */ 2243 static void loadSFieldFromDex(ClassObject* clazz, 2244 const DexField* pDexSField, StaticField* sfield) 2245 { 2246 DexFile* pDexFile = clazz->pDvmDex->pDexFile; 2247 const DexFieldId* pFieldId; 2248 2249 pFieldId = dexGetFieldId(pDexFile, pDexSField->fieldIdx); 2250 2251 sfield->field.clazz = clazz; 2252 sfield->field.name = dexStringById(pDexFile, pFieldId->nameIdx); 2253 sfield->field.signature = dexStringByTypeIdx(pDexFile, pFieldId->typeIdx); 2254 sfield->field.accessFlags = pDexSField->accessFlags; 2255 2256 /* Static object field values are set to "standard default values" 2257 * (null or 0) until the class is initialized. We delay loading 2258 * constant values from the class until that time. 2259 */ 2260 //sfield->value.j = 0; 2261 assert(sfield->value.j == 0LL); // cleared earlier with calloc 2262 2263 #ifdef PROFILE_FIELD_ACCESS 2264 sfield->field.gets = sfield->field.puts = 0; 2265 #endif 2266 } 2267 2268 /* 2269 * Load information about an instance field. 2270 */ 2271 static void loadIFieldFromDex(ClassObject* clazz, 2272 const DexField* pDexIField, InstField* ifield) 2273 { 2274 DexFile* pDexFile = clazz->pDvmDex->pDexFile; 2275 const DexFieldId* pFieldId; 2276 2277 pFieldId = dexGetFieldId(pDexFile, pDexIField->fieldIdx); 2278 2279 ifield->field.clazz = clazz; 2280 ifield->field.name = dexStringById(pDexFile, pFieldId->nameIdx); 2281 ifield->field.signature = dexStringByTypeIdx(pDexFile, pFieldId->typeIdx); 2282 ifield->field.accessFlags = pDexIField->accessFlags; 2283 #ifndef NDEBUG 2284 assert(ifield->byteOffset == 0); // cleared earlier with calloc 2285 ifield->byteOffset = -1; // make it obvious if we fail to set later 2286 #endif 2287 2288 #ifdef PROFILE_FIELD_ACCESS 2289 ifield->field.gets = ifield->field.puts = 0; 2290 #endif 2291 } 2292 2293 /* 2294 * Cache java.lang.ref.Reference fields and methods. 2295 */ 2296 static bool precacheReferenceOffsets(ClassObject* clazz) 2297 { 2298 Method *meth; 2299 int i; 2300 2301 /* We trick the GC object scanner by not counting 2302 * java.lang.ref.Reference.referent as an object 2303 * field. It will get explicitly scanned as part 2304 * of the reference-walking process. 2305 * 2306 * Find the object field named "referent" and put it 2307 * just after the list of object reference fields. 2308 */ 2309 dvmLinearReadWrite(clazz->classLoader, clazz->ifields); 2310 for (i = 0; i < clazz->ifieldRefCount; i++) { 2311 InstField *pField = &clazz->ifields[i]; 2312 if (strcmp(pField->field.name, "referent") == 0) { 2313 int targetIndex; 2314 2315 /* Swap this field with the last object field. 2316 */ 2317 targetIndex = clazz->ifieldRefCount - 1; 2318 if (i != targetIndex) { 2319 InstField *swapField = &clazz->ifields[targetIndex]; 2320 InstField tmpField; 2321 int tmpByteOffset; 2322 2323 /* It's not currently strictly necessary 2324 * for the fields to be in byteOffset order, 2325 * but it's more predictable that way. 2326 */ 2327 tmpByteOffset = swapField->byteOffset; 2328 swapField->byteOffset = pField->byteOffset; 2329 pField->byteOffset = tmpByteOffset; 2330 2331 tmpField = *swapField; 2332 *swapField = *pField; 2333 *pField = tmpField; 2334 } 2335 2336 /* One fewer object field (wink wink). 2337 */ 2338 clazz->ifieldRefCount--; 2339 i--; /* don't trip "didn't find it" test if field was last */ 2340 break; 2341 } 2342 } 2343 dvmLinearReadOnly(clazz->classLoader, clazz->ifields); 2344 if (i == clazz->ifieldRefCount) { 2345 LOGE("Unable to reorder 'referent' in %s\n", clazz->descriptor); 2346 return false; 2347 } 2348 2349 /* Cache pretty much everything about Reference so that 2350 * we don't need to call interpreted code when clearing/enqueueing 2351 * references. This is fragile, so we'll be paranoid. 2352 */ 2353 gDvm.classJavaLangRefReference = clazz; 2354 2355 gDvm.offJavaLangRefReference_referent = 2356 dvmFindFieldOffset(gDvm.classJavaLangRefReference, 2357 "referent", "Ljava/lang/Object;"); 2358 assert(gDvm.offJavaLangRefReference_referent >= 0); 2359 2360 gDvm.offJavaLangRefReference_queue = 2361 dvmFindFieldOffset(gDvm.classJavaLangRefReference, 2362 "queue", "Ljava/lang/ref/ReferenceQueue;"); 2363 assert(gDvm.offJavaLangRefReference_queue >= 0); 2364 2365 gDvm.offJavaLangRefReference_queueNext = 2366 dvmFindFieldOffset(gDvm.classJavaLangRefReference, 2367 "queueNext", "Ljava/lang/ref/Reference;"); 2368 assert(gDvm.offJavaLangRefReference_queueNext >= 0); 2369 2370 gDvm.offJavaLangRefReference_vmData = 2371 dvmFindFieldOffset(gDvm.classJavaLangRefReference, 2372 "vmData", "I"); 2373 assert(gDvm.offJavaLangRefReference_vmData >= 0); 2374 2375 /* enqueueInternal() is private and thus a direct method. */ 2376 meth = dvmFindDirectMethodByDescriptor(clazz, "enqueueInternal", "()Z"); 2377 assert(meth != NULL); 2378 gDvm.methJavaLangRefReference_enqueueInternal = meth; 2379 2380 return true; 2381 } 2382 2383 2384 /* 2385 * Set the bitmap of reference offsets, refOffsets, from the ifields 2386 * list. 2387 */ 2388 static void computeRefOffsets(ClassObject* clazz) 2389 { 2390 if (clazz->super != NULL) { 2391 clazz->refOffsets = clazz->super->refOffsets; 2392 } else { 2393 clazz->refOffsets = 0; 2394 } 2395 /* 2396 * If our superclass overflowed, we don't stand a chance. 2397 */ 2398 if (clazz->refOffsets != CLASS_WALK_SUPER) { 2399 InstField *f; 2400 int i; 2401 2402 /* All of the fields that contain object references 2403 * are guaranteed to be at the beginning of the ifields list. 2404 */ 2405 f = clazz->ifields; 2406 const int ifieldRefCount = clazz->ifieldRefCount; 2407 for (i = 0; i < ifieldRefCount; i++) { 2408 /* 2409 * Note that, per the comment on struct InstField, 2410 * f->byteOffset is the offset from the beginning of 2411 * obj, not the offset into obj->instanceData. 2412 */ 2413 assert(f->byteOffset >= (int) CLASS_SMALLEST_OFFSET); 2414 assert((f->byteOffset & (CLASS_OFFSET_ALIGNMENT - 1)) == 0); 2415 if (CLASS_CAN_ENCODE_OFFSET(f->byteOffset)) { 2416 u4 newBit = CLASS_BIT_FROM_OFFSET(f->byteOffset); 2417 assert(newBit != 0); 2418 clazz->refOffsets |= newBit; 2419 } else { 2420 clazz->refOffsets = CLASS_WALK_SUPER; 2421 break; 2422 } 2423 f++; 2424 } 2425 } 2426 } 2427 2428 2429 /* 2430 * Link (prepare and resolve). Verification is deferred until later. 2431 * 2432 * This converts symbolic references into pointers. It's independent of 2433 * the source file format. 2434 * 2435 * If "classesResolved" is false, we assume that superclassIdx and 2436 * interfaces[] are holding class reference indices rather than pointers. 2437 * The class references will be resolved during link. (This is done when 2438 * loading from DEX to avoid having to create additional storage to pass 2439 * the indices around.) 2440 * 2441 * Returns "false" with an exception pending on failure. 2442 */ 2443 bool dvmLinkClass(ClassObject* clazz, bool classesResolved) 2444 { 2445 u4 superclassIdx = 0; 2446 bool okay = false; 2447 bool resolve_okay; 2448 int numInterfacesResolved = 0; 2449 int i; 2450 2451 if (gDvm.verboseClass) 2452 LOGV("CLASS: linking '%s'...\n", clazz->descriptor); 2453 2454 /* "Resolve" the class. 2455 * 2456 * At this point, clazz's reference fields contain Dex 2457 * file indices instead of direct object references. 2458 * We need to translate those indices into real references, 2459 * while making sure that the GC doesn't sweep any of 2460 * the referenced objects. 2461 * 2462 * The GC will avoid scanning this object as long as 2463 * clazz->obj.clazz is gDvm.unlinkedJavaLangClass. 2464 * Once clazz is ready, we'll replace clazz->obj.clazz 2465 * with gDvm.classJavaLangClass to let the GC know 2466 * to look at it. 2467 */ 2468 assert(clazz->obj.clazz == gDvm.unlinkedJavaLangClass); 2469 2470 /* It's important that we take care of java.lang.Class 2471 * first. If we were to do this after looking up the 2472 * superclass (below), Class wouldn't be ready when 2473 * java.lang.Object needed it. 2474 * 2475 * Note that we don't set clazz->obj.clazz yet. 2476 */ 2477 if (gDvm.classJavaLangClass == NULL) { 2478 if (clazz->classLoader == NULL && 2479 strcmp(clazz->descriptor, "Ljava/lang/Class;") == 0) 2480 { 2481 gDvm.classJavaLangClass = clazz; 2482 } else { 2483 gDvm.classJavaLangClass = 2484 dvmFindSystemClassNoInit("Ljava/lang/Class;"); 2485 if (gDvm.classJavaLangClass == NULL) { 2486 /* should have thrown one */ 2487 assert(dvmCheckException(dvmThreadSelf())); 2488 goto bail; 2489 } 2490 } 2491 } 2492 assert(gDvm.classJavaLangClass != NULL); 2493 2494 /* 2495 * Resolve all Dex indices so we can hand the ClassObject 2496 * over to the GC. If we fail at any point, we need to remove 2497 * any tracked references to avoid leaking memory. 2498 */ 2499 2500 /* 2501 * All classes have a direct superclass, except for java/lang/Object. 2502 */ 2503 if (!classesResolved) { 2504 superclassIdx = (u4) clazz->super; /* unpack temp store */ 2505 clazz->super = NULL; 2506 } 2507 if (strcmp(clazz->descriptor, "Ljava/lang/Object;") == 0) { 2508 assert(!classesResolved); 2509 if (superclassIdx != kDexNoIndex) { 2510 /* TODO: is this invariant true for all java/lang/Objects, 2511 * regardless of the class loader? For now, assume it is. 2512 */ 2513 dvmThrowException("Ljava/lang/ClassFormatError;", 2514 "java.lang.Object has a superclass"); 2515 goto bail; 2516 } 2517 2518 /* Don't finalize objects whose classes use the 2519 * default (empty) Object.finalize(). 2520 */ 2521 CLEAR_CLASS_FLAG(clazz, CLASS_ISFINALIZABLE); 2522 } else { 2523 if (!classesResolved) { 2524 if (superclassIdx == kDexNoIndex) { 2525 dvmThrowException("Ljava/lang/LinkageError;", 2526 "no superclass defined"); 2527 goto bail; 2528 } 2529 clazz->super = dvmResolveClass(clazz, superclassIdx, false); 2530 if (clazz->super == NULL) { 2531 assert(dvmCheckException(dvmThreadSelf())); 2532 if (gDvm.optimizing) { 2533 /* happens with "external" libs */ 2534 LOGV("Unable to resolve superclass of %s (%d)\n", 2535 clazz->descriptor, superclassIdx); 2536 } else { 2537 LOGW("Unable to resolve superclass of %s (%d)\n", 2538 clazz->descriptor, superclassIdx); 2539 } 2540 goto bail; 2541 } 2542 } 2543 /* verify */ 2544 if (dvmIsFinalClass(clazz->super)) { 2545 LOGW("Superclass of '%s' is final '%s'\n", 2546 clazz->descriptor, clazz->super->descriptor); 2547 dvmThrowException("Ljava/lang/IncompatibleClassChangeError;", 2548 "superclass is final"); 2549 goto bail; 2550 } else if (dvmIsInterfaceClass(clazz->super)) { 2551 LOGW("Superclass of '%s' is interface '%s'\n", 2552 clazz->descriptor, clazz->super->descriptor); 2553 dvmThrowException("Ljava/lang/IncompatibleClassChangeError;", 2554 "superclass is an interface"); 2555 goto bail; 2556 } else if (!dvmCheckClassAccess(clazz, clazz->super)) { 2557 LOGW("Superclass of '%s' (%s) is not accessible\n", 2558 clazz->descriptor, clazz->super->descriptor); 2559 dvmThrowException("Ljava/lang/IllegalAccessError;", 2560 "superclass not accessible"); 2561 goto bail; 2562 } 2563 2564 /* Don't let the GC reclaim the superclass. 2565 * TODO: shouldn't be needed; remove when things stabilize 2566 */ 2567 dvmAddTrackedAlloc((Object *)clazz->super, NULL); 2568 2569 /* Inherit finalizability from the superclass. If this 2570 * class also overrides finalize(), its CLASS_ISFINALIZABLE 2571 * bit will already be set. 2572 */ 2573 if (IS_CLASS_FLAG_SET(clazz->super, CLASS_ISFINALIZABLE)) { 2574 SET_CLASS_FLAG(clazz, CLASS_ISFINALIZABLE); 2575 } 2576 2577 /* See if this class descends from java.lang.Reference 2578 * and set the class flags appropriately. 2579 */ 2580 if (IS_CLASS_FLAG_SET(clazz->super, CLASS_ISREFERENCE)) { 2581 u4 superRefFlags; 2582 2583 /* We've already determined the reference type of this 2584 * inheritance chain. Inherit reference-ness from the superclass. 2585 */ 2586 superRefFlags = GET_CLASS_FLAG_GROUP(clazz->super, 2587 CLASS_ISREFERENCE | 2588 CLASS_ISWEAKREFERENCE | 2589 CLASS_ISPHANTOMREFERENCE); 2590 SET_CLASS_FLAG(clazz, superRefFlags); 2591 } else if (clazz->classLoader == NULL && 2592 clazz->super->classLoader == NULL && 2593 strcmp(clazz->super->descriptor, 2594 "Ljava/lang/ref/Reference;") == 0) 2595 { 2596 u4 refFlags; 2597 2598 /* This class extends Reference, which means it should 2599 * be one of the magic Soft/Weak/PhantomReference classes. 2600 */ 2601 refFlags = CLASS_ISREFERENCE; 2602 if (strcmp(clazz->descriptor, 2603 "Ljava/lang/ref/SoftReference;") == 0) 2604 { 2605 /* Only CLASS_ISREFERENCE is set for soft references. 2606 */ 2607 } else if (strcmp(clazz->descriptor, 2608 "Ljava/lang/ref/WeakReference;") == 0) 2609 { 2610 refFlags |= CLASS_ISWEAKREFERENCE; 2611 } else if (strcmp(clazz->descriptor, 2612 "Ljava/lang/ref/PhantomReference;") == 0) 2613 { 2614 refFlags |= CLASS_ISPHANTOMREFERENCE; 2615 } else { 2616 /* No-one else is allowed to inherit directly 2617 * from Reference. 2618 */ 2619 //xxx is this the right exception? better than an assertion. 2620 dvmThrowException("Ljava/lang/LinkageError;", 2621 "illegal inheritance from Reference"); 2622 goto bail; 2623 } 2624 2625 /* The class should not have any reference bits set yet. 2626 */ 2627 assert(GET_CLASS_FLAG_GROUP(clazz, 2628 CLASS_ISREFERENCE | 2629 CLASS_ISWEAKREFERENCE | 2630 CLASS_ISPHANTOMREFERENCE) == 0); 2631 2632 SET_CLASS_FLAG(clazz, refFlags); 2633 } 2634 } 2635 2636 if (!classesResolved && clazz->interfaceCount > 0) { 2637 /* 2638 * Resolve the interfaces implemented directly by this class. We 2639 * stuffed the class index into the interface pointer slot. 2640 */ 2641 dvmLinearReadWrite(clazz->classLoader, clazz->interfaces); 2642 for (i = 0; i < clazz->interfaceCount; i++) { 2643 u4 interfaceIdx; 2644 2645 interfaceIdx = (u4) clazz->interfaces[i]; /* unpack temp store */ 2646 assert(interfaceIdx != kDexNoIndex); 2647 2648 clazz->interfaces[i] = dvmResolveClass(clazz, interfaceIdx, false); 2649 if (clazz->interfaces[i] == NULL) { 2650 const DexFile* pDexFile = clazz->pDvmDex->pDexFile; 2651 2652 assert(dvmCheckException(dvmThreadSelf())); 2653 dvmLinearReadOnly(clazz->classLoader, clazz->interfaces); 2654 2655 const char* classDescriptor; 2656 classDescriptor = dexStringByTypeIdx(pDexFile, interfaceIdx); 2657 if (gDvm.optimizing) { 2658 /* happens with "external" libs */ 2659 LOGV("Failed resolving %s interface %d '%s'\n", 2660 clazz->descriptor, interfaceIdx, classDescriptor); 2661 } else { 2662 LOGI("Failed resolving %s interface %d '%s'\n", 2663 clazz->descriptor, interfaceIdx, classDescriptor); 2664 } 2665 goto bail_during_resolve; 2666 } 2667 2668 /* are we allowed to implement this interface? */ 2669 if (!dvmCheckClassAccess(clazz, clazz->interfaces[i])) { 2670 dvmLinearReadOnly(clazz->classLoader, clazz->interfaces); 2671 LOGW("Interface '%s' is not accessible to '%s'\n", 2672 clazz->interfaces[i]->descriptor, clazz->descriptor); 2673 dvmThrowException("Ljava/lang/IllegalAccessError;", 2674 "interface not accessible"); 2675 goto bail_during_resolve; 2676 } 2677 2678 /* Don't let the GC reclaim the interface class. 2679 * TODO: shouldn't be needed; remove when things stabilize 2680 */ 2681 dvmAddTrackedAlloc((Object *)clazz->interfaces[i], NULL); 2682 numInterfacesResolved++; 2683 2684 LOGVV("+++ found interface '%s'\n", 2685 clazz->interfaces[i]->descriptor); 2686 } 2687 dvmLinearReadOnly(clazz->classLoader, clazz->interfaces); 2688 } 2689 2690 /* 2691 * The ClassObject is now in a GC-able state. We let the GC 2692 * realize this by punching in the real class type, which is 2693 * always java.lang.Class. 2694 * 2695 * After this line, clazz will be fair game for the GC. 2696 * Every field that the GC will look at must now be valid: 2697 * - clazz->super 2698 * - class->classLoader 2699 * - clazz->sfields 2700 * - clazz->interfaces 2701 */ 2702 clazz->obj.clazz = gDvm.classJavaLangClass; 2703 2704 if (false) { 2705 bail_during_resolve: 2706 resolve_okay = false; 2707 } else { 2708 resolve_okay = true; 2709 } 2710 2711 /* 2712 * Now that the GC can scan the ClassObject, we can let 2713 * go of the explicit references we were holding onto. 2714 * 2715 * Either that or we failed, in which case we need to 2716 * release the references so we don't leak memory. 2717 */ 2718 if (clazz->super != NULL) { 2719 dvmReleaseTrackedAlloc((Object *)clazz->super, NULL); 2720 } 2721 for (i = 0; i < numInterfacesResolved; i++) { 2722 dvmReleaseTrackedAlloc((Object *)clazz->interfaces[i], NULL); 2723 } 2724 2725 if (!resolve_okay) { 2726 //LOGW("resolve_okay is false\n"); 2727 goto bail; 2728 } 2729 2730 /* 2731 * Populate vtable. 2732 */ 2733 if (dvmIsInterfaceClass(clazz)) { 2734 /* no vtable; just set the method indices */ 2735 int count = clazz->virtualMethodCount; 2736 2737 if (count != (u2) count) { 2738 LOGE("Too many methods (%d) in interface '%s'\n", count, 2739 clazz->descriptor); 2740 goto bail; 2741 } 2742 2743 dvmLinearReadWrite(clazz->classLoader, clazz->virtualMethods); 2744 2745 for (i = 0; i < count; i++) 2746 clazz->virtualMethods[i].methodIndex = (u2) i; 2747 2748 dvmLinearReadOnly(clazz->classLoader, clazz->virtualMethods); 2749 } else { 2750 if (!createVtable(clazz)) { 2751 LOGW("failed creating vtable\n"); 2752 goto bail; 2753 } 2754 } 2755 2756 /* 2757 * Populate interface method tables. Can alter the vtable. 2758 */ 2759 if (!createIftable(clazz)) 2760 goto bail; 2761 2762 /* 2763 * Insert special-purpose "stub" method implementations. 2764 */ 2765 if (!insertMethodStubs(clazz)) 2766 goto bail; 2767 2768 /* 2769 * Compute instance field offsets and, hence, the size of the object. 2770 */ 2771 if (!computeFieldOffsets(clazz)) 2772 goto bail; 2773 2774 /* 2775 * Cache fields and methods from java/lang/ref/Reference and 2776 * java/lang/Class. This has to happen after computeFieldOffsets(). 2777 */ 2778 if (clazz->classLoader == NULL) { 2779 if (strcmp(clazz->descriptor, "Ljava/lang/ref/Reference;") == 0) { 2780 if (!precacheReferenceOffsets(clazz)) { 2781 LOGE("failed pre-caching Reference offsets\n"); 2782 dvmThrowException("Ljava/lang/InternalError;", NULL); 2783 goto bail; 2784 } 2785 } else if (clazz == gDvm.classJavaLangClass) { 2786 gDvm.offJavaLangClass_pd = dvmFindFieldOffset(clazz, "pd", 2787 "Ljava/security/ProtectionDomain;"); 2788 if (gDvm.offJavaLangClass_pd <= 0) { 2789 LOGE("ERROR: unable to find 'pd' field in Class\n"); 2790 dvmAbort(); /* we're not going to get much farther */ 2791 //goto bail; 2792 } 2793 } 2794 } 2795 2796 /* 2797 * Compact the offsets the GC has to examine into a bitmap, if 2798 * possible. (This has to happen after Reference.referent is 2799 * massaged in precacheReferenceOffsets.) 2800 */ 2801 computeRefOffsets(clazz); 2802 2803 /* 2804 * Done! 2805 */ 2806 if (IS_CLASS_FLAG_SET(clazz, CLASS_ISPREVERIFIED)) 2807 clazz->status = CLASS_VERIFIED; 2808 else 2809 clazz->status = CLASS_RESOLVED; 2810 okay = true; 2811 if (gDvm.verboseClass) 2812 LOGV("CLASS: linked '%s'\n", clazz->descriptor); 2813 2814 /* 2815 * We send CLASS_PREPARE events to the debugger from here. The 2816 * definition of "preparation" is creating the static fields for a 2817 * class and initializing them to the standard default values, but not 2818 * executing any code (that comes later, during "initialization"). 2819 * 2820 * We did the static prep in loadSFieldFromDex() while loading the class. 2821 * 2822 * The class has been prepared and resolved but possibly not yet verified 2823 * at this point. 2824 */ 2825 if (gDvm.debuggerActive) { 2826 dvmDbgPostClassPrepare(clazz); 2827 } 2828 2829 bail: 2830 if (!okay) { 2831 clazz->status = CLASS_ERROR; 2832 if (!dvmCheckException(dvmThreadSelf())) { 2833 dvmThrowException("Ljava/lang/VirtualMachineError;", NULL); 2834 } 2835 } 2836 return okay; 2837 } 2838 2839 /* 2840 * Create the virtual method table. 2841 * 2842 * The top part of the table is a copy of the table from our superclass, 2843 * with our local methods overriding theirs. The bottom part of the table 2844 * has any new methods we defined. 2845 */ 2846 static bool createVtable(ClassObject* clazz) 2847 { 2848 bool result = false; 2849 int maxCount; 2850 int i; 2851 2852 if (clazz->super != NULL) { 2853 //LOGI("SUPER METHODS %d %s->%s\n", clazz->super->vtableCount, 2854 // clazz->descriptor, clazz->super->descriptor); 2855 } 2856 2857 /* the virtual methods we define, plus the superclass vtable size */ 2858 maxCount = clazz->virtualMethodCount; 2859 if (clazz->super != NULL) { 2860 maxCount += clazz->super->vtableCount; 2861 } else { 2862 /* TODO: is this invariant true for all java/lang/Objects, 2863 * regardless of the class loader? For now, assume it is. 2864 */ 2865 assert(strcmp(clazz->descriptor, "Ljava/lang/Object;") == 0); 2866 } 2867 //LOGD("+++ max vmethods for '%s' is %d\n", clazz->descriptor, maxCount); 2868 2869 /* 2870 * Over-allocate the table, then realloc it down if necessary. So 2871 * long as we don't allocate anything in between we won't cause 2872 * fragmentation, and reducing the size should be unlikely to cause 2873 * a buffer copy. 2874 */ 2875 dvmLinearReadWrite(clazz->classLoader, clazz->virtualMethods); 2876 clazz->vtable = (Method**) dvmLinearAlloc(clazz->classLoader, 2877 sizeof(Method*) * maxCount); 2878 if (clazz->vtable == NULL) 2879 goto bail; 2880 2881 if (clazz->super != NULL) { 2882 int actualCount; 2883 2884 memcpy(clazz->vtable, clazz->super->vtable, 2885 sizeof(*(clazz->vtable)) * clazz->super->vtableCount); 2886 actualCount = clazz->super->vtableCount; 2887 2888 /* 2889 * See if any of our virtual methods override the superclass. 2890 */ 2891 for (i = 0; i < clazz->virtualMethodCount; i++) { 2892 Method* localMeth = &clazz->virtualMethods[i]; 2893 int si; 2894 2895 for (si = 0; si < clazz->super->vtableCount; si++) { 2896 Method* superMeth = clazz->vtable[si]; 2897 2898 if (dvmCompareMethodNamesAndProtos(localMeth, superMeth) == 0) 2899 { 2900 /* verify */ 2901 if (dvmIsFinalMethod(superMeth)) { 2902 LOGW("Method %s.%s overrides final %s.%s\n", 2903 localMeth->clazz->descriptor, localMeth->name, 2904 superMeth->clazz->descriptor, superMeth->name); 2905 goto bail; 2906 } 2907 clazz->vtable[si] = localMeth; 2908 localMeth->methodIndex = (u2) si; 2909 //LOGV("+++ override %s.%s (slot %d)\n", 2910 // clazz->descriptor, localMeth->name, si); 2911 break; 2912 } 2913 } 2914 2915 if (si == clazz->super->vtableCount) { 2916 /* not an override, add to end */ 2917 clazz->vtable[actualCount] = localMeth; 2918 localMeth->methodIndex = (u2) actualCount; 2919 actualCount++; 2920 2921 //LOGV("+++ add method %s.%s\n", 2922 // clazz->descriptor, localMeth->name); 2923 } 2924 } 2925 2926 if (actualCount != (u2) actualCount) { 2927 LOGE("Too many methods (%d) in class '%s'\n", actualCount, 2928 clazz->descriptor); 2929 goto bail; 2930 } 2931 2932 assert(actualCount <= maxCount); 2933 2934 if (actualCount < maxCount) { 2935 assert(clazz->vtable != NULL); 2936 dvmLinearReadOnly(clazz->classLoader, clazz->vtable); 2937 clazz->vtable = dvmLinearRealloc(clazz->classLoader, clazz->vtable, 2938 sizeof(*(clazz->vtable)) * actualCount); 2939 if (clazz->vtable == NULL) { 2940 LOGE("vtable realloc failed\n"); 2941 goto bail; 2942 } else { 2943 LOGVV("+++ reduced vtable from %d to %d\n", 2944 maxCount, actualCount); 2945 } 2946 } 2947 2948 clazz->vtableCount = actualCount; 2949 } else { 2950 /* java/lang/Object case */ 2951 int count = clazz->virtualMethodCount; 2952 if (count != (u2) count) { 2953 LOGE("Too many methods (%d) in base class '%s'\n", count, 2954 clazz->descriptor); 2955 goto bail; 2956 } 2957 2958 for (i = 0; i < count; i++) { 2959 clazz->vtable[i] = &clazz->virtualMethods[i]; 2960 clazz->virtualMethods[i].methodIndex = (u2) i; 2961 } 2962 clazz->vtableCount = clazz->virtualMethodCount; 2963 } 2964 2965 result = true; 2966 2967 bail: 2968 dvmLinearReadOnly(clazz->classLoader, clazz->vtable); 2969 dvmLinearReadOnly(clazz->classLoader, clazz->virtualMethods); 2970 return result; 2971 } 2972 2973 /* 2974 * Create and populate "iftable". 2975 * 2976 * The set of interfaces we support is the combination of the interfaces 2977 * we implement directly and those implemented by our superclass. Each 2978 * interface can have one or more "superinterfaces", which we must also 2979 * support. For speed we flatten the tree out. 2980 * 2981 * We might be able to speed this up when there are lots of interfaces 2982 * by merge-sorting the class pointers and binary-searching when removing 2983 * duplicates. We could also drop the duplicate removal -- it's only 2984 * there to reduce the memory footprint. 2985 * 2986 * Because of "Miranda methods", this may reallocate clazz->virtualMethods. 2987 * 2988 * Returns "true" on success. 2989 */ 2990 static bool createIftable(ClassObject* clazz) 2991 { 2992 bool result = false; 2993 bool zapIftable = false; 2994 bool zapVtable = false; 2995 bool zapIfvipool = false; 2996 int ifCount, superIfCount, idx; 2997 int i; 2998 2999 if (clazz->super != NULL) 3000 superIfCount = clazz->super->iftableCount; 3001 else 3002 superIfCount = 0; 3003 3004 ifCount = superIfCount; 3005 ifCount += clazz->interfaceCount; 3006 for (i = 0; i < clazz->interfaceCount; i++) 3007 ifCount += clazz->interfaces[i]->iftableCount; 3008 3009 LOGVV("INTF: class '%s' direct w/supra=%d super=%d total=%d\n", 3010 clazz->descriptor, ifCount - superIfCount, superIfCount, ifCount); 3011 3012 if (ifCount == 0) { 3013 assert(clazz->iftableCount == 0); 3014 assert(clazz->iftable == NULL); 3015 result = true; 3016 goto bail; 3017 } 3018 3019 /* 3020 * Create a table with enough space for all interfaces, and copy the 3021 * superclass' table in. 3022 */ 3023 clazz->iftable = (InterfaceEntry*) dvmLinearAlloc(clazz->classLoader, 3024 sizeof(InterfaceEntry) * ifCount); 3025 zapIftable = true; 3026 memset(clazz->iftable, 0x00, sizeof(InterfaceEntry) * ifCount); 3027 if (superIfCount != 0) { 3028 memcpy(clazz->iftable, clazz->super->iftable, 3029 sizeof(InterfaceEntry) * superIfCount); 3030 } 3031 3032 /* 3033 * Create a flattened interface hierarchy of our immediate interfaces. 3034 */ 3035 idx = superIfCount; 3036 3037 for (i = 0; i < clazz->interfaceCount; i++) { 3038 ClassObject* interf; 3039 int j; 3040 3041 interf = clazz->interfaces[i]; 3042 assert(interf != NULL); 3043 3044 /* make sure this is still an interface class */ 3045 if (!dvmIsInterfaceClass(interf)) { 3046 LOGW("Class '%s' implements non-interface '%s'\n", 3047 clazz->descriptor, interf->descriptor); 3048 dvmThrowExceptionWithClassMessage( 3049 "Ljava/lang/IncompatibleClassChangeError;", 3050 clazz->descriptor); 3051 goto bail; 3052 } 3053 3054 /* add entry for this interface */ 3055 clazz->iftable[idx++].clazz = interf; 3056 3057 /* add entries for the interface's superinterfaces */ 3058 for (j = 0; j < interf->iftableCount; j++) { 3059 clazz->iftable[idx++].clazz = interf->iftable[j].clazz; 3060 } 3061 } 3062 3063 assert(idx == ifCount); 3064 3065 if (false) { 3066 /* 3067 * Remove anything redundant from our recent additions. Note we have 3068 * to traverse the recent adds when looking for duplicates, because 3069 * it's possible the recent additions are self-redundant. This 3070 * reduces the memory footprint of classes with lots of inherited 3071 * interfaces. 3072 * 3073 * (I don't know if this will cause problems later on when we're trying 3074 * to find a static field. It looks like the proper search order is 3075 * (1) current class, (2) interfaces implemented by current class, 3076 * (3) repeat with superclass. A field implemented by an interface 3077 * and by a superclass might come out wrong if the superclass also 3078 * implements the interface. The javac compiler will reject the 3079 * situation as ambiguous, so the concern is somewhat artificial.) 3080 * 3081 * UPDATE: this makes ReferenceType.Interfaces difficult to implement, 3082 * because it wants to return just the interfaces declared to be 3083 * implemented directly by the class. I'm excluding this code for now. 3084 */ 3085 for (i = superIfCount; i < ifCount; i++) { 3086 int j; 3087 3088 for (j = 0; j < ifCount; j++) { 3089 if (i == j) 3090 continue; 3091 if (clazz->iftable[i].clazz == clazz->iftable[j].clazz) { 3092 LOGVV("INTF: redundant interface %s in %s\n", 3093 clazz->iftable[i].clazz->descriptor, 3094 clazz->descriptor); 3095 3096 if (i != ifCount-1) 3097 memmove(&clazz->iftable[i], &clazz->iftable[i+1], 3098 (ifCount - i -1) * sizeof(InterfaceEntry)); 3099 ifCount--; 3100 i--; // adjust for i++ above 3101 break; 3102 } 3103 } 3104 } 3105 LOGVV("INTF: class '%s' nodupes=%d\n", clazz->descriptor, ifCount); 3106 } // if (false) 3107 3108 clazz->iftableCount = ifCount; 3109 3110 /* 3111 * If we're an interface, we don't need the vtable pointers, so 3112 * we're done. If this class doesn't implement an interface that our 3113 * superclass doesn't have, then we again have nothing to do. 3114 */ 3115 if (dvmIsInterfaceClass(clazz) || superIfCount == ifCount) { 3116 //dvmDumpClass(clazz, kDumpClassFullDetail); 3117 result = true; 3118 goto bail; 3119 } 3120 3121 /* 3122 * When we're handling invokeinterface, we probably have an object 3123 * whose type is an interface class rather than a concrete class. We 3124 * need to convert the method reference into a vtable index. So, for 3125 * every entry in "iftable", we create a list of vtable indices. 3126 * 3127 * Because our vtable encompasses the superclass vtable, we can use 3128 * the vtable indices from our superclass for all of the interfaces 3129 * that weren't directly implemented by us. 3130 * 3131 * Each entry in "iftable" has a pointer to the start of its set of 3132 * vtable offsets. The iftable entries in the superclass point to 3133 * storage allocated in the superclass, and the iftable entries added 3134 * for this class point to storage allocated in this class. "iftable" 3135 * is flat for fast access in a class and all of its subclasses, but 3136 * "ifviPool" is only created for the topmost implementor. 3137 */ 3138 int poolSize = 0; 3139 for (i = superIfCount; i < ifCount; i++) { 3140 /* 3141 * Note it's valid for an interface to have no methods (e.g. 3142 * java/io/Serializable). 3143 */ 3144 LOGVV("INTF: pool: %d from %s\n", 3145 clazz->iftable[i].clazz->virtualMethodCount, 3146 clazz->iftable[i].clazz->descriptor); 3147 poolSize += clazz->iftable[i].clazz->virtualMethodCount; 3148 } 3149 3150 if (poolSize == 0) { 3151 LOGVV("INTF: didn't find any new interfaces with methods\n"); 3152 result = true; 3153 goto bail; 3154 } 3155 3156 clazz->ifviPoolCount = poolSize; 3157 clazz->ifviPool = (int*) dvmLinearAlloc(clazz->classLoader, 3158 poolSize * sizeof(int*)); 3159 zapIfvipool = true; 3160 3161 /* 3162 * Fill in the vtable offsets for the interfaces that weren't part of 3163 * our superclass. 3164 */ 3165 int poolOffset = 0; 3166 Method** mirandaList = NULL; 3167 int mirandaCount = 0, mirandaAlloc = 0; 3168 3169 for (i = superIfCount; i < ifCount; i++) { 3170 ClassObject* interface; 3171 int methIdx; 3172 3173 clazz->iftable[i].methodIndexArray = clazz->ifviPool + poolOffset; 3174 interface = clazz->iftable[i].clazz; 3175 poolOffset += interface->virtualMethodCount; // end here 3176 3177 /* 3178 * For each method listed in the interface's method list, find the 3179 * matching method in our class's method list. We want to favor the 3180 * subclass over the superclass, which just requires walking 3181 * back from the end of the vtable. (This only matters if the 3182 * superclass defines a private method and this class redefines 3183 * it -- otherwise it would use the same vtable slot. In Dalvik 3184 * those don't end up in the virtual method table, so it shouldn't 3185 * matter which direction we go. We walk it backward anyway.) 3186 * 3187 * 3188 * Suppose we have the following arrangement: 3189 * public interface MyInterface 3190 * public boolean inInterface(); 3191 * public abstract class MirandaAbstract implements MirandaInterface 3192 * //public abstract boolean inInterface(); // not declared! 3193 * public boolean inAbstract() { stuff } // in vtable 3194 * public class MirandClass extends MirandaAbstract 3195 * public boolean inInterface() { stuff } 3196 * public boolean inAbstract() { stuff } // in vtable 3197 * 3198 * The javac compiler happily compiles MirandaAbstract even though 3199 * it doesn't declare all methods from its interface. When we try 3200 * to set up a vtable for MirandaAbstract, we find that we don't 3201 * have an slot for inInterface. To prevent this, we synthesize 3202 * abstract method declarations in MirandaAbstract. 3203 * 3204 * We have to expand vtable and update some things that point at it, 3205 * so we accumulate the method list and do it all at once below. 3206 */ 3207 for (methIdx = 0; methIdx < interface->virtualMethodCount; methIdx++) { 3208 Method* imeth = &interface->virtualMethods[methIdx]; 3209 int j; 3210 3211 IF_LOGVV() { 3212 char* desc = dexProtoCopyMethodDescriptor(&imeth->prototype); 3213 LOGVV("INTF: matching '%s' '%s'\n", imeth->name, desc); 3214 free(desc); 3215 } 3216 3217 for (j = clazz->vtableCount-1; j >= 0; j--) { 3218 if (dvmCompareMethodNamesAndProtos(imeth, clazz->vtable[j]) 3219 == 0) 3220 { 3221 LOGVV("INTF: matched at %d\n", j); 3222 if (!dvmIsPublicMethod(clazz->vtable[j])) { 3223 LOGW("Implementation of %s.%s is not public\n", 3224 clazz->descriptor, clazz->vtable[j]->name); 3225 dvmThrowException("Ljava/lang/IllegalAccessError;", 3226 "interface implementation not public"); 3227 goto bail; 3228 } 3229 clazz->iftable[i].methodIndexArray[methIdx] = j; 3230 break; 3231 } 3232 } 3233 if (j < 0) { 3234 IF_LOGV() { 3235 char* desc = 3236 dexProtoCopyMethodDescriptor(&imeth->prototype); 3237 LOGV("No match for '%s' '%s' in '%s' (creating miranda)\n", 3238 imeth->name, desc, clazz->descriptor); 3239 free(desc); 3240 } 3241 //dvmThrowException("Ljava/lang/RuntimeException;", "Miranda!"); 3242 //return false; 3243 3244 if (mirandaCount == mirandaAlloc) { 3245 mirandaAlloc += 8; 3246 if (mirandaList == NULL) { 3247 mirandaList = dvmLinearAlloc(clazz->classLoader, 3248 mirandaAlloc * sizeof(Method*)); 3249 } else { 3250 dvmLinearReadOnly(clazz->classLoader, mirandaList); 3251 mirandaList = dvmLinearRealloc(clazz->classLoader, 3252 mirandaList, mirandaAlloc * sizeof(Method*)); 3253 } 3254 assert(mirandaList != NULL); // mem failed + we leaked 3255 } 3256 3257 /* 3258 * These may be redundant (e.g. method with same name and 3259 * signature declared in two interfaces implemented by the 3260 * same abstract class). We can squeeze the duplicates 3261 * out here. 3262 */ 3263 int mir; 3264 for (mir = 0; mir < mirandaCount; mir++) { 3265 if (dvmCompareMethodNamesAndProtos( 3266 mirandaList[mir], imeth) == 0) 3267 { 3268 IF_LOGVV() { 3269 char* desc = dexProtoCopyMethodDescriptor( 3270 &imeth->prototype); 3271 LOGVV("MIRANDA dupe: %s and %s %s%s\n", 3272 mirandaList[mir]->clazz->descriptor, 3273 imeth->clazz->descriptor, 3274 imeth->name, desc); 3275 free(desc); 3276 } 3277 break; 3278 } 3279 } 3280 3281 /* point the iftable at a phantom slot index */ 3282 clazz->iftable[i].methodIndexArray[methIdx] = 3283 clazz->vtableCount + mir; 3284 LOGVV("MIRANDA: %s points at slot %d\n", 3285 imeth->name, clazz->vtableCount + mir); 3286 3287 /* if non-duplicate among Mirandas, add to Miranda list */ 3288 if (mir == mirandaCount) { 3289 //LOGV("MIRANDA: holding '%s' in slot %d\n", 3290 // imeth->name, mir); 3291 mirandaList[mirandaCount++] = imeth; 3292 } 3293 } 3294 } 3295 } 3296 3297 if (mirandaCount != 0) { 3298 static const int kManyMirandas = 150; /* arbitrary */ 3299 Method* newVirtualMethods; 3300 Method* meth; 3301 int oldMethodCount, oldVtableCount; 3302 3303 for (i = 0; i < mirandaCount; i++) { 3304 LOGVV("MIRANDA %d: %s.%s\n", i, 3305 mirandaList[i]->clazz->descriptor, mirandaList[i]->name); 3306 } 3307 if (mirandaCount > kManyMirandas) { 3308 /* 3309 * Some obfuscators like to create an interface with a huge 3310 * pile of methods, declare classes as implementing it, and then 3311 * only define a couple of methods. This leads to a rather 3312 * massive collection of Miranda methods and a lot of wasted 3313 * space, sometimes enough to blow out the LinearAlloc cap. 3314 */ 3315 LOGD("Note: class %s has %d unimplemented (abstract) methods\n", 3316 clazz->descriptor, mirandaCount); 3317 } 3318 3319 /* 3320 * We found methods in one or more interfaces for which we do not 3321 * have vtable entries. We have to expand our virtualMethods 3322 * table (which might be empty) to hold some new entries. 3323 */ 3324 if (clazz->virtualMethods == NULL) { 3325 newVirtualMethods = (Method*) dvmLinearAlloc(clazz->classLoader, 3326 sizeof(Method) * (clazz->virtualMethodCount + mirandaCount)); 3327 } else { 3328 //dvmLinearReadOnly(clazz->classLoader, clazz->virtualMethods); 3329 newVirtualMethods = (Method*) dvmLinearRealloc(clazz->classLoader, 3330 clazz->virtualMethods, 3331 sizeof(Method) * (clazz->virtualMethodCount + mirandaCount)); 3332 } 3333 if (newVirtualMethods != clazz->virtualMethods) { 3334 /* 3335 * Table was moved in memory. We have to run through the 3336 * vtable and fix the pointers. The vtable entries might be 3337 * pointing at superclasses, so we flip it around: run through 3338 * all locally-defined virtual methods, and fix their entries 3339 * in the vtable. (This would get really messy if sub-classes 3340 * had already been loaded.) 3341 * 3342 * Reminder: clazz->virtualMethods and clazz->virtualMethodCount 3343 * hold the virtual methods declared by this class. The 3344 * method's methodIndex is the vtable index, and is the same 3345 * for all sub-classes (and all super classes in which it is 3346 * defined). We're messing with these because the Miranda 3347 * stuff makes it look like the class actually has an abstract 3348 * method declaration in it. 3349 */ 3350 LOGVV("MIRANDA fixing vtable pointers\n"); 3351 dvmLinearReadWrite(clazz->classLoader, clazz->vtable); 3352 Method* meth = newVirtualMethods; 3353 for (i = 0; i < clazz->virtualMethodCount; i++, meth++) 3354 clazz->vtable[meth->methodIndex] = meth; 3355 dvmLinearReadOnly(clazz->classLoader, clazz->vtable); 3356 } 3357 3358 oldMethodCount = clazz->virtualMethodCount; 3359 clazz->virtualMethods = newVirtualMethods; 3360 clazz->virtualMethodCount += mirandaCount; 3361 3362 dvmLinearReadOnly(clazz->classLoader, clazz->virtualMethods); 3363 3364 /* 3365 * We also have to expand the vtable. 3366 */ 3367 assert(clazz->vtable != NULL); 3368 clazz->vtable = (Method**) dvmLinearRealloc(clazz->classLoader, 3369 clazz->vtable, 3370 sizeof(Method*) * (clazz->vtableCount + mirandaCount)); 3371 if (clazz->vtable == NULL) { 3372 assert(false); 3373 goto bail; 3374 } 3375 zapVtable = true; 3376 3377 oldVtableCount = clazz->vtableCount; 3378 clazz->vtableCount += mirandaCount; 3379 3380 /* 3381 * Now we need to create the fake methods. We clone the abstract 3382 * method definition from the interface and then replace a few 3383 * things. 3384 * 3385 * The Method will be an "abstract native", with nativeFunc set to 3386 * dvmAbstractMethodStub(). 3387 */ 3388 meth = clazz->virtualMethods + oldMethodCount; 3389 for (i = 0; i < mirandaCount; i++, meth++) { 3390 dvmLinearReadWrite(clazz->classLoader, clazz->virtualMethods); 3391 cloneMethod(meth, mirandaList[i]); 3392 meth->clazz = clazz; 3393 meth->accessFlags |= ACC_MIRANDA; 3394 meth->methodIndex = (u2) (oldVtableCount + i); 3395 dvmLinearReadOnly(clazz->classLoader, clazz->virtualMethods); 3396 3397 /* point the new vtable entry at the new method */ 3398 clazz->vtable[oldVtableCount + i] = meth; 3399 } 3400 3401 dvmLinearReadOnly(clazz->classLoader, mirandaList); 3402 dvmLinearFree(clazz->classLoader, mirandaList); 3403 3404 } 3405 3406 /* 3407 * TODO? 3408 * Sort the interfaces by number of declared methods. All we really 3409 * want is to get the interfaces with zero methods at the end of the 3410 * list, so that when we walk through the list during invoke-interface 3411 * we don't examine interfaces that can't possibly be useful. 3412 * 3413 * The set will usually be small, so a simple insertion sort works. 3414 * 3415 * We have to be careful not to change the order of two interfaces 3416 * that define the same method. (Not a problem if we only move the 3417 * zero-method interfaces to the end.) 3418 * 3419 * PROBLEM: 3420 * If we do this, we will no longer be able to identify super vs. 3421 * current class interfaces by comparing clazz->super->iftableCount. This 3422 * breaks anything that only wants to find interfaces declared directly 3423 * by the class (dvmFindStaticFieldHier, ReferenceType.Interfaces, 3424 * dvmDbgOutputAllInterfaces, etc). Need to provide a workaround. 3425 * 3426 * We can sort just the interfaces implemented directly by this class, 3427 * but that doesn't seem like it would provide much of an advantage. I'm 3428 * not sure this is worthwhile. 3429 * 3430 * (This has been made largely obsolete by the interface cache mechanism.) 3431 */ 3432 3433 //dvmDumpClass(clazz); 3434 3435 result = true; 3436 3437 bail: 3438 if (zapIftable) 3439 dvmLinearReadOnly(clazz->classLoader, clazz->iftable); 3440 if (zapVtable) 3441 dvmLinearReadOnly(clazz->classLoader, clazz->vtable); 3442 if (zapIfvipool) 3443 dvmLinearReadOnly(clazz->classLoader, clazz->ifviPool); 3444 return result; 3445 } 3446 3447 3448 /* 3449 * Provide "stub" implementations for methods without them. 3450 * 3451 * Currently we provide an implementation for all abstract methods that 3452 * throws an AbstractMethodError exception. This allows us to avoid an 3453 * explicit check for abstract methods in every virtual call. 3454 * 3455 * NOTE: for Miranda methods, the method declaration is a clone of what 3456 * was found in the interface class. That copy may already have had the 3457 * function pointer filled in, so don't be surprised if it's not NULL. 3458 * 3459 * NOTE: this sets the "native" flag, giving us an "abstract native" method, 3460 * which is nonsensical. Need to make sure that this doesn't escape the 3461 * VM. We can either mask it out in reflection calls, or copy "native" 3462 * into the high 16 bits of accessFlags and check that internally. 3463 */ 3464 static bool insertMethodStubs(ClassObject* clazz) 3465 { 3466 dvmLinearReadWrite(clazz->classLoader, clazz->virtualMethods); 3467 3468 Method* meth; 3469 int i; 3470 3471 meth = clazz->virtualMethods; 3472 for (i = 0; i < clazz->virtualMethodCount; i++, meth++) { 3473 if (dvmIsAbstractMethod(meth)) { 3474 assert(meth->insns == NULL); 3475 assert(meth->nativeFunc == NULL || 3476 meth->nativeFunc == (DalvikBridgeFunc)dvmAbstractMethodStub); 3477 3478 meth->accessFlags |= ACC_NATIVE; 3479 meth->nativeFunc = (DalvikBridgeFunc) dvmAbstractMethodStub; 3480 } 3481 } 3482 3483 dvmLinearReadOnly(clazz->classLoader, clazz->virtualMethods); 3484 return true; 3485 } 3486 3487 3488 /* 3489 * Swap two instance fields. 3490 */ 3491 static inline void swapField(InstField* pOne, InstField* pTwo) 3492 { 3493 InstField swap; 3494 3495 LOGVV(" --- swap '%s' and '%s'\n", pOne->field.name, pTwo->field.name); 3496 swap = *pOne; 3497 *pOne = *pTwo; 3498 *pTwo = swap; 3499 } 3500 3501 /* 3502 * Assign instance fields to u4 slots. 3503 * 3504 * The top portion of the instance field area is occupied by the superclass 3505 * fields, the bottom by the fields for this class. 3506 * 3507 * "long" and "double" fields occupy two adjacent slots. On some 3508 * architectures, 64-bit quantities must be 64-bit aligned, so we need to 3509 * arrange fields (or introduce padding) to ensure this. We assume the 3510 * fields of the topmost superclass (i.e. Object) are 64-bit aligned, so 3511 * we can just ensure that the offset is "even". To avoid wasting space, 3512 * we want to move non-reference 32-bit fields into gaps rather than 3513 * creating pad words. 3514 * 3515 * In the worst case we will waste 4 bytes, but because objects are 3516 * allocated on >= 64-bit boundaries, those bytes may well be wasted anyway 3517 * (assuming this is the most-derived class). 3518 * 3519 * Pad words are not represented in the field table, so the field table 3520 * itself does not change size. 3521 * 3522 * The number of field slots determines the size of the object, so we 3523 * set that here too. 3524 * 3525 * This function feels a little more complicated than I'd like, but it 3526 * has the property of moving the smallest possible set of fields, which 3527 * should reduce the time required to load a class. 3528 * 3529 * NOTE: reference fields *must* come first, or precacheReferenceOffsets() 3530 * will break. 3531 */ 3532 static bool computeFieldOffsets(ClassObject* clazz) 3533 { 3534 int fieldOffset; 3535 int i, j; 3536 3537 dvmLinearReadWrite(clazz->classLoader, clazz->ifields); 3538 3539 if (clazz->super != NULL) 3540 fieldOffset = clazz->super->objectSize; 3541 else 3542 fieldOffset = offsetof(DataObject, instanceData); 3543 3544 LOGVV("--- computeFieldOffsets '%s'\n", clazz->descriptor); 3545 3546 //LOGI("OFFSETS fieldCount=%d\n", clazz->ifieldCount); 3547 //LOGI("dataobj, instance: %d\n", offsetof(DataObject, instanceData)); 3548 //LOGI("classobj, access: %d\n", offsetof(ClassObject, accessFlags)); 3549 //LOGI("super=%p, fieldOffset=%d\n", clazz->super, fieldOffset); 3550 3551 /* 3552 * Start by moving all reference fields to the front. 3553 */ 3554 clazz->ifieldRefCount = 0; 3555 j = clazz->ifieldCount - 1; 3556 for (i = 0; i < clazz->ifieldCount; i++) { 3557 InstField* pField = &clazz->ifields[i]; 3558 char c = pField->field.signature[0]; 3559 3560 if (c != '[' && c != 'L') { 3561 /* This isn't a reference field; see if any reference fields 3562 * follow this one. If so, we'll move it to this position. 3563 * (quicksort-style partitioning) 3564 */ 3565 while (j > i) { 3566 InstField* refField = &clazz->ifields[j--]; 3567 char rc = refField->field.signature[0]; 3568 3569 if (rc == '[' || rc == 'L') { 3570 /* Here's a reference field that follows at least one 3571 * non-reference field. Swap it with the current field. 3572 * (When this returns, "pField" points to the reference 3573 * field, and "refField" points to the non-ref field.) 3574 */ 3575 swapField(pField, refField); 3576 3577 /* Fix the signature. 3578 */ 3579 c = rc; 3580 3581 clazz->ifieldRefCount++; 3582 break; 3583 } 3584 } 3585 /* We may or may not have swapped a field. 3586 */ 3587 } else { 3588 /* This is a reference field. 3589 */ 3590 clazz->ifieldRefCount++; 3591 } 3592 3593 /* 3594 * If we've hit the end of the reference fields, break. 3595 */ 3596 if (c != '[' && c != 'L') 3597 break; 3598 3599 pField->byteOffset = fieldOffset; 3600 fieldOffset += sizeof(u4); 3601 LOGVV(" --- offset1 '%s'=%d\n", pField->field.name,pField->byteOffset); 3602 } 3603 3604 /* 3605 * Now we want to pack all of the double-wide fields together. If we're 3606 * not aligned, though, we want to shuffle one 32-bit field into place. 3607 * If we can't find one, we'll have to pad it. 3608 */ 3609 if (i != clazz->ifieldCount && (fieldOffset & 0x04) != 0) { 3610 LOGVV(" +++ not aligned\n"); 3611 3612 InstField* pField = &clazz->ifields[i]; 3613 char c = pField->field.signature[0]; 3614 3615 if (c != 'J' && c != 'D') { 3616 /* 3617 * The field that comes next is 32-bit, so just advance past it. 3618 */ 3619 assert(c != '[' && c != 'L'); 3620 pField->byteOffset = fieldOffset; 3621 fieldOffset += sizeof(u4); 3622 i++; 3623 LOGVV(" --- offset2 '%s'=%d\n", 3624 pField->field.name, pField->byteOffset); 3625 } else { 3626 /* 3627 * Next field is 64-bit, so search for a 32-bit field we can 3628 * swap into it. 3629 */ 3630 bool found = false; 3631 j = clazz->ifieldCount - 1; 3632 while (j > i) { 3633 InstField* singleField = &clazz->ifields[j--]; 3634 char rc = singleField->field.signature[0]; 3635 3636 if (rc != 'J' && rc != 'D') { 3637 swapField(pField, singleField); 3638 //c = rc; 3639 LOGVV(" +++ swapped '%s' for alignment\n", 3640 pField->field.name); 3641 pField->byteOffset = fieldOffset; 3642 fieldOffset += sizeof(u4); 3643 LOGVV(" --- offset3 '%s'=%d\n", 3644 pField->field.name, pField->byteOffset); 3645 found = true; 3646 i++; 3647 break; 3648 } 3649 } 3650 if (!found) { 3651 LOGV(" +++ inserting pad field in '%s'\n", clazz->descriptor); 3652 fieldOffset += sizeof(u4); 3653 } 3654 } 3655 } 3656 3657 /* 3658 * Alignment is good, shuffle any double-wide fields forward, and 3659 * finish assigning field offsets to all fields. 3660 */ 3661 assert(i == clazz->ifieldCount || (fieldOffset & 0x04) == 0); 3662 j = clazz->ifieldCount - 1; 3663 for ( ; i < clazz->ifieldCount; i++) { 3664 InstField* pField = &clazz->ifields[i]; 3665 char c = pField->field.signature[0]; 3666 3667 if (c != 'D' && c != 'J') { 3668 /* This isn't a double-wide field; see if any double fields 3669 * follow this one. If so, we'll move it to this position. 3670 * (quicksort-style partitioning) 3671 */ 3672 while (j > i) { 3673 InstField* doubleField = &clazz->ifields[j--]; 3674 char rc = doubleField->field.signature[0]; 3675 3676 if (rc == 'D' || rc == 'J') { 3677 /* Here's a double-wide field that follows at least one 3678 * non-double field. Swap it with the current field. 3679 * (When this returns, "pField" points to the reference 3680 * field, and "doubleField" points to the non-double field.) 3681 */ 3682 swapField(pField, doubleField); 3683 c = rc; 3684 3685 break; 3686 } 3687 } 3688 /* We may or may not have swapped a field. 3689 */ 3690 } else { 3691 /* This is a double-wide field, leave it be. 3692 */ 3693 } 3694 3695 pField->byteOffset = fieldOffset; 3696 LOGVV(" --- offset4 '%s'=%d\n", pField->field.name,pField->byteOffset); 3697 fieldOffset += sizeof(u4); 3698 if (c == 'J' || c == 'D') 3699 fieldOffset += sizeof(u4); 3700 } 3701 3702 #ifndef NDEBUG 3703 /* Make sure that all reference fields appear before 3704 * non-reference fields, and all double-wide fields are aligned. 3705 */ 3706 j = 0; // seen non-ref 3707 for (i = 0; i < clazz->ifieldCount; i++) { 3708 InstField *pField = &clazz->ifields[i]; 3709 char c = pField->field.signature[0]; 3710 3711 if (c == 'D' || c == 'J') { 3712 assert((pField->byteOffset & 0x07) == 0); 3713 } 3714 3715 if (c != '[' && c != 'L') { 3716 if (!j) { 3717 assert(i == clazz->ifieldRefCount); 3718 j = 1; 3719 } 3720 } else if (j) { 3721 assert(false); 3722 } 3723 } 3724 if (!j) { 3725 assert(clazz->ifieldRefCount == clazz->ifieldCount); 3726 } 3727 #endif 3728 3729 /* 3730 * We map a C struct directly on top of java/lang/Class objects. Make 3731 * sure we left enough room for the instance fields. 3732 */ 3733 assert(clazz != gDvm.classJavaLangClass || (size_t)fieldOffset < 3734 offsetof(ClassObject, instanceData) + sizeof(clazz->instanceData)); 3735 3736 clazz->objectSize = fieldOffset; 3737 3738 dvmLinearReadOnly(clazz->classLoader, clazz->ifields); 3739 return true; 3740 } 3741 3742 /* 3743 * Throw the VM-spec-mandated error when an exception is thrown during 3744 * class initialization. 3745 * 3746 * The safest way to do this is to call the ExceptionInInitializerError 3747 * constructor that takes a Throwable. 3748 * 3749 * [Do we want to wrap it if the original is an Error rather than 3750 * an Exception?] 3751 */ 3752 static void throwClinitError(void) 3753 { 3754 Thread* self = dvmThreadSelf(); 3755 Object* exception; 3756 Object* eiie; 3757 3758 exception = dvmGetException(self); 3759 dvmAddTrackedAlloc(exception, self); 3760 dvmClearException(self); 3761 3762 if (gDvm.classJavaLangExceptionInInitializerError == NULL) { 3763 /* 3764 * Always resolves to same thing -- no race condition. 3765 */ 3766 gDvm.classJavaLangExceptionInInitializerError = 3767 dvmFindSystemClass( 3768 "Ljava/lang/ExceptionInInitializerError;"); 3769 if (gDvm.classJavaLangExceptionInInitializerError == NULL) { 3770 LOGE("Unable to prep java/lang/ExceptionInInitializerError\n"); 3771 goto fail; 3772 } 3773 3774 gDvm.methJavaLangExceptionInInitializerError_init = 3775 dvmFindDirectMethodByDescriptor(gDvm.classJavaLangExceptionInInitializerError, 3776 "<init>", "(Ljava/lang/Throwable;)V"); 3777 if (gDvm.methJavaLangExceptionInInitializerError_init == NULL) { 3778 LOGE("Unable to prep java/lang/ExceptionInInitializerError\n"); 3779 goto fail; 3780 } 3781 } 3782 3783 eiie = dvmAllocObject(gDvm.classJavaLangExceptionInInitializerError, 3784 ALLOC_DEFAULT); 3785 if (eiie == NULL) 3786 goto fail; 3787 3788 /* 3789 * Construct the new object, and replace the exception with it. 3790 */ 3791 JValue unused; 3792 dvmCallMethod(self, gDvm.methJavaLangExceptionInInitializerError_init, 3793 eiie, &unused, exception); 3794 dvmSetException(self, eiie); 3795 dvmReleaseTrackedAlloc(eiie, NULL); 3796 dvmReleaseTrackedAlloc(exception, self); 3797 return; 3798 3799 fail: /* restore original exception */ 3800 dvmSetException(self, exception); 3801 dvmReleaseTrackedAlloc(exception, self); 3802 return; 3803 } 3804 3805 /* 3806 * The class failed to initialize on a previous attempt, so we want to throw 3807 * a NoClassDefFoundError (v2 2.17.5). The exception to this rule is if we 3808 * failed in verification, in which case v2 5.4.1 says we need to re-throw 3809 * the previous error. 3810 */ 3811 static void throwEarlierClassFailure(ClassObject* clazz) 3812 { 3813 LOGI("Rejecting re-init on previously-failed class %s v=%p\n", 3814 clazz->descriptor, clazz->verifyErrorClass); 3815 3816 if (clazz->verifyErrorClass == NULL) { 3817 dvmThrowExceptionWithClassMessage("Ljava/lang/NoClassDefFoundError;", 3818 clazz->descriptor); 3819 } else { 3820 dvmThrowExceptionByClassWithClassMessage(clazz->verifyErrorClass, 3821 clazz->descriptor); 3822 } 3823 } 3824 3825 /* 3826 * Initialize any static fields whose values are stored in 3827 * the DEX file. This must be done during class initialization. 3828 */ 3829 static void initSFields(ClassObject* clazz) 3830 { 3831 Thread* self = dvmThreadSelf(); /* for dvmReleaseTrackedAlloc() */ 3832 DexFile* pDexFile; 3833 const DexClassDef* pClassDef; 3834 const DexEncodedArray* pValueList; 3835 EncodedArrayIterator iterator; 3836 int i; 3837 3838 if (clazz->sfieldCount == 0) { 3839 return; 3840 } 3841 if (clazz->pDvmDex == NULL) { 3842 /* generated class; any static fields should already be set up */ 3843 LOGV("Not initializing static fields in %s\n", clazz->descriptor); 3844 return; 3845 } 3846 pDexFile = clazz->pDvmDex->pDexFile; 3847 3848 pClassDef = dexFindClass(pDexFile, clazz->descriptor); 3849 assert(pClassDef != NULL); 3850 3851 pValueList = dexGetStaticValuesList(pDexFile, pClassDef); 3852 if (pValueList == NULL) { 3853 return; 3854 } 3855 3856 dvmEncodedArrayIteratorInitialize(&iterator, pValueList, clazz); 3857 3858 /* 3859 * Iterate over the initial values array, setting the corresponding 3860 * static field for each array element. 3861 */ 3862 3863 for (i = 0; dvmEncodedArrayIteratorHasNext(&iterator); i++) { 3864 AnnotationValue value; 3865 bool parsed = dvmEncodedArrayIteratorGetNext(&iterator, &value); 3866 StaticField* sfield = &clazz->sfields[i]; 3867 const char* descriptor = sfield->field.signature; 3868 bool needRelease = false; 3869 3870 if (! parsed) { 3871 /* 3872 * TODO: Eventually verification should attempt to ensure 3873 * that this can't happen at least due to a data integrity 3874 * problem. 3875 */ 3876 LOGE("Static initializer parse failed for %s at index %d", 3877 clazz->descriptor, i); 3878 dvmAbort(); 3879 } 3880 3881 /* Verify that the value we got was of a valid type. */ 3882 3883 switch (descriptor[0]) { 3884 case 'Z': parsed = (value.type == kDexAnnotationBoolean); break; 3885 case 'B': parsed = (value.type == kDexAnnotationByte); break; 3886 case 'C': parsed = (value.type == kDexAnnotationChar); break; 3887 case 'S': parsed = (value.type == kDexAnnotationShort); break; 3888 case 'I': parsed = (value.type == kDexAnnotationInt); break; 3889 case 'J': parsed = (value.type == kDexAnnotationLong); break; 3890 case 'F': parsed = (value.type == kDexAnnotationFloat); break; 3891 case 'D': parsed = (value.type == kDexAnnotationDouble); break; 3892 case '[': parsed = (value.type == kDexAnnotationNull); break; 3893 case 'L': { 3894 switch (value.type) { 3895 case kDexAnnotationNull: { 3896 /* No need for further tests. */ 3897 break; 3898 } 3899 case kDexAnnotationString: { 3900 parsed = 3901 (strcmp(descriptor, "Ljava/lang/String;") == 0); 3902 needRelease = true; 3903 break; 3904 } 3905 case kDexAnnotationType: { 3906 parsed = 3907 (strcmp(descriptor, "Ljava/lang/Class;") == 0); 3908 needRelease = true; 3909 break; 3910 } 3911 default: { 3912 parsed = false; 3913 break; 3914 } 3915 } 3916 break; 3917 } 3918 default: { 3919 parsed = false; 3920 break; 3921 } 3922 } 3923 3924 if (parsed) { 3925 /* 3926 * All's well, so store the value. Note: This always 3927 * stores the full width of a JValue, even though most of 3928 * the time only the first word is needed. 3929 */ 3930 sfield->value = value.value; 3931 if (needRelease) { 3932 dvmReleaseTrackedAlloc(value.value.l, self); 3933 } 3934 } else { 3935 /* 3936 * Something up above had a problem. TODO: See comment 3937 * above the switch about verfication. 3938 */ 3939 LOGE("Bogus static initialization: value type %d in field type " 3940 "%s for %s at index %d", 3941 value.type, descriptor, clazz->descriptor, i); 3942 dvmAbort(); 3943 } 3944 } 3945 } 3946 3947 3948 /* 3949 * Determine whether "descriptor" yields the same class object in the 3950 * context of clazz1 and clazz2. 3951 * 3952 * The caller must hold gDvm.loadedClasses. 3953 * 3954 * Returns "true" if they match. 3955 */ 3956 static bool compareDescriptorClasses(const char* descriptor, 3957 const ClassObject* clazz1, const ClassObject* clazz2) 3958 { 3959 ClassObject* result1; 3960 ClassObject* result2; 3961 3962 /* 3963 * Do the first lookup by name. 3964 */ 3965 result1 = dvmFindClassNoInit(descriptor, clazz1->classLoader); 3966 3967 /* 3968 * We can skip a second lookup by name if the second class loader is 3969 * in the initiating loader list of the class object we retrieved. 3970 * (This means that somebody already did a lookup of this class through 3971 * the second loader, and it resolved to the same class.) If it's not 3972 * there, we may simply not have had an opportunity to add it yet, so 3973 * we do the full lookup. 3974 * 3975 * The initiating loader test should catch the majority of cases 3976 * (in particular, the zillions of references to String/Object). 3977 * 3978 * Unfortunately we're still stuck grabbing a mutex to do the lookup. 3979 * 3980 * For this to work, the superclass/interface should be the first 3981 * argument, so that way if it's from the bootstrap loader this test 3982 * will work. (The bootstrap loader, by definition, never shows up 3983 * as the initiating loader of a class defined by some other loader.) 3984 */ 3985 dvmHashTableLock(gDvm.loadedClasses); 3986 bool isInit = dvmLoaderInInitiatingList(result1, clazz2->classLoader); 3987 dvmHashTableUnlock(gDvm.loadedClasses); 3988 3989 if (isInit) { 3990 //printf("%s(obj=%p) / %s(cl=%p): initiating\n", 3991 // result1->descriptor, result1, 3992 // clazz2->descriptor, clazz2->classLoader); 3993 return true; 3994 } else { 3995 //printf("%s(obj=%p) / %s(cl=%p): RAW\n", 3996 // result1->descriptor, result1, 3997 // clazz2->descriptor, clazz2->classLoader); 3998 result2 = dvmFindClassNoInit(descriptor, clazz2->classLoader); 3999 } 4000 4001 if (result1 == NULL || result2 == NULL) { 4002 dvmClearException(dvmThreadSelf()); 4003 if (result1 == result2) { 4004 /* 4005 * Neither class loader could find this class. Apparently it 4006 * doesn't exist. 4007 * 4008 * We can either throw some sort of exception now, or just 4009 * assume that it'll fail later when something actually tries 4010 * to use the class. For strict handling we should throw now, 4011 * because a "tricky" class loader could start returning 4012 * something later, and a pair of "tricky" loaders could set 4013 * us up for confusion. 4014 * 4015 * I'm not sure if we're allowed to complain about nonexistent 4016 * classes in method signatures during class init, so for now 4017 * this will just return "true" and let nature take its course. 4018 */ 4019 return true; 4020 } else { 4021 /* only one was found, so clearly they're not the same */ 4022 return false; 4023 } 4024 } 4025 4026 return result1 == result2; 4027 } 4028 4029 /* 4030 * For every component in the method descriptor, resolve the class in the 4031 * context of the two classes and compare the results. 4032 * 4033 * For best results, the "superclass" class should be first. 4034 * 4035 * Returns "true" if the classes match, "false" otherwise. 4036 */ 4037 static bool checkMethodDescriptorClasses(const Method* meth, 4038 const ClassObject* clazz1, const ClassObject* clazz2) 4039 { 4040 DexParameterIterator iterator; 4041 const char* descriptor; 4042 4043 /* walk through the list of parameters */ 4044 dexParameterIteratorInit(&iterator, &meth->prototype); 4045 while (true) { 4046 descriptor = dexParameterIteratorNextDescriptor(&iterator); 4047 4048 if (descriptor == NULL) 4049 break; 4050 4051 if (descriptor[0] == 'L' || descriptor[0] == '[') { 4052 /* non-primitive type */ 4053 if (!compareDescriptorClasses(descriptor, clazz1, clazz2)) 4054 return false; 4055 } 4056 } 4057 4058 /* check the return type */ 4059 descriptor = dexProtoGetReturnType(&meth->prototype); 4060 if (descriptor[0] == 'L' || descriptor[0] == '[') { 4061 if (!compareDescriptorClasses(descriptor, clazz1, clazz2)) 4062 return false; 4063 } 4064 return true; 4065 } 4066 4067 /* 4068 * Validate the descriptors in the superclass and interfaces. 4069 * 4070 * What we need to do is ensure that the classes named in the method 4071 * descriptors in our ancestors and ourselves resolve to the same class 4072 * objects. We can get conflicts when the classes come from different 4073 * class loaders, and the resolver comes up with different results for 4074 * the same class name in different contexts. 4075 * 4076 * An easy way to cause the problem is to declare a base class that uses 4077 * class Foo in a method signature (e.g. as the return type). Then, 4078 * define a subclass and a different version of Foo, and load them from a 4079 * different class loader. If the subclass overrides the method, it will 4080 * have a different concept of what Foo is than its parent does, so even 4081 * though the method signature strings are identical, they actually mean 4082 * different things. 4083 * 4084 * A call to the method through a base-class reference would be treated 4085 * differently than a call to the method through a subclass reference, which 4086 * isn't the way polymorphism works, so we have to reject the subclass. 4087 * If the subclass doesn't override the base method, then there's no 4088 * problem, because calls through base-class references and subclass 4089 * references end up in the same place. 4090 * 4091 * We don't need to check to see if an interface's methods match with its 4092 * superinterface's methods, because you can't instantiate an interface 4093 * and do something inappropriate with it. If interface I1 extends I2 4094 * and is implemented by C, and I1 and I2 are in separate class loaders 4095 * and have conflicting views of other classes, we will catch the conflict 4096 * when we process C. Anything that implements I1 is doomed to failure, 4097 * but we don't need to catch that while processing I1. 4098 * 4099 * On failure, throws an exception and returns "false". 4100 */ 4101 static bool validateSuperDescriptors(const ClassObject* clazz) 4102 { 4103 int i; 4104 4105 if (dvmIsInterfaceClass(clazz)) 4106 return true; 4107 4108 /* 4109 * Start with the superclass-declared methods. 4110 */ 4111 if (clazz->super != NULL && 4112 clazz->classLoader != clazz->super->classLoader) 4113 { 4114 /* 4115 * Walk through every overridden method and compare resolved 4116 * descriptor components. We pull the Method structs out of 4117 * the vtable. It doesn't matter whether we get the struct from 4118 * the parent or child, since we just need the UTF-8 descriptor, 4119 * which must match. 4120 * 4121 * We need to do this even for the stuff inherited from Object, 4122 * because it's possible that the new class loader has redefined 4123 * a basic class like String. 4124 * 4125 * We don't need to check stuff defined in a superclass because 4126 * it was checked when the superclass was loaded. 4127 */ 4128 const Method* meth; 4129 4130 //printf("Checking %s %p vs %s %p\n", 4131 // clazz->descriptor, clazz->classLoader, 4132 // clazz->super->descriptor, clazz->super->classLoader); 4133 for (i = clazz->super->vtableCount - 1; i >= 0; i--) { 4134 meth = clazz->vtable[i]; 4135 if (meth != clazz->super->vtable[i] && 4136 !checkMethodDescriptorClasses(meth, clazz->super, clazz)) 4137 { 4138 LOGW("Method mismatch: %s in %s (cl=%p) and super %s (cl=%p)\n", 4139 meth->name, clazz->descriptor, clazz->classLoader, 4140 clazz->super->descriptor, clazz->super->classLoader); 4141 dvmThrowException("Ljava/lang/LinkageError;", 4142 "Classes resolve differently in superclass"); 4143 return false; 4144 } 4145 } 4146 } 4147 4148 /* 4149 * Check the methods defined by this class against the interfaces it 4150 * implements. If we inherited the implementation from a superclass, 4151 * we have to check it against the superclass (which might be in a 4152 * different class loader). If the superclass also implements the 4153 * interface, we could skip the check since by definition it was 4154 * performed when the class was loaded. 4155 */ 4156 for (i = 0; i < clazz->iftableCount; i++) { 4157 const InterfaceEntry* iftable = &clazz->iftable[i]; 4158 4159 if (clazz->classLoader != iftable->clazz->classLoader) { 4160 const ClassObject* iface = iftable->clazz; 4161 int j; 4162 4163 for (j = 0; j < iface->virtualMethodCount; j++) { 4164 const Method* meth; 4165 int vtableIndex; 4166 4167 vtableIndex = iftable->methodIndexArray[j]; 4168 meth = clazz->vtable[vtableIndex]; 4169 4170 if (!checkMethodDescriptorClasses(meth, iface, meth->clazz)) { 4171 LOGW("Method mismatch: %s in %s (cl=%p) and " 4172 "iface %s (cl=%p)\n", 4173 meth->name, clazz->descriptor, clazz->classLoader, 4174 iface->descriptor, iface->classLoader); 4175 dvmThrowException("Ljava/lang/LinkageError;", 4176 "Classes resolve differently in interface"); 4177 return false; 4178 } 4179 } 4180 } 4181 } 4182 4183 return true; 4184 } 4185 4186 /* 4187 * Returns true if the class is being initialized by us (which means that 4188 * calling dvmInitClass will return immediately after fiddling with locks). 4189 * 4190 * There isn't a race here, because either clazz->initThreadId won't match 4191 * us, or it will and it was set in the same thread. 4192 */ 4193 bool dvmIsClassInitializing(const ClassObject* clazz) 4194 { 4195 return (clazz->status == CLASS_INITIALIZING && 4196 clazz->initThreadId == dvmThreadSelf()->threadId); 4197 } 4198 4199 /* 4200 * If a class has not been initialized, do so by executing the code in 4201 * <clinit>. The sequence is described in the VM spec v2 2.17.5. 4202 * 4203 * It is possible for multiple threads to arrive here simultaneously, so 4204 * we need to lock the class while we check stuff. We know that no 4205 * interpreted code has access to the class yet, so we can use the class's 4206 * monitor lock. 4207 * 4208 * We will often be called recursively, e.g. when the <clinit> code resolves 4209 * one of its fields, the field resolution will try to initialize the class. 4210 * 4211 * This can get very interesting if a class has a static field initialized 4212 * to a new instance of itself. <clinit> will end up calling <init> on 4213 * the members it is initializing, which is fine unless it uses the contents 4214 * of static fields to initialize instance fields. This will leave the 4215 * static-referenced objects in a partially initialized state. This is 4216 * reasonably rare and can sometimes be cured with proper field ordering. 4217 * 4218 * On failure, returns "false" with an exception raised. 4219 * 4220 * ----- 4221 * 4222 * It is possible to cause a deadlock by having a situation like this: 4223 * class A { static { sleep(10000); new B(); } } 4224 * class B { static { sleep(10000); new A(); } } 4225 * new Thread() { public void run() { new A(); } }.start(); 4226 * new Thread() { public void run() { new B(); } }.start(); 4227 * This appears to be expected under the spec. 4228 * 4229 * The interesting question is what to do if somebody calls Thread.interrupt() 4230 * on one of the deadlocked threads. According to the VM spec, they're both 4231 * sitting in "wait". Should the interrupt code quietly raise the 4232 * "interrupted" flag, or should the "wait" return immediately with an 4233 * exception raised? 4234 * 4235 * This gets a little murky. The VM spec says we call "wait", and the 4236 * spec for Thread.interrupt says Object.wait is interruptible. So it 4237 * seems that, if we get unlucky and interrupt class initialization, we 4238 * are expected to throw (which gets converted to ExceptionInInitializerError 4239 * since InterruptedException is checked). 4240 * 4241 * There are a couple of problems here. First, all threads are expected to 4242 * present a consistent view of class initialization, so we can't have it 4243 * fail in one thread and succeed in another. Second, once a class fails 4244 * to initialize, it must *always* fail. This means that a stray interrupt() 4245 * call could render a class unusable for the lifetime of the VM. 4246 * 4247 * In most cases -- the deadlock example above being a counter-example -- 4248 * the interrupting thread can't tell whether the target thread handled 4249 * the initialization itself or had to wait while another thread did the 4250 * work. Refusing to interrupt class initialization is, in most cases, 4251 * not something that a program can reliably detect. 4252 * 4253 * On the assumption that interrupting class initialization is highly 4254 * undesirable in most circumstances, and that failing to do so does not 4255 * deviate from the spec in a meaningful way, we don't allow class init 4256 * to be interrupted by Thread.interrupt(). 4257 */ 4258 bool dvmInitClass(ClassObject* clazz) 4259 { 4260 #if LOG_CLASS_LOADING 4261 bool initializedByUs = false; 4262 #endif 4263 4264 Thread* self = dvmThreadSelf(); 4265 const Method* method; 4266 4267 dvmLockObject(self, (Object*) clazz); 4268 assert(dvmIsClassLinked(clazz) || clazz->status == CLASS_ERROR); 4269 4270 /* 4271 * If the class hasn't been verified yet, do so now. 4272 */ 4273 if (clazz->status < CLASS_VERIFIED) { 4274 /* 4275 * If we're in an "erroneous" state, throw an exception and bail. 4276 */ 4277 if (clazz->status == CLASS_ERROR) { 4278 throwEarlierClassFailure(clazz); 4279 goto bail_unlock; 4280 } 4281 4282 assert(clazz->status == CLASS_RESOLVED); 4283 assert(!IS_CLASS_FLAG_SET(clazz, CLASS_ISPREVERIFIED)); 4284 4285 if (gDvm.classVerifyMode == VERIFY_MODE_NONE || 4286 (gDvm.classVerifyMode == VERIFY_MODE_REMOTE && 4287 clazz->classLoader == NULL)) 4288 { 4289 /* advance to "verified" state */ 4290 LOGV("+++ not verifying class %s (cl=%p)\n", 4291 clazz->descriptor, clazz->classLoader); 4292 clazz->status = CLASS_VERIFIED; 4293 goto noverify; 4294 } 4295 4296 if (!gDvm.optimizing) 4297 LOGV("+++ late verify on %s\n", clazz->descriptor); 4298 4299 /* 4300 * We're not supposed to optimize an unverified class, but during 4301 * development this mode was useful. We can't verify an optimized 4302 * class because the optimization process discards information. 4303 */ 4304 if (IS_CLASS_FLAG_SET(clazz, CLASS_ISOPTIMIZED)) { 4305 LOGW("Class '%s' was optimized without verification; " 4306 "not verifying now\n", 4307 clazz->descriptor); 4308 LOGW(" ('rm /data/dalvik-cache/*' and restart to fix this)"); 4309 goto verify_failed; 4310 } 4311 4312 clazz->status = CLASS_VERIFYING; 4313 if (!dvmVerifyClass(clazz, VERIFY_DEFAULT)) { 4314 verify_failed: 4315 dvmThrowExceptionWithClassMessage("Ljava/lang/VerifyError;", 4316 clazz->descriptor); 4317 clazz->verifyErrorClass = dvmGetException(self)->clazz; 4318 clazz->status = CLASS_ERROR; 4319 goto bail_unlock; 4320 } 4321 4322 clazz->status = CLASS_VERIFIED; 4323 } 4324 noverify: 4325 4326 #ifdef WITH_DEBUGGER 4327 /* update instruction stream now that the verifier is done */ 4328 dvmFlushBreakpoints(clazz); 4329 #endif 4330 4331 if (clazz->status == CLASS_INITIALIZED) 4332 goto bail_unlock; 4333 4334 while (clazz->status == CLASS_INITIALIZING) { 4335 /* we caught somebody else in the act; was it us? */ 4336 if (clazz->initThreadId == self->threadId) { 4337 //LOGV("HEY: found a recursive <clinit>\n"); 4338 goto bail_unlock; 4339 } 4340 4341 if (dvmCheckException(self)) { 4342 LOGW("GLITCH: exception pending at start of class init\n"); 4343 dvmAbort(); 4344 } 4345 4346 /* 4347 * Wait for the other thread to finish initialization. We pass 4348 * "false" for the "interruptShouldThrow" arg so it doesn't throw 4349 * an exception on interrupt. 4350 */ 4351 dvmObjectWait(self, (Object*) clazz, 0, 0, false); 4352 4353 /* 4354 * When we wake up, repeat the test for init-in-progress. If there's 4355 * an exception pending (only possible if "interruptShouldThrow" 4356 * was set), bail out. 4357 */ 4358 if (dvmCheckException(self)) { 4359 LOGI("Class init of '%s' failing with wait() exception\n", 4360 clazz->descriptor); 4361 /* 4362 * TODO: this is bogus, because it means the two threads have a 4363 * different idea of the class status. We need to flag the 4364 * class as bad and ensure that the initializer thread respects 4365 * our notice. If we get lucky and wake up after the class has 4366 * finished initialization but before being woken, we have to 4367 * swallow the exception, perhaps raising thread->interrupted 4368 * to preserve semantics. 4369 * 4370 * Since we're not currently allowing interrupts, this should 4371 * never happen and we don't need to fix this. 4372 */ 4373 assert(false); 4374 throwClinitError(); 4375 clazz->status = CLASS_ERROR; 4376 goto bail_unlock; 4377 } 4378 if (clazz->status == CLASS_INITIALIZING) { 4379 LOGI("Waiting again for class init\n"); 4380 continue; 4381 } 4382 assert(clazz->status == CLASS_INITIALIZED || 4383 clazz->status == CLASS_ERROR); 4384 if (clazz->status == CLASS_ERROR) { 4385 /* 4386 * The caller wants an exception, but it was thrown in a 4387 * different thread. Synthesize one here. 4388 */ 4389 dvmThrowException("Ljava/lang/UnsatisfiedLinkError;", 4390 "(<clinit> failed, see exception in other thread)"); 4391 } 4392 goto bail_unlock; 4393 } 4394 4395 /* see if we failed previously */ 4396 if (clazz->status == CLASS_ERROR) { 4397 // might be wise to unlock before throwing; depends on which class 4398 // it is that we have locked 4399 dvmUnlockObject(self, (Object*) clazz); 4400 throwEarlierClassFailure(clazz); 4401 return false; 4402 } 4403 4404 u8 startWhen = 0; 4405 if (gDvm.allocProf.enabled) { 4406 startWhen = dvmGetRelativeTimeNsec(); 4407 } 4408 4409 /* 4410 * We're ready to go, and have exclusive access to the class. 4411 * 4412 * Before we start initialization, we need to do one extra bit of 4413 * validation: make sure that the methods declared here match up 4414 * with our superclass and interfaces. We know that the UTF-8 4415 * descriptors match, but classes from different class loaders can 4416 * have the same name. 4417 * 4418 * We do this now, rather than at load/link time, for the same reason 4419 * that we defer verification. 4420 * 4421 * It's unfortunate that we need to do this at all, but we risk 4422 * mixing reference types with identical names (see Dalvik test 068). 4423 */ 4424 if (!validateSuperDescriptors(clazz)) { 4425 assert(dvmCheckException(self)); 4426 clazz->status = CLASS_ERROR; 4427 goto bail_unlock; 4428 } 4429 4430 /* 4431 * Let's initialize this thing. 4432 * 4433 * We unlock the object so that other threads can politely sleep on 4434 * our mutex with Object.wait(), instead of hanging or spinning trying 4435 * to grab our mutex. 4436 */ 4437 assert(clazz->status < CLASS_INITIALIZING); 4438 4439 #if LOG_CLASS_LOADING 4440 // We started initializing. 4441 logClassLoad('+', clazz); 4442 initializedByUs = true; 4443 #endif 4444 4445 clazz->status = CLASS_INITIALIZING; 4446 clazz->initThreadId = self->threadId; 4447 dvmUnlockObject(self, (Object*) clazz); 4448 4449 /* init our superclass */ 4450 if (clazz->super != NULL && clazz->super->status != CLASS_INITIALIZED) { 4451 assert(!dvmIsInterfaceClass(clazz)); 4452 if (!dvmInitClass(clazz->super)) { 4453 assert(dvmCheckException(self)); 4454 clazz->status = CLASS_ERROR; 4455 /* wake up anybody who started waiting while we were unlocked */ 4456 dvmLockObject(self, (Object*) clazz); 4457 goto bail_notify; 4458 } 4459 } 4460 4461 /* Initialize any static fields whose values are 4462 * stored in the Dex file. This should include all of the 4463 * simple "final static" fields, which are required to 4464 * be initialized first. (vmspec 2 sec 2.17.5 item 8) 4465 * More-complicated final static fields should be set 4466 * at the beginning of <clinit>; all we can do is trust 4467 * that the compiler did the right thing. 4468 */ 4469 initSFields(clazz); 4470 4471 /* Execute any static initialization code. 4472 */ 4473 method = dvmFindDirectMethodByDescriptor(clazz, "<clinit>", "()V"); 4474 if (method == NULL) { 4475 LOGVV("No <clinit> found for %s\n", clazz->descriptor); 4476 } else { 4477 LOGVV("Invoking %s.<clinit>\n", clazz->descriptor); 4478 JValue unused; 4479 dvmCallMethod(self, method, NULL, &unused); 4480 } 4481 4482 if (dvmCheckException(self)) { 4483 /* 4484 * We've had an exception thrown during static initialization. We 4485 * need to throw an ExceptionInInitializerError, but we want to 4486 * tuck the original exception into the "cause" field. 4487 */ 4488 LOGW("Exception %s thrown during %s.<clinit>\n", 4489 (dvmGetException(self)->clazz)->descriptor, clazz->descriptor); 4490 throwClinitError(); 4491 //LOGW("+++ replaced\n"); 4492 4493 dvmLockObject(self, (Object*) clazz); 4494 clazz->status = CLASS_ERROR; 4495 } else { 4496 /* success! */ 4497 dvmLockObject(self, (Object*) clazz); 4498 clazz->status = CLASS_INITIALIZED; 4499 LOGVV("Initialized class: %s\n", clazz->descriptor); 4500 4501 /* 4502 * Update alloc counters. TODO: guard with mutex. 4503 */ 4504 if (gDvm.allocProf.enabled && startWhen != 0) { 4505 u8 initDuration = dvmGetRelativeTimeNsec() - startWhen; 4506 gDvm.allocProf.classInitTime += initDuration; 4507 self->allocProf.classInitTime += initDuration; 4508 gDvm.allocProf.classInitCount++; 4509 self->allocProf.classInitCount++; 4510 } 4511 } 4512 4513 bail_notify: 4514 /* 4515 * Notify anybody waiting on the object. 4516 */ 4517 dvmObjectNotifyAll(self, (Object*) clazz); 4518 4519 bail_unlock: 4520 4521 #if LOG_CLASS_LOADING 4522 if (initializedByUs) { 4523 // We finished initializing. 4524 logClassLoad('-', clazz); 4525 } 4526 #endif 4527 4528 dvmUnlockObject(self, (Object*) clazz); 4529 4530 return (clazz->status != CLASS_ERROR); 4531 } 4532 4533 /* 4534 * Replace method->nativeFunc and method->insns with new values. This is 4535 * performed on resolution of a native method. 4536 */ 4537 void dvmSetNativeFunc(const Method* method, DalvikBridgeFunc func, 4538 const u2* insns) 4539 { 4540 ClassObject* clazz = method->clazz; 4541 4542 /* just open up both; easier that way */ 4543 dvmLinearReadWrite(clazz->classLoader, clazz->virtualMethods); 4544 dvmLinearReadWrite(clazz->classLoader, clazz->directMethods); 4545 4546 ((Method*)method)->nativeFunc = func; 4547 ((Method*)method)->insns = insns; 4548 4549 dvmLinearReadOnly(clazz->classLoader, clazz->virtualMethods); 4550 dvmLinearReadOnly(clazz->classLoader, clazz->directMethods); 4551 } 4552 4553 /* 4554 * Add a RegisterMap to a Method. This is done when we verify the class 4555 * and compute the register maps at class initialization time (i.e. when 4556 * we don't have a pre-generated map). This means "pMap" is on the heap 4557 * and should be freed when the Method is discarded. 4558 */ 4559 void dvmSetRegisterMap(Method* method, const RegisterMap* pMap) 4560 { 4561 ClassObject* clazz = method->clazz; 4562 4563 if (method->registerMap != NULL) { 4564 /* unexpected during class loading, okay on first use (uncompress) */ 4565 LOGV("NOTE: registerMap already set for %s.%s\n", 4566 method->clazz->descriptor, method->name); 4567 /* keep going */ 4568 } 4569 assert(!dvmIsNativeMethod(method) && !dvmIsAbstractMethod(method)); 4570 4571 /* might be virtual or direct */ 4572 dvmLinearReadWrite(clazz->classLoader, clazz->virtualMethods); 4573 dvmLinearReadWrite(clazz->classLoader, clazz->directMethods); 4574 4575 method->registerMap = pMap; 4576 4577 dvmLinearReadOnly(clazz->classLoader, clazz->virtualMethods); 4578 dvmLinearReadOnly(clazz->classLoader, clazz->directMethods); 4579 } 4580 4581 /* 4582 * dvmHashForeach callback. A nonzero return value causes foreach to 4583 * bail out. 4584 */ 4585 static int findClassCallback(void* vclazz, void* arg) 4586 { 4587 ClassObject* clazz = vclazz; 4588 const char* descriptor = (const char*) arg; 4589 4590 if (strcmp(clazz->descriptor, descriptor) == 0) 4591 return (int) clazz; 4592 return 0; 4593 } 4594 4595 /* 4596 * Find a loaded class by descriptor. Returns the first one found. 4597 * Because there can be more than one if class loaders are involved, 4598 * this is not an especially good API. (Currently only used by the 4599 * debugger and "checking" JNI.) 4600 * 4601 * "descriptor" should have the form "Ljava/lang/Class;" or 4602 * "[Ljava/lang/Class;", i.e. a descriptor and not an internal-form 4603 * class name. 4604 */ 4605 ClassObject* dvmFindLoadedClass(const char* descriptor) 4606 { 4607 int result; 4608 4609 dvmHashTableLock(gDvm.loadedClasses); 4610 result = dvmHashForeach(gDvm.loadedClasses, findClassCallback, 4611 (void*) descriptor); 4612 dvmHashTableUnlock(gDvm.loadedClasses); 4613 4614 return (ClassObject*) result; 4615 } 4616 4617 /* 4618 * Retrieve the system (a/k/a application) class loader. 4619 */ 4620 Object* dvmGetSystemClassLoader(void) 4621 { 4622 ClassObject* clazz; 4623 Method* getSysMeth; 4624 Object* loader; 4625 4626 clazz = dvmFindSystemClass("Ljava/lang/ClassLoader;"); 4627 if (clazz == NULL) 4628 return NULL; 4629 4630 getSysMeth = dvmFindDirectMethodByDescriptor(clazz, "getSystemClassLoader", 4631 "()Ljava/lang/ClassLoader;"); 4632 if (getSysMeth == NULL) 4633 return NULL; 4634 4635 JValue result; 4636 dvmCallMethod(dvmThreadSelf(), getSysMeth, NULL, &result); 4637 loader = (Object*)result.l; 4638 return loader; 4639 } 4640 4641 4642 /* 4643 * This is a dvmHashForeach callback. 4644 */ 4645 static int dumpClass(void* vclazz, void* varg) 4646 { 4647 const ClassObject* clazz = (const ClassObject*) vclazz; 4648 const ClassObject* super; 4649 int flags = (int) varg; 4650 char* desc; 4651 int i; 4652 4653 if (clazz == NULL) { 4654 LOGI("dumpClass: ignoring request to dump null class\n"); 4655 return 0; 4656 } 4657 4658 if ((flags & kDumpClassFullDetail) == 0) { 4659 bool showInit = (flags & kDumpClassInitialized) != 0; 4660 bool showLoader = (flags & kDumpClassClassLoader) != 0; 4661 const char* initStr; 4662 4663 initStr = dvmIsClassInitialized(clazz) ? "true" : "false"; 4664 4665 if (showInit && showLoader) 4666 LOGI("%s %p %s\n", clazz->descriptor, clazz->classLoader, initStr); 4667 else if (showInit) 4668 LOGI("%s %s\n", clazz->descriptor, initStr); 4669 else if (showLoader) 4670 LOGI("%s %p\n", clazz->descriptor, clazz->classLoader); 4671 else 4672 LOGI("%s\n", clazz->descriptor); 4673 4674 return 0; 4675 } 4676 4677 /* clazz->super briefly holds the superclass index during class prep */ 4678 if ((u4)clazz->super > 0x10000 && (u4) clazz->super != (u4)-1) 4679 super = clazz->super; 4680 else 4681 super = NULL; 4682 4683 LOGI("----- %s '%s' cl=%p ser=0x%08x -----\n", 4684 dvmIsInterfaceClass(clazz) ? "interface" : "class", 4685 clazz->descriptor, clazz->classLoader, clazz->serialNumber); 4686 LOGI(" objectSize=%d (%d from super)\n", (int) clazz->objectSize, 4687 super != NULL ? (int) super->objectSize : -1); 4688 LOGI(" access=0x%04x.%04x\n", clazz->accessFlags >> 16, 4689 clazz->accessFlags & JAVA_FLAGS_MASK); 4690 if (super != NULL) 4691 LOGI(" super='%s' (cl=%p)\n", super->descriptor, super->classLoader); 4692 if (dvmIsArrayClass(clazz)) { 4693 LOGI(" dimensions=%d elementClass=%s\n", 4694 clazz->arrayDim, clazz->elementClass->descriptor); 4695 } 4696 if (clazz->iftableCount > 0) { 4697 LOGI(" interfaces (%d):\n", clazz->iftableCount); 4698 for (i = 0; i < clazz->iftableCount; i++) { 4699 InterfaceEntry* ent = &clazz->iftable[i]; 4700 int j; 4701 4702 LOGI(" %2d: %s (cl=%p)\n", 4703 i, ent->clazz->descriptor, ent->clazz->classLoader); 4704 4705 /* enable when needed */ 4706 if (false && ent->methodIndexArray != NULL) { 4707 for (j = 0; j < ent->clazz->virtualMethodCount; j++) 4708 LOGI(" %2d: %d %s %s\n", 4709 j, ent->methodIndexArray[j], 4710 ent->clazz->virtualMethods[j].name, 4711 clazz->vtable[ent->methodIndexArray[j]]->name); 4712 } 4713 } 4714 } 4715 if (!dvmIsInterfaceClass(clazz)) { 4716 LOGI(" vtable (%d entries, %d in super):\n", clazz->vtableCount, 4717 super != NULL ? super->vtableCount : 0); 4718 for (i = 0; i < clazz->vtableCount; i++) { 4719 desc = dexProtoCopyMethodDescriptor(&clazz->vtable[i]->prototype); 4720 LOGI(" %s%2d: %p %20s %s\n", 4721 (i != clazz->vtable[i]->methodIndex) ? "*** " : "", 4722 (u4) clazz->vtable[i]->methodIndex, clazz->vtable[i], 4723 clazz->vtable[i]->name, desc); 4724 free(desc); 4725 } 4726 LOGI(" direct methods (%d entries):\n", clazz->directMethodCount); 4727 for (i = 0; i < clazz->directMethodCount; i++) { 4728 desc = dexProtoCopyMethodDescriptor( 4729 &clazz->directMethods[i].prototype); 4730 LOGI(" %2d: %20s %s\n", i, clazz->directMethods[i].name, 4731 desc); 4732 free(desc); 4733 } 4734 } else { 4735 LOGI(" interface methods (%d):\n", clazz->virtualMethodCount); 4736 for (i = 0; i < clazz->virtualMethodCount; i++) { 4737 desc = dexProtoCopyMethodDescriptor( 4738 &clazz->virtualMethods[i].prototype); 4739 LOGI(" %2d: %2d %20s %s\n", i, 4740 (u4) clazz->virtualMethods[i].methodIndex, 4741 clazz->virtualMethods[i].name, 4742 desc); 4743 free(desc); 4744 } 4745 } 4746 if (clazz->sfieldCount > 0) { 4747 LOGI(" static fields (%d entries):\n", clazz->sfieldCount); 4748 for (i = 0; i < clazz->sfieldCount; i++) { 4749 LOGI(" %2d: %20s %s\n", i, clazz->sfields[i].field.name, 4750 clazz->sfields[i].field.signature); 4751 } 4752 } 4753 if (clazz->ifieldCount > 0) { 4754 LOGI(" instance fields (%d entries):\n", clazz->ifieldCount); 4755 for (i = 0; i < clazz->ifieldCount; i++) { 4756 LOGI(" %2d: %20s %s\n", i, clazz->ifields[i].field.name, 4757 clazz->ifields[i].field.signature); 4758 } 4759 } 4760 return 0; 4761 } 4762 4763 /* 4764 * Dump the contents of a single class. 4765 * 4766 * Pass kDumpClassFullDetail into "flags" to get lots of detail. 4767 */ 4768 void dvmDumpClass(const ClassObject* clazz, int flags) 4769 { 4770 dumpClass((void*) clazz, (void*) flags); 4771 } 4772 4773 /* 4774 * Dump the contents of all classes. 4775 */ 4776 void dvmDumpAllClasses(int flags) 4777 { 4778 dvmHashTableLock(gDvm.loadedClasses); 4779 dvmHashForeach(gDvm.loadedClasses, dumpClass, (void*) flags); 4780 dvmHashTableUnlock(gDvm.loadedClasses); 4781 } 4782 4783 /* 4784 * Get the number of loaded classes 4785 */ 4786 int dvmGetNumLoadedClasses() 4787 { 4788 int count; 4789 dvmHashTableLock(gDvm.loadedClasses); 4790 count = dvmHashTableNumEntries(gDvm.loadedClasses); 4791 dvmHashTableUnlock(gDvm.loadedClasses); 4792 return count; 4793 } 4794 4795 /* 4796 * Write some statistics to the log file. 4797 */ 4798 void dvmDumpLoaderStats(const char* msg) 4799 { 4800 LOGV("VM stats (%s): cls=%d/%d meth=%d ifld=%d sfld=%d linear=%d\n", 4801 msg, gDvm.numLoadedClasses, dvmHashTableNumEntries(gDvm.loadedClasses), 4802 gDvm.numDeclaredMethods, gDvm.numDeclaredInstFields, 4803 gDvm.numDeclaredStaticFields, gDvm.pBootLoaderAlloc->curOffset); 4804 #ifdef COUNT_PRECISE_METHODS 4805 LOGI("GC precise methods: %d\n", 4806 dvmPointerSetGetCount(gDvm.preciseMethods)); 4807 #endif 4808 } 4809 4810 #ifdef PROFILE_FIELD_ACCESS 4811 /* 4812 * Dump the field access counts for all fields in this method. 4813 */ 4814 static int dumpAccessCounts(void* vclazz, void* varg) 4815 { 4816 const ClassObject* clazz = (const ClassObject*) vclazz; 4817 int i; 4818 4819 for (i = 0; i < clazz->ifieldCount; i++) { 4820 Field* field = &clazz->ifields[i].field; 4821 4822 if (field->gets != 0) 4823 printf("GI %d %s.%s\n", field->gets, 4824 field->clazz->descriptor, field->name); 4825 if (field->puts != 0) 4826 printf("PI %d %s.%s\n", field->puts, 4827 field->clazz->descriptor, field->name); 4828 } 4829 for (i = 0; i < clazz->sfieldCount; i++) { 4830 Field* field = &clazz->sfields[i].field; 4831 4832 if (field->gets != 0) 4833 printf("GS %d %s.%s\n", field->gets, 4834 field->clazz->descriptor, field->name); 4835 if (field->puts != 0) 4836 printf("PS %d %s.%s\n", field->puts, 4837 field->clazz->descriptor, field->name); 4838 } 4839 4840 return 0; 4841 } 4842 4843 /* 4844 * Dump the field access counts for all loaded classes. 4845 */ 4846 void dvmDumpFieldAccessCounts(void) 4847 { 4848 dvmHashTableLock(gDvm.loadedClasses); 4849 dvmHashForeach(gDvm.loadedClasses, dumpAccessCounts, NULL); 4850 dvmHashTableUnlock(gDvm.loadedClasses); 4851 } 4852 #endif 4853 4854 4855 /* 4856 * Mark all classes associated with the built-in loader. 4857 */ 4858 static int markClassObject(void *clazz, void *arg) 4859 { 4860 UNUSED_PARAMETER(arg); 4861 4862 dvmMarkObjectNonNull((Object *)clazz); 4863 return 0; 4864 } 4865 4866 /* 4867 * The garbage collector calls this to mark the class objects for all 4868 * loaded classes. 4869 */ 4870 void dvmGcScanRootClassLoader() 4871 { 4872 /* dvmClassStartup() may not have been called before the first GC. 4873 */ 4874 if (gDvm.loadedClasses != NULL) { 4875 dvmHashTableLock(gDvm.loadedClasses); 4876 dvmHashForeach(gDvm.loadedClasses, markClassObject, NULL); 4877 dvmHashTableUnlock(gDvm.loadedClasses); 4878 } 4879 } 4880 4881 4882 /* 4883 * =========================================================================== 4884 * Method Prototypes and Descriptors 4885 * =========================================================================== 4886 */ 4887 4888 /* 4889 * Compare the two method names and prototypes, a la strcmp(). The 4890 * name is considered the "major" order and the prototype the "minor" 4891 * order. The prototypes are compared as if by dvmCompareMethodProtos(). 4892 */ 4893 int dvmCompareMethodNamesAndProtos(const Method* method1, 4894 const Method* method2) 4895 { 4896 int result = strcmp(method1->name, method2->name); 4897 4898 if (result != 0) { 4899 return result; 4900 } 4901 4902 return dvmCompareMethodProtos(method1, method2); 4903 } 4904 4905 /* 4906 * Compare the two method names and prototypes, a la strcmp(), ignoring 4907 * the return value. The name is considered the "major" order and the 4908 * prototype the "minor" order. The prototypes are compared as if by 4909 * dvmCompareMethodArgProtos(). 4910 */ 4911 int dvmCompareMethodNamesAndParameterProtos(const Method* method1, 4912 const Method* method2) 4913 { 4914 int result = strcmp(method1->name, method2->name); 4915 4916 if (result != 0) { 4917 return result; 4918 } 4919 4920 return dvmCompareMethodParameterProtos(method1, method2); 4921 } 4922 4923 /* 4924 * Compare a (name, prototype) pair with the (name, prototype) of 4925 * a method, a la strcmp(). The name is considered the "major" order and 4926 * the prototype the "minor" order. The descriptor and prototype are 4927 * compared as if by dvmCompareDescriptorAndMethodProto(). 4928 */ 4929 int dvmCompareNameProtoAndMethod(const char* name, 4930 const DexProto* proto, const Method* method) 4931 { 4932 int result = strcmp(name, method->name); 4933 4934 if (result != 0) { 4935 return result; 4936 } 4937 4938 return dexProtoCompare(proto, &method->prototype); 4939 } 4940 4941 /* 4942 * Compare a (name, method descriptor) pair with the (name, prototype) of 4943 * a method, a la strcmp(). The name is considered the "major" order and 4944 * the prototype the "minor" order. The descriptor and prototype are 4945 * compared as if by dvmCompareDescriptorAndMethodProto(). 4946 */ 4947 int dvmCompareNameDescriptorAndMethod(const char* name, 4948 const char* descriptor, const Method* method) 4949 { 4950 int result = strcmp(name, method->name); 4951 4952 if (result != 0) { 4953 return result; 4954 } 4955 4956 return dvmCompareDescriptorAndMethodProto(descriptor, method); 4957 } 4958