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