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