Class.cpp revision e3c01dac83e6eea7f82fe81ed89cfbdd9791dbc9
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 } else { 2482 gDvm.classJavaLangClass = 2483 dvmFindSystemClassNoInit("Ljava/lang/Class;"); 2484 if (gDvm.classJavaLangClass == NULL) { 2485 /* should have thrown one */ 2486 assert(dvmCheckException(dvmThreadSelf())); 2487 goto bail; 2488 } 2489 } 2490 } 2491 assert(gDvm.classJavaLangClass != NULL); 2492 2493 /* 2494 * Resolve all Dex indices so we can hand the ClassObject 2495 * over to the GC. If we fail at any point, we need to remove 2496 * any tracked references to avoid leaking memory. 2497 */ 2498 2499 /* 2500 * All classes have a direct superclass, except for java/lang/Object. 2501 */ 2502 if (!classesResolved) { 2503 superclassIdx = (u4) clazz->super; /* unpack temp store */ 2504 clazz->super = NULL; 2505 } 2506 if (strcmp(clazz->descriptor, "Ljava/lang/Object;") == 0) { 2507 assert(!classesResolved); 2508 if (superclassIdx != kDexNoIndex) { 2509 /* TODO: is this invariant true for all java/lang/Objects, 2510 * regardless of the class loader? For now, assume it is. 2511 */ 2512 dvmThrowException("Ljava/lang/ClassFormatError;", 2513 "java.lang.Object has a superclass"); 2514 goto bail; 2515 } 2516 2517 /* Don't finalize objects whose classes use the 2518 * default (empty) Object.finalize(). 2519 */ 2520 CLEAR_CLASS_FLAG(clazz, CLASS_ISFINALIZABLE); 2521 } else { 2522 if (!classesResolved) { 2523 if (superclassIdx == kDexNoIndex) { 2524 dvmThrowException("Ljava/lang/LinkageError;", 2525 "no superclass defined"); 2526 goto bail; 2527 } 2528 clazz->super = dvmResolveClass(clazz, superclassIdx, false); 2529 if (clazz->super == NULL) { 2530 assert(dvmCheckException(dvmThreadSelf())); 2531 if (gDvm.optimizing) { 2532 /* happens with "external" libs */ 2533 LOGV("Unable to resolve superclass of %s (%d)\n", 2534 clazz->descriptor, superclassIdx); 2535 } else { 2536 LOGW("Unable to resolve superclass of %s (%d)\n", 2537 clazz->descriptor, superclassIdx); 2538 } 2539 goto bail; 2540 } 2541 } 2542 /* verify */ 2543 if (dvmIsFinalClass(clazz->super)) { 2544 LOGW("Superclass of '%s' is final '%s'\n", 2545 clazz->descriptor, clazz->super->descriptor); 2546 dvmThrowException("Ljava/lang/IncompatibleClassChangeError;", 2547 "superclass is final"); 2548 goto bail; 2549 } else if (dvmIsInterfaceClass(clazz->super)) { 2550 LOGW("Superclass of '%s' is interface '%s'\n", 2551 clazz->descriptor, clazz->super->descriptor); 2552 dvmThrowException("Ljava/lang/IncompatibleClassChangeError;", 2553 "superclass is an interface"); 2554 goto bail; 2555 } else if (!dvmCheckClassAccess(clazz, clazz->super)) { 2556 LOGW("Superclass of '%s' (%s) is not accessible\n", 2557 clazz->descriptor, clazz->super->descriptor); 2558 dvmThrowException("Ljava/lang/IllegalAccessError;", 2559 "superclass not accessible"); 2560 goto bail; 2561 } 2562 2563 /* Don't let the GC reclaim the superclass. 2564 * TODO: shouldn't be needed; remove when things stabilize 2565 */ 2566 dvmAddTrackedAlloc((Object *)clazz->super, NULL); 2567 2568 /* Inherit finalizability from the superclass. If this 2569 * class also overrides finalize(), its CLASS_ISFINALIZABLE 2570 * bit will already be set. 2571 */ 2572 if (IS_CLASS_FLAG_SET(clazz->super, CLASS_ISFINALIZABLE)) { 2573 SET_CLASS_FLAG(clazz, CLASS_ISFINALIZABLE); 2574 } 2575 2576 /* See if this class descends from java.lang.Reference 2577 * and set the class flags appropriately. 2578 */ 2579 if (IS_CLASS_FLAG_SET(clazz->super, CLASS_ISREFERENCE)) { 2580 u4 superRefFlags; 2581 2582 /* We've already determined the reference type of this 2583 * inheritance chain. Inherit reference-ness from the superclass. 2584 */ 2585 superRefFlags = GET_CLASS_FLAG_GROUP(clazz->super, 2586 CLASS_ISREFERENCE | 2587 CLASS_ISWEAKREFERENCE | 2588 CLASS_ISPHANTOMREFERENCE); 2589 SET_CLASS_FLAG(clazz, superRefFlags); 2590 } else if (clazz->classLoader == NULL && 2591 clazz->super->classLoader == NULL && 2592 strcmp(clazz->super->descriptor, 2593 "Ljava/lang/ref/Reference;") == 0) 2594 { 2595 u4 refFlags; 2596 2597 /* This class extends Reference, which means it should 2598 * be one of the magic Soft/Weak/PhantomReference classes. 2599 */ 2600 refFlags = CLASS_ISREFERENCE; 2601 if (strcmp(clazz->descriptor, 2602 "Ljava/lang/ref/SoftReference;") == 0) 2603 { 2604 /* Only CLASS_ISREFERENCE is set for soft references. 2605 */ 2606 } else if (strcmp(clazz->descriptor, 2607 "Ljava/lang/ref/WeakReference;") == 0) 2608 { 2609 refFlags |= CLASS_ISWEAKREFERENCE; 2610 } else if (strcmp(clazz->descriptor, 2611 "Ljava/lang/ref/PhantomReference;") == 0) 2612 { 2613 refFlags |= CLASS_ISPHANTOMREFERENCE; 2614 } else { 2615 /* No-one else is allowed to inherit directly 2616 * from Reference. 2617 */ 2618//xxx is this the right exception? better than an assertion. 2619 dvmThrowException("Ljava/lang/LinkageError;", 2620 "illegal inheritance from Reference"); 2621 goto bail; 2622 } 2623 2624 /* The class should not have any reference bits set yet. 2625 */ 2626 assert(GET_CLASS_FLAG_GROUP(clazz, 2627 CLASS_ISREFERENCE | 2628 CLASS_ISWEAKREFERENCE | 2629 CLASS_ISPHANTOMREFERENCE) == 0); 2630 2631 SET_CLASS_FLAG(clazz, refFlags); 2632 } 2633 } 2634 2635 if (!classesResolved && clazz->interfaceCount > 0) { 2636 /* 2637 * Resolve the interfaces implemented directly by this class. We 2638 * stuffed the class index into the interface pointer slot. 2639 */ 2640 dvmLinearReadWrite(clazz->classLoader, clazz->interfaces); 2641 for (i = 0; i < clazz->interfaceCount; i++) { 2642 u4 interfaceIdx; 2643 2644 interfaceIdx = (u4) clazz->interfaces[i]; /* unpack temp store */ 2645 assert(interfaceIdx != kDexNoIndex); 2646 2647 clazz->interfaces[i] = dvmResolveClass(clazz, interfaceIdx, false); 2648 if (clazz->interfaces[i] == NULL) { 2649 const DexFile* pDexFile = clazz->pDvmDex->pDexFile; 2650 2651 assert(dvmCheckException(dvmThreadSelf())); 2652 dvmLinearReadOnly(clazz->classLoader, clazz->interfaces); 2653 2654 const char* classDescriptor; 2655 classDescriptor = dexStringByTypeIdx(pDexFile, interfaceIdx); 2656 if (gDvm.optimizing) { 2657 /* happens with "external" libs */ 2658 LOGV("Failed resolving %s interface %d '%s'\n", 2659 clazz->descriptor, interfaceIdx, classDescriptor); 2660 } else { 2661 LOGI("Failed resolving %s interface %d '%s'\n", 2662 clazz->descriptor, interfaceIdx, classDescriptor); 2663 } 2664 goto bail_during_resolve; 2665 } 2666 2667 /* are we allowed to implement this interface? */ 2668 if (!dvmCheckClassAccess(clazz, clazz->interfaces[i])) { 2669 dvmLinearReadOnly(clazz->classLoader, clazz->interfaces); 2670 LOGW("Interface '%s' is not accessible to '%s'\n", 2671 clazz->interfaces[i]->descriptor, clazz->descriptor); 2672 dvmThrowException("Ljava/lang/IllegalAccessError;", 2673 "interface not accessible"); 2674 goto bail_during_resolve; 2675 } 2676 2677 /* Don't let the GC reclaim the interface class. 2678 * TODO: shouldn't be needed; remove when things stabilize 2679 */ 2680 dvmAddTrackedAlloc((Object *)clazz->interfaces[i], NULL); 2681 numInterfacesResolved++; 2682 2683 LOGVV("+++ found interface '%s'\n", 2684 clazz->interfaces[i]->descriptor); 2685 } 2686 dvmLinearReadOnly(clazz->classLoader, clazz->interfaces); 2687 } 2688 2689 /* 2690 * The ClassObject is now in a GC-able state. We let the GC 2691 * realize this by punching in the real class type, which is 2692 * always java.lang.Class. 2693 * 2694 * After this line, clazz will be fair game for the GC. 2695 * Every field that the GC will look at must now be valid: 2696 * - clazz->super 2697 * - class->classLoader 2698 * - clazz->sfields 2699 * - clazz->interfaces 2700 */ 2701 clazz->obj.clazz = gDvm.classJavaLangClass; 2702 2703 if (false) { 2704bail_during_resolve: 2705 resolve_okay = false; 2706 } else { 2707 resolve_okay = true; 2708 } 2709 2710 /* 2711 * Now that the GC can scan the ClassObject, we can let 2712 * go of the explicit references we were holding onto. 2713 * 2714 * Either that or we failed, in which case we need to 2715 * release the references so we don't leak memory. 2716 */ 2717 if (clazz->super != NULL) { 2718 dvmReleaseTrackedAlloc((Object *)clazz->super, NULL); 2719 } 2720 for (i = 0; i < numInterfacesResolved; i++) { 2721 dvmReleaseTrackedAlloc((Object *)clazz->interfaces[i], NULL); 2722 } 2723 2724 if (!resolve_okay) { 2725 //LOGW("resolve_okay is false\n"); 2726 goto bail; 2727 } 2728 2729 /* 2730 * Populate vtable. 2731 */ 2732 if (dvmIsInterfaceClass(clazz)) { 2733 /* no vtable; just set the method indices */ 2734 int count = clazz->virtualMethodCount; 2735 2736 if (count != (u2) count) { 2737 LOGE("Too many methods (%d) in interface '%s'\n", count, 2738 clazz->descriptor); 2739 goto bail; 2740 } 2741 2742 dvmLinearReadWrite(clazz->classLoader, clazz->virtualMethods); 2743 2744 for (i = 0; i < count; i++) 2745 clazz->virtualMethods[i].methodIndex = (u2) i; 2746 2747 dvmLinearReadOnly(clazz->classLoader, clazz->virtualMethods); 2748 } else { 2749 if (!createVtable(clazz)) { 2750 LOGW("failed creating vtable\n"); 2751 goto bail; 2752 } 2753 } 2754 2755 /* 2756 * Populate interface method tables. Can alter the vtable. 2757 */ 2758 if (!createIftable(clazz)) 2759 goto bail; 2760 2761 /* 2762 * Insert special-purpose "stub" method implementations. 2763 */ 2764 if (!insertMethodStubs(clazz)) 2765 goto bail; 2766 2767 /* 2768 * Compute instance field offsets and, hence, the size of the object. 2769 */ 2770 if (!computeFieldOffsets(clazz)) 2771 goto bail; 2772 2773 /* 2774 * Cache fields and methods from java/lang/ref/Reference and 2775 * java/lang/Class. This has to happen after computeFieldOffsets(). 2776 */ 2777 if (clazz->classLoader == NULL) { 2778 if (strcmp(clazz->descriptor, "Ljava/lang/ref/Reference;") == 0) { 2779 if (!precacheReferenceOffsets(clazz)) { 2780 LOGE("failed pre-caching Reference offsets\n"); 2781 dvmThrowException("Ljava/lang/InternalError;", NULL); 2782 goto bail; 2783 } 2784 } else if (clazz == gDvm.classJavaLangClass) { 2785 gDvm.offJavaLangClass_pd = dvmFindFieldOffset(clazz, "pd", 2786 "Ljava/security/ProtectionDomain;"); 2787 if (gDvm.offJavaLangClass_pd <= 0) { 2788 LOGE("ERROR: unable to find 'pd' field in Class\n"); 2789 dvmAbort(); /* we're not going to get much farther */ 2790 //goto bail; 2791 } 2792 } 2793 } 2794 2795 /* 2796 * Compact the offsets the GC has to examine into a bitmap, if 2797 * possible. (This has to happen after Reference.referent is 2798 * massaged in precacheReferenceOffsets.) 2799 */ 2800 computeRefOffsets(clazz); 2801 2802 /* 2803 * Done! 2804 */ 2805 if (IS_CLASS_FLAG_SET(clazz, CLASS_ISPREVERIFIED)) 2806 clazz->status = CLASS_VERIFIED; 2807 else 2808 clazz->status = CLASS_RESOLVED; 2809 okay = true; 2810 if (gDvm.verboseClass) 2811 LOGV("CLASS: linked '%s'\n", clazz->descriptor); 2812 2813 /* 2814 * We send CLASS_PREPARE events to the debugger from here. The 2815 * definition of "preparation" is creating the static fields for a 2816 * class and initializing them to the standard default values, but not 2817 * executing any code (that comes later, during "initialization"). 2818 * 2819 * We did the static prep in loadSFieldFromDex() while loading the class. 2820 * 2821 * The class has been prepared and resolved but possibly not yet verified 2822 * at this point. 2823 */ 2824 if (gDvm.debuggerActive) { 2825 dvmDbgPostClassPrepare(clazz); 2826 } 2827 2828bail: 2829 if (!okay) { 2830 clazz->status = CLASS_ERROR; 2831 if (!dvmCheckException(dvmThreadSelf())) { 2832 dvmThrowException("Ljava/lang/VirtualMachineError;", NULL); 2833 } 2834 } 2835 return okay; 2836} 2837 2838/* 2839 * Create the virtual method table. 2840 * 2841 * The top part of the table is a copy of the table from our superclass, 2842 * with our local methods overriding theirs. The bottom part of the table 2843 * has any new methods we defined. 2844 */ 2845static bool createVtable(ClassObject* clazz) 2846{ 2847 bool result = false; 2848 int maxCount; 2849 int i; 2850 2851 if (clazz->super != NULL) { 2852 //LOGI("SUPER METHODS %d %s->%s\n", clazz->super->vtableCount, 2853 // clazz->descriptor, clazz->super->descriptor); 2854 } 2855 2856 /* the virtual methods we define, plus the superclass vtable size */ 2857 maxCount = clazz->virtualMethodCount; 2858 if (clazz->super != NULL) { 2859 maxCount += clazz->super->vtableCount; 2860 } else { 2861 /* TODO: is this invariant true for all java/lang/Objects, 2862 * regardless of the class loader? For now, assume it is. 2863 */ 2864 assert(strcmp(clazz->descriptor, "Ljava/lang/Object;") == 0); 2865 } 2866 //LOGD("+++ max vmethods for '%s' is %d\n", clazz->descriptor, maxCount); 2867 2868 /* 2869 * Over-allocate the table, then realloc it down if necessary. So 2870 * long as we don't allocate anything in between we won't cause 2871 * fragmentation, and reducing the size should be unlikely to cause 2872 * a buffer copy. 2873 */ 2874 dvmLinearReadWrite(clazz->classLoader, clazz->virtualMethods); 2875 clazz->vtable = (Method**) dvmLinearAlloc(clazz->classLoader, 2876 sizeof(Method*) * maxCount); 2877 if (clazz->vtable == NULL) 2878 goto bail; 2879 2880 if (clazz->super != NULL) { 2881 int actualCount; 2882 2883 memcpy(clazz->vtable, clazz->super->vtable, 2884 sizeof(*(clazz->vtable)) * clazz->super->vtableCount); 2885 actualCount = clazz->super->vtableCount; 2886 2887 /* 2888 * See if any of our virtual methods override the superclass. 2889 */ 2890 for (i = 0; i < clazz->virtualMethodCount; i++) { 2891 Method* localMeth = &clazz->virtualMethods[i]; 2892 int si; 2893 2894 for (si = 0; si < clazz->super->vtableCount; si++) { 2895 Method* superMeth = clazz->vtable[si]; 2896 2897 if (dvmCompareMethodNamesAndProtos(localMeth, superMeth) == 0) 2898 { 2899 /* verify */ 2900 if (dvmIsFinalMethod(superMeth)) { 2901 LOGW("Method %s.%s overrides final %s.%s\n", 2902 localMeth->clazz->descriptor, localMeth->name, 2903 superMeth->clazz->descriptor, superMeth->name); 2904 goto bail; 2905 } 2906 clazz->vtable[si] = localMeth; 2907 localMeth->methodIndex = (u2) si; 2908 //LOGV("+++ override %s.%s (slot %d)\n", 2909 // clazz->descriptor, localMeth->name, si); 2910 break; 2911 } 2912 } 2913 2914 if (si == clazz->super->vtableCount) { 2915 /* not an override, add to end */ 2916 clazz->vtable[actualCount] = localMeth; 2917 localMeth->methodIndex = (u2) actualCount; 2918 actualCount++; 2919 2920 //LOGV("+++ add method %s.%s\n", 2921 // clazz->descriptor, localMeth->name); 2922 } 2923 } 2924 2925 if (actualCount != (u2) actualCount) { 2926 LOGE("Too many methods (%d) in class '%s'\n", actualCount, 2927 clazz->descriptor); 2928 goto bail; 2929 } 2930 2931 assert(actualCount <= maxCount); 2932 2933 if (actualCount < maxCount) { 2934 assert(clazz->vtable != NULL); 2935 dvmLinearReadOnly(clazz->classLoader, clazz->vtable); 2936 clazz->vtable = dvmLinearRealloc(clazz->classLoader, clazz->vtable, 2937 sizeof(*(clazz->vtable)) * actualCount); 2938 if (clazz->vtable == NULL) { 2939 LOGE("vtable realloc failed\n"); 2940 goto bail; 2941 } else { 2942 LOGVV("+++ reduced vtable from %d to %d\n", 2943 maxCount, actualCount); 2944 } 2945 } 2946 2947 clazz->vtableCount = actualCount; 2948 } else { 2949 /* java/lang/Object case */ 2950 int count = clazz->virtualMethodCount; 2951 if (count != (u2) count) { 2952 LOGE("Too many methods (%d) in base class '%s'\n", count, 2953 clazz->descriptor); 2954 goto bail; 2955 } 2956 2957 for (i = 0; i < count; i++) { 2958 clazz->vtable[i] = &clazz->virtualMethods[i]; 2959 clazz->virtualMethods[i].methodIndex = (u2) i; 2960 } 2961 clazz->vtableCount = clazz->virtualMethodCount; 2962 } 2963 2964 result = true; 2965 2966bail: 2967 dvmLinearReadOnly(clazz->classLoader, clazz->vtable); 2968 dvmLinearReadOnly(clazz->classLoader, clazz->virtualMethods); 2969 return result; 2970} 2971 2972/* 2973 * Create and populate "iftable". 2974 * 2975 * The set of interfaces we support is the combination of the interfaces 2976 * we implement directly and those implemented by our superclass. Each 2977 * interface can have one or more "superinterfaces", which we must also 2978 * support. For speed we flatten the tree out. 2979 * 2980 * We might be able to speed this up when there are lots of interfaces 2981 * by merge-sorting the class pointers and binary-searching when removing 2982 * duplicates. We could also drop the duplicate removal -- it's only 2983 * there to reduce the memory footprint. 2984 * 2985 * Because of "Miranda methods", this may reallocate clazz->virtualMethods. 2986 * 2987 * Returns "true" on success. 2988 */ 2989static bool createIftable(ClassObject* clazz) 2990{ 2991 bool result = false; 2992 bool zapIftable = false; 2993 bool zapVtable = false; 2994 bool zapIfvipool = false; 2995 int ifCount, superIfCount, idx; 2996 int i; 2997 2998 if (clazz->super != NULL) 2999 superIfCount = clazz->super->iftableCount; 3000 else 3001 superIfCount = 0; 3002 3003 ifCount = superIfCount; 3004 ifCount += clazz->interfaceCount; 3005 for (i = 0; i < clazz->interfaceCount; i++) 3006 ifCount += clazz->interfaces[i]->iftableCount; 3007 3008 LOGVV("INTF: class '%s' direct w/supra=%d super=%d total=%d\n", 3009 clazz->descriptor, ifCount - superIfCount, superIfCount, ifCount); 3010 3011 if (ifCount == 0) { 3012 assert(clazz->iftableCount == 0); 3013 assert(clazz->iftable == NULL); 3014 result = true; 3015 goto bail; 3016 } 3017 3018 /* 3019 * Create a table with enough space for all interfaces, and copy the 3020 * superclass' table in. 3021 */ 3022 clazz->iftable = (InterfaceEntry*) dvmLinearAlloc(clazz->classLoader, 3023 sizeof(InterfaceEntry) * ifCount); 3024 zapIftable = true; 3025 memset(clazz->iftable, 0x00, sizeof(InterfaceEntry) * ifCount); 3026 if (superIfCount != 0) { 3027 memcpy(clazz->iftable, clazz->super->iftable, 3028 sizeof(InterfaceEntry) * superIfCount); 3029 } 3030 3031 /* 3032 * Create a flattened interface hierarchy of our immediate interfaces. 3033 */ 3034 idx = superIfCount; 3035 3036 for (i = 0; i < clazz->interfaceCount; i++) { 3037 ClassObject* interf; 3038 int j; 3039 3040 interf = clazz->interfaces[i]; 3041 assert(interf != NULL); 3042 3043 /* make sure this is still an interface class */ 3044 if (!dvmIsInterfaceClass(interf)) { 3045 LOGW("Class '%s' implements non-interface '%s'\n", 3046 clazz->descriptor, interf->descriptor); 3047 dvmThrowExceptionWithClassMessage( 3048 "Ljava/lang/IncompatibleClassChangeError;", 3049 clazz->descriptor); 3050 goto bail; 3051 } 3052 3053 /* add entry for this interface */ 3054 clazz->iftable[idx++].clazz = interf; 3055 3056 /* add entries for the interface's superinterfaces */ 3057 for (j = 0; j < interf->iftableCount; j++) { 3058 clazz->iftable[idx++].clazz = interf->iftable[j].clazz; 3059 } 3060 } 3061 3062 assert(idx == ifCount); 3063 3064 if (false) { 3065 /* 3066 * Remove anything redundant from our recent additions. Note we have 3067 * to traverse the recent adds when looking for duplicates, because 3068 * it's possible the recent additions are self-redundant. This 3069 * reduces the memory footprint of classes with lots of inherited 3070 * interfaces. 3071 * 3072 * (I don't know if this will cause problems later on when we're trying 3073 * to find a static field. It looks like the proper search order is 3074 * (1) current class, (2) interfaces implemented by current class, 3075 * (3) repeat with superclass. A field implemented by an interface 3076 * and by a superclass might come out wrong if the superclass also 3077 * implements the interface. The javac compiler will reject the 3078 * situation as ambiguous, so the concern is somewhat artificial.) 3079 * 3080 * UPDATE: this makes ReferenceType.Interfaces difficult to implement, 3081 * because it wants to return just the interfaces declared to be 3082 * implemented directly by the class. I'm excluding this code for now. 3083 */ 3084 for (i = superIfCount; i < ifCount; i++) { 3085 int j; 3086 3087 for (j = 0; j < ifCount; j++) { 3088 if (i == j) 3089 continue; 3090 if (clazz->iftable[i].clazz == clazz->iftable[j].clazz) { 3091 LOGVV("INTF: redundant interface %s in %s\n", 3092 clazz->iftable[i].clazz->descriptor, 3093 clazz->descriptor); 3094 3095 if (i != ifCount-1) 3096 memmove(&clazz->iftable[i], &clazz->iftable[i+1], 3097 (ifCount - i -1) * sizeof(InterfaceEntry)); 3098 ifCount--; 3099 i--; // adjust for i++ above 3100 break; 3101 } 3102 } 3103 } 3104 LOGVV("INTF: class '%s' nodupes=%d\n", clazz->descriptor, ifCount); 3105 } // if (false) 3106 3107 clazz->iftableCount = ifCount; 3108 3109 /* 3110 * If we're an interface, we don't need the vtable pointers, so 3111 * we're done. If this class doesn't implement an interface that our 3112 * superclass doesn't have, then we again have nothing to do. 3113 */ 3114 if (dvmIsInterfaceClass(clazz) || superIfCount == ifCount) { 3115 //dvmDumpClass(clazz, kDumpClassFullDetail); 3116 result = true; 3117 goto bail; 3118 } 3119 3120 /* 3121 * When we're handling invokeinterface, we probably have an object 3122 * whose type is an interface class rather than a concrete class. We 3123 * need to convert the method reference into a vtable index. So, for 3124 * every entry in "iftable", we create a list of vtable indices. 3125 * 3126 * Because our vtable encompasses the superclass vtable, we can use 3127 * the vtable indices from our superclass for all of the interfaces 3128 * that weren't directly implemented by us. 3129 * 3130 * Each entry in "iftable" has a pointer to the start of its set of 3131 * vtable offsets. The iftable entries in the superclass point to 3132 * storage allocated in the superclass, and the iftable entries added 3133 * for this class point to storage allocated in this class. "iftable" 3134 * is flat for fast access in a class and all of its subclasses, but 3135 * "ifviPool" is only created for the topmost implementor. 3136 */ 3137 int poolSize = 0; 3138 for (i = superIfCount; i < ifCount; i++) { 3139 /* 3140 * Note it's valid for an interface to have no methods (e.g. 3141 * java/io/Serializable). 3142 */ 3143 LOGVV("INTF: pool: %d from %s\n", 3144 clazz->iftable[i].clazz->virtualMethodCount, 3145 clazz->iftable[i].clazz->descriptor); 3146 poolSize += clazz->iftable[i].clazz->virtualMethodCount; 3147 } 3148 3149 if (poolSize == 0) { 3150 LOGVV("INTF: didn't find any new interfaces with methods\n"); 3151 result = true; 3152 goto bail; 3153 } 3154 3155 clazz->ifviPoolCount = poolSize; 3156 clazz->ifviPool = (int*) dvmLinearAlloc(clazz->classLoader, 3157 poolSize * sizeof(int*)); 3158 zapIfvipool = true; 3159 3160 /* 3161 * Fill in the vtable offsets for the interfaces that weren't part of 3162 * our superclass. 3163 */ 3164 int poolOffset = 0; 3165 Method** mirandaList = NULL; 3166 int mirandaCount = 0, mirandaAlloc = 0; 3167 3168 for (i = superIfCount; i < ifCount; i++) { 3169 ClassObject* interface; 3170 int methIdx; 3171 3172 clazz->iftable[i].methodIndexArray = clazz->ifviPool + poolOffset; 3173 interface = clazz->iftable[i].clazz; 3174 poolOffset += interface->virtualMethodCount; // end here 3175 3176 /* 3177 * For each method listed in the interface's method list, find the 3178 * matching method in our class's method list. We want to favor the 3179 * subclass over the superclass, which just requires walking 3180 * back from the end of the vtable. (This only matters if the 3181 * superclass defines a private method and this class redefines 3182 * it -- otherwise it would use the same vtable slot. In Dalvik 3183 * those don't end up in the virtual method table, so it shouldn't 3184 * matter which direction we go. We walk it backward anyway.) 3185 * 3186 * 3187 * Suppose we have the following arrangement: 3188 * public interface MyInterface 3189 * public boolean inInterface(); 3190 * public abstract class MirandaAbstract implements MirandaInterface 3191 * //public abstract boolean inInterface(); // not declared! 3192 * public boolean inAbstract() { stuff } // in vtable 3193 * public class MirandClass extends MirandaAbstract 3194 * public boolean inInterface() { stuff } 3195 * public boolean inAbstract() { stuff } // in vtable 3196 * 3197 * The javac compiler happily compiles MirandaAbstract even though 3198 * it doesn't declare all methods from its interface. When we try 3199 * to set up a vtable for MirandaAbstract, we find that we don't 3200 * have an slot for inInterface. To prevent this, we synthesize 3201 * abstract method declarations in MirandaAbstract. 3202 * 3203 * We have to expand vtable and update some things that point at it, 3204 * so we accumulate the method list and do it all at once below. 3205 */ 3206 for (methIdx = 0; methIdx < interface->virtualMethodCount; methIdx++) { 3207 Method* imeth = &interface->virtualMethods[methIdx]; 3208 int j; 3209 3210 IF_LOGVV() { 3211 char* desc = dexProtoCopyMethodDescriptor(&imeth->prototype); 3212 LOGVV("INTF: matching '%s' '%s'\n", imeth->name, desc); 3213 free(desc); 3214 } 3215 3216 for (j = clazz->vtableCount-1; j >= 0; j--) { 3217 if (dvmCompareMethodNamesAndProtos(imeth, clazz->vtable[j]) 3218 == 0) 3219 { 3220 LOGVV("INTF: matched at %d\n", j); 3221 if (!dvmIsPublicMethod(clazz->vtable[j])) { 3222 LOGW("Implementation of %s.%s is not public\n", 3223 clazz->descriptor, clazz->vtable[j]->name); 3224 dvmThrowException("Ljava/lang/IllegalAccessError;", 3225 "interface implementation not public"); 3226 goto bail; 3227 } 3228 clazz->iftable[i].methodIndexArray[methIdx] = j; 3229 break; 3230 } 3231 } 3232 if (j < 0) { 3233 IF_LOGV() { 3234 char* desc = 3235 dexProtoCopyMethodDescriptor(&imeth->prototype); 3236 LOGV("No match for '%s' '%s' in '%s' (creating miranda)\n", 3237 imeth->name, desc, clazz->descriptor); 3238 free(desc); 3239 } 3240 //dvmThrowException("Ljava/lang/RuntimeException;", "Miranda!"); 3241 //return false; 3242 3243 if (mirandaCount == mirandaAlloc) { 3244 mirandaAlloc += 8; 3245 if (mirandaList == NULL) { 3246 mirandaList = dvmLinearAlloc(clazz->classLoader, 3247 mirandaAlloc * sizeof(Method*)); 3248 } else { 3249 dvmLinearReadOnly(clazz->classLoader, mirandaList); 3250 mirandaList = dvmLinearRealloc(clazz->classLoader, 3251 mirandaList, mirandaAlloc * sizeof(Method*)); 3252 } 3253 assert(mirandaList != NULL); // mem failed + we leaked 3254 } 3255 3256 /* 3257 * These may be redundant (e.g. method with same name and 3258 * signature declared in two interfaces implemented by the 3259 * same abstract class). We can squeeze the duplicates 3260 * out here. 3261 */ 3262 int mir; 3263 for (mir = 0; mir < mirandaCount; mir++) { 3264 if (dvmCompareMethodNamesAndProtos( 3265 mirandaList[mir], imeth) == 0) 3266 { 3267 IF_LOGVV() { 3268 char* desc = dexProtoCopyMethodDescriptor( 3269 &imeth->prototype); 3270 LOGVV("MIRANDA dupe: %s and %s %s%s\n", 3271 mirandaList[mir]->clazz->descriptor, 3272 imeth->clazz->descriptor, 3273 imeth->name, desc); 3274 free(desc); 3275 } 3276 break; 3277 } 3278 } 3279 3280 /* point the iftable at a phantom slot index */ 3281 clazz->iftable[i].methodIndexArray[methIdx] = 3282 clazz->vtableCount + mir; 3283 LOGVV("MIRANDA: %s points at slot %d\n", 3284 imeth->name, clazz->vtableCount + mir); 3285 3286 /* if non-duplicate among Mirandas, add to Miranda list */ 3287 if (mir == mirandaCount) { 3288 //LOGV("MIRANDA: holding '%s' in slot %d\n", 3289 // imeth->name, mir); 3290 mirandaList[mirandaCount++] = imeth; 3291 } 3292 } 3293 } 3294 } 3295 3296 if (mirandaCount != 0) { 3297 static const int kManyMirandas = 150; /* arbitrary */ 3298 Method* newVirtualMethods; 3299 Method* meth; 3300 int oldMethodCount, oldVtableCount; 3301 3302 for (i = 0; i < mirandaCount; i++) { 3303 LOGVV("MIRANDA %d: %s.%s\n", i, 3304 mirandaList[i]->clazz->descriptor, mirandaList[i]->name); 3305 } 3306 if (mirandaCount > kManyMirandas) { 3307 /* 3308 * Some obfuscators like to create an interface with a huge 3309 * pile of methods, declare classes as implementing it, and then 3310 * only define a couple of methods. This leads to a rather 3311 * massive collection of Miranda methods and a lot of wasted 3312 * space, sometimes enough to blow out the LinearAlloc cap. 3313 */ 3314 LOGD("Note: class %s has %d unimplemented (abstract) methods\n", 3315 clazz->descriptor, mirandaCount); 3316 } 3317 3318 /* 3319 * We found methods in one or more interfaces for which we do not 3320 * have vtable entries. We have to expand our virtualMethods 3321 * table (which might be empty) to hold some new entries. 3322 */ 3323 if (clazz->virtualMethods == NULL) { 3324 newVirtualMethods = (Method*) dvmLinearAlloc(clazz->classLoader, 3325 sizeof(Method) * (clazz->virtualMethodCount + mirandaCount)); 3326 } else { 3327 //dvmLinearReadOnly(clazz->classLoader, clazz->virtualMethods); 3328 newVirtualMethods = (Method*) dvmLinearRealloc(clazz->classLoader, 3329 clazz->virtualMethods, 3330 sizeof(Method) * (clazz->virtualMethodCount + mirandaCount)); 3331 } 3332 if (newVirtualMethods != clazz->virtualMethods) { 3333 /* 3334 * Table was moved in memory. We have to run through the 3335 * vtable and fix the pointers. The vtable entries might be 3336 * pointing at superclasses, so we flip it around: run through 3337 * all locally-defined virtual methods, and fix their entries 3338 * in the vtable. (This would get really messy if sub-classes 3339 * had already been loaded.) 3340 * 3341 * Reminder: clazz->virtualMethods and clazz->virtualMethodCount 3342 * hold the virtual methods declared by this class. The 3343 * method's methodIndex is the vtable index, and is the same 3344 * for all sub-classes (and all super classes in which it is 3345 * defined). We're messing with these because the Miranda 3346 * stuff makes it look like the class actually has an abstract 3347 * method declaration in it. 3348 */ 3349 LOGVV("MIRANDA fixing vtable pointers\n"); 3350 dvmLinearReadWrite(clazz->classLoader, clazz->vtable); 3351 Method* meth = newVirtualMethods; 3352 for (i = 0; i < clazz->virtualMethodCount; i++, meth++) 3353 clazz->vtable[meth->methodIndex] = meth; 3354 dvmLinearReadOnly(clazz->classLoader, clazz->vtable); 3355 } 3356 3357 oldMethodCount = clazz->virtualMethodCount; 3358 clazz->virtualMethods = newVirtualMethods; 3359 clazz->virtualMethodCount += mirandaCount; 3360 3361 dvmLinearReadOnly(clazz->classLoader, clazz->virtualMethods); 3362 3363 /* 3364 * We also have to expand the vtable. 3365 */ 3366 assert(clazz->vtable != NULL); 3367 clazz->vtable = (Method**) dvmLinearRealloc(clazz->classLoader, 3368 clazz->vtable, 3369 sizeof(Method*) * (clazz->vtableCount + mirandaCount)); 3370 if (clazz->vtable == NULL) { 3371 assert(false); 3372 goto bail; 3373 } 3374 zapVtable = true; 3375 3376 oldVtableCount = clazz->vtableCount; 3377 clazz->vtableCount += mirandaCount; 3378 3379 /* 3380 * Now we need to create the fake methods. We clone the abstract 3381 * method definition from the interface and then replace a few 3382 * things. 3383 * 3384 * The Method will be an "abstract native", with nativeFunc set to 3385 * dvmAbstractMethodStub(). 3386 */ 3387 meth = clazz->virtualMethods + oldMethodCount; 3388 for (i = 0; i < mirandaCount; i++, meth++) { 3389 dvmLinearReadWrite(clazz->classLoader, clazz->virtualMethods); 3390 cloneMethod(meth, mirandaList[i]); 3391 meth->clazz = clazz; 3392 meth->accessFlags |= ACC_MIRANDA; 3393 meth->methodIndex = (u2) (oldVtableCount + i); 3394 dvmLinearReadOnly(clazz->classLoader, clazz->virtualMethods); 3395 3396 /* point the new vtable entry at the new method */ 3397 clazz->vtable[oldVtableCount + i] = meth; 3398 } 3399 3400 dvmLinearReadOnly(clazz->classLoader, mirandaList); 3401 dvmLinearFree(clazz->classLoader, mirandaList); 3402 3403 } 3404 3405 /* 3406 * TODO? 3407 * Sort the interfaces by number of declared methods. All we really 3408 * want is to get the interfaces with zero methods at the end of the 3409 * list, so that when we walk through the list during invoke-interface 3410 * we don't examine interfaces that can't possibly be useful. 3411 * 3412 * The set will usually be small, so a simple insertion sort works. 3413 * 3414 * We have to be careful not to change the order of two interfaces 3415 * that define the same method. (Not a problem if we only move the 3416 * zero-method interfaces to the end.) 3417 * 3418 * PROBLEM: 3419 * If we do this, we will no longer be able to identify super vs. 3420 * current class interfaces by comparing clazz->super->iftableCount. This 3421 * breaks anything that only wants to find interfaces declared directly 3422 * by the class (dvmFindStaticFieldHier, ReferenceType.Interfaces, 3423 * dvmDbgOutputAllInterfaces, etc). Need to provide a workaround. 3424 * 3425 * We can sort just the interfaces implemented directly by this class, 3426 * but that doesn't seem like it would provide much of an advantage. I'm 3427 * not sure this is worthwhile. 3428 * 3429 * (This has been made largely obsolete by the interface cache mechanism.) 3430 */ 3431 3432 //dvmDumpClass(clazz); 3433 3434 result = true; 3435 3436bail: 3437 if (zapIftable) 3438 dvmLinearReadOnly(clazz->classLoader, clazz->iftable); 3439 if (zapVtable) 3440 dvmLinearReadOnly(clazz->classLoader, clazz->vtable); 3441 if (zapIfvipool) 3442 dvmLinearReadOnly(clazz->classLoader, clazz->ifviPool); 3443 return result; 3444} 3445 3446 3447/* 3448 * Provide "stub" implementations for methods without them. 3449 * 3450 * Currently we provide an implementation for all abstract methods that 3451 * throws an AbstractMethodError exception. This allows us to avoid an 3452 * explicit check for abstract methods in every virtual call. 3453 * 3454 * NOTE: for Miranda methods, the method declaration is a clone of what 3455 * was found in the interface class. That copy may already have had the 3456 * function pointer filled in, so don't be surprised if it's not NULL. 3457 * 3458 * NOTE: this sets the "native" flag, giving us an "abstract native" method, 3459 * which is nonsensical. Need to make sure that this doesn't escape the 3460 * VM. We can either mask it out in reflection calls, or copy "native" 3461 * into the high 16 bits of accessFlags and check that internally. 3462 */ 3463static bool insertMethodStubs(ClassObject* clazz) 3464{ 3465 dvmLinearReadWrite(clazz->classLoader, clazz->virtualMethods); 3466 3467 Method* meth; 3468 int i; 3469 3470 meth = clazz->virtualMethods; 3471 for (i = 0; i < clazz->virtualMethodCount; i++, meth++) { 3472 if (dvmIsAbstractMethod(meth)) { 3473 assert(meth->insns == NULL); 3474 assert(meth->nativeFunc == NULL || 3475 meth->nativeFunc == (DalvikBridgeFunc)dvmAbstractMethodStub); 3476 3477 meth->accessFlags |= ACC_NATIVE; 3478 meth->nativeFunc = (DalvikBridgeFunc) dvmAbstractMethodStub; 3479 } 3480 } 3481 3482 dvmLinearReadOnly(clazz->classLoader, clazz->virtualMethods); 3483 return true; 3484} 3485 3486 3487/* 3488 * Swap two instance fields. 3489 */ 3490static inline void swapField(InstField* pOne, InstField* pTwo) 3491{ 3492 InstField swap; 3493 3494 LOGVV(" --- swap '%s' and '%s'\n", pOne->field.name, pTwo->field.name); 3495 swap = *pOne; 3496 *pOne = *pTwo; 3497 *pTwo = swap; 3498} 3499 3500/* 3501 * Assign instance fields to u4 slots. 3502 * 3503 * The top portion of the instance field area is occupied by the superclass 3504 * fields, the bottom by the fields for this class. 3505 * 3506 * "long" and "double" fields occupy two adjacent slots. On some 3507 * architectures, 64-bit quantities must be 64-bit aligned, so we need to 3508 * arrange fields (or introduce padding) to ensure this. We assume the 3509 * fields of the topmost superclass (i.e. Object) are 64-bit aligned, so 3510 * we can just ensure that the offset is "even". To avoid wasting space, 3511 * we want to move non-reference 32-bit fields into gaps rather than 3512 * creating pad words. 3513 * 3514 * In the worst case we will waste 4 bytes, but because objects are 3515 * allocated on >= 64-bit boundaries, those bytes may well be wasted anyway 3516 * (assuming this is the most-derived class). 3517 * 3518 * Pad words are not represented in the field table, so the field table 3519 * itself does not change size. 3520 * 3521 * The number of field slots determines the size of the object, so we 3522 * set that here too. 3523 * 3524 * This function feels a little more complicated than I'd like, but it 3525 * has the property of moving the smallest possible set of fields, which 3526 * should reduce the time required to load a class. 3527 * 3528 * NOTE: reference fields *must* come first, or precacheReferenceOffsets() 3529 * will break. 3530 */ 3531static bool computeFieldOffsets(ClassObject* clazz) 3532{ 3533 int fieldOffset; 3534 int i, j; 3535 3536 dvmLinearReadWrite(clazz->classLoader, clazz->ifields); 3537 3538 if (clazz->super != NULL) 3539 fieldOffset = clazz->super->objectSize; 3540 else 3541 fieldOffset = offsetof(DataObject, instanceData); 3542 3543 LOGVV("--- computeFieldOffsets '%s'\n", clazz->descriptor); 3544 3545 //LOGI("OFFSETS fieldCount=%d\n", clazz->ifieldCount); 3546 //LOGI("dataobj, instance: %d\n", offsetof(DataObject, instanceData)); 3547 //LOGI("classobj, access: %d\n", offsetof(ClassObject, accessFlags)); 3548 //LOGI("super=%p, fieldOffset=%d\n", clazz->super, fieldOffset); 3549 3550 /* 3551 * Start by moving all reference fields to the front. 3552 */ 3553 clazz->ifieldRefCount = 0; 3554 j = clazz->ifieldCount - 1; 3555 for (i = 0; i < clazz->ifieldCount; i++) { 3556 InstField* pField = &clazz->ifields[i]; 3557 char c = pField->field.signature[0]; 3558 3559 if (c != '[' && c != 'L') { 3560 /* This isn't a reference field; see if any reference fields 3561 * follow this one. If so, we'll move it to this position. 3562 * (quicksort-style partitioning) 3563 */ 3564 while (j > i) { 3565 InstField* refField = &clazz->ifields[j--]; 3566 char rc = refField->field.signature[0]; 3567 3568 if (rc == '[' || rc == 'L') { 3569 /* Here's a reference field that follows at least one 3570 * non-reference field. Swap it with the current field. 3571 * (When this returns, "pField" points to the reference 3572 * field, and "refField" points to the non-ref field.) 3573 */ 3574 swapField(pField, refField); 3575 3576 /* Fix the signature. 3577 */ 3578 c = rc; 3579 3580 clazz->ifieldRefCount++; 3581 break; 3582 } 3583 } 3584 /* We may or may not have swapped a field. 3585 */ 3586 } else { 3587 /* This is a reference field. 3588 */ 3589 clazz->ifieldRefCount++; 3590 } 3591 3592 /* 3593 * If we've hit the end of the reference fields, break. 3594 */ 3595 if (c != '[' && c != 'L') 3596 break; 3597 3598 pField->byteOffset = fieldOffset; 3599 fieldOffset += sizeof(u4); 3600 LOGVV(" --- offset1 '%s'=%d\n", pField->field.name,pField->byteOffset); 3601 } 3602 3603 /* 3604 * Now we want to pack all of the double-wide fields together. If we're 3605 * not aligned, though, we want to shuffle one 32-bit field into place. 3606 * If we can't find one, we'll have to pad it. 3607 */ 3608 if (i != clazz->ifieldCount && (fieldOffset & 0x04) != 0) { 3609 LOGVV(" +++ not aligned\n"); 3610 3611 InstField* pField = &clazz->ifields[i]; 3612 char c = pField->field.signature[0]; 3613 3614 if (c != 'J' && c != 'D') { 3615 /* 3616 * The field that comes next is 32-bit, so just advance past it. 3617 */ 3618 assert(c != '[' && c != 'L'); 3619 pField->byteOffset = fieldOffset; 3620 fieldOffset += sizeof(u4); 3621 i++; 3622 LOGVV(" --- offset2 '%s'=%d\n", 3623 pField->field.name, pField->byteOffset); 3624 } else { 3625 /* 3626 * Next field is 64-bit, so search for a 32-bit field we can 3627 * swap into it. 3628 */ 3629 bool found = false; 3630 j = clazz->ifieldCount - 1; 3631 while (j > i) { 3632 InstField* singleField = &clazz->ifields[j--]; 3633 char rc = singleField->field.signature[0]; 3634 3635 if (rc != 'J' && rc != 'D') { 3636 swapField(pField, singleField); 3637 //c = rc; 3638 LOGVV(" +++ swapped '%s' for alignment\n", 3639 pField->field.name); 3640 pField->byteOffset = fieldOffset; 3641 fieldOffset += sizeof(u4); 3642 LOGVV(" --- offset3 '%s'=%d\n", 3643 pField->field.name, pField->byteOffset); 3644 found = true; 3645 i++; 3646 break; 3647 } 3648 } 3649 if (!found) { 3650 LOGV(" +++ inserting pad field in '%s'\n", clazz->descriptor); 3651 fieldOffset += sizeof(u4); 3652 } 3653 } 3654 } 3655 3656 /* 3657 * Alignment is good, shuffle any double-wide fields forward, and 3658 * finish assigning field offsets to all fields. 3659 */ 3660 assert(i == clazz->ifieldCount || (fieldOffset & 0x04) == 0); 3661 j = clazz->ifieldCount - 1; 3662 for ( ; i < clazz->ifieldCount; i++) { 3663 InstField* pField = &clazz->ifields[i]; 3664 char c = pField->field.signature[0]; 3665 3666 if (c != 'D' && c != 'J') { 3667 /* This isn't a double-wide field; see if any double fields 3668 * follow this one. If so, we'll move it to this position. 3669 * (quicksort-style partitioning) 3670 */ 3671 while (j > i) { 3672 InstField* doubleField = &clazz->ifields[j--]; 3673 char rc = doubleField->field.signature[0]; 3674 3675 if (rc == 'D' || rc == 'J') { 3676 /* Here's a double-wide field that follows at least one 3677 * non-double field. Swap it with the current field. 3678 * (When this returns, "pField" points to the reference 3679 * field, and "doubleField" points to the non-double field.) 3680 */ 3681 swapField(pField, doubleField); 3682 c = rc; 3683 3684 break; 3685 } 3686 } 3687 /* We may or may not have swapped a field. 3688 */ 3689 } else { 3690 /* This is a double-wide field, leave it be. 3691 */ 3692 } 3693 3694 pField->byteOffset = fieldOffset; 3695 LOGVV(" --- offset4 '%s'=%d\n", pField->field.name,pField->byteOffset); 3696 fieldOffset += sizeof(u4); 3697 if (c == 'J' || c == 'D') 3698 fieldOffset += sizeof(u4); 3699 } 3700 3701#ifndef NDEBUG 3702 /* Make sure that all reference fields appear before 3703 * non-reference fields, and all double-wide fields are aligned. 3704 */ 3705 j = 0; // seen non-ref 3706 for (i = 0; i < clazz->ifieldCount; i++) { 3707 InstField *pField = &clazz->ifields[i]; 3708 char c = pField->field.signature[0]; 3709 3710 if (c == 'D' || c == 'J') { 3711 assert((pField->byteOffset & 0x07) == 0); 3712 } 3713 3714 if (c != '[' && c != 'L') { 3715 if (!j) { 3716 assert(i == clazz->ifieldRefCount); 3717 j = 1; 3718 } 3719 } else if (j) { 3720 assert(false); 3721 } 3722 } 3723 if (!j) { 3724 assert(clazz->ifieldRefCount == clazz->ifieldCount); 3725 } 3726#endif 3727 3728 /* 3729 * We map a C struct directly on top of java/lang/Class objects. Make 3730 * sure we left enough room for the instance fields. 3731 */ 3732 assert(clazz != gDvm.classJavaLangClass || (size_t)fieldOffset < 3733 offsetof(ClassObject, instanceData) + sizeof(clazz->instanceData)); 3734 3735 clazz->objectSize = fieldOffset; 3736 3737 dvmLinearReadOnly(clazz->classLoader, clazz->ifields); 3738 return true; 3739} 3740 3741/* 3742 * Throw the VM-spec-mandated error when an exception is thrown during 3743 * class initialization. 3744 * 3745 * The safest way to do this is to call the ExceptionInInitializerError 3746 * constructor that takes a Throwable. 3747 * 3748 * [Do we want to wrap it if the original is an Error rather than 3749 * an Exception?] 3750 */ 3751static void throwClinitError(void) 3752{ 3753 Thread* self = dvmThreadSelf(); 3754 Object* exception; 3755 Object* eiie; 3756 3757 exception = dvmGetException(self); 3758 dvmAddTrackedAlloc(exception, self); 3759 dvmClearException(self); 3760 3761 if (gDvm.classJavaLangExceptionInInitializerError == NULL) { 3762 /* 3763 * Always resolves to same thing -- no race condition. 3764 */ 3765 gDvm.classJavaLangExceptionInInitializerError = 3766 dvmFindSystemClass( 3767 "Ljava/lang/ExceptionInInitializerError;"); 3768 if (gDvm.classJavaLangExceptionInInitializerError == NULL) { 3769 LOGE("Unable to prep java/lang/ExceptionInInitializerError\n"); 3770 goto fail; 3771 } 3772 3773 gDvm.methJavaLangExceptionInInitializerError_init = 3774 dvmFindDirectMethodByDescriptor(gDvm.classJavaLangExceptionInInitializerError, 3775 "<init>", "(Ljava/lang/Throwable;)V"); 3776 if (gDvm.methJavaLangExceptionInInitializerError_init == NULL) { 3777 LOGE("Unable to prep java/lang/ExceptionInInitializerError\n"); 3778 goto fail; 3779 } 3780 } 3781 3782 eiie = dvmAllocObject(gDvm.classJavaLangExceptionInInitializerError, 3783 ALLOC_DEFAULT); 3784 if (eiie == NULL) 3785 goto fail; 3786 3787 /* 3788 * Construct the new object, and replace the exception with it. 3789 */ 3790 JValue unused; 3791 dvmCallMethod(self, gDvm.methJavaLangExceptionInInitializerError_init, 3792 eiie, &unused, exception); 3793 dvmSetException(self, eiie); 3794 dvmReleaseTrackedAlloc(eiie, NULL); 3795 dvmReleaseTrackedAlloc(exception, self); 3796 return; 3797 3798fail: /* restore original exception */ 3799 dvmSetException(self, exception); 3800 dvmReleaseTrackedAlloc(exception, self); 3801 return; 3802} 3803 3804/* 3805 * The class failed to initialize on a previous attempt, so we want to throw 3806 * a NoClassDefFoundError (v2 2.17.5). The exception to this rule is if we 3807 * failed in verification, in which case v2 5.4.1 says we need to re-throw 3808 * the previous error. 3809 */ 3810static void throwEarlierClassFailure(ClassObject* clazz) 3811{ 3812 LOGI("Rejecting re-init on previously-failed class %s v=%p\n", 3813 clazz->descriptor, clazz->verifyErrorClass); 3814 3815 if (clazz->verifyErrorClass == NULL) { 3816 dvmThrowExceptionWithClassMessage("Ljava/lang/NoClassDefFoundError;", 3817 clazz->descriptor); 3818 } else { 3819 dvmThrowExceptionByClassWithClassMessage(clazz->verifyErrorClass, 3820 clazz->descriptor); 3821 } 3822} 3823 3824/* 3825 * Initialize any static fields whose values are stored in 3826 * the DEX file. This must be done during class initialization. 3827 */ 3828static void initSFields(ClassObject* clazz) 3829{ 3830 Thread* self = dvmThreadSelf(); /* for dvmReleaseTrackedAlloc() */ 3831 DexFile* pDexFile; 3832 const DexClassDef* pClassDef; 3833 const DexEncodedArray* pValueList; 3834 EncodedArrayIterator iterator; 3835 int i; 3836 3837 if (clazz->sfieldCount == 0) { 3838 return; 3839 } 3840 if (clazz->pDvmDex == NULL) { 3841 /* generated class; any static fields should already be set up */ 3842 LOGV("Not initializing static fields in %s\n", clazz->descriptor); 3843 return; 3844 } 3845 pDexFile = clazz->pDvmDex->pDexFile; 3846 3847 pClassDef = dexFindClass(pDexFile, clazz->descriptor); 3848 assert(pClassDef != NULL); 3849 3850 pValueList = dexGetStaticValuesList(pDexFile, pClassDef); 3851 if (pValueList == NULL) { 3852 return; 3853 } 3854 3855 dvmEncodedArrayIteratorInitialize(&iterator, pValueList, clazz); 3856 3857 /* 3858 * Iterate over the initial values array, setting the corresponding 3859 * static field for each array element. 3860 */ 3861 3862 for (i = 0; dvmEncodedArrayIteratorHasNext(&iterator); i++) { 3863 AnnotationValue value; 3864 bool parsed = dvmEncodedArrayIteratorGetNext(&iterator, &value); 3865 StaticField* sfield = &clazz->sfields[i]; 3866 const char* descriptor = sfield->field.signature; 3867 bool needRelease = false; 3868 3869 if (! parsed) { 3870 /* 3871 * TODO: Eventually verification should attempt to ensure 3872 * that this can't happen at least due to a data integrity 3873 * problem. 3874 */ 3875 LOGE("Static initializer parse failed for %s at index %d", 3876 clazz->descriptor, i); 3877 dvmAbort(); 3878 } 3879 3880 /* Verify that the value we got was of a valid type. */ 3881 3882 switch (descriptor[0]) { 3883 case 'Z': parsed = (value.type == kDexAnnotationBoolean); break; 3884 case 'B': parsed = (value.type == kDexAnnotationByte); break; 3885 case 'C': parsed = (value.type == kDexAnnotationChar); break; 3886 case 'S': parsed = (value.type == kDexAnnotationShort); break; 3887 case 'I': parsed = (value.type == kDexAnnotationInt); break; 3888 case 'J': parsed = (value.type == kDexAnnotationLong); break; 3889 case 'F': parsed = (value.type == kDexAnnotationFloat); break; 3890 case 'D': parsed = (value.type == kDexAnnotationDouble); break; 3891 case '[': parsed = (value.type == kDexAnnotationNull); break; 3892 case 'L': { 3893 switch (value.type) { 3894 case kDexAnnotationNull: { 3895 /* No need for further tests. */ 3896 break; 3897 } 3898 case kDexAnnotationString: { 3899 parsed = 3900 (strcmp(descriptor, "Ljava/lang/String;") == 0); 3901 needRelease = true; 3902 break; 3903 } 3904 case kDexAnnotationType: { 3905 parsed = 3906 (strcmp(descriptor, "Ljava/lang/Class;") == 0); 3907 needRelease = true; 3908 break; 3909 } 3910 default: { 3911 parsed = false; 3912 break; 3913 } 3914 } 3915 break; 3916 } 3917 default: { 3918 parsed = false; 3919 break; 3920 } 3921 } 3922 3923 if (parsed) { 3924 /* 3925 * All's well, so store the value. Note: This always 3926 * stores the full width of a JValue, even though most of 3927 * the time only the first word is needed. 3928 */ 3929 sfield->value = value.value; 3930 if (needRelease) { 3931 dvmReleaseTrackedAlloc(value.value.l, self); 3932 } 3933 } else { 3934 /* 3935 * Something up above had a problem. TODO: See comment 3936 * above the switch about verfication. 3937 */ 3938 LOGE("Bogus static initialization: value type %d in field type " 3939 "%s for %s at index %d", 3940 value.type, descriptor, clazz->descriptor, i); 3941 dvmAbort(); 3942 } 3943 } 3944} 3945 3946 3947/* 3948 * Determine whether "descriptor" yields the same class object in the 3949 * context of clazz1 and clazz2. 3950 * 3951 * The caller must hold gDvm.loadedClasses. 3952 * 3953 * Returns "true" if they match. 3954 */ 3955static bool compareDescriptorClasses(const char* descriptor, 3956 const ClassObject* clazz1, const ClassObject* clazz2) 3957{ 3958 ClassObject* result1; 3959 ClassObject* result2; 3960 3961 /* 3962 * Do the first lookup by name. 3963 */ 3964 result1 = dvmFindClassNoInit(descriptor, clazz1->classLoader); 3965 3966 /* 3967 * We can skip a second lookup by name if the second class loader is 3968 * in the initiating loader list of the class object we retrieved. 3969 * (This means that somebody already did a lookup of this class through 3970 * the second loader, and it resolved to the same class.) If it's not 3971 * there, we may simply not have had an opportunity to add it yet, so 3972 * we do the full lookup. 3973 * 3974 * The initiating loader test should catch the majority of cases 3975 * (in particular, the zillions of references to String/Object). 3976 * 3977 * Unfortunately we're still stuck grabbing a mutex to do the lookup. 3978 * 3979 * For this to work, the superclass/interface should be the first 3980 * argument, so that way if it's from the bootstrap loader this test 3981 * will work. (The bootstrap loader, by definition, never shows up 3982 * as the initiating loader of a class defined by some other loader.) 3983 */ 3984 dvmHashTableLock(gDvm.loadedClasses); 3985 bool isInit = dvmLoaderInInitiatingList(result1, clazz2->classLoader); 3986 dvmHashTableUnlock(gDvm.loadedClasses); 3987 3988 if (isInit) { 3989 //printf("%s(obj=%p) / %s(cl=%p): initiating\n", 3990 // result1->descriptor, result1, 3991 // clazz2->descriptor, clazz2->classLoader); 3992 return true; 3993 } else { 3994 //printf("%s(obj=%p) / %s(cl=%p): RAW\n", 3995 // result1->descriptor, result1, 3996 // clazz2->descriptor, clazz2->classLoader); 3997 result2 = dvmFindClassNoInit(descriptor, clazz2->classLoader); 3998 } 3999 4000 if (result1 == NULL || result2 == NULL) { 4001 dvmClearException(dvmThreadSelf()); 4002 if (result1 == result2) { 4003 /* 4004 * Neither class loader could find this class. Apparently it 4005 * doesn't exist. 4006 * 4007 * We can either throw some sort of exception now, or just 4008 * assume that it'll fail later when something actually tries 4009 * to use the class. For strict handling we should throw now, 4010 * because a "tricky" class loader could start returning 4011 * something later, and a pair of "tricky" loaders could set 4012 * us up for confusion. 4013 * 4014 * I'm not sure if we're allowed to complain about nonexistent 4015 * classes in method signatures during class init, so for now 4016 * this will just return "true" and let nature take its course. 4017 */ 4018 return true; 4019 } else { 4020 /* only one was found, so clearly they're not the same */ 4021 return false; 4022 } 4023 } 4024 4025 return result1 == result2; 4026} 4027 4028/* 4029 * For every component in the method descriptor, resolve the class in the 4030 * context of the two classes and compare the results. 4031 * 4032 * For best results, the "superclass" class should be first. 4033 * 4034 * Returns "true" if the classes match, "false" otherwise. 4035 */ 4036static bool checkMethodDescriptorClasses(const Method* meth, 4037 const ClassObject* clazz1, const ClassObject* clazz2) 4038{ 4039 DexParameterIterator iterator; 4040 const char* descriptor; 4041 4042 /* walk through the list of parameters */ 4043 dexParameterIteratorInit(&iterator, &meth->prototype); 4044 while (true) { 4045 descriptor = dexParameterIteratorNextDescriptor(&iterator); 4046 4047 if (descriptor == NULL) 4048 break; 4049 4050 if (descriptor[0] == 'L' || descriptor[0] == '[') { 4051 /* non-primitive type */ 4052 if (!compareDescriptorClasses(descriptor, clazz1, clazz2)) 4053 return false; 4054 } 4055 } 4056 4057 /* check the return type */ 4058 descriptor = dexProtoGetReturnType(&meth->prototype); 4059 if (descriptor[0] == 'L' || descriptor[0] == '[') { 4060 if (!compareDescriptorClasses(descriptor, clazz1, clazz2)) 4061 return false; 4062 } 4063 return true; 4064} 4065 4066/* 4067 * Validate the descriptors in the superclass and interfaces. 4068 * 4069 * What we need to do is ensure that the classes named in the method 4070 * descriptors in our ancestors and ourselves resolve to the same class 4071 * objects. We can get conflicts when the classes come from different 4072 * class loaders, and the resolver comes up with different results for 4073 * the same class name in different contexts. 4074 * 4075 * An easy way to cause the problem is to declare a base class that uses 4076 * class Foo in a method signature (e.g. as the return type). Then, 4077 * define a subclass and a different version of Foo, and load them from a 4078 * different class loader. If the subclass overrides the method, it will 4079 * have a different concept of what Foo is than its parent does, so even 4080 * though the method signature strings are identical, they actually mean 4081 * different things. 4082 * 4083 * A call to the method through a base-class reference would be treated 4084 * differently than a call to the method through a subclass reference, which 4085 * isn't the way polymorphism works, so we have to reject the subclass. 4086 * If the subclass doesn't override the base method, then there's no 4087 * problem, because calls through base-class references and subclass 4088 * references end up in the same place. 4089 * 4090 * We don't need to check to see if an interface's methods match with its 4091 * superinterface's methods, because you can't instantiate an interface 4092 * and do something inappropriate with it. If interface I1 extends I2 4093 * and is implemented by C, and I1 and I2 are in separate class loaders 4094 * and have conflicting views of other classes, we will catch the conflict 4095 * when we process C. Anything that implements I1 is doomed to failure, 4096 * but we don't need to catch that while processing I1. 4097 * 4098 * On failure, throws an exception and returns "false". 4099 */ 4100static bool validateSuperDescriptors(const ClassObject* clazz) 4101{ 4102 int i; 4103 4104 if (dvmIsInterfaceClass(clazz)) 4105 return true; 4106 4107 /* 4108 * Start with the superclass-declared methods. 4109 */ 4110 if (clazz->super != NULL && 4111 clazz->classLoader != clazz->super->classLoader) 4112 { 4113 /* 4114 * Walk through every overridden method and compare resolved 4115 * descriptor components. We pull the Method structs out of 4116 * the vtable. It doesn't matter whether we get the struct from 4117 * the parent or child, since we just need the UTF-8 descriptor, 4118 * which must match. 4119 * 4120 * We need to do this even for the stuff inherited from Object, 4121 * because it's possible that the new class loader has redefined 4122 * a basic class like String. 4123 * 4124 * We don't need to check stuff defined in a superclass because 4125 * it was checked when the superclass was loaded. 4126 */ 4127 const Method* meth; 4128 4129 //printf("Checking %s %p vs %s %p\n", 4130 // clazz->descriptor, clazz->classLoader, 4131 // clazz->super->descriptor, clazz->super->classLoader); 4132 for (i = clazz->super->vtableCount - 1; i >= 0; i--) { 4133 meth = clazz->vtable[i]; 4134 if (meth != clazz->super->vtable[i] && 4135 !checkMethodDescriptorClasses(meth, clazz->super, clazz)) 4136 { 4137 LOGW("Method mismatch: %s in %s (cl=%p) and super %s (cl=%p)\n", 4138 meth->name, clazz->descriptor, clazz->classLoader, 4139 clazz->super->descriptor, clazz->super->classLoader); 4140 dvmThrowException("Ljava/lang/LinkageError;", 4141 "Classes resolve differently in superclass"); 4142 return false; 4143 } 4144 } 4145 } 4146 4147 /* 4148 * Check the methods defined by this class against the interfaces it 4149 * implements. If we inherited the implementation from a superclass, 4150 * we have to check it against the superclass (which might be in a 4151 * different class loader). If the superclass also implements the 4152 * interface, we could skip the check since by definition it was 4153 * performed when the class was loaded. 4154 */ 4155 for (i = 0; i < clazz->iftableCount; i++) { 4156 const InterfaceEntry* iftable = &clazz->iftable[i]; 4157 4158 if (clazz->classLoader != iftable->clazz->classLoader) { 4159 const ClassObject* iface = iftable->clazz; 4160 int j; 4161 4162 for (j = 0; j < iface->virtualMethodCount; j++) { 4163 const Method* meth; 4164 int vtableIndex; 4165 4166 vtableIndex = iftable->methodIndexArray[j]; 4167 meth = clazz->vtable[vtableIndex]; 4168 4169 if (!checkMethodDescriptorClasses(meth, iface, meth->clazz)) { 4170 LOGW("Method mismatch: %s in %s (cl=%p) and " 4171 "iface %s (cl=%p)\n", 4172 meth->name, clazz->descriptor, clazz->classLoader, 4173 iface->descriptor, iface->classLoader); 4174 dvmThrowException("Ljava/lang/LinkageError;", 4175 "Classes resolve differently in interface"); 4176 return false; 4177 } 4178 } 4179 } 4180 } 4181 4182 return true; 4183} 4184 4185/* 4186 * Returns true if the class is being initialized by us (which means that 4187 * calling dvmInitClass will return immediately after fiddling with locks). 4188 * 4189 * There isn't a race here, because either clazz->initThreadId won't match 4190 * us, or it will and it was set in the same thread. 4191 */ 4192bool dvmIsClassInitializing(const ClassObject* clazz) 4193{ 4194 return (clazz->status == CLASS_INITIALIZING && 4195 clazz->initThreadId == dvmThreadSelf()->threadId); 4196} 4197 4198/* 4199 * If a class has not been initialized, do so by executing the code in 4200 * <clinit>. The sequence is described in the VM spec v2 2.17.5. 4201 * 4202 * It is possible for multiple threads to arrive here simultaneously, so 4203 * we need to lock the class while we check stuff. We know that no 4204 * interpreted code has access to the class yet, so we can use the class's 4205 * monitor lock. 4206 * 4207 * We will often be called recursively, e.g. when the <clinit> code resolves 4208 * one of its fields, the field resolution will try to initialize the class. 4209 * In that case we will return "true" even though the class isn't actually 4210 * ready to go. The ambiguity can be resolved with dvmIsClassInitializing(). 4211 * (TODO: consider having this return an enum to avoid the extra call -- 4212 * return -1 on failure, 0 on success, 1 on still-initializing. Looks like 4213 * dvmIsClassInitializing() is always paired with *Initialized()) 4214 * 4215 * This can get very interesting if a class has a static field initialized 4216 * to a new instance of itself. <clinit> will end up calling <init> on 4217 * the members it is initializing, which is fine unless it uses the contents 4218 * of static fields to initialize instance fields. This will leave the 4219 * static-referenced objects in a partially initialized state. This is 4220 * reasonably rare and can sometimes be cured with proper field ordering. 4221 * 4222 * On failure, returns "false" with an exception raised. 4223 * 4224 * ----- 4225 * 4226 * It is possible to cause a deadlock by having a situation like this: 4227 * class A { static { sleep(10000); new B(); } } 4228 * class B { static { sleep(10000); new A(); } } 4229 * new Thread() { public void run() { new A(); } }.start(); 4230 * new Thread() { public void run() { new B(); } }.start(); 4231 * This appears to be expected under the spec. 4232 * 4233 * The interesting question is what to do if somebody calls Thread.interrupt() 4234 * on one of the deadlocked threads. According to the VM spec, they're both 4235 * sitting in "wait". Should the interrupt code quietly raise the 4236 * "interrupted" flag, or should the "wait" return immediately with an 4237 * exception raised? 4238 * 4239 * This gets a little murky. The VM spec says we call "wait", and the 4240 * spec for Thread.interrupt says Object.wait is interruptible. So it 4241 * seems that, if we get unlucky and interrupt class initialization, we 4242 * are expected to throw (which gets converted to ExceptionInInitializerError 4243 * since InterruptedException is checked). 4244 * 4245 * There are a couple of problems here. First, all threads are expected to 4246 * present a consistent view of class initialization, so we can't have it 4247 * fail in one thread and succeed in another. Second, once a class fails 4248 * to initialize, it must *always* fail. This means that a stray interrupt() 4249 * call could render a class unusable for the lifetime of the VM. 4250 * 4251 * In most cases -- the deadlock example above being a counter-example -- 4252 * the interrupting thread can't tell whether the target thread handled 4253 * the initialization itself or had to wait while another thread did the 4254 * work. Refusing to interrupt class initialization is, in most cases, 4255 * not something that a program can reliably detect. 4256 * 4257 * On the assumption that interrupting class initialization is highly 4258 * undesirable in most circumstances, and that failing to do so does not 4259 * deviate from the spec in a meaningful way, we don't allow class init 4260 * to be interrupted by Thread.interrupt(). 4261 */ 4262bool dvmInitClass(ClassObject* clazz) 4263{ 4264#if LOG_CLASS_LOADING 4265 bool initializedByUs = false; 4266#endif 4267 4268 Thread* self = dvmThreadSelf(); 4269 const Method* method; 4270 4271 dvmLockObject(self, (Object*) clazz); 4272 assert(dvmIsClassLinked(clazz) || clazz->status == CLASS_ERROR); 4273 4274 /* 4275 * If the class hasn't been verified yet, do so now. 4276 */ 4277 if (clazz->status < CLASS_VERIFIED) { 4278 /* 4279 * If we're in an "erroneous" state, throw an exception and bail. 4280 */ 4281 if (clazz->status == CLASS_ERROR) { 4282 throwEarlierClassFailure(clazz); 4283 goto bail_unlock; 4284 } 4285 4286 assert(clazz->status == CLASS_RESOLVED); 4287 assert(!IS_CLASS_FLAG_SET(clazz, CLASS_ISPREVERIFIED)); 4288 4289 if (gDvm.classVerifyMode == VERIFY_MODE_NONE || 4290 (gDvm.classVerifyMode == VERIFY_MODE_REMOTE && 4291 clazz->classLoader == NULL)) 4292 { 4293 /* advance to "verified" state */ 4294 LOGV("+++ not verifying class %s (cl=%p)\n", 4295 clazz->descriptor, clazz->classLoader); 4296 clazz->status = CLASS_VERIFIED; 4297 goto noverify; 4298 } 4299 4300 if (!gDvm.optimizing) 4301 LOGV("+++ late verify on %s\n", clazz->descriptor); 4302 4303 /* 4304 * We're not supposed to optimize an unverified class, but during 4305 * development this mode was useful. We can't verify an optimized 4306 * class because the optimization process discards information. 4307 */ 4308 if (IS_CLASS_FLAG_SET(clazz, CLASS_ISOPTIMIZED)) { 4309 LOGW("Class '%s' was optimized without verification; " 4310 "not verifying now\n", 4311 clazz->descriptor); 4312 LOGW(" ('rm /data/dalvik-cache/*' and restart to fix this)"); 4313 goto verify_failed; 4314 } 4315 4316 clazz->status = CLASS_VERIFYING; 4317 if (!dvmVerifyClass(clazz, VERIFY_DEFAULT)) { 4318verify_failed: 4319 dvmThrowExceptionWithClassMessage("Ljava/lang/VerifyError;", 4320 clazz->descriptor); 4321 clazz->verifyErrorClass = dvmGetException(self)->clazz; 4322 clazz->status = CLASS_ERROR; 4323 goto bail_unlock; 4324 } 4325 4326 clazz->status = CLASS_VERIFIED; 4327 } 4328noverify: 4329 4330#ifdef WITH_DEBUGGER 4331 /* update instruction stream now that the verifier is done */ 4332 dvmFlushBreakpoints(clazz); 4333#endif 4334 4335 if (clazz->status == CLASS_INITIALIZED) 4336 goto bail_unlock; 4337 4338 while (clazz->status == CLASS_INITIALIZING) { 4339 /* we caught somebody else in the act; was it us? */ 4340 if (clazz->initThreadId == self->threadId) { 4341 //LOGV("HEY: found a recursive <clinit>\n"); 4342 goto bail_unlock; 4343 } 4344 4345 if (dvmCheckException(self)) { 4346 LOGW("GLITCH: exception pending at start of class init\n"); 4347 dvmAbort(); 4348 } 4349 4350 /* 4351 * Wait for the other thread to finish initialization. We pass 4352 * "false" for the "interruptShouldThrow" arg so it doesn't throw 4353 * an exception on interrupt. 4354 */ 4355 dvmObjectWait(self, (Object*) clazz, 0, 0, false); 4356 4357 /* 4358 * When we wake up, repeat the test for init-in-progress. If there's 4359 * an exception pending (only possible if "interruptShouldThrow" 4360 * was set), bail out. 4361 */ 4362 if (dvmCheckException(self)) { 4363 LOGI("Class init of '%s' failing with wait() exception\n", 4364 clazz->descriptor); 4365 /* 4366 * TODO: this is bogus, because it means the two threads have a 4367 * different idea of the class status. We need to flag the 4368 * class as bad and ensure that the initializer thread respects 4369 * our notice. If we get lucky and wake up after the class has 4370 * finished initialization but before being woken, we have to 4371 * swallow the exception, perhaps raising thread->interrupted 4372 * to preserve semantics. 4373 * 4374 * Since we're not currently allowing interrupts, this should 4375 * never happen and we don't need to fix this. 4376 */ 4377 assert(false); 4378 throwClinitError(); 4379 clazz->status = CLASS_ERROR; 4380 goto bail_unlock; 4381 } 4382 if (clazz->status == CLASS_INITIALIZING) { 4383 LOGI("Waiting again for class init\n"); 4384 continue; 4385 } 4386 assert(clazz->status == CLASS_INITIALIZED || 4387 clazz->status == CLASS_ERROR); 4388 if (clazz->status == CLASS_ERROR) { 4389 /* 4390 * The caller wants an exception, but it was thrown in a 4391 * different thread. Synthesize one here. 4392 */ 4393 dvmThrowException("Ljava/lang/UnsatisfiedLinkError;", 4394 "(<clinit> failed, see exception in other thread)"); 4395 } 4396 goto bail_unlock; 4397 } 4398 4399 /* see if we failed previously */ 4400 if (clazz->status == CLASS_ERROR) { 4401 // might be wise to unlock before throwing; depends on which class 4402 // it is that we have locked 4403 dvmUnlockObject(self, (Object*) clazz); 4404 throwEarlierClassFailure(clazz); 4405 return false; 4406 } 4407 4408#ifdef WITH_PROFILER 4409 u8 startWhen = 0; 4410 if (gDvm.allocProf.enabled) { 4411 startWhen = dvmGetRelativeTimeNsec(); 4412 } 4413#endif 4414 4415 /* 4416 * We're ready to go, and have exclusive access to the class. 4417 * 4418 * Before we start initialization, we need to do one extra bit of 4419 * validation: make sure that the methods declared here match up 4420 * with our superclass and interfaces. We know that the UTF-8 4421 * descriptors match, but classes from different class loaders can 4422 * have the same name. 4423 * 4424 * We do this now, rather than at load/link time, for the same reason 4425 * that we defer verification. 4426 * 4427 * It's unfortunate that we need to do this at all, but we risk 4428 * mixing reference types with identical names (see Dalvik test 068). 4429 */ 4430 if (!validateSuperDescriptors(clazz)) { 4431 assert(dvmCheckException(self)); 4432 clazz->status = CLASS_ERROR; 4433 goto bail_unlock; 4434 } 4435 4436 /* 4437 * Let's initialize this thing. 4438 * 4439 * We unlock the object so that other threads can politely sleep on 4440 * our mutex with Object.wait(), instead of hanging or spinning trying 4441 * to grab our mutex. 4442 */ 4443 assert(clazz->status < CLASS_INITIALIZING); 4444 4445#if LOG_CLASS_LOADING 4446 // We started initializing. 4447 logClassLoad('+', clazz); 4448 initializedByUs = true; 4449#endif 4450 4451 clazz->status = CLASS_INITIALIZING; 4452 clazz->initThreadId = self->threadId; 4453 dvmUnlockObject(self, (Object*) clazz); 4454 4455 /* init our superclass */ 4456 if (clazz->super != NULL && clazz->super->status != CLASS_INITIALIZED) { 4457 assert(!dvmIsInterfaceClass(clazz)); 4458 if (!dvmInitClass(clazz->super)) { 4459 assert(dvmCheckException(self)); 4460 clazz->status = CLASS_ERROR; 4461 /* wake up anybody who started waiting while we were unlocked */ 4462 dvmLockObject(self, (Object*) clazz); 4463 goto bail_notify; 4464 } 4465 } 4466 4467 /* Initialize any static fields whose values are 4468 * stored in the Dex file. This should include all of the 4469 * simple "final static" fields, which are required to 4470 * be initialized first. (vmspec 2 sec 2.17.5 item 8) 4471 * More-complicated final static fields should be set 4472 * at the beginning of <clinit>; all we can do is trust 4473 * that the compiler did the right thing. 4474 */ 4475 initSFields(clazz); 4476 4477 /* Execute any static initialization code. 4478 */ 4479 method = dvmFindDirectMethodByDescriptor(clazz, "<clinit>", "()V"); 4480 if (method == NULL) { 4481 LOGVV("No <clinit> found for %s\n", clazz->descriptor); 4482 } else { 4483 LOGVV("Invoking %s.<clinit>\n", clazz->descriptor); 4484 JValue unused; 4485 dvmCallMethod(self, method, NULL, &unused); 4486 } 4487 4488 if (dvmCheckException(self)) { 4489 /* 4490 * We've had an exception thrown during static initialization. We 4491 * need to throw an ExceptionInInitializerError, but we want to 4492 * tuck the original exception into the "cause" field. 4493 */ 4494 LOGW("Exception %s thrown during %s.<clinit>\n", 4495 (dvmGetException(self)->clazz)->descriptor, clazz->descriptor); 4496 throwClinitError(); 4497 //LOGW("+++ replaced\n"); 4498 4499 dvmLockObject(self, (Object*) clazz); 4500 clazz->status = CLASS_ERROR; 4501 } else { 4502 /* success! */ 4503 dvmLockObject(self, (Object*) clazz); 4504 clazz->status = CLASS_INITIALIZED; 4505 LOGVV("Initialized class: %s\n", clazz->descriptor); 4506 4507#ifdef WITH_PROFILER 4508 /* 4509 * Update alloc counters. TODO: guard with mutex. 4510 */ 4511 if (gDvm.allocProf.enabled && startWhen != 0) { 4512 u8 initDuration = dvmGetRelativeTimeNsec() - startWhen; 4513 gDvm.allocProf.classInitTime += initDuration; 4514 self->allocProf.classInitTime += initDuration; 4515 gDvm.allocProf.classInitCount++; 4516 self->allocProf.classInitCount++; 4517 } 4518#endif 4519 } 4520 4521bail_notify: 4522 /* 4523 * Notify anybody waiting on the object. 4524 */ 4525 dvmObjectNotifyAll(self, (Object*) clazz); 4526 4527bail_unlock: 4528 4529#if LOG_CLASS_LOADING 4530 if (initializedByUs) { 4531 // We finished initializing. 4532 logClassLoad('-', clazz); 4533 } 4534#endif 4535 4536 dvmUnlockObject(self, (Object*) clazz); 4537 4538 return (clazz->status != CLASS_ERROR); 4539} 4540 4541/* 4542 * Replace method->nativeFunc and method->insns with new values. This is 4543 * performed on resolution of a native method. 4544 */ 4545void dvmSetNativeFunc(const Method* method, DalvikBridgeFunc func, 4546 const u2* insns) 4547{ 4548 ClassObject* clazz = method->clazz; 4549 4550 /* just open up both; easier that way */ 4551 dvmLinearReadWrite(clazz->classLoader, clazz->virtualMethods); 4552 dvmLinearReadWrite(clazz->classLoader, clazz->directMethods); 4553 4554 ((Method*)method)->nativeFunc = func; 4555 ((Method*)method)->insns = insns; 4556 4557 dvmLinearReadOnly(clazz->classLoader, clazz->virtualMethods); 4558 dvmLinearReadOnly(clazz->classLoader, clazz->directMethods); 4559} 4560 4561/* 4562 * Add a RegisterMap to a Method. This is done when we verify the class 4563 * and compute the register maps at class initialization time (i.e. when 4564 * we don't have a pre-generated map). This means "pMap" is on the heap 4565 * and should be freed when the Method is discarded. 4566 */ 4567void dvmSetRegisterMap(Method* method, const RegisterMap* pMap) 4568{ 4569 ClassObject* clazz = method->clazz; 4570 4571 if (method->registerMap != NULL) { 4572 /* unexpected during class loading, okay on first use (uncompress) */ 4573 LOGV("NOTE: registerMap already set for %s.%s\n", 4574 method->clazz->descriptor, method->name); 4575 /* keep going */ 4576 } 4577 assert(!dvmIsNativeMethod(method) && !dvmIsAbstractMethod(method)); 4578 4579 /* might be virtual or direct */ 4580 dvmLinearReadWrite(clazz->classLoader, clazz->virtualMethods); 4581 dvmLinearReadWrite(clazz->classLoader, clazz->directMethods); 4582 4583 method->registerMap = pMap; 4584 4585 dvmLinearReadOnly(clazz->classLoader, clazz->virtualMethods); 4586 dvmLinearReadOnly(clazz->classLoader, clazz->directMethods); 4587} 4588 4589/* 4590 * dvmHashForeach callback. A nonzero return value causes foreach to 4591 * bail out. 4592 */ 4593static int findClassCallback(void* vclazz, void* arg) 4594{ 4595 ClassObject* clazz = vclazz; 4596 const char* descriptor = (const char*) arg; 4597 4598 if (strcmp(clazz->descriptor, descriptor) == 0) 4599 return (int) clazz; 4600 return 0; 4601} 4602 4603/* 4604 * Find a loaded class by descriptor. Returns the first one found. 4605 * Because there can be more than one if class loaders are involved, 4606 * this is not an especially good API. (Currently only used by the 4607 * debugger and "checking" JNI.) 4608 * 4609 * "descriptor" should have the form "Ljava/lang/Class;" or 4610 * "[Ljava/lang/Class;", i.e. a descriptor and not an internal-form 4611 * class name. 4612 */ 4613ClassObject* dvmFindLoadedClass(const char* descriptor) 4614{ 4615 int result; 4616 4617 dvmHashTableLock(gDvm.loadedClasses); 4618 result = dvmHashForeach(gDvm.loadedClasses, findClassCallback, 4619 (void*) descriptor); 4620 dvmHashTableUnlock(gDvm.loadedClasses); 4621 4622 return (ClassObject*) result; 4623} 4624 4625/* 4626 * Retrieve the system (a/k/a application) class loader. 4627 */ 4628Object* dvmGetSystemClassLoader(void) 4629{ 4630 ClassObject* clazz; 4631 Method* getSysMeth; 4632 Object* loader; 4633 4634 clazz = dvmFindSystemClass("Ljava/lang/ClassLoader;"); 4635 if (clazz == NULL) 4636 return NULL; 4637 4638 getSysMeth = dvmFindDirectMethodByDescriptor(clazz, "getSystemClassLoader", 4639 "()Ljava/lang/ClassLoader;"); 4640 if (getSysMeth == NULL) 4641 return NULL; 4642 4643 JValue result; 4644 dvmCallMethod(dvmThreadSelf(), getSysMeth, NULL, &result); 4645 loader = (Object*)result.l; 4646 return loader; 4647} 4648 4649 4650/* 4651 * This is a dvmHashForeach callback. 4652 */ 4653static int dumpClass(void* vclazz, void* varg) 4654{ 4655 const ClassObject* clazz = (const ClassObject*) vclazz; 4656 const ClassObject* super; 4657 int flags = (int) varg; 4658 char* desc; 4659 int i; 4660 4661 if (clazz == NULL) { 4662 LOGI("dumpClass: ignoring request to dump null class\n"); 4663 return 0; 4664 } 4665 4666 if ((flags & kDumpClassFullDetail) == 0) { 4667 bool showInit = (flags & kDumpClassInitialized) != 0; 4668 bool showLoader = (flags & kDumpClassClassLoader) != 0; 4669 const char* initStr; 4670 4671 initStr = dvmIsClassInitialized(clazz) ? "true" : "false"; 4672 4673 if (showInit && showLoader) 4674 LOGI("%s %p %s\n", clazz->descriptor, clazz->classLoader, initStr); 4675 else if (showInit) 4676 LOGI("%s %s\n", clazz->descriptor, initStr); 4677 else if (showLoader) 4678 LOGI("%s %p\n", clazz->descriptor, clazz->classLoader); 4679 else 4680 LOGI("%s\n", clazz->descriptor); 4681 4682 return 0; 4683 } 4684 4685 /* clazz->super briefly holds the superclass index during class prep */ 4686 if ((u4)clazz->super > 0x10000 && (u4) clazz->super != (u4)-1) 4687 super = clazz->super; 4688 else 4689 super = NULL; 4690 4691 LOGI("----- %s '%s' cl=%p ser=0x%08x -----\n", 4692 dvmIsInterfaceClass(clazz) ? "interface" : "class", 4693 clazz->descriptor, clazz->classLoader, clazz->serialNumber); 4694 LOGI(" objectSize=%d (%d from super)\n", (int) clazz->objectSize, 4695 super != NULL ? (int) super->objectSize : -1); 4696 LOGI(" access=0x%04x.%04x\n", clazz->accessFlags >> 16, 4697 clazz->accessFlags & JAVA_FLAGS_MASK); 4698 if (super != NULL) 4699 LOGI(" super='%s' (cl=%p)\n", super->descriptor, super->classLoader); 4700 if (dvmIsArrayClass(clazz)) { 4701 LOGI(" dimensions=%d elementClass=%s\n", 4702 clazz->arrayDim, clazz->elementClass->descriptor); 4703 } 4704 if (clazz->iftableCount > 0) { 4705 LOGI(" interfaces (%d):\n", clazz->iftableCount); 4706 for (i = 0; i < clazz->iftableCount; i++) { 4707 InterfaceEntry* ent = &clazz->iftable[i]; 4708 int j; 4709 4710 LOGI(" %2d: %s (cl=%p)\n", 4711 i, ent->clazz->descriptor, ent->clazz->classLoader); 4712 4713 /* enable when needed */ 4714 if (false && ent->methodIndexArray != NULL) { 4715 for (j = 0; j < ent->clazz->virtualMethodCount; j++) 4716 LOGI(" %2d: %d %s %s\n", 4717 j, ent->methodIndexArray[j], 4718 ent->clazz->virtualMethods[j].name, 4719 clazz->vtable[ent->methodIndexArray[j]]->name); 4720 } 4721 } 4722 } 4723 if (!dvmIsInterfaceClass(clazz)) { 4724 LOGI(" vtable (%d entries, %d in super):\n", clazz->vtableCount, 4725 super != NULL ? super->vtableCount : 0); 4726 for (i = 0; i < clazz->vtableCount; i++) { 4727 desc = dexProtoCopyMethodDescriptor(&clazz->vtable[i]->prototype); 4728 LOGI(" %s%2d: %p %20s %s\n", 4729 (i != clazz->vtable[i]->methodIndex) ? "*** " : "", 4730 (u4) clazz->vtable[i]->methodIndex, clazz->vtable[i], 4731 clazz->vtable[i]->name, desc); 4732 free(desc); 4733 } 4734 LOGI(" direct methods (%d entries):\n", clazz->directMethodCount); 4735 for (i = 0; i < clazz->directMethodCount; i++) { 4736 desc = dexProtoCopyMethodDescriptor( 4737 &clazz->directMethods[i].prototype); 4738 LOGI(" %2d: %20s %s\n", i, clazz->directMethods[i].name, 4739 desc); 4740 free(desc); 4741 } 4742 } else { 4743 LOGI(" interface methods (%d):\n", clazz->virtualMethodCount); 4744 for (i = 0; i < clazz->virtualMethodCount; i++) { 4745 desc = dexProtoCopyMethodDescriptor( 4746 &clazz->virtualMethods[i].prototype); 4747 LOGI(" %2d: %2d %20s %s\n", i, 4748 (u4) clazz->virtualMethods[i].methodIndex, 4749 clazz->virtualMethods[i].name, 4750 desc); 4751 free(desc); 4752 } 4753 } 4754 if (clazz->sfieldCount > 0) { 4755 LOGI(" static fields (%d entries):\n", clazz->sfieldCount); 4756 for (i = 0; i < clazz->sfieldCount; i++) { 4757 LOGI(" %2d: %20s %s\n", i, clazz->sfields[i].field.name, 4758 clazz->sfields[i].field.signature); 4759 } 4760 } 4761 if (clazz->ifieldCount > 0) { 4762 LOGI(" instance fields (%d entries):\n", clazz->ifieldCount); 4763 for (i = 0; i < clazz->ifieldCount; i++) { 4764 LOGI(" %2d: %20s %s\n", i, clazz->ifields[i].field.name, 4765 clazz->ifields[i].field.signature); 4766 } 4767 } 4768 return 0; 4769} 4770 4771/* 4772 * Dump the contents of a single class. 4773 * 4774 * Pass kDumpClassFullDetail into "flags" to get lots of detail. 4775 */ 4776void dvmDumpClass(const ClassObject* clazz, int flags) 4777{ 4778 dumpClass((void*) clazz, (void*) flags); 4779} 4780 4781/* 4782 * Dump the contents of all classes. 4783 */ 4784void dvmDumpAllClasses(int flags) 4785{ 4786 dvmHashTableLock(gDvm.loadedClasses); 4787 dvmHashForeach(gDvm.loadedClasses, dumpClass, (void*) flags); 4788 dvmHashTableUnlock(gDvm.loadedClasses); 4789} 4790 4791/* 4792 * Get the number of loaded classes 4793 */ 4794int dvmGetNumLoadedClasses() 4795{ 4796 int count; 4797 dvmHashTableLock(gDvm.loadedClasses); 4798 count = dvmHashTableNumEntries(gDvm.loadedClasses); 4799 dvmHashTableUnlock(gDvm.loadedClasses); 4800 return count; 4801} 4802 4803/* 4804 * Write some statistics to the log file. 4805 */ 4806void dvmDumpLoaderStats(const char* msg) 4807{ 4808 LOGV("VM stats (%s): cls=%d/%d meth=%d ifld=%d sfld=%d linear=%d\n", 4809 msg, gDvm.numLoadedClasses, dvmHashTableNumEntries(gDvm.loadedClasses), 4810 gDvm.numDeclaredMethods, gDvm.numDeclaredInstFields, 4811 gDvm.numDeclaredStaticFields, gDvm.pBootLoaderAlloc->curOffset); 4812#ifdef COUNT_PRECISE_METHODS 4813 LOGI("GC precise methods: %d\n", 4814 dvmPointerSetGetCount(gDvm.preciseMethods)); 4815#endif 4816} 4817 4818#ifdef PROFILE_FIELD_ACCESS 4819/* 4820 * Dump the field access counts for all fields in this method. 4821 */ 4822static int dumpAccessCounts(void* vclazz, void* varg) 4823{ 4824 const ClassObject* clazz = (const ClassObject*) vclazz; 4825 int i; 4826 4827 for (i = 0; i < clazz->ifieldCount; i++) { 4828 Field* field = &clazz->ifields[i].field; 4829 4830 if (field->gets != 0) 4831 printf("GI %d %s.%s\n", field->gets, 4832 field->clazz->descriptor, field->name); 4833 if (field->puts != 0) 4834 printf("PI %d %s.%s\n", field->puts, 4835 field->clazz->descriptor, field->name); 4836 } 4837 for (i = 0; i < clazz->sfieldCount; i++) { 4838 Field* field = &clazz->sfields[i].field; 4839 4840 if (field->gets != 0) 4841 printf("GS %d %s.%s\n", field->gets, 4842 field->clazz->descriptor, field->name); 4843 if (field->puts != 0) 4844 printf("PS %d %s.%s\n", field->puts, 4845 field->clazz->descriptor, field->name); 4846 } 4847 4848 return 0; 4849} 4850 4851/* 4852 * Dump the field access counts for all loaded classes. 4853 */ 4854void dvmDumpFieldAccessCounts(void) 4855{ 4856 dvmHashTableLock(gDvm.loadedClasses); 4857 dvmHashForeach(gDvm.loadedClasses, dumpAccessCounts, NULL); 4858 dvmHashTableUnlock(gDvm.loadedClasses); 4859} 4860#endif 4861 4862 4863/* 4864 * Mark all classes associated with the built-in loader. 4865 */ 4866static int markClassObject(void *clazz, void *arg) 4867{ 4868 UNUSED_PARAMETER(arg); 4869 4870 dvmMarkObjectNonNull((Object *)clazz); 4871 return 0; 4872} 4873 4874/* 4875 * The garbage collector calls this to mark the class objects for all 4876 * loaded classes. 4877 */ 4878void dvmGcScanRootClassLoader() 4879{ 4880 /* dvmClassStartup() may not have been called before the first GC. 4881 */ 4882 if (gDvm.unlinkedJavaLangClass != NULL) { 4883 dvmMarkObjectNonNull((Object *)gDvm.unlinkedJavaLangClass); 4884 } 4885 if (gDvm.loadedClasses != NULL) { 4886 dvmHashTableLock(gDvm.loadedClasses); 4887 dvmHashForeach(gDvm.loadedClasses, markClassObject, NULL); 4888 dvmHashTableUnlock(gDvm.loadedClasses); 4889 } 4890} 4891 4892 4893/* 4894 * =========================================================================== 4895 * Method Prototypes and Descriptors 4896 * =========================================================================== 4897 */ 4898 4899/* 4900 * Compare the two method names and prototypes, a la strcmp(). The 4901 * name is considered the "major" order and the prototype the "minor" 4902 * order. The prototypes are compared as if by dvmCompareMethodProtos(). 4903 */ 4904int dvmCompareMethodNamesAndProtos(const Method* method1, 4905 const Method* method2) 4906{ 4907 int result = strcmp(method1->name, method2->name); 4908 4909 if (result != 0) { 4910 return result; 4911 } 4912 4913 return dvmCompareMethodProtos(method1, method2); 4914} 4915 4916/* 4917 * Compare the two method names and prototypes, a la strcmp(), ignoring 4918 * the return value. The name is considered the "major" order and the 4919 * prototype the "minor" order. The prototypes are compared as if by 4920 * dvmCompareMethodArgProtos(). 4921 */ 4922int dvmCompareMethodNamesAndParameterProtos(const Method* method1, 4923 const Method* method2) 4924{ 4925 int result = strcmp(method1->name, method2->name); 4926 4927 if (result != 0) { 4928 return result; 4929 } 4930 4931 return dvmCompareMethodParameterProtos(method1, method2); 4932} 4933 4934/* 4935 * Compare a (name, prototype) pair with the (name, prototype) of 4936 * a method, a la strcmp(). The name is considered the "major" order and 4937 * the prototype the "minor" order. The descriptor and prototype are 4938 * compared as if by dvmCompareDescriptorAndMethodProto(). 4939 */ 4940int dvmCompareNameProtoAndMethod(const char* name, 4941 const DexProto* proto, const Method* method) 4942{ 4943 int result = strcmp(name, method->name); 4944 4945 if (result != 0) { 4946 return result; 4947 } 4948 4949 return dexProtoCompare(proto, &method->prototype); 4950} 4951 4952/* 4953 * Compare a (name, method descriptor) pair with the (name, prototype) of 4954 * a method, a la strcmp(). The name is considered the "major" order and 4955 * the prototype the "minor" order. The descriptor and prototype are 4956 * compared as if by dvmCompareDescriptorAndMethodProto(). 4957 */ 4958int dvmCompareNameDescriptorAndMethod(const char* name, 4959 const char* descriptor, const Method* method) 4960{ 4961 int result = strcmp(name, method->name); 4962 4963 if (result != 0) { 4964 return result; 4965 } 4966 4967 return dvmCompareDescriptorAndMethodProto(descriptor, method); 4968} 4969 4970size_t dvmClassObjectSize(const ClassObject *clazz) 4971{ 4972 size_t size; 4973 4974 assert(clazz != NULL); 4975 size = offsetof(ClassObject, sfields); 4976 size += sizeof(StaticField) * clazz->sfieldCount; 4977 return size; 4978} 4979