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