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