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