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