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