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