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     ALOG(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     ALOGI("GOT: '%s'", str);
    278 
    279     /* try to check the bounds; allocator may round allocation size up */
    280     fiddle = (char*)dvmLinearAlloc(NULL, 12);
    281     ALOGI("Should be 1: %d", dvmLinearAllocContains(fiddle, 12));
    282     ALOGI("Should be 0: %d", dvmLinearAllocContains(fiddle, 13));
    283     ALOGI("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             ALOGW("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         ALOGE("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         ALOGI("  %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         ALOGD("Unable to stat classpath element '%s'", cpe->fileName);
    609         return false;
    610     }
    611     if (S_ISDIR(sb.st_mode)) {
    612         ALOGE("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         ALOGE("Unknown type suffix '%s'", suffix);
    636     }
    637 
    638     ALOGD("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                 ALOGE("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         ALOGE("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         //ALOGV("+++  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             ALOGE("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     ALOGV("+++ 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         ALOGV("No resources in DEX files");
    914         goto bail;
    915     default:
    916         assert(false);
    917         goto bail;
    918     }
    919 
    920     ALOGV("+++ 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             //ALOGI("+++ 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         //    ALOGW("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             //ALOGI("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     //    ALOGI("+++ %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         ALOGV("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     ALOGV("+++ 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     ALOGV("+++ removeClassFromHash '%s'", clazz->descriptor);
   1218 
   1219     u4 hash = dvmComputeUtf8Hash(clazz->descriptor);
   1220 
   1221     dvmHashTableLock(gDvm.loadedClasses);
   1222     if (!dvmHashTableRemove(gDvm.loadedClasses, hash, clazz))
   1223         ALOGW("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     //ALOGI("##### 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             ALOGD("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             ALOGW("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         ALOGE("Class lookup %s attempted with exception pending", descriptor);
   1499         ALOGW("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             //ALOGW("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             ALOG(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                 ALOGV("Link of class '%s' failed", descriptor);
   1621             } else {
   1622                 ALOGW("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                 ALOGW("Recursive link on class %s", clazz->descriptor);
   1680                 dvmUnlockObject(self, (Object*) clazz);
   1681                 dvmThrowClassCircularityError(clazz->descriptor);
   1682                 clazz = NULL;
   1683                 goto bail;
   1684             }
   1685             //ALOGI("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         //ALOGI("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     /* bits we can reasonably expect to see set in a DEX access flags field */
   1744     const uint32_t EXPECTED_FILE_FLAGS = (ACC_CLASS_MASK | CLASS_ISPREVERIFIED |
   1745                                           CLASS_ISOPTIMIZED);
   1746     if ((pClassDef->accessFlags & ~EXPECTED_FILE_FLAGS) != 0) {
   1747         ALOGW("Invalid file flags in class %s: %04x",
   1748             descriptor, pClassDef->accessFlags);
   1749         return NULL;
   1750     }
   1751 
   1752     /*
   1753      * Allocate storage for the class object on the GC heap, so that other
   1754      * objects can have references to it.  We bypass the usual mechanism
   1755      * (allocObject), because we don't have all the bits and pieces yet.
   1756      *
   1757      * Note that we assume that java.lang.Class does not override
   1758      * finalize().
   1759      */
   1760     /* TODO: Can there be fewer special checks in the usual path? */
   1761     assert(descriptor != NULL);
   1762     if (classLoader == NULL &&
   1763         strcmp(descriptor, "Ljava/lang/Class;") == 0) {
   1764         assert(gDvm.classJavaLangClass != NULL);
   1765         newClass = gDvm.classJavaLangClass;
   1766     } else {
   1767         size_t size = classObjectSize(pHeader->staticFieldsSize);
   1768         newClass = (ClassObject*) dvmMalloc(size, ALLOC_NON_MOVING);
   1769     }
   1770     if (newClass == NULL)
   1771         return NULL;
   1772 
   1773     DVM_OBJECT_INIT(newClass, gDvm.classJavaLangClass);
   1774     dvmSetClassSerialNumber(newClass);
   1775     newClass->descriptor = descriptor;
   1776     assert(newClass->descriptorAlloc == NULL);
   1777     SET_CLASS_FLAG(newClass, pClassDef->accessFlags);
   1778     dvmSetFieldObject((Object *)newClass,
   1779                       OFFSETOF_MEMBER(ClassObject, classLoader),
   1780                       (Object *)classLoader);
   1781     newClass->pDvmDex = pDvmDex;
   1782     newClass->primitiveType = PRIM_NOT;
   1783     newClass->status = CLASS_IDX;
   1784 
   1785     /*
   1786      * Stuff the superclass index into the object pointer field.  The linker
   1787      * pulls it out and replaces it with a resolved ClassObject pointer.
   1788      * I'm doing it this way (rather than having a dedicated superclassIdx
   1789      * field) to save a few bytes of overhead per class.
   1790      *
   1791      * newClass->super is not traversed or freed by dvmFreeClassInnards, so
   1792      * this is safe.
   1793      */
   1794     assert(sizeof(u4) == sizeof(ClassObject*)); /* 32-bit check */
   1795     newClass->super = (ClassObject*) pClassDef->superclassIdx;
   1796 
   1797     /*
   1798      * Stuff class reference indices into the pointer fields.
   1799      *
   1800      * The elements of newClass->interfaces are not traversed or freed by
   1801      * dvmFreeClassInnards, so this is GC-safe.
   1802      */
   1803     const DexTypeList* pInterfacesList;
   1804     pInterfacesList = dexGetInterfacesList(pDexFile, pClassDef);
   1805     if (pInterfacesList != NULL) {
   1806         newClass->interfaceCount = pInterfacesList->size;
   1807         newClass->interfaces = (ClassObject**) dvmLinearAlloc(classLoader,
   1808                 newClass->interfaceCount * sizeof(ClassObject*));
   1809 
   1810         for (i = 0; i < newClass->interfaceCount; i++) {
   1811             const DexTypeItem* pType = dexGetTypeItem(pInterfacesList, i);
   1812             newClass->interfaces[i] = (ClassObject*)(u4) pType->typeIdx;
   1813         }
   1814         dvmLinearReadOnly(classLoader, newClass->interfaces);
   1815     }
   1816 
   1817     /* load field definitions */
   1818 
   1819     /*
   1820      * Over-allocate the class object and append static field info
   1821      * onto the end.  It's fixed-size and known at alloc time.  This
   1822      * seems to increase zygote sharing.  Heap compaction will have to
   1823      * be careful if it ever tries to move ClassObject instances,
   1824      * because we pass Field pointers around internally. But at least
   1825      * now these Field pointers are in the object heap.
   1826      */
   1827 
   1828     if (pHeader->staticFieldsSize != 0) {
   1829         /* static fields stay on system heap; field data isn't "write once" */
   1830         int count = (int) pHeader->staticFieldsSize;
   1831         u4 lastIndex = 0;
   1832         DexField field;
   1833 
   1834         newClass->sfieldCount = count;
   1835         for (i = 0; i < count; i++) {
   1836             dexReadClassDataField(&pEncodedData, &field, &lastIndex);
   1837             loadSFieldFromDex(newClass, &field, &newClass->sfields[i]);
   1838         }
   1839     }
   1840 
   1841     if (pHeader->instanceFieldsSize != 0) {
   1842         int count = (int) pHeader->instanceFieldsSize;
   1843         u4 lastIndex = 0;
   1844         DexField field;
   1845 
   1846         newClass->ifieldCount = count;
   1847         newClass->ifields = (InstField*) dvmLinearAlloc(classLoader,
   1848                 count * sizeof(InstField));
   1849         for (i = 0; i < count; i++) {
   1850             dexReadClassDataField(&pEncodedData, &field, &lastIndex);
   1851             loadIFieldFromDex(newClass, &field, &newClass->ifields[i]);
   1852         }
   1853         dvmLinearReadOnly(classLoader, newClass->ifields);
   1854     }
   1855 
   1856     /*
   1857      * Load method definitions.  We do this in two batches, direct then
   1858      * virtual.
   1859      *
   1860      * If register maps have already been generated for this class, and
   1861      * precise GC is enabled, we pull out pointers to them.  We know that
   1862      * they were streamed to the DEX file in the same order in which the
   1863      * methods appear.
   1864      *
   1865      * If the class wasn't pre-verified, the maps will be generated when
   1866      * the class is verified during class initialization.
   1867      */
   1868     u4 classDefIdx = dexGetIndexForClassDef(pDexFile, pClassDef);
   1869     const void* classMapData;
   1870     u4 numMethods;
   1871 
   1872     if (gDvm.preciseGc) {
   1873         classMapData =
   1874             dvmRegisterMapGetClassData(pDexFile, classDefIdx, &numMethods);
   1875 
   1876         /* sanity check */
   1877         if (classMapData != NULL &&
   1878             pHeader->directMethodsSize + pHeader->virtualMethodsSize != numMethods)
   1879         {
   1880             ALOGE("ERROR: in %s, direct=%d virtual=%d, maps have %d",
   1881                 newClass->descriptor, pHeader->directMethodsSize,
   1882                 pHeader->virtualMethodsSize, numMethods);
   1883             assert(false);
   1884             classMapData = NULL;        /* abandon */
   1885         }
   1886     } else {
   1887         classMapData = NULL;
   1888     }
   1889 
   1890     if (pHeader->directMethodsSize != 0) {
   1891         int count = (int) pHeader->directMethodsSize;
   1892         u4 lastIndex = 0;
   1893         DexMethod method;
   1894 
   1895         newClass->directMethodCount = count;
   1896         newClass->directMethods = (Method*) dvmLinearAlloc(classLoader,
   1897                 count * sizeof(Method));
   1898         for (i = 0; i < count; i++) {
   1899             dexReadClassDataMethod(&pEncodedData, &method, &lastIndex);
   1900             loadMethodFromDex(newClass, &method, &newClass->directMethods[i]);
   1901             if (classMapData != NULL) {
   1902                 const RegisterMap* pMap = dvmRegisterMapGetNext(&classMapData);
   1903                 if (dvmRegisterMapGetFormat(pMap) != kRegMapFormatNone) {
   1904                     newClass->directMethods[i].registerMap = pMap;
   1905                     /* TODO: add rigorous checks */
   1906                     assert((newClass->directMethods[i].registersSize+7) / 8 ==
   1907                         newClass->directMethods[i].registerMap->regWidth);
   1908                 }
   1909             }
   1910         }
   1911         dvmLinearReadOnly(classLoader, newClass->directMethods);
   1912     }
   1913 
   1914     if (pHeader->virtualMethodsSize != 0) {
   1915         int count = (int) pHeader->virtualMethodsSize;
   1916         u4 lastIndex = 0;
   1917         DexMethod method;
   1918 
   1919         newClass->virtualMethodCount = count;
   1920         newClass->virtualMethods = (Method*) dvmLinearAlloc(classLoader,
   1921                 count * sizeof(Method));
   1922         for (i = 0; i < count; i++) {
   1923             dexReadClassDataMethod(&pEncodedData, &method, &lastIndex);
   1924             loadMethodFromDex(newClass, &method, &newClass->virtualMethods[i]);
   1925             if (classMapData != NULL) {
   1926                 const RegisterMap* pMap = dvmRegisterMapGetNext(&classMapData);
   1927                 if (dvmRegisterMapGetFormat(pMap) != kRegMapFormatNone) {
   1928                     newClass->virtualMethods[i].registerMap = pMap;
   1929                     /* TODO: add rigorous checks */
   1930                     assert((newClass->virtualMethods[i].registersSize+7) / 8 ==
   1931                         newClass->virtualMethods[i].registerMap->regWidth);
   1932                 }
   1933             }
   1934         }
   1935         dvmLinearReadOnly(classLoader, newClass->virtualMethods);
   1936     }
   1937 
   1938     newClass->sourceFile = dexGetSourceFile(pDexFile, pClassDef);
   1939 
   1940     /* caller must call dvmReleaseTrackedAlloc */
   1941     return newClass;
   1942 }
   1943 
   1944 /*
   1945  * Try to load the indicated class from the specified DEX file.
   1946  *
   1947  * This is effectively loadClass()+defineClass() for a DexClassDef.  The
   1948  * loading was largely done when we crunched through the DEX.
   1949  *
   1950  * Returns NULL on failure.  If we locate the class but encounter an error
   1951  * while processing it, an appropriate exception is thrown.
   1952  */
   1953 static ClassObject* loadClassFromDex(DvmDex* pDvmDex,
   1954     const DexClassDef* pClassDef, Object* classLoader)
   1955 {
   1956     ClassObject* result;
   1957     DexClassDataHeader header;
   1958     const u1* pEncodedData;
   1959     const DexFile* pDexFile;
   1960 
   1961     assert((pDvmDex != NULL) && (pClassDef != NULL));
   1962     pDexFile = pDvmDex->pDexFile;
   1963 
   1964     if (gDvm.verboseClass) {
   1965         ALOGV("CLASS: loading '%s'...",
   1966             dexGetClassDescriptor(pDexFile, pClassDef));
   1967     }
   1968 
   1969     pEncodedData = dexGetClassData(pDexFile, pClassDef);
   1970 
   1971     if (pEncodedData != NULL) {
   1972         dexReadClassDataHeader(&pEncodedData, &header);
   1973     } else {
   1974         // Provide an all-zeroes header for the rest of the loading.
   1975         memset(&header, 0, sizeof(header));
   1976     }
   1977 
   1978     result = loadClassFromDex0(pDvmDex, pClassDef, &header, pEncodedData,
   1979             classLoader);
   1980 
   1981     if (gDvm.verboseClass && (result != NULL)) {
   1982         ALOGI("[Loaded %s from DEX %p (cl=%p)]",
   1983             result->descriptor, pDvmDex, classLoader);
   1984     }
   1985 
   1986     return result;
   1987 }
   1988 
   1989 /*
   1990  * Free anything in a ClassObject that was allocated on the system heap.
   1991  *
   1992  * The ClassObject itself is allocated on the GC heap, so we leave it for
   1993  * the garbage collector.
   1994  *
   1995  * NOTE: this may be called with a partially-constructed object.
   1996  * NOTE: there is no particular ordering imposed, so don't go poking at
   1997  * superclasses.
   1998  */
   1999 void dvmFreeClassInnards(ClassObject* clazz)
   2000 {
   2001     void *tp;
   2002     int i;
   2003 
   2004     if (clazz == NULL)
   2005         return;
   2006 
   2007     assert(clazz->clazz == gDvm.classJavaLangClass);
   2008     assert(dvmIsClassObject(clazz));
   2009 
   2010     /* Guarantee that dvmFreeClassInnards can be called on a given
   2011      * class multiple times by clearing things out as we free them.
   2012      * We don't make any attempt at real atomicity here; higher
   2013      * levels need to make sure that no two threads can free the
   2014      * same ClassObject at the same time.
   2015      *
   2016      * TODO: maybe just make it so the GC will never free the
   2017      * innards of an already-freed class.
   2018      *
   2019      * TODO: this #define isn't MT-safe -- the compiler could rearrange it.
   2020      */
   2021 #define NULL_AND_FREE(p) \
   2022     do { \
   2023         if ((p) != NULL) { \
   2024             tp = (p); \
   2025             (p) = NULL; \
   2026             free(tp); \
   2027         } \
   2028     } while (0)
   2029 #define NULL_AND_LINEAR_FREE(p) \
   2030     do { \
   2031         if ((p) != NULL) { \
   2032             tp = (p); \
   2033             (p) = NULL; \
   2034             dvmLinearFree(clazz->classLoader, tp); \
   2035         } \
   2036     } while (0)
   2037 
   2038     /* arrays just point at Object's vtable; don't free vtable in this case.
   2039      */
   2040     clazz->vtableCount = -1;
   2041     if (clazz->vtable == gDvm.classJavaLangObject->vtable) {
   2042         clazz->vtable = NULL;
   2043     } else {
   2044         NULL_AND_LINEAR_FREE(clazz->vtable);
   2045     }
   2046 
   2047     clazz->descriptor = NULL;
   2048     NULL_AND_FREE(clazz->descriptorAlloc);
   2049 
   2050     if (clazz->directMethods != NULL) {
   2051         Method *directMethods = clazz->directMethods;
   2052         int directMethodCount = clazz->directMethodCount;
   2053         clazz->directMethods = NULL;
   2054         clazz->directMethodCount = -1;
   2055         dvmLinearReadWrite(clazz->classLoader, directMethods);
   2056         for (i = 0; i < directMethodCount; i++) {
   2057             freeMethodInnards(&directMethods[i]);
   2058         }
   2059         dvmLinearReadOnly(clazz->classLoader, directMethods);
   2060         dvmLinearFree(clazz->classLoader, directMethods);
   2061     }
   2062     if (clazz->virtualMethods != NULL) {
   2063         Method *virtualMethods = clazz->virtualMethods;
   2064         int virtualMethodCount = clazz->virtualMethodCount;
   2065         clazz->virtualMethodCount = -1;
   2066         clazz->virtualMethods = NULL;
   2067         dvmLinearReadWrite(clazz->classLoader, virtualMethods);
   2068         for (i = 0; i < virtualMethodCount; i++) {
   2069             freeMethodInnards(&virtualMethods[i]);
   2070         }
   2071         dvmLinearReadOnly(clazz->classLoader, virtualMethods);
   2072         dvmLinearFree(clazz->classLoader, virtualMethods);
   2073     }
   2074 
   2075     InitiatingLoaderList *loaderList = dvmGetInitiatingLoaderList(clazz);
   2076     loaderList->initiatingLoaderCount = -1;
   2077     NULL_AND_FREE(loaderList->initiatingLoaders);
   2078 
   2079     clazz->interfaceCount = -1;
   2080     NULL_AND_LINEAR_FREE(clazz->interfaces);
   2081 
   2082     clazz->iftableCount = -1;
   2083     NULL_AND_LINEAR_FREE(clazz->iftable);
   2084 
   2085     clazz->ifviPoolCount = -1;
   2086     NULL_AND_LINEAR_FREE(clazz->ifviPool);
   2087 
   2088     clazz->sfieldCount = -1;
   2089     /* The sfields are attached to the ClassObject, and will be freed
   2090      * with it. */
   2091 
   2092     clazz->ifieldCount = -1;
   2093     NULL_AND_LINEAR_FREE(clazz->ifields);
   2094 
   2095 #undef NULL_AND_FREE
   2096 #undef NULL_AND_LINEAR_FREE
   2097 }
   2098 
   2099 /*
   2100  * Free anything in a Method that was allocated on the system heap.
   2101  *
   2102  * The containing class is largely torn down by this point.
   2103  */
   2104 static void freeMethodInnards(Method* meth)
   2105 {
   2106 #if 0
   2107     free(meth->exceptions);
   2108     free(meth->lines);
   2109     free(meth->locals);
   2110 #endif
   2111 
   2112     /*
   2113      * Some register maps are allocated on the heap, either because of late
   2114      * verification or because we're caching an uncompressed form.
   2115      */
   2116     const RegisterMap* pMap = meth->registerMap;
   2117     if (pMap != NULL && dvmRegisterMapGetOnHeap(pMap)) {
   2118         dvmFreeRegisterMap((RegisterMap*) pMap);
   2119         meth->registerMap = NULL;
   2120     }
   2121 
   2122     /*
   2123      * We may have copied the instructions.
   2124      */
   2125     if (IS_METHOD_FLAG_SET(meth, METHOD_ISWRITABLE)) {
   2126         DexCode* methodDexCode = (DexCode*) dvmGetMethodCode(meth);
   2127         dvmLinearFree(meth->clazz->classLoader, methodDexCode);
   2128     }
   2129 }
   2130 
   2131 /*
   2132  * Clone a Method, making new copies of anything that will be freed up
   2133  * by freeMethodInnards().  This is used for "miranda" methods.
   2134  */
   2135 static void cloneMethod(Method* dst, const Method* src)
   2136 {
   2137     if (src->registerMap != NULL) {
   2138         ALOGE("GLITCH: only expected abstract methods here");
   2139         ALOGE("        cloning %s.%s", src->clazz->descriptor, src->name);
   2140         dvmAbort();
   2141     }
   2142     memcpy(dst, src, sizeof(Method));
   2143 }
   2144 
   2145 /*
   2146  * Pull the interesting pieces out of a DexMethod.
   2147  *
   2148  * The DEX file isn't going anywhere, so we don't need to make copies of
   2149  * the code area.
   2150  */
   2151 static void loadMethodFromDex(ClassObject* clazz, const DexMethod* pDexMethod,
   2152     Method* meth)
   2153 {
   2154     DexFile* pDexFile = clazz->pDvmDex->pDexFile;
   2155     const DexMethodId* pMethodId;
   2156     const DexCode* pDexCode;
   2157 
   2158     pMethodId = dexGetMethodId(pDexFile, pDexMethod->methodIdx);
   2159 
   2160     meth->name = dexStringById(pDexFile, pMethodId->nameIdx);
   2161     dexProtoSetFromMethodId(&meth->prototype, pDexFile, pMethodId);
   2162     meth->shorty = dexProtoGetShorty(&meth->prototype);
   2163     meth->accessFlags = pDexMethod->accessFlags;
   2164     meth->clazz = clazz;
   2165     meth->jniArgInfo = 0;
   2166 
   2167     if (dvmCompareNameDescriptorAndMethod("finalize", "()V", meth) == 0) {
   2168         /*
   2169          * The Enum class declares a "final" finalize() method to
   2170          * prevent subclasses from introducing a finalizer.  We don't
   2171          * want to set the finalizable flag for Enum or its subclasses,
   2172          * so we check for it here.
   2173          *
   2174          * We also want to avoid setting it on Object, but it's easier
   2175          * to just strip that out later.
   2176          */
   2177         if (clazz->classLoader != NULL ||
   2178             strcmp(clazz->descriptor, "Ljava/lang/Enum;") != 0)
   2179         {
   2180             SET_CLASS_FLAG(clazz, CLASS_ISFINALIZABLE);
   2181         }
   2182     }
   2183 
   2184     pDexCode = dexGetCode(pDexFile, pDexMethod);
   2185     if (pDexCode != NULL) {
   2186         /* integer constants, copy over for faster access */
   2187         meth->registersSize = pDexCode->registersSize;
   2188         meth->insSize = pDexCode->insSize;
   2189         meth->outsSize = pDexCode->outsSize;
   2190 
   2191         /* pointer to code area */
   2192         meth->insns = pDexCode->insns;
   2193     } else {
   2194         /*
   2195          * We don't have a DexCode block, but we still want to know how
   2196          * much space is needed for the arguments (so we don't have to
   2197          * compute it later).  We also take this opportunity to compute
   2198          * JNI argument info.
   2199          *
   2200          * We do this for abstract methods as well, because we want to
   2201          * be able to substitute our exception-throwing "stub" in.
   2202          */
   2203         int argsSize = dvmComputeMethodArgsSize(meth);
   2204         if (!dvmIsStaticMethod(meth))
   2205             argsSize++;
   2206         meth->registersSize = meth->insSize = argsSize;
   2207         assert(meth->outsSize == 0);
   2208         assert(meth->insns == NULL);
   2209 
   2210         if (dvmIsNativeMethod(meth)) {
   2211             meth->nativeFunc = dvmResolveNativeMethod;
   2212             meth->jniArgInfo = computeJniArgInfo(&meth->prototype);
   2213         }
   2214     }
   2215 }
   2216 
   2217 #if 0       /* replaced with private/read-write mapping */
   2218 /*
   2219  * We usually map bytecode directly out of the DEX file, which is mapped
   2220  * shared read-only.  If we want to be able to modify it, we have to make
   2221  * a new copy.
   2222  *
   2223  * Once copied, the code will be in the LinearAlloc region, which may be
   2224  * marked read-only.
   2225  *
   2226  * The bytecode instructions are embedded inside a DexCode structure, so we
   2227  * need to copy all of that.  (The dvmGetMethodCode function backs up the
   2228  * instruction pointer to find the start of the DexCode.)
   2229  */
   2230 void dvmMakeCodeReadWrite(Method* meth)
   2231 {
   2232     DexCode* methodDexCode = (DexCode*) dvmGetMethodCode(meth);
   2233 
   2234     if (IS_METHOD_FLAG_SET(meth, METHOD_ISWRITABLE)) {
   2235         dvmLinearReadWrite(meth->clazz->classLoader, methodDexCode);
   2236         return;
   2237     }
   2238 
   2239     assert(!dvmIsNativeMethod(meth) && !dvmIsAbstractMethod(meth));
   2240 
   2241     size_t dexCodeSize = dexGetDexCodeSize(methodDexCode);
   2242     ALOGD("Making a copy of %s.%s code (%d bytes)",
   2243         meth->clazz->descriptor, meth->name, dexCodeSize);
   2244 
   2245     DexCode* newCode =
   2246         (DexCode*) dvmLinearAlloc(meth->clazz->classLoader, dexCodeSize);
   2247     memcpy(newCode, methodDexCode, dexCodeSize);
   2248 
   2249     meth->insns = newCode->insns;
   2250     SET_METHOD_FLAG(meth, METHOD_ISWRITABLE);
   2251 }
   2252 
   2253 /*
   2254  * Mark the bytecode read-only.
   2255  *
   2256  * If the contents of the DexCode haven't actually changed, we could revert
   2257  * to the original shared page.
   2258  */
   2259 void dvmMakeCodeReadOnly(Method* meth)
   2260 {
   2261     DexCode* methodDexCode = (DexCode*) dvmGetMethodCode(meth);
   2262     ALOGV("+++ marking %p read-only", methodDexCode);
   2263     dvmLinearReadOnly(meth->clazz->classLoader, methodDexCode);
   2264 }
   2265 #endif
   2266 
   2267 
   2268 /*
   2269  * jniArgInfo (32-bit int) layout:
   2270  *   SRRRHHHH HHHHHHHH HHHHHHHH HHHHHHHH
   2271  *
   2272  *   S - if set, do things the hard way (scan the signature)
   2273  *   R - return-type enumeration
   2274  *   H - target-specific hints
   2275  *
   2276  * This info is used at invocation time by dvmPlatformInvoke.  In most
   2277  * cases, the target-specific hints allow dvmPlatformInvoke to avoid
   2278  * having to fully parse the signature.
   2279  *
   2280  * The return-type bits are always set, even if target-specific hint bits
   2281  * are unavailable.
   2282  */
   2283 static int computeJniArgInfo(const DexProto* proto)
   2284 {
   2285     const char* sig = dexProtoGetShorty(proto);
   2286     int returnType, jniArgInfo;
   2287     u4 hints;
   2288 
   2289     /* The first shorty character is the return type. */
   2290     switch (*(sig++)) {
   2291     case 'V':
   2292         returnType = DALVIK_JNI_RETURN_VOID;
   2293         break;
   2294     case 'F':
   2295         returnType = DALVIK_JNI_RETURN_FLOAT;
   2296         break;
   2297     case 'D':
   2298         returnType = DALVIK_JNI_RETURN_DOUBLE;
   2299         break;
   2300     case 'J':
   2301         returnType = DALVIK_JNI_RETURN_S8;
   2302         break;
   2303     case 'Z':
   2304     case 'B':
   2305         returnType = DALVIK_JNI_RETURN_S1;
   2306         break;
   2307     case 'C':
   2308         returnType = DALVIK_JNI_RETURN_U2;
   2309         break;
   2310     case 'S':
   2311         returnType = DALVIK_JNI_RETURN_S2;
   2312         break;
   2313     default:
   2314         returnType = DALVIK_JNI_RETURN_S4;
   2315         break;
   2316     }
   2317 
   2318     jniArgInfo = returnType << DALVIK_JNI_RETURN_SHIFT;
   2319 
   2320     hints = dvmPlatformInvokeHints(proto);
   2321 
   2322     if (hints & DALVIK_JNI_NO_ARG_INFO) {
   2323         jniArgInfo |= DALVIK_JNI_NO_ARG_INFO;
   2324     } else {
   2325         assert((hints & DALVIK_JNI_RETURN_MASK) == 0);
   2326         jniArgInfo |= hints;
   2327     }
   2328 
   2329     return jniArgInfo;
   2330 }
   2331 
   2332 /*
   2333  * Load information about a static field.
   2334  *
   2335  * This also "prepares" static fields by initializing them
   2336  * to their "standard default values".
   2337  */
   2338 static void loadSFieldFromDex(ClassObject* clazz,
   2339     const DexField* pDexSField, StaticField* sfield)
   2340 {
   2341     DexFile* pDexFile = clazz->pDvmDex->pDexFile;
   2342     const DexFieldId* pFieldId;
   2343 
   2344     pFieldId = dexGetFieldId(pDexFile, pDexSField->fieldIdx);
   2345 
   2346     sfield->clazz = clazz;
   2347     sfield->name = dexStringById(pDexFile, pFieldId->nameIdx);
   2348     sfield->signature = dexStringByTypeIdx(pDexFile, pFieldId->typeIdx);
   2349     sfield->accessFlags = pDexSField->accessFlags;
   2350 
   2351     /* Static object field values are set to "standard default values"
   2352      * (null or 0) until the class is initialized.  We delay loading
   2353      * constant values from the class until that time.
   2354      */
   2355     //sfield->value.j = 0;
   2356     assert(sfield->value.j == 0LL);     // cleared earlier with calloc
   2357 }
   2358 
   2359 /*
   2360  * Load information about an instance field.
   2361  */
   2362 static void loadIFieldFromDex(ClassObject* clazz,
   2363     const DexField* pDexIField, InstField* ifield)
   2364 {
   2365     DexFile* pDexFile = clazz->pDvmDex->pDexFile;
   2366     const DexFieldId* pFieldId;
   2367 
   2368     pFieldId = dexGetFieldId(pDexFile, pDexIField->fieldIdx);
   2369 
   2370     ifield->clazz = clazz;
   2371     ifield->name = dexStringById(pDexFile, pFieldId->nameIdx);
   2372     ifield->signature = dexStringByTypeIdx(pDexFile, pFieldId->typeIdx);
   2373     ifield->accessFlags = pDexIField->accessFlags;
   2374 #ifndef NDEBUG
   2375     assert(ifield->byteOffset == 0);    // cleared earlier with calloc
   2376     ifield->byteOffset = -1;    // make it obvious if we fail to set later
   2377 #endif
   2378 }
   2379 
   2380 /*
   2381  * Cache java.lang.ref.Reference fields and methods.
   2382  */
   2383 static bool precacheReferenceOffsets(ClassObject* clazz)
   2384 {
   2385     int i;
   2386 
   2387     /* We trick the GC object scanner by not counting
   2388      * java.lang.ref.Reference.referent as an object
   2389      * field.  It will get explicitly scanned as part
   2390      * of the reference-walking process.
   2391      *
   2392      * Find the object field named "referent" and put it
   2393      * just after the list of object reference fields.
   2394      */
   2395     dvmLinearReadWrite(clazz->classLoader, clazz->ifields);
   2396     for (i = 0; i < clazz->ifieldRefCount; i++) {
   2397         InstField *pField = &clazz->ifields[i];
   2398         if (strcmp(pField->name, "referent") == 0) {
   2399             int targetIndex;
   2400 
   2401             /* Swap this field with the last object field.
   2402              */
   2403             targetIndex = clazz->ifieldRefCount - 1;
   2404             if (i != targetIndex) {
   2405                 InstField *swapField = &clazz->ifields[targetIndex];
   2406                 InstField tmpField;
   2407                 int tmpByteOffset;
   2408 
   2409                 /* It's not currently strictly necessary
   2410                  * for the fields to be in byteOffset order,
   2411                  * but it's more predictable that way.
   2412                  */
   2413                 tmpByteOffset = swapField->byteOffset;
   2414                 swapField->byteOffset = pField->byteOffset;
   2415                 pField->byteOffset = tmpByteOffset;
   2416 
   2417                 tmpField = *swapField;
   2418                 *swapField = *pField;
   2419                 *pField = tmpField;
   2420             }
   2421 
   2422             /* One fewer object field (wink wink).
   2423              */
   2424             clazz->ifieldRefCount--;
   2425             i--;        /* don't trip "didn't find it" test if field was last */
   2426             break;
   2427         }
   2428     }
   2429     dvmLinearReadOnly(clazz->classLoader, clazz->ifields);
   2430     if (i == clazz->ifieldRefCount) {
   2431         ALOGE("Unable to reorder 'referent' in %s", clazz->descriptor);
   2432         return false;
   2433     }
   2434 
   2435     /*
   2436      * Now that the above has been done, it is safe to cache
   2437      * info about the class.
   2438      */
   2439     if (!dvmFindReferenceMembers(clazz)) {
   2440         ALOGE("Trouble with Reference setup");
   2441         return false;
   2442     }
   2443 
   2444     return true;
   2445 }
   2446 
   2447 
   2448 /*
   2449  * Set the bitmap of reference offsets, refOffsets, from the ifields
   2450  * list.
   2451  */
   2452 static void computeRefOffsets(ClassObject* clazz)
   2453 {
   2454     if (clazz->super != NULL) {
   2455         clazz->refOffsets = clazz->super->refOffsets;
   2456     } else {
   2457         clazz->refOffsets = 0;
   2458     }
   2459     /*
   2460      * If our superclass overflowed, we don't stand a chance.
   2461      */
   2462     if (clazz->refOffsets != CLASS_WALK_SUPER) {
   2463         InstField *f;
   2464         int i;
   2465 
   2466         /* All of the fields that contain object references
   2467          * are guaranteed to be at the beginning of the ifields list.
   2468          */
   2469         f = clazz->ifields;
   2470         const int ifieldRefCount = clazz->ifieldRefCount;
   2471         for (i = 0; i < ifieldRefCount; i++) {
   2472           /*
   2473            * Note that, per the comment on struct InstField,
   2474            * f->byteOffset is the offset from the beginning of
   2475            * obj, not the offset into obj->instanceData.
   2476            */
   2477           assert(f->byteOffset >= (int) CLASS_SMALLEST_OFFSET);
   2478           assert((f->byteOffset & (CLASS_OFFSET_ALIGNMENT - 1)) == 0);
   2479           if (CLASS_CAN_ENCODE_OFFSET(f->byteOffset)) {
   2480               u4 newBit = CLASS_BIT_FROM_OFFSET(f->byteOffset);
   2481               assert(newBit != 0);
   2482               clazz->refOffsets |= newBit;
   2483           } else {
   2484               clazz->refOffsets = CLASS_WALK_SUPER;
   2485               break;
   2486           }
   2487           f++;
   2488         }
   2489     }
   2490 }
   2491 
   2492 
   2493 /*
   2494  * Link (prepare and resolve).  Verification is deferred until later.
   2495  *
   2496  * This converts symbolic references into pointers.  It's independent of
   2497  * the source file format.
   2498  *
   2499  * If clazz->status is CLASS_IDX, then clazz->super and interfaces[] are
   2500  * holding class reference indices rather than pointers.  The class
   2501  * references will be resolved during link.  (This is done when
   2502  * loading from DEX to avoid having to create additional storage to
   2503  * pass the indices around.)
   2504  *
   2505  * Returns "false" with an exception pending on failure.
   2506  */
   2507 bool dvmLinkClass(ClassObject* clazz)
   2508 {
   2509     u4 superclassIdx = 0;
   2510     u4 *interfaceIdxArray = NULL;
   2511     bool okay = false;
   2512     int i;
   2513 
   2514     assert(clazz != NULL);
   2515     assert(clazz->descriptor != NULL);
   2516     assert(clazz->status == CLASS_IDX || clazz->status == CLASS_LOADED);
   2517     if (gDvm.verboseClass)
   2518         ALOGV("CLASS: linking '%s'...", clazz->descriptor);
   2519 
   2520     assert(gDvm.classJavaLangClass != NULL);
   2521     assert(clazz->clazz == gDvm.classJavaLangClass);
   2522     assert(dvmIsClassObject(clazz));
   2523     if (clazz->classLoader == NULL &&
   2524         (strcmp(clazz->descriptor, "Ljava/lang/Class;") == 0))
   2525     {
   2526         if (gDvm.classJavaLangClass->ifieldCount > CLASS_FIELD_SLOTS) {
   2527             ALOGE("java.lang.Class has %d instance fields (expected at most %d)",
   2528                  gDvm.classJavaLangClass->ifieldCount, CLASS_FIELD_SLOTS);
   2529             dvmAbort();
   2530         }
   2531         if (gDvm.classJavaLangClass->sfieldCount != CLASS_SFIELD_SLOTS) {
   2532             ALOGE("java.lang.Class has %d static fields (expected %d)",
   2533                  gDvm.classJavaLangClass->sfieldCount, CLASS_SFIELD_SLOTS);
   2534             dvmAbort();
   2535         }
   2536     }
   2537 
   2538     /* "Resolve" the class.
   2539      *
   2540      * At this point, clazz's reference fields may contain Dex file
   2541      * indices instead of direct object references.  Proxy objects are
   2542      * an exception, and may be the only exception.  We need to
   2543      * translate those indices into real references, and let the GC
   2544      * look inside this ClassObject.
   2545      */
   2546     if (clazz->status == CLASS_IDX) {
   2547         if (clazz->interfaceCount > 0) {
   2548             /* Copy u4 DEX idx values out of the ClassObject* array
   2549              * where we stashed them.
   2550              */
   2551             assert(sizeof(*interfaceIdxArray) == sizeof(*clazz->interfaces));
   2552             size_t len = clazz->interfaceCount * sizeof(*interfaceIdxArray);
   2553             interfaceIdxArray = (u4*)malloc(len);
   2554             if (interfaceIdxArray == NULL) {
   2555                 ALOGW("Unable to allocate memory to link %s", clazz->descriptor);
   2556                 goto bail;
   2557             }
   2558             memcpy(interfaceIdxArray, clazz->interfaces, len);
   2559 
   2560             dvmLinearReadWrite(clazz->classLoader, clazz->interfaces);
   2561             memset(clazz->interfaces, 0, len);
   2562             dvmLinearReadOnly(clazz->classLoader, clazz->interfaces);
   2563         }
   2564 
   2565         assert(sizeof(superclassIdx) == sizeof(clazz->super));
   2566         superclassIdx = (u4) clazz->super;
   2567         clazz->super = NULL;
   2568         /* After this line, clazz will be fair game for the GC. The
   2569          * superclass and interfaces are all NULL.
   2570          */
   2571         clazz->status = CLASS_LOADED;
   2572 
   2573         if (superclassIdx != kDexNoIndex) {
   2574             ClassObject* super = dvmResolveClass(clazz, superclassIdx, false);
   2575             if (super == NULL) {
   2576                 assert(dvmCheckException(dvmThreadSelf()));
   2577                 if (gDvm.optimizing) {
   2578                     /* happens with "external" libs */
   2579                     ALOGV("Unable to resolve superclass of %s (%d)",
   2580                          clazz->descriptor, superclassIdx);
   2581                 } else {
   2582                     ALOGW("Unable to resolve superclass of %s (%d)",
   2583                          clazz->descriptor, superclassIdx);
   2584                 }
   2585                 goto bail;
   2586             }
   2587             dvmSetFieldObject((Object *)clazz,
   2588                               OFFSETOF_MEMBER(ClassObject, super),
   2589                               (Object *)super);
   2590         }
   2591 
   2592         if (clazz->interfaceCount > 0) {
   2593             /* Resolve the interfaces implemented directly by this class. */
   2594             assert(interfaceIdxArray != NULL);
   2595             dvmLinearReadWrite(clazz->classLoader, clazz->interfaces);
   2596             for (i = 0; i < clazz->interfaceCount; i++) {
   2597                 assert(interfaceIdxArray[i] != kDexNoIndex);
   2598                 clazz->interfaces[i] =
   2599                     dvmResolveClass(clazz, interfaceIdxArray[i], false);
   2600                 if (clazz->interfaces[i] == NULL) {
   2601                     const DexFile* pDexFile = clazz->pDvmDex->pDexFile;
   2602 
   2603                     assert(dvmCheckException(dvmThreadSelf()));
   2604                     dvmLinearReadOnly(clazz->classLoader, clazz->interfaces);
   2605 
   2606                     const char* classDescriptor;
   2607                     classDescriptor =
   2608                         dexStringByTypeIdx(pDexFile, interfaceIdxArray[i]);
   2609                     if (gDvm.optimizing) {
   2610                         /* happens with "external" libs */
   2611                         ALOGV("Failed resolving %s interface %d '%s'",
   2612                              clazz->descriptor, interfaceIdxArray[i],
   2613                              classDescriptor);
   2614                     } else {
   2615                         ALOGI("Failed resolving %s interface %d '%s'",
   2616                              clazz->descriptor, interfaceIdxArray[i],
   2617                              classDescriptor);
   2618                     }
   2619                     goto bail;
   2620                 }
   2621 
   2622                 /* are we allowed to implement this interface? */
   2623                 if (!dvmCheckClassAccess(clazz, clazz->interfaces[i])) {
   2624                     dvmLinearReadOnly(clazz->classLoader, clazz->interfaces);
   2625                     ALOGW("Interface '%s' is not accessible to '%s'",
   2626                          clazz->interfaces[i]->descriptor, clazz->descriptor);
   2627                     dvmThrowIllegalAccessError("interface not accessible");
   2628                     goto bail;
   2629                 }
   2630                 LOGVV("+++  found interface '%s'",
   2631                       clazz->interfaces[i]->descriptor);
   2632             }
   2633             dvmLinearReadOnly(clazz->classLoader, clazz->interfaces);
   2634         }
   2635     }
   2636     /*
   2637      * There are now Class references visible to the GC in super and
   2638      * interfaces.
   2639      */
   2640 
   2641     /*
   2642      * All classes have a direct superclass, except for
   2643      * java/lang/Object and primitive classes. Primitive classes are
   2644      * are created CLASS_INITIALIZED, so won't get here.
   2645      */
   2646     assert(clazz->primitiveType == PRIM_NOT);
   2647     if (strcmp(clazz->descriptor, "Ljava/lang/Object;") == 0) {
   2648         if (clazz->super != NULL) {
   2649             /* TODO: is this invariant true for all java/lang/Objects,
   2650              * regardless of the class loader?  For now, assume it is.
   2651              */
   2652             dvmThrowClassFormatError("java.lang.Object has a superclass");
   2653             goto bail;
   2654         }
   2655 
   2656         /* Don't finalize objects whose classes use the
   2657          * default (empty) Object.finalize().
   2658          */
   2659         CLEAR_CLASS_FLAG(clazz, CLASS_ISFINALIZABLE);
   2660     } else {
   2661         if (clazz->super == NULL) {
   2662             dvmThrowLinkageError("no superclass defined");
   2663             goto bail;
   2664         }
   2665         /* verify */
   2666         if (dvmIsFinalClass(clazz->super)) {
   2667             ALOGW("Superclass of '%s' is final '%s'",
   2668                 clazz->descriptor, clazz->super->descriptor);
   2669             dvmThrowIncompatibleClassChangeError("superclass is final");
   2670             goto bail;
   2671         } else if (dvmIsInterfaceClass(clazz->super)) {
   2672             ALOGW("Superclass of '%s' is interface '%s'",
   2673                 clazz->descriptor, clazz->super->descriptor);
   2674             dvmThrowIncompatibleClassChangeError("superclass is an interface");
   2675             goto bail;
   2676         } else if (!dvmCheckClassAccess(clazz, clazz->super)) {
   2677             ALOGW("Superclass of '%s' (%s) is not accessible",
   2678                 clazz->descriptor, clazz->super->descriptor);
   2679             dvmThrowIllegalAccessError("superclass not accessible");
   2680             goto bail;
   2681         }
   2682 
   2683         /* Inherit finalizability from the superclass.  If this
   2684          * class also overrides finalize(), its CLASS_ISFINALIZABLE
   2685          * bit will already be set.
   2686          */
   2687         if (IS_CLASS_FLAG_SET(clazz->super, CLASS_ISFINALIZABLE)) {
   2688             SET_CLASS_FLAG(clazz, CLASS_ISFINALIZABLE);
   2689         }
   2690 
   2691         /* See if this class descends from java.lang.Reference
   2692          * and set the class flags appropriately.
   2693          */
   2694         if (IS_CLASS_FLAG_SET(clazz->super, CLASS_ISREFERENCE)) {
   2695             u4 superRefFlags;
   2696 
   2697             /* We've already determined the reference type of this
   2698              * inheritance chain.  Inherit reference-ness from the superclass.
   2699              */
   2700             superRefFlags = GET_CLASS_FLAG_GROUP(clazz->super,
   2701                     CLASS_ISREFERENCE |
   2702                     CLASS_ISWEAKREFERENCE |
   2703                     CLASS_ISFINALIZERREFERENCE |
   2704                     CLASS_ISPHANTOMREFERENCE);
   2705             SET_CLASS_FLAG(clazz, superRefFlags);
   2706         } else if (clazz->classLoader == NULL &&
   2707                 clazz->super->classLoader == NULL &&
   2708                 strcmp(clazz->super->descriptor,
   2709                        "Ljava/lang/ref/Reference;") == 0)
   2710         {
   2711             u4 refFlags;
   2712 
   2713             /* This class extends Reference, which means it should
   2714              * be one of the magic Soft/Weak/PhantomReference classes.
   2715              */
   2716             refFlags = CLASS_ISREFERENCE;
   2717             if (strcmp(clazz->descriptor,
   2718                        "Ljava/lang/ref/SoftReference;") == 0)
   2719             {
   2720                 /* Only CLASS_ISREFERENCE is set for soft references.
   2721                  */
   2722             } else if (strcmp(clazz->descriptor,
   2723                        "Ljava/lang/ref/WeakReference;") == 0)
   2724             {
   2725                 refFlags |= CLASS_ISWEAKREFERENCE;
   2726             } else if (strcmp(clazz->descriptor,
   2727                        "Ljava/lang/ref/FinalizerReference;") == 0)
   2728             {
   2729                 refFlags |= CLASS_ISFINALIZERREFERENCE;
   2730             }  else if (strcmp(clazz->descriptor,
   2731                        "Ljava/lang/ref/PhantomReference;") == 0)
   2732             {
   2733                 refFlags |= CLASS_ISPHANTOMREFERENCE;
   2734             } else {
   2735                 /* No-one else is allowed to inherit directly
   2736                  * from Reference.
   2737                  */
   2738 //xxx is this the right exception?  better than an assertion.
   2739                 dvmThrowLinkageError("illegal inheritance from Reference");
   2740                 goto bail;
   2741             }
   2742 
   2743             /* The class should not have any reference bits set yet.
   2744              */
   2745             assert(GET_CLASS_FLAG_GROUP(clazz,
   2746                     CLASS_ISREFERENCE |
   2747                     CLASS_ISWEAKREFERENCE |
   2748                     CLASS_ISFINALIZERREFERENCE |
   2749                     CLASS_ISPHANTOMREFERENCE) == 0);
   2750 
   2751             SET_CLASS_FLAG(clazz, refFlags);
   2752         }
   2753     }
   2754 
   2755     /*
   2756      * Populate vtable.
   2757      */
   2758     if (dvmIsInterfaceClass(clazz)) {
   2759         /* no vtable; just set the method indices */
   2760         int count = clazz->virtualMethodCount;
   2761 
   2762         if (count != (u2) count) {
   2763             ALOGE("Too many methods (%d) in interface '%s'", count,
   2764                  clazz->descriptor);
   2765             goto bail;
   2766         }
   2767 
   2768         dvmLinearReadWrite(clazz->classLoader, clazz->virtualMethods);
   2769 
   2770         for (i = 0; i < count; i++)
   2771             clazz->virtualMethods[i].methodIndex = (u2) i;
   2772 
   2773         dvmLinearReadOnly(clazz->classLoader, clazz->virtualMethods);
   2774     } else {
   2775         if (!createVtable(clazz)) {
   2776             ALOGW("failed creating vtable");
   2777             goto bail;
   2778         }
   2779     }
   2780 
   2781     /*
   2782      * Populate interface method tables.  Can alter the vtable.
   2783      */
   2784     if (!createIftable(clazz))
   2785         goto bail;
   2786 
   2787     /*
   2788      * Insert special-purpose "stub" method implementations.
   2789      */
   2790     if (!insertMethodStubs(clazz))
   2791         goto bail;
   2792 
   2793     /*
   2794      * Compute instance field offsets and, hence, the size of the object.
   2795      */
   2796     if (!computeFieldOffsets(clazz))
   2797         goto bail;
   2798 
   2799     /*
   2800      * Cache field and method info for the class Reference (as loaded
   2801      * by the boot classloader). This has to happen after the call to
   2802      * computeFieldOffsets().
   2803      */
   2804     if ((clazz->classLoader == NULL)
   2805             && (strcmp(clazz->descriptor, "Ljava/lang/ref/Reference;") == 0)) {
   2806         if (!precacheReferenceOffsets(clazz)) {
   2807             ALOGE("failed pre-caching Reference offsets");
   2808             dvmThrowInternalError(NULL);
   2809             goto bail;
   2810         }
   2811     }
   2812 
   2813     /*
   2814      * Compact the offsets the GC has to examine into a bitmap, if
   2815      * possible.  (This has to happen after Reference.referent is
   2816      * massaged in precacheReferenceOffsets.)
   2817      */
   2818     computeRefOffsets(clazz);
   2819 
   2820     /*
   2821      * Done!
   2822      */
   2823     if (IS_CLASS_FLAG_SET(clazz, CLASS_ISPREVERIFIED))
   2824         clazz->status = CLASS_VERIFIED;
   2825     else
   2826         clazz->status = CLASS_RESOLVED;
   2827     okay = true;
   2828     if (gDvm.verboseClass)
   2829         ALOGV("CLASS: linked '%s'", clazz->descriptor);
   2830 
   2831     /*
   2832      * We send CLASS_PREPARE events to the debugger from here.  The
   2833      * definition of "preparation" is creating the static fields for a
   2834      * class and initializing them to the standard default values, but not
   2835      * executing any code (that comes later, during "initialization").
   2836      *
   2837      * We did the static prep in loadSFieldFromDex() while loading the class.
   2838      *
   2839      * The class has been prepared and resolved but possibly not yet verified
   2840      * at this point.
   2841      */
   2842     if (gDvm.debuggerActive) {
   2843         dvmDbgPostClassPrepare(clazz);
   2844     }
   2845 
   2846 bail:
   2847     if (!okay) {
   2848         clazz->status = CLASS_ERROR;
   2849         if (!dvmCheckException(dvmThreadSelf())) {
   2850             dvmThrowVirtualMachineError(NULL);
   2851         }
   2852     }
   2853     if (interfaceIdxArray != NULL) {
   2854         free(interfaceIdxArray);
   2855     }
   2856 
   2857     return okay;
   2858 }
   2859 
   2860 /*
   2861  * Create the virtual method table.
   2862  *
   2863  * The top part of the table is a copy of the table from our superclass,
   2864  * with our local methods overriding theirs.  The bottom part of the table
   2865  * has any new methods we defined.
   2866  */
   2867 static bool createVtable(ClassObject* clazz)
   2868 {
   2869     bool result = false;
   2870     int maxCount;
   2871     int i;
   2872 
   2873     if (clazz->super != NULL) {
   2874         //ALOGI("SUPER METHODS %d %s->%s", clazz->super->vtableCount,
   2875         //    clazz->descriptor, clazz->super->descriptor);
   2876     }
   2877 
   2878     /* the virtual methods we define, plus the superclass vtable size */
   2879     maxCount = clazz->virtualMethodCount;
   2880     if (clazz->super != NULL) {
   2881         maxCount += clazz->super->vtableCount;
   2882     } else {
   2883         /* TODO: is this invariant true for all java/lang/Objects,
   2884          * regardless of the class loader?  For now, assume it is.
   2885          */
   2886         assert(strcmp(clazz->descriptor, "Ljava/lang/Object;") == 0);
   2887     }
   2888     //ALOGD("+++ max vmethods for '%s' is %d", clazz->descriptor, maxCount);
   2889 
   2890     /*
   2891      * Over-allocate the table, then realloc it down if necessary.  So
   2892      * long as we don't allocate anything in between we won't cause
   2893      * fragmentation, and reducing the size should be unlikely to cause
   2894      * a buffer copy.
   2895      */
   2896     dvmLinearReadWrite(clazz->classLoader, clazz->virtualMethods);
   2897     clazz->vtable = (Method**) dvmLinearAlloc(clazz->classLoader,
   2898                         sizeof(Method*) * maxCount);
   2899     if (clazz->vtable == NULL)
   2900         goto bail;
   2901 
   2902     if (clazz->super != NULL) {
   2903         int actualCount;
   2904 
   2905         memcpy(clazz->vtable, clazz->super->vtable,
   2906             sizeof(*(clazz->vtable)) * clazz->super->vtableCount);
   2907         actualCount = clazz->super->vtableCount;
   2908 
   2909         /*
   2910          * See if any of our virtual methods override the superclass.
   2911          */
   2912         for (i = 0; i < clazz->virtualMethodCount; i++) {
   2913             Method* localMeth = &clazz->virtualMethods[i];
   2914             int si;
   2915 
   2916             for (si = 0; si < clazz->super->vtableCount; si++) {
   2917                 Method* superMeth = clazz->vtable[si];
   2918 
   2919                 if (dvmCompareMethodNamesAndProtos(localMeth, superMeth) == 0) {
   2920                     // We should have an access check here, but some apps rely on us not
   2921                     // checking access: http://b/7301030
   2922                     bool isAccessible = dvmCheckMethodAccess(clazz, superMeth);
   2923                     if (dvmIsFinalMethod(superMeth)) {
   2924                         ALOGE("Method %s.%s overrides final %s.%s",
   2925                               localMeth->clazz->descriptor, localMeth->name,
   2926                               superMeth->clazz->descriptor, superMeth->name);
   2927                         goto bail;
   2928                     }
   2929 
   2930                     // Warn if we just spotted code relying on this bug...
   2931                     if (!isAccessible) {
   2932                         ALOGW("method %s.%s incorrectly overrides "
   2933                               "package-private method with same name in %s",
   2934                               localMeth->clazz->descriptor, localMeth->name,
   2935                               superMeth->clazz->descriptor);
   2936                     }
   2937 
   2938                     clazz->vtable[si] = localMeth;
   2939                     localMeth->methodIndex = (u2) si;
   2940                     //ALOGV("+++   override %s.%s (slot %d)",
   2941                     //    clazz->descriptor, localMeth->name, si);
   2942                     break;
   2943                 }
   2944             }
   2945 
   2946             if (si == clazz->super->vtableCount) {
   2947                 /* not an override, add to end */
   2948                 clazz->vtable[actualCount] = localMeth;
   2949                 localMeth->methodIndex = (u2) actualCount;
   2950                 actualCount++;
   2951 
   2952                 //ALOGV("+++   add method %s.%s",
   2953                 //    clazz->descriptor, localMeth->name);
   2954             }
   2955         }
   2956 
   2957         if (actualCount != (u2) actualCount) {
   2958             ALOGE("Too many methods (%d) in class '%s'", actualCount,
   2959                  clazz->descriptor);
   2960             goto bail;
   2961         }
   2962 
   2963         assert(actualCount <= maxCount);
   2964 
   2965         if (actualCount < maxCount) {
   2966             assert(clazz->vtable != NULL);
   2967             dvmLinearReadOnly(clazz->classLoader, clazz->vtable);
   2968             clazz->vtable = (Method **)dvmLinearRealloc(clazz->classLoader,
   2969                 clazz->vtable, sizeof(*(clazz->vtable)) * actualCount);
   2970             if (clazz->vtable == NULL) {
   2971                 ALOGE("vtable realloc failed");
   2972                 goto bail;
   2973             } else {
   2974                 LOGVV("+++  reduced vtable from %d to %d",
   2975                     maxCount, actualCount);
   2976             }
   2977         }
   2978 
   2979         clazz->vtableCount = actualCount;
   2980     } else {
   2981         /* java/lang/Object case */
   2982         int count = clazz->virtualMethodCount;
   2983         if (count != (u2) count) {
   2984             ALOGE("Too many methods (%d) in base class '%s'", count,
   2985                  clazz->descriptor);
   2986             goto bail;
   2987         }
   2988 
   2989         for (i = 0; i < count; i++) {
   2990             clazz->vtable[i] = &clazz->virtualMethods[i];
   2991             clazz->virtualMethods[i].methodIndex = (u2) i;
   2992         }
   2993         clazz->vtableCount = clazz->virtualMethodCount;
   2994     }
   2995 
   2996     result = true;
   2997 
   2998 bail:
   2999     dvmLinearReadOnly(clazz->classLoader, clazz->vtable);
   3000     dvmLinearReadOnly(clazz->classLoader, clazz->virtualMethods);
   3001     return result;
   3002 }
   3003 
   3004 /*
   3005  * Create and populate "iftable".
   3006  *
   3007  * The set of interfaces we support is the combination of the interfaces
   3008  * we implement directly and those implemented by our superclass.  Each
   3009  * interface can have one or more "superinterfaces", which we must also
   3010  * support.  For speed we flatten the tree out.
   3011  *
   3012  * We might be able to speed this up when there are lots of interfaces
   3013  * by merge-sorting the class pointers and binary-searching when removing
   3014  * duplicates.  We could also drop the duplicate removal -- it's only
   3015  * there to reduce the memory footprint.
   3016  *
   3017  * Because of "Miranda methods", this may reallocate clazz->virtualMethods.
   3018  *
   3019  * Returns "true" on success.
   3020  */
   3021 static bool createIftable(ClassObject* clazz)
   3022 {
   3023     bool result = false;
   3024     bool zapIftable = false;
   3025     bool zapVtable = false;
   3026     bool zapIfvipool = false;
   3027     int poolOffset = 0, poolSize = 0;
   3028     Method** mirandaList = NULL;
   3029     int mirandaCount = 0, mirandaAlloc = 0;
   3030 
   3031     int superIfCount;
   3032     if (clazz->super != NULL)
   3033         superIfCount = clazz->super->iftableCount;
   3034     else
   3035         superIfCount = 0;
   3036 
   3037     int ifCount = superIfCount;
   3038     ifCount += clazz->interfaceCount;
   3039     for (int i = 0; i < clazz->interfaceCount; i++)
   3040         ifCount += clazz->interfaces[i]->iftableCount;
   3041 
   3042     LOGVV("INTF: class '%s' direct w/supra=%d super=%d total=%d",
   3043         clazz->descriptor, ifCount - superIfCount, superIfCount, ifCount);
   3044 
   3045     if (ifCount == 0) {
   3046         assert(clazz->iftableCount == 0);
   3047         assert(clazz->iftable == NULL);
   3048         return true;
   3049     }
   3050 
   3051     /*
   3052      * Create a table with enough space for all interfaces, and copy the
   3053      * superclass' table in.
   3054      */
   3055     clazz->iftable = (InterfaceEntry*) dvmLinearAlloc(clazz->classLoader,
   3056                         sizeof(InterfaceEntry) * ifCount);
   3057     zapIftable = true;
   3058     memset(clazz->iftable, 0x00, sizeof(InterfaceEntry) * ifCount);
   3059     if (superIfCount != 0) {
   3060         memcpy(clazz->iftable, clazz->super->iftable,
   3061             sizeof(InterfaceEntry) * superIfCount);
   3062     }
   3063 
   3064     /*
   3065      * Create a flattened interface hierarchy of our immediate interfaces.
   3066      */
   3067     int idx = superIfCount;
   3068 
   3069     for (int i = 0; i < clazz->interfaceCount; i++) {
   3070         ClassObject* interf = clazz->interfaces[i];
   3071         assert(interf != NULL);
   3072 
   3073         /* make sure this is still an interface class */
   3074         if (!dvmIsInterfaceClass(interf)) {
   3075             ALOGW("Class '%s' implements non-interface '%s'",
   3076                 clazz->descriptor, interf->descriptor);
   3077             dvmThrowIncompatibleClassChangeErrorWithClassMessage(
   3078                 clazz->descriptor);
   3079             goto bail;
   3080         }
   3081 
   3082         /* add entry for this interface */
   3083         clazz->iftable[idx++].clazz = interf;
   3084 
   3085         /* add entries for the interface's superinterfaces */
   3086         for (int j = 0; j < interf->iftableCount; j++) {
   3087             int k;
   3088             ClassObject *cand;
   3089 
   3090             cand = interf->iftable[j].clazz;
   3091 
   3092             /*
   3093              * Check if this interface was already added and add only if new.
   3094              * This is to avoid a potential blowup in the number of
   3095              * interfaces for sufficiently complicated interface hierarchies.
   3096              * This has quadratic runtime in the number of interfaces.
   3097              * However, in common cases with little interface inheritance, this
   3098              * doesn't make much of a difference.
   3099              */
   3100             for (k = 0; k < idx; k++)
   3101                 if (clazz->iftable[k].clazz == cand)
   3102                     break;
   3103 
   3104             if (k == idx)
   3105                 clazz->iftable[idx++].clazz = cand;
   3106         }
   3107     }
   3108 
   3109     assert(idx <= ifCount);
   3110 
   3111     /*
   3112      * Adjust the ifCount. We could reallocate the interface memory here,
   3113      * but it's probably not worth the effort, the important thing here
   3114      * is to avoid the interface blowup and keep the ifCount low.
   3115      */
   3116     if (false) {
   3117         if (idx != ifCount) {
   3118             int newIfCount = idx;
   3119             InterfaceEntry* oldmem = clazz->iftable;
   3120 
   3121             clazz->iftable = (InterfaceEntry*) dvmLinearAlloc(clazz->classLoader,
   3122                             sizeof(InterfaceEntry) * newIfCount);
   3123             memcpy(clazz->iftable, oldmem, sizeof(InterfaceEntry) * newIfCount);
   3124             dvmLinearFree(clazz->classLoader, oldmem);
   3125         }
   3126     }
   3127 
   3128     ifCount = idx;
   3129     clazz->iftableCount = ifCount;
   3130 
   3131     /*
   3132      * If we're an interface, we don't need the vtable pointers, so
   3133      * we're done.  If this class doesn't implement an interface that our
   3134      * superclass doesn't have, then we again have nothing to do.
   3135      */
   3136     if (dvmIsInterfaceClass(clazz) || superIfCount == ifCount) {
   3137         //dvmDumpClass(clazz, kDumpClassFullDetail);
   3138         result = true;
   3139         goto bail;
   3140     }
   3141 
   3142     /*
   3143      * When we're handling invokeinterface, we probably have an object
   3144      * whose type is an interface class rather than a concrete class.  We
   3145      * need to convert the method reference into a vtable index.  So, for
   3146      * every entry in "iftable", we create a list of vtable indices.
   3147      *
   3148      * Because our vtable encompasses the superclass vtable, we can use
   3149      * the vtable indices from our superclass for all of the interfaces
   3150      * that weren't directly implemented by us.
   3151      *
   3152      * Each entry in "iftable" has a pointer to the start of its set of
   3153      * vtable offsets.  The iftable entries in the superclass point to
   3154      * storage allocated in the superclass, and the iftable entries added
   3155      * for this class point to storage allocated in this class.  "iftable"
   3156      * is flat for fast access in a class and all of its subclasses, but
   3157      * "ifviPool" is only created for the topmost implementor.
   3158      */
   3159     for (int i = superIfCount; i < ifCount; i++) {
   3160         /*
   3161          * Note it's valid for an interface to have no methods (e.g.
   3162          * java/io/Serializable).
   3163          */
   3164         LOGVV("INTF: pool: %d from %s",
   3165             clazz->iftable[i].clazz->virtualMethodCount,
   3166             clazz->iftable[i].clazz->descriptor);
   3167         poolSize += clazz->iftable[i].clazz->virtualMethodCount;
   3168     }
   3169 
   3170     if (poolSize == 0) {
   3171         LOGVV("INTF: didn't find any new interfaces with methods");
   3172         result = true;
   3173         goto bail;
   3174     }
   3175 
   3176     clazz->ifviPoolCount = poolSize;
   3177     clazz->ifviPool = (int*) dvmLinearAlloc(clazz->classLoader,
   3178                         poolSize * sizeof(int*));
   3179     zapIfvipool = true;
   3180 
   3181     /*
   3182      * Fill in the vtable offsets for the interfaces that weren't part of
   3183      * our superclass.
   3184      */
   3185     for (int i = superIfCount; i < ifCount; i++) {
   3186         ClassObject* interface;
   3187         int methIdx;
   3188 
   3189         clazz->iftable[i].methodIndexArray = clazz->ifviPool + poolOffset;
   3190         interface = clazz->iftable[i].clazz;
   3191         poolOffset += interface->virtualMethodCount;    // end here
   3192 
   3193         /*
   3194          * For each method listed in the interface's method list, find the
   3195          * matching method in our class's method list.  We want to favor the
   3196          * subclass over the superclass, which just requires walking
   3197          * back from the end of the vtable.  (This only matters if the
   3198          * superclass defines a private method and this class redefines
   3199          * it -- otherwise it would use the same vtable slot.  In Dalvik
   3200          * those don't end up in the virtual method table, so it shouldn't
   3201          * matter which direction we go.  We walk it backward anyway.)
   3202          *
   3203          *
   3204          * Suppose we have the following arrangement:
   3205          *   public interface MyInterface
   3206          *     public boolean inInterface();
   3207          *   public abstract class MirandaAbstract implements MirandaInterface
   3208          *     //public abstract boolean inInterface(); // not declared!
   3209          *     public boolean inAbstract() { stuff }    // in vtable
   3210          *   public class MirandClass extends MirandaAbstract
   3211          *     public boolean inInterface() { stuff }
   3212          *     public boolean inAbstract() { stuff }    // in vtable
   3213          *
   3214          * The javac compiler happily compiles MirandaAbstract even though
   3215          * it doesn't declare all methods from its interface.  When we try
   3216          * to set up a vtable for MirandaAbstract, we find that we don't
   3217          * have an slot for inInterface.  To prevent this, we synthesize
   3218          * abstract method declarations in MirandaAbstract.
   3219          *
   3220          * We have to expand vtable and update some things that point at it,
   3221          * so we accumulate the method list and do it all at once below.
   3222          */
   3223         for (methIdx = 0; methIdx < interface->virtualMethodCount; methIdx++) {
   3224             Method* imeth = &interface->virtualMethods[methIdx];
   3225             int j;
   3226 
   3227             IF_LOGVV() {
   3228                 char* desc = dexProtoCopyMethodDescriptor(&imeth->prototype);
   3229                 LOGVV("INTF:  matching '%s' '%s'", imeth->name, desc);
   3230                 free(desc);
   3231             }
   3232 
   3233             for (j = clazz->vtableCount-1; j >= 0; j--) {
   3234                 if (dvmCompareMethodNamesAndProtos(imeth, clazz->vtable[j])
   3235                     == 0)
   3236                 {
   3237                     LOGVV("INTF:   matched at %d", j);
   3238                     if (!dvmIsAbstractMethod(clazz->vtable[j]) &&
   3239                         !dvmIsPublicMethod(clazz->vtable[j]))
   3240                     {
   3241                         ALOGW("Implementation of %s.%s is not public",
   3242                             clazz->descriptor, clazz->vtable[j]->name);
   3243                         dvmThrowIllegalAccessError(
   3244                             "interface implementation not public");
   3245                         goto bail;
   3246                     }
   3247                     clazz->iftable[i].methodIndexArray[methIdx] = j;
   3248                     break;
   3249                 }
   3250             }
   3251             if (j < 0) {
   3252                 IF_ALOGV() {
   3253                     char* desc =
   3254                         dexProtoCopyMethodDescriptor(&imeth->prototype);
   3255                     ALOGV("No match for '%s' '%s' in '%s' (creating miranda)",
   3256                             imeth->name, desc, clazz->descriptor);
   3257                     free(desc);
   3258                 }
   3259                 //dvmThrowRuntimeException("Miranda!");
   3260                 //return false;
   3261 
   3262                 if (mirandaCount == mirandaAlloc) {
   3263                     mirandaAlloc += 8;
   3264                     if (mirandaList == NULL) {
   3265                         mirandaList = (Method**)dvmLinearAlloc(
   3266                                         clazz->classLoader,
   3267                                         mirandaAlloc * sizeof(Method*));
   3268                     } else {
   3269                         dvmLinearReadOnly(clazz->classLoader, mirandaList);
   3270                         mirandaList = (Method**)dvmLinearRealloc(
   3271                                 clazz->classLoader,
   3272                                 mirandaList, mirandaAlloc * sizeof(Method*));
   3273                     }
   3274                     assert(mirandaList != NULL);    // mem failed + we leaked
   3275                 }
   3276 
   3277                 /*
   3278                  * These may be redundant (e.g. method with same name and
   3279                  * signature declared in two interfaces implemented by the
   3280                  * same abstract class).  We can squeeze the duplicates
   3281                  * out here.
   3282                  */
   3283                 int mir;
   3284                 for (mir = 0; mir < mirandaCount; mir++) {
   3285                     if (dvmCompareMethodNamesAndProtos(
   3286                             mirandaList[mir], imeth) == 0)
   3287                     {
   3288                         IF_LOGVV() {
   3289                             char* desc = dexProtoCopyMethodDescriptor(
   3290                                     &imeth->prototype);
   3291                             LOGVV("MIRANDA dupe: %s and %s %s%s",
   3292                                 mirandaList[mir]->clazz->descriptor,
   3293                                 imeth->clazz->descriptor,
   3294                                 imeth->name, desc);
   3295                             free(desc);
   3296                         }
   3297                         break;
   3298                     }
   3299                 }
   3300 
   3301                 /* point the iftable at a phantom slot index */
   3302                 clazz->iftable[i].methodIndexArray[methIdx] =
   3303                     clazz->vtableCount + mir;
   3304                 LOGVV("MIRANDA: %s points at slot %d",
   3305                     imeth->name, clazz->vtableCount + mir);
   3306 
   3307                 /* if non-duplicate among Mirandas, add to Miranda list */
   3308                 if (mir == mirandaCount) {
   3309                     //ALOGV("MIRANDA: holding '%s' in slot %d",
   3310                     //    imeth->name, mir);
   3311                     mirandaList[mirandaCount++] = imeth;
   3312                 }
   3313             }
   3314         }
   3315     }
   3316 
   3317     if (mirandaCount != 0) {
   3318         static const int kManyMirandas = 150;   /* arbitrary */
   3319         Method* newVirtualMethods;
   3320         Method* meth;
   3321         int oldMethodCount, oldVtableCount;
   3322 
   3323         for (int i = 0; i < mirandaCount; i++) {
   3324             LOGVV("MIRANDA %d: %s.%s", i,
   3325                 mirandaList[i]->clazz->descriptor, mirandaList[i]->name);
   3326         }
   3327         if (mirandaCount > kManyMirandas) {
   3328             /*
   3329              * Some obfuscators like to create an interface with a huge
   3330              * pile of methods, declare classes as implementing it, and then
   3331              * only define a couple of methods.  This leads to a rather
   3332              * massive collection of Miranda methods and a lot of wasted
   3333              * space, sometimes enough to blow out the LinearAlloc cap.
   3334              */
   3335             ALOGD("Note: class %s has %d unimplemented (abstract) methods",
   3336                 clazz->descriptor, mirandaCount);
   3337         }
   3338 
   3339         /*
   3340          * We found methods in one or more interfaces for which we do not
   3341          * have vtable entries.  We have to expand our virtualMethods
   3342          * table (which might be empty) to hold some new entries.
   3343          */
   3344         if (clazz->virtualMethods == NULL) {
   3345             newVirtualMethods = (Method*) dvmLinearAlloc(clazz->classLoader,
   3346                 sizeof(Method) * (clazz->virtualMethodCount + mirandaCount));
   3347         } else {
   3348             //dvmLinearReadOnly(clazz->classLoader, clazz->virtualMethods);
   3349             newVirtualMethods = (Method*) dvmLinearRealloc(clazz->classLoader,
   3350                 clazz->virtualMethods,
   3351                 sizeof(Method) * (clazz->virtualMethodCount + mirandaCount));
   3352         }
   3353         if (newVirtualMethods != clazz->virtualMethods) {
   3354             /*
   3355              * Table was moved in memory.  We have to run through the
   3356              * vtable and fix the pointers.  The vtable entries might be
   3357              * pointing at superclasses, so we flip it around: run through
   3358              * all locally-defined virtual methods, and fix their entries
   3359              * in the vtable.  (This would get really messy if sub-classes
   3360              * had already been loaded.)
   3361              *
   3362              * Reminder: clazz->virtualMethods and clazz->virtualMethodCount
   3363              * hold the virtual methods declared by this class.  The
   3364              * method's methodIndex is the vtable index, and is the same
   3365              * for all sub-classes (and all super classes in which it is
   3366              * defined).  We're messing with these because the Miranda
   3367              * stuff makes it look like the class actually has an abstract
   3368              * method declaration in it.
   3369              */
   3370             LOGVV("MIRANDA fixing vtable pointers");
   3371             dvmLinearReadWrite(clazz->classLoader, clazz->vtable);
   3372             Method* meth = newVirtualMethods;
   3373             for (int i = 0; i < clazz->virtualMethodCount; i++, meth++)
   3374                 clazz->vtable[meth->methodIndex] = meth;
   3375             dvmLinearReadOnly(clazz->classLoader, clazz->vtable);
   3376         }
   3377 
   3378         oldMethodCount = clazz->virtualMethodCount;
   3379         clazz->virtualMethods = newVirtualMethods;
   3380         clazz->virtualMethodCount += mirandaCount;
   3381 
   3382         dvmLinearReadOnly(clazz->classLoader, clazz->virtualMethods);
   3383 
   3384         /*
   3385          * We also have to expand the vtable.
   3386          */
   3387         assert(clazz->vtable != NULL);
   3388         clazz->vtable = (Method**) dvmLinearRealloc(clazz->classLoader,
   3389                         clazz->vtable,
   3390                         sizeof(Method*) * (clazz->vtableCount + mirandaCount));
   3391         if (clazz->vtable == NULL) {
   3392             assert(false);
   3393             goto bail;
   3394         }
   3395         zapVtable = true;
   3396 
   3397         oldVtableCount = clazz->vtableCount;
   3398         clazz->vtableCount += mirandaCount;
   3399 
   3400         /*
   3401          * Now we need to create the fake methods.  We clone the abstract
   3402          * method definition from the interface and then replace a few
   3403          * things.
   3404          *
   3405          * The Method will be an "abstract native", with nativeFunc set to
   3406          * dvmAbstractMethodStub().
   3407          */
   3408         meth = clazz->virtualMethods + oldMethodCount;
   3409         for (int i = 0; i < mirandaCount; i++, meth++) {
   3410             dvmLinearReadWrite(clazz->classLoader, clazz->virtualMethods);
   3411             cloneMethod(meth, mirandaList[i]);
   3412             meth->clazz = clazz;
   3413             meth->accessFlags |= ACC_MIRANDA;
   3414             meth->methodIndex = (u2) (oldVtableCount + i);
   3415             dvmLinearReadOnly(clazz->classLoader, clazz->virtualMethods);
   3416 
   3417             /* point the new vtable entry at the new method */
   3418             clazz->vtable[oldVtableCount + i] = meth;
   3419         }
   3420 
   3421         dvmLinearReadOnly(clazz->classLoader, mirandaList);
   3422         dvmLinearFree(clazz->classLoader, mirandaList);
   3423 
   3424     }
   3425 
   3426     /*
   3427      * TODO?
   3428      * Sort the interfaces by number of declared methods.  All we really
   3429      * want is to get the interfaces with zero methods at the end of the
   3430      * list, so that when we walk through the list during invoke-interface
   3431      * we don't examine interfaces that can't possibly be useful.
   3432      *
   3433      * The set will usually be small, so a simple insertion sort works.
   3434      *
   3435      * We have to be careful not to change the order of two interfaces
   3436      * that define the same method.  (Not a problem if we only move the
   3437      * zero-method interfaces to the end.)
   3438      *
   3439      * PROBLEM:
   3440      * If we do this, we will no longer be able to identify super vs.
   3441      * current class interfaces by comparing clazz->super->iftableCount.  This
   3442      * breaks anything that only wants to find interfaces declared directly
   3443      * by the class (dvmFindStaticFieldHier, ReferenceType.Interfaces,
   3444      * dvmDbgOutputAllInterfaces, etc).  Need to provide a workaround.
   3445      *
   3446      * We can sort just the interfaces implemented directly by this class,
   3447      * but that doesn't seem like it would provide much of an advantage.  I'm
   3448      * not sure this is worthwhile.
   3449      *
   3450      * (This has been made largely obsolete by the interface cache mechanism.)
   3451      */
   3452 
   3453     //dvmDumpClass(clazz);
   3454 
   3455     result = true;
   3456 
   3457 bail:
   3458     if (zapIftable)
   3459         dvmLinearReadOnly(clazz->classLoader, clazz->iftable);
   3460     if (zapVtable)
   3461         dvmLinearReadOnly(clazz->classLoader, clazz->vtable);
   3462     if (zapIfvipool)
   3463         dvmLinearReadOnly(clazz->classLoader, clazz->ifviPool);
   3464     return result;
   3465 }
   3466 
   3467 
   3468 /*
   3469  * Provide "stub" implementations for methods without them.
   3470  *
   3471  * Currently we provide an implementation for all abstract methods that
   3472  * throws an AbstractMethodError exception.  This allows us to avoid an
   3473  * explicit check for abstract methods in every virtual call.
   3474  *
   3475  * NOTE: for Miranda methods, the method declaration is a clone of what
   3476  * was found in the interface class.  That copy may already have had the
   3477  * function pointer filled in, so don't be surprised if it's not NULL.
   3478  *
   3479  * NOTE: this sets the "native" flag, giving us an "abstract native" method,
   3480  * which is nonsensical.  Need to make sure that this doesn't escape the
   3481  * VM.  We can either mask it out in reflection calls, or copy "native"
   3482  * into the high 16 bits of accessFlags and check that internally.
   3483  */
   3484 static bool insertMethodStubs(ClassObject* clazz)
   3485 {
   3486     dvmLinearReadWrite(clazz->classLoader, clazz->virtualMethods);
   3487 
   3488     Method* meth;
   3489     int i;
   3490 
   3491     meth = clazz->virtualMethods;
   3492     for (i = 0; i < clazz->virtualMethodCount; i++, meth++) {
   3493         if (dvmIsAbstractMethod(meth)) {
   3494             assert(meth->insns == NULL);
   3495             assert(meth->nativeFunc == NULL ||
   3496                 meth->nativeFunc == (DalvikBridgeFunc)dvmAbstractMethodStub);
   3497 
   3498             meth->accessFlags |= ACC_NATIVE;
   3499             meth->nativeFunc = (DalvikBridgeFunc) dvmAbstractMethodStub;
   3500         }
   3501     }
   3502 
   3503     dvmLinearReadOnly(clazz->classLoader, clazz->virtualMethods);
   3504     return true;
   3505 }
   3506 
   3507 
   3508 /*
   3509  * Swap two instance fields.
   3510  */
   3511 static inline void swapField(InstField* pOne, InstField* pTwo)
   3512 {
   3513     InstField swap;
   3514 
   3515     LOGVV("  --- swap '%s' and '%s'", pOne->name, pTwo->name);
   3516     swap = *pOne;
   3517     *pOne = *pTwo;
   3518     *pTwo = swap;
   3519 }
   3520 
   3521 /*
   3522  * Assign instance fields to u4 slots.
   3523  *
   3524  * The top portion of the instance field area is occupied by the superclass
   3525  * fields, the bottom by the fields for this class.
   3526  *
   3527  * "long" and "double" fields occupy two adjacent slots.  On some
   3528  * architectures, 64-bit quantities must be 64-bit aligned, so we need to
   3529  * arrange fields (or introduce padding) to ensure this.  We assume the
   3530  * fields of the topmost superclass (i.e. Object) are 64-bit aligned, so
   3531  * we can just ensure that the offset is "even".  To avoid wasting space,
   3532  * we want to move non-reference 32-bit fields into gaps rather than
   3533  * creating pad words.
   3534  *
   3535  * In the worst case we will waste 4 bytes, but because objects are
   3536  * allocated on >= 64-bit boundaries, those bytes may well be wasted anyway
   3537  * (assuming this is the most-derived class).
   3538  *
   3539  * Pad words are not represented in the field table, so the field table
   3540  * itself does not change size.
   3541  *
   3542  * The number of field slots determines the size of the object, so we
   3543  * set that here too.
   3544  *
   3545  * This function feels a little more complicated than I'd like, but it
   3546  * has the property of moving the smallest possible set of fields, which
   3547  * should reduce the time required to load a class.
   3548  *
   3549  * NOTE: reference fields *must* come first, or precacheReferenceOffsets()
   3550  * will break.
   3551  */
   3552 static bool computeFieldOffsets(ClassObject* clazz)
   3553 {
   3554     int fieldOffset;
   3555     int i, j;
   3556 
   3557     dvmLinearReadWrite(clazz->classLoader, clazz->ifields);
   3558 
   3559     if (clazz->super != NULL)
   3560         fieldOffset = clazz->super->objectSize;
   3561     else
   3562         fieldOffset = OFFSETOF_MEMBER(DataObject, instanceData);
   3563 
   3564     LOGVV("--- computeFieldOffsets '%s'", clazz->descriptor);
   3565 
   3566     //ALOGI("OFFSETS fieldCount=%d", clazz->ifieldCount);
   3567     //ALOGI("dataobj, instance: %d", offsetof(DataObject, instanceData));
   3568     //ALOGI("classobj, access: %d", offsetof(ClassObject, accessFlags));
   3569     //ALOGI("super=%p, fieldOffset=%d", clazz->super, fieldOffset);
   3570 
   3571     /*
   3572      * Start by moving all reference fields to the front.
   3573      */
   3574     clazz->ifieldRefCount = 0;
   3575     j = clazz->ifieldCount - 1;
   3576     for (i = 0; i < clazz->ifieldCount; i++) {
   3577         InstField* pField = &clazz->ifields[i];
   3578         char c = pField->signature[0];
   3579 
   3580         if (c != '[' && c != 'L') {
   3581             /* This isn't a reference field; see if any reference fields
   3582              * follow this one.  If so, we'll move it to this position.
   3583              * (quicksort-style partitioning)
   3584              */
   3585             while (j > i) {
   3586                 InstField* refField = &clazz->ifields[j--];
   3587                 char rc = refField->signature[0];
   3588 
   3589                 if (rc == '[' || rc == 'L') {
   3590                     /* Here's a reference field that follows at least one
   3591                      * non-reference field.  Swap it with the current field.
   3592                      * (When this returns, "pField" points to the reference
   3593                      * field, and "refField" points to the non-ref field.)
   3594                      */
   3595                     swapField(pField, refField);
   3596 
   3597                     /* Fix the signature.
   3598                      */
   3599                     c = rc;
   3600 
   3601                     clazz->ifieldRefCount++;
   3602                     break;
   3603                 }
   3604             }
   3605             /* We may or may not have swapped a field.
   3606              */
   3607         } else {
   3608             /* This is a reference field.
   3609              */
   3610             clazz->ifieldRefCount++;
   3611         }
   3612 
   3613         /*
   3614          * If we've hit the end of the reference fields, break.
   3615          */
   3616         if (c != '[' && c != 'L')
   3617             break;
   3618 
   3619         pField->byteOffset = fieldOffset;
   3620         fieldOffset += sizeof(u4);
   3621         LOGVV("  --- offset1 '%s'=%d", pField->name,pField->byteOffset);
   3622     }
   3623 
   3624     /*
   3625      * Now we want to pack all of the double-wide fields together.  If we're
   3626      * not aligned, though, we want to shuffle one 32-bit field into place.
   3627      * If we can't find one, we'll have to pad it.
   3628      */
   3629     if (i != clazz->ifieldCount && (fieldOffset & 0x04) != 0) {
   3630         LOGVV("  +++ not aligned");
   3631 
   3632         InstField* pField = &clazz->ifields[i];
   3633         char c = pField->signature[0];
   3634 
   3635         if (c != 'J' && c != 'D') {
   3636             /*
   3637              * The field that comes next is 32-bit, so just advance past it.
   3638              */
   3639             assert(c != '[' && c != 'L');
   3640             pField->byteOffset = fieldOffset;
   3641             fieldOffset += sizeof(u4);
   3642             i++;
   3643             LOGVV("  --- offset2 '%s'=%d",
   3644                 pField->name, pField->byteOffset);
   3645         } else {
   3646             /*
   3647              * Next field is 64-bit, so search for a 32-bit field we can
   3648              * swap into it.
   3649              */
   3650             bool found = false;
   3651             j = clazz->ifieldCount - 1;
   3652             while (j > i) {
   3653                 InstField* singleField = &clazz->ifields[j--];
   3654                 char rc = singleField->signature[0];
   3655 
   3656                 if (rc != 'J' && rc != 'D') {
   3657                     swapField(pField, singleField);
   3658                     //c = rc;
   3659                     LOGVV("  +++ swapped '%s' for alignment",
   3660                         pField->name);
   3661                     pField->byteOffset = fieldOffset;
   3662                     fieldOffset += sizeof(u4);
   3663                     LOGVV("  --- offset3 '%s'=%d",
   3664                         pField->name, pField->byteOffset);
   3665                     found = true;
   3666                     i++;
   3667                     break;
   3668                 }
   3669             }
   3670             if (!found) {
   3671                 ALOGV("  +++ inserting pad field in '%s'", clazz->descriptor);
   3672                 fieldOffset += sizeof(u4);
   3673             }
   3674         }
   3675     }
   3676 
   3677     /*
   3678      * Alignment is good, shuffle any double-wide fields forward, and
   3679      * finish assigning field offsets to all fields.
   3680      */
   3681     assert(i == clazz->ifieldCount || (fieldOffset & 0x04) == 0);
   3682     j = clazz->ifieldCount - 1;
   3683     for ( ; i < clazz->ifieldCount; i++) {
   3684         InstField* pField = &clazz->ifields[i];
   3685         char c = pField->signature[0];
   3686 
   3687         if (c != 'D' && c != 'J') {
   3688             /* This isn't a double-wide field; see if any double fields
   3689              * follow this one.  If so, we'll move it to this position.
   3690              * (quicksort-style partitioning)
   3691              */
   3692             while (j > i) {
   3693                 InstField* doubleField = &clazz->ifields[j--];
   3694                 char rc = doubleField->signature[0];
   3695 
   3696                 if (rc == 'D' || rc == 'J') {
   3697                     /* Here's a double-wide field that follows at least one
   3698                      * non-double field.  Swap it with the current field.
   3699                      * (When this returns, "pField" points to the reference
   3700                      * field, and "doubleField" points to the non-double field.)
   3701                      */
   3702                     swapField(pField, doubleField);
   3703                     c = rc;
   3704 
   3705                     break;
   3706                 }
   3707             }
   3708             /* We may or may not have swapped a field.
   3709              */
   3710         } else {
   3711             /* This is a double-wide field, leave it be.
   3712              */
   3713         }
   3714 
   3715         pField->byteOffset = fieldOffset;
   3716         LOGVV("  --- offset4 '%s'=%d", pField->name,pField->byteOffset);
   3717         fieldOffset += sizeof(u4);
   3718         if (c == 'J' || c == 'D')
   3719             fieldOffset += sizeof(u4);
   3720     }
   3721 
   3722 #ifndef NDEBUG
   3723     /* Make sure that all reference fields appear before
   3724      * non-reference fields, and all double-wide fields are aligned.
   3725      */
   3726     j = 0;  // seen non-ref
   3727     for (i = 0; i < clazz->ifieldCount; i++) {
   3728         InstField *pField = &clazz->ifields[i];
   3729         char c = pField->signature[0];
   3730 
   3731         if (c == 'D' || c == 'J') {
   3732             assert((pField->byteOffset & 0x07) == 0);
   3733         }
   3734 
   3735         if (c != '[' && c != 'L') {
   3736             if (!j) {
   3737                 assert(i == clazz->ifieldRefCount);
   3738                 j = 1;
   3739             }
   3740         } else if (j) {
   3741             assert(false);
   3742         }
   3743     }
   3744     if (!j) {
   3745         assert(clazz->ifieldRefCount == clazz->ifieldCount);
   3746     }
   3747 #endif
   3748 
   3749     /*
   3750      * We map a C struct directly on top of java/lang/Class objects.  Make
   3751      * sure we left enough room for the instance fields.
   3752      */
   3753     assert(!dvmIsTheClassClass(clazz) || (size_t)fieldOffset <
   3754         OFFSETOF_MEMBER(ClassObject, instanceData) + sizeof(clazz->instanceData));
   3755 
   3756     clazz->objectSize = fieldOffset;
   3757 
   3758     dvmLinearReadOnly(clazz->classLoader, clazz->ifields);
   3759     return true;
   3760 }
   3761 
   3762 /*
   3763  * The class failed to initialize on a previous attempt, so we want to throw
   3764  * a NoClassDefFoundError (v2 2.17.5).  The exception to this rule is if we
   3765  * failed in verification, in which case v2 5.4.1 says we need to re-throw
   3766  * the previous error.
   3767  */
   3768 static void throwEarlierClassFailure(ClassObject* clazz)
   3769 {
   3770     ALOGI("Rejecting re-init on previously-failed class %s v=%p",
   3771         clazz->descriptor, clazz->verifyErrorClass);
   3772 
   3773     if (clazz->verifyErrorClass == NULL) {
   3774         dvmThrowNoClassDefFoundError(clazz->descriptor);
   3775     } else {
   3776         dvmThrowExceptionWithClassMessage(clazz->verifyErrorClass,
   3777             clazz->descriptor);
   3778     }
   3779 }
   3780 
   3781 /*
   3782  * Initialize any static fields whose values are stored in
   3783  * the DEX file.  This must be done during class initialization.
   3784  */
   3785 static void initSFields(ClassObject* clazz)
   3786 {
   3787     Thread* self = dvmThreadSelf(); /* for dvmReleaseTrackedAlloc() */
   3788     DexFile* pDexFile;
   3789     const DexClassDef* pClassDef;
   3790     const DexEncodedArray* pValueList;
   3791     EncodedArrayIterator iterator;
   3792     int i;
   3793 
   3794     if (clazz->sfieldCount == 0) {
   3795         return;
   3796     }
   3797     if (clazz->pDvmDex == NULL) {
   3798         /* generated class; any static fields should already be set up */
   3799         ALOGV("Not initializing static fields in %s", clazz->descriptor);
   3800         return;
   3801     }
   3802     pDexFile = clazz->pDvmDex->pDexFile;
   3803 
   3804     pClassDef = dexFindClass(pDexFile, clazz->descriptor);
   3805     assert(pClassDef != NULL);
   3806 
   3807     pValueList = dexGetStaticValuesList(pDexFile, pClassDef);
   3808     if (pValueList == NULL) {
   3809         return;
   3810     }
   3811 
   3812     dvmEncodedArrayIteratorInitialize(&iterator, pValueList, clazz);
   3813 
   3814     /*
   3815      * Iterate over the initial values array, setting the corresponding
   3816      * static field for each array element.
   3817      */
   3818 
   3819     for (i = 0; dvmEncodedArrayIteratorHasNext(&iterator); i++) {
   3820         AnnotationValue value;
   3821         bool parsed = dvmEncodedArrayIteratorGetNext(&iterator, &value);
   3822         StaticField* sfield = &clazz->sfields[i];
   3823         const char* descriptor = sfield->signature;
   3824         bool isObj = false;
   3825 
   3826         if (! parsed) {
   3827             /*
   3828              * TODO: Eventually verification should attempt to ensure
   3829              * that this can't happen at least due to a data integrity
   3830              * problem.
   3831              */
   3832             ALOGE("Static initializer parse failed for %s at index %d",
   3833                     clazz->descriptor, i);
   3834             dvmAbort();
   3835         }
   3836 
   3837         /* Verify that the value we got was of a valid type. */
   3838 
   3839         switch (descriptor[0]) {
   3840             case 'Z': parsed = (value.type == kDexAnnotationBoolean); break;
   3841             case 'B': parsed = (value.type == kDexAnnotationByte);    break;
   3842             case 'C': parsed = (value.type == kDexAnnotationChar);    break;
   3843             case 'S': parsed = (value.type == kDexAnnotationShort);   break;
   3844             case 'I': parsed = (value.type == kDexAnnotationInt);     break;
   3845             case 'J': parsed = (value.type == kDexAnnotationLong);    break;
   3846             case 'F': parsed = (value.type == kDexAnnotationFloat);   break;
   3847             case 'D': parsed = (value.type == kDexAnnotationDouble);  break;
   3848             case '[': parsed = (value.type == kDexAnnotationNull);    break;
   3849             case 'L': {
   3850                 switch (value.type) {
   3851                     case kDexAnnotationNull: {
   3852                         /* No need for further tests. */
   3853                         break;
   3854                     }
   3855                     case kDexAnnotationString: {
   3856                         parsed =
   3857                             (strcmp(descriptor, "Ljava/lang/String;") == 0);
   3858                         isObj = true;
   3859                         break;
   3860                     }
   3861                     case kDexAnnotationType: {
   3862                         parsed =
   3863                             (strcmp(descriptor, "Ljava/lang/Class;") == 0);
   3864                         isObj = true;
   3865                         break;
   3866                     }
   3867                     default: {
   3868                         parsed = false;
   3869                         break;
   3870                     }
   3871                 }
   3872                 break;
   3873             }
   3874             default: {
   3875                 parsed = false;
   3876                 break;
   3877             }
   3878         }
   3879 
   3880         if (parsed) {
   3881             /*
   3882              * All's well, so store the value.
   3883              */
   3884             if (isObj) {
   3885                 dvmSetStaticFieldObject(sfield, (Object*)value.value.l);
   3886                 dvmReleaseTrackedAlloc((Object*)value.value.l, self);
   3887             } else {
   3888                 /*
   3889                  * Note: This always stores the full width of a
   3890                  * JValue, even though most of the time only the first
   3891                  * word is needed.
   3892                  */
   3893                 sfield->value = value.value;
   3894             }
   3895         } else {
   3896             /*
   3897              * Something up above had a problem. TODO: See comment
   3898              * above the switch about verfication.
   3899              */
   3900             ALOGE("Bogus static initialization: value type %d in field type "
   3901                     "%s for %s at index %d",
   3902                 value.type, descriptor, clazz->descriptor, i);
   3903             dvmAbort();
   3904         }
   3905