Class.cpp revision 77514abeade6960daf67f5fec3a865df29ea0256
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, padFlags, jniArgInfo;
2191    char sigByte;
2192    int stackOffset, padMask;
2193    u4 hints;
2194
2195    /* The first shorty character is the return type. */
2196    switch (*(sig++)) {
2197    case 'V':
2198        returnType = DALVIK_JNI_RETURN_VOID;
2199        break;
2200    case 'F':
2201        returnType = DALVIK_JNI_RETURN_FLOAT;
2202        break;
2203    case 'D':
2204        returnType = DALVIK_JNI_RETURN_DOUBLE;
2205        break;
2206    case 'J':
2207        returnType = DALVIK_JNI_RETURN_S8;
2208        break;
2209    case 'Z':
2210    case 'B':
2211        returnType = DALVIK_JNI_RETURN_S1;
2212        break;
2213    case 'C':
2214        returnType = DALVIK_JNI_RETURN_U2;
2215        break;
2216    case 'S':
2217        returnType = DALVIK_JNI_RETURN_S2;
2218        break;
2219    default:
2220        returnType = DALVIK_JNI_RETURN_S4;
2221        break;
2222    }
2223
2224    jniArgInfo = returnType << DALVIK_JNI_RETURN_SHIFT;
2225
2226    hints = dvmPlatformInvokeHints(proto);
2227
2228    if (hints & DALVIK_JNI_NO_ARG_INFO) {
2229        jniArgInfo |= DALVIK_JNI_NO_ARG_INFO;
2230    } else {
2231        assert((hints & DALVIK_JNI_RETURN_MASK) == 0);
2232        jniArgInfo |= hints;
2233    }
2234
2235    return jniArgInfo;
2236}
2237
2238/*
2239 * Load information about a static field.
2240 *
2241 * This also "prepares" static fields by initializing them
2242 * to their "standard default values".
2243 */
2244static void loadSFieldFromDex(ClassObject* clazz,
2245    const DexField* pDexSField, StaticField* sfield)
2246{
2247    DexFile* pDexFile = clazz->pDvmDex->pDexFile;
2248    const DexFieldId* pFieldId;
2249
2250    pFieldId = dexGetFieldId(pDexFile, pDexSField->fieldIdx);
2251
2252    sfield->field.clazz = clazz;
2253    sfield->field.name = dexStringById(pDexFile, pFieldId->nameIdx);
2254    sfield->field.signature = dexStringByTypeIdx(pDexFile, pFieldId->typeIdx);
2255    sfield->field.accessFlags = pDexSField->accessFlags;
2256
2257    /* Static object field values are set to "standard default values"
2258     * (null or 0) until the class is initialized.  We delay loading
2259     * constant values from the class until that time.
2260     */
2261    //sfield->value.j = 0;
2262    assert(sfield->value.j == 0LL);     // cleared earlier with calloc
2263
2264#ifdef PROFILE_FIELD_ACCESS
2265    sfield->field.gets = sfield->field.puts = 0;
2266#endif
2267}
2268
2269/*
2270 * Load information about an instance field.
2271 */
2272static void loadIFieldFromDex(ClassObject* clazz,
2273    const DexField* pDexIField, InstField* ifield)
2274{
2275    DexFile* pDexFile = clazz->pDvmDex->pDexFile;
2276    const DexFieldId* pFieldId;
2277
2278    pFieldId = dexGetFieldId(pDexFile, pDexIField->fieldIdx);
2279
2280    ifield->field.clazz = clazz;
2281    ifield->field.name = dexStringById(pDexFile, pFieldId->nameIdx);
2282    ifield->field.signature = dexStringByTypeIdx(pDexFile, pFieldId->typeIdx);
2283    ifield->field.accessFlags = pDexIField->accessFlags;
2284#ifndef NDEBUG
2285    assert(ifield->byteOffset == 0);    // cleared earlier with calloc
2286    ifield->byteOffset = -1;    // make it obvious if we fail to set later
2287#endif
2288
2289#ifdef PROFILE_FIELD_ACCESS
2290    ifield->field.gets = ifield->field.puts = 0;
2291#endif
2292}
2293
2294/*
2295 * Cache java.lang.ref.Reference fields and methods.
2296 */
2297static bool precacheReferenceOffsets(ClassObject* clazz)
2298{
2299    Method *meth;
2300    int i;
2301
2302    /* We trick the GC object scanner by not counting
2303     * java.lang.ref.Reference.referent as an object
2304     * field.  It will get explicitly scanned as part
2305     * of the reference-walking process.
2306     *
2307     * Find the object field named "referent" and put it
2308     * just after the list of object reference fields.
2309     */
2310    dvmLinearReadWrite(clazz->classLoader, clazz->ifields);
2311    for (i = 0; i < clazz->ifieldRefCount; i++) {
2312        InstField *pField = &clazz->ifields[i];
2313        if (strcmp(pField->field.name, "referent") == 0) {
2314            int targetIndex;
2315
2316            /* Swap this field with the last object field.
2317             */
2318            targetIndex = clazz->ifieldRefCount - 1;
2319            if (i != targetIndex) {
2320                InstField *swapField = &clazz->ifields[targetIndex];
2321                InstField tmpField;
2322                int tmpByteOffset;
2323
2324                /* It's not currently strictly necessary
2325                 * for the fields to be in byteOffset order,
2326                 * but it's more predictable that way.
2327                 */
2328                tmpByteOffset = swapField->byteOffset;
2329                swapField->byteOffset = pField->byteOffset;
2330                pField->byteOffset = tmpByteOffset;
2331
2332                tmpField = *swapField;
2333                *swapField = *pField;
2334                *pField = tmpField;
2335            }
2336
2337            /* One fewer object field (wink wink).
2338             */
2339            clazz->ifieldRefCount--;
2340            i--;        /* don't trip "didn't find it" test if field was last */
2341            break;
2342        }
2343    }
2344    dvmLinearReadOnly(clazz->classLoader, clazz->ifields);
2345    if (i == clazz->ifieldRefCount) {
2346        LOGE("Unable to reorder 'referent' in %s\n", clazz->descriptor);
2347        return false;
2348    }
2349
2350    /* Cache pretty much everything about Reference so that
2351     * we don't need to call interpreted code when clearing/enqueueing
2352     * references.  This is fragile, so we'll be paranoid.
2353     */
2354    gDvm.classJavaLangRefReference = clazz;
2355
2356    gDvm.offJavaLangRefReference_referent =
2357        dvmFindFieldOffset(gDvm.classJavaLangRefReference,
2358                "referent", "Ljava/lang/Object;");
2359    assert(gDvm.offJavaLangRefReference_referent >= 0);
2360
2361    gDvm.offJavaLangRefReference_queue =
2362        dvmFindFieldOffset(gDvm.classJavaLangRefReference,
2363                "queue", "Ljava/lang/ref/ReferenceQueue;");
2364    assert(gDvm.offJavaLangRefReference_queue >= 0);
2365
2366    gDvm.offJavaLangRefReference_queueNext =
2367        dvmFindFieldOffset(gDvm.classJavaLangRefReference,
2368                "queueNext", "Ljava/lang/ref/Reference;");
2369    assert(gDvm.offJavaLangRefReference_queueNext >= 0);
2370
2371    gDvm.offJavaLangRefReference_vmData =
2372        dvmFindFieldOffset(gDvm.classJavaLangRefReference,
2373                "vmData", "I");
2374    assert(gDvm.offJavaLangRefReference_vmData >= 0);
2375
2376    /* enqueueInternal() is private and thus a direct method. */
2377    meth = dvmFindDirectMethodByDescriptor(clazz, "enqueueInternal", "()Z");
2378    assert(meth != NULL);
2379    gDvm.methJavaLangRefReference_enqueueInternal = meth;
2380
2381    return true;
2382}
2383
2384
2385/*
2386 * Set the bitmap of reference offsets, refOffsets, from the ifields
2387 * list.
2388 */
2389static void computeRefOffsets(ClassObject* clazz)
2390{
2391    if (clazz->super != NULL) {
2392        clazz->refOffsets = clazz->super->refOffsets;
2393    } else {
2394        clazz->refOffsets = 0;
2395    }
2396    /*
2397     * If our superclass overflowed, we don't stand a chance.
2398     */
2399    if (clazz->refOffsets != CLASS_WALK_SUPER) {
2400        InstField *f;
2401        int i;
2402
2403        /* All of the fields that contain object references
2404         * are guaranteed to be at the beginning of the ifields list.
2405         */
2406        f = clazz->ifields;
2407        const int ifieldRefCount = clazz->ifieldRefCount;
2408        for (i = 0; i < ifieldRefCount; i++) {
2409          /*
2410           * Note that, per the comment on struct InstField,
2411           * f->byteOffset is the offset from the beginning of
2412           * obj, not the offset into obj->instanceData.
2413           */
2414          assert(f->byteOffset >= (int) CLASS_SMALLEST_OFFSET);
2415          assert((f->byteOffset & (CLASS_OFFSET_ALIGNMENT - 1)) == 0);
2416          if (CLASS_CAN_ENCODE_OFFSET(f->byteOffset)) {
2417              u4 newBit = CLASS_BIT_FROM_OFFSET(f->byteOffset);
2418              assert(newBit != 0);
2419              clazz->refOffsets |= newBit;
2420          } else {
2421              clazz->refOffsets = CLASS_WALK_SUPER;
2422              break;
2423          }
2424          f++;
2425        }
2426    }
2427}
2428
2429
2430/*
2431 * Link (prepare and resolve).  Verification is deferred until later.
2432 *
2433 * This converts symbolic references into pointers.  It's independent of
2434 * the source file format.
2435 *
2436 * If "classesResolved" is false, we assume that superclassIdx and
2437 * interfaces[] are holding class reference indices rather than pointers.
2438 * The class references will be resolved during link.  (This is done when
2439 * loading from DEX to avoid having to create additional storage to pass
2440 * the indices around.)
2441 *
2442 * Returns "false" with an exception pending on failure.
2443 */
2444bool dvmLinkClass(ClassObject* clazz, bool classesResolved)
2445{
2446    u4 superclassIdx = 0;
2447    bool okay = false;
2448    bool resolve_okay;
2449    int numInterfacesResolved = 0;
2450    int i;
2451
2452    if (gDvm.verboseClass)
2453        LOGV("CLASS: linking '%s'...\n", clazz->descriptor);
2454
2455    /* "Resolve" the class.
2456     *
2457     * At this point, clazz's reference fields contain Dex
2458     * file indices instead of direct object references.
2459     * We need to translate those indices into real references,
2460     * while making sure that the GC doesn't sweep any of
2461     * the referenced objects.
2462     *
2463     * The GC will avoid scanning this object as long as
2464     * clazz->obj.clazz is gDvm.unlinkedJavaLangClass.
2465     * Once clazz is ready, we'll replace clazz->obj.clazz
2466     * with gDvm.classJavaLangClass to let the GC know
2467     * to look at it.
2468     */
2469    assert(clazz->obj.clazz == gDvm.unlinkedJavaLangClass);
2470
2471    /* It's important that we take care of java.lang.Class
2472     * first.  If we were to do this after looking up the
2473     * superclass (below), Class wouldn't be ready when
2474     * java.lang.Object needed it.
2475     *
2476     * Note that we don't set clazz->obj.clazz yet.
2477     */
2478    if (gDvm.classJavaLangClass == NULL) {
2479        if (clazz->classLoader == NULL &&
2480            strcmp(clazz->descriptor, "Ljava/lang/Class;") == 0)
2481        {
2482            gDvm.classJavaLangClass = clazz;
2483        } else {
2484            gDvm.classJavaLangClass =
2485                dvmFindSystemClassNoInit("Ljava/lang/Class;");
2486            if (gDvm.classJavaLangClass == NULL) {
2487                /* should have thrown one */
2488                assert(dvmCheckException(dvmThreadSelf()));
2489                goto bail;
2490            }
2491        }
2492    }
2493    assert(gDvm.classJavaLangClass != NULL);
2494
2495    /*
2496     * Resolve all Dex indices so we can hand the ClassObject
2497     * over to the GC.  If we fail at any point, we need to remove
2498     * any tracked references to avoid leaking memory.
2499     */
2500
2501    /*
2502     * All classes have a direct superclass, except for java/lang/Object.
2503     */
2504    if (!classesResolved) {
2505        superclassIdx = (u4) clazz->super;          /* unpack temp store */
2506        clazz->super = NULL;
2507    }
2508    if (strcmp(clazz->descriptor, "Ljava/lang/Object;") == 0) {
2509        assert(!classesResolved);
2510        if (superclassIdx != kDexNoIndex) {
2511            /* TODO: is this invariant true for all java/lang/Objects,
2512             * regardless of the class loader?  For now, assume it is.
2513             */
2514            dvmThrowException("Ljava/lang/ClassFormatError;",
2515                "java.lang.Object has a superclass");
2516            goto bail;
2517        }
2518
2519        /* Don't finalize objects whose classes use the
2520         * default (empty) Object.finalize().
2521         */
2522        CLEAR_CLASS_FLAG(clazz, CLASS_ISFINALIZABLE);
2523    } else {
2524        if (!classesResolved) {
2525            if (superclassIdx == kDexNoIndex) {
2526                dvmThrowException("Ljava/lang/LinkageError;",
2527                    "no superclass defined");
2528                goto bail;
2529            }
2530            clazz->super = dvmResolveClass(clazz, superclassIdx, false);
2531            if (clazz->super == NULL) {
2532                assert(dvmCheckException(dvmThreadSelf()));
2533                if (gDvm.optimizing) {
2534                    /* happens with "external" libs */
2535                    LOGV("Unable to resolve superclass of %s (%d)\n",
2536                        clazz->descriptor, superclassIdx);
2537                } else {
2538                    LOGW("Unable to resolve superclass of %s (%d)\n",
2539                        clazz->descriptor, superclassIdx);
2540                }
2541                goto bail;
2542            }
2543        }
2544        /* verify */
2545        if (dvmIsFinalClass(clazz->super)) {
2546            LOGW("Superclass of '%s' is final '%s'\n",
2547                clazz->descriptor, clazz->super->descriptor);
2548            dvmThrowException("Ljava/lang/IncompatibleClassChangeError;",
2549                "superclass is final");
2550            goto bail;
2551        } else if (dvmIsInterfaceClass(clazz->super)) {
2552            LOGW("Superclass of '%s' is interface '%s'\n",
2553                clazz->descriptor, clazz->super->descriptor);
2554            dvmThrowException("Ljava/lang/IncompatibleClassChangeError;",
2555                "superclass is an interface");
2556            goto bail;
2557        } else if (!dvmCheckClassAccess(clazz, clazz->super)) {
2558            LOGW("Superclass of '%s' (%s) is not accessible\n",
2559                clazz->descriptor, clazz->super->descriptor);
2560            dvmThrowException("Ljava/lang/IllegalAccessError;",
2561                "superclass not accessible");
2562            goto bail;
2563        }
2564
2565        /* Don't let the GC reclaim the superclass.
2566         * TODO: shouldn't be needed; remove when things stabilize
2567         */
2568        dvmAddTrackedAlloc((Object *)clazz->super, NULL);
2569
2570        /* Inherit finalizability from the superclass.  If this
2571         * class also overrides finalize(), its CLASS_ISFINALIZABLE
2572         * bit will already be set.
2573         */
2574        if (IS_CLASS_FLAG_SET(clazz->super, CLASS_ISFINALIZABLE)) {
2575            SET_CLASS_FLAG(clazz, CLASS_ISFINALIZABLE);
2576        }
2577
2578        /* See if this class descends from java.lang.Reference
2579         * and set the class flags appropriately.
2580         */
2581        if (IS_CLASS_FLAG_SET(clazz->super, CLASS_ISREFERENCE)) {
2582            u4 superRefFlags;
2583
2584            /* We've already determined the reference type of this
2585             * inheritance chain.  Inherit reference-ness from the superclass.
2586             */
2587            superRefFlags = GET_CLASS_FLAG_GROUP(clazz->super,
2588                    CLASS_ISREFERENCE |
2589                    CLASS_ISWEAKREFERENCE |
2590                    CLASS_ISPHANTOMREFERENCE);
2591            SET_CLASS_FLAG(clazz, superRefFlags);
2592        } else if (clazz->classLoader == NULL &&
2593                clazz->super->classLoader == NULL &&
2594                strcmp(clazz->super->descriptor,
2595                       "Ljava/lang/ref/Reference;") == 0)
2596        {
2597            u4 refFlags;
2598
2599            /* This class extends Reference, which means it should
2600             * be one of the magic Soft/Weak/PhantomReference classes.
2601             */
2602            refFlags = CLASS_ISREFERENCE;
2603            if (strcmp(clazz->descriptor,
2604                       "Ljava/lang/ref/SoftReference;") == 0)
2605            {
2606                /* Only CLASS_ISREFERENCE is set for soft references.
2607                 */
2608            } else if (strcmp(clazz->descriptor,
2609                       "Ljava/lang/ref/WeakReference;") == 0)
2610            {
2611                refFlags |= CLASS_ISWEAKREFERENCE;
2612            } else if (strcmp(clazz->descriptor,
2613                       "Ljava/lang/ref/PhantomReference;") == 0)
2614            {
2615                refFlags |= CLASS_ISPHANTOMREFERENCE;
2616            } else {
2617                /* No-one else is allowed to inherit directly
2618                 * from Reference.
2619                 */
2620//xxx is this the right exception?  better than an assertion.
2621                dvmThrowException("Ljava/lang/LinkageError;",
2622                    "illegal inheritance from Reference");
2623                goto bail;
2624            }
2625
2626            /* The class should not have any reference bits set yet.
2627             */
2628            assert(GET_CLASS_FLAG_GROUP(clazz,
2629                    CLASS_ISREFERENCE |
2630                    CLASS_ISWEAKREFERENCE |
2631                    CLASS_ISPHANTOMREFERENCE) == 0);
2632
2633            SET_CLASS_FLAG(clazz, refFlags);
2634        }
2635    }
2636
2637    if (!classesResolved && clazz->interfaceCount > 0) {
2638        /*
2639         * Resolve the interfaces implemented directly by this class.  We
2640         * stuffed the class index into the interface pointer slot.
2641         */
2642        dvmLinearReadWrite(clazz->classLoader, clazz->interfaces);
2643        for (i = 0; i < clazz->interfaceCount; i++) {
2644            u4 interfaceIdx;
2645
2646            interfaceIdx = (u4) clazz->interfaces[i];   /* unpack temp store */
2647            assert(interfaceIdx != kDexNoIndex);
2648
2649            clazz->interfaces[i] = dvmResolveClass(clazz, interfaceIdx, false);
2650            if (clazz->interfaces[i] == NULL) {
2651                const DexFile* pDexFile = clazz->pDvmDex->pDexFile;
2652
2653                assert(dvmCheckException(dvmThreadSelf()));
2654                dvmLinearReadOnly(clazz->classLoader, clazz->interfaces);
2655
2656                const char* classDescriptor;
2657                classDescriptor = dexStringByTypeIdx(pDexFile, interfaceIdx);
2658                if (gDvm.optimizing) {
2659                    /* happens with "external" libs */
2660                    LOGV("Failed resolving %s interface %d '%s'\n",
2661                        clazz->descriptor, interfaceIdx, classDescriptor);
2662                } else {
2663                    LOGI("Failed resolving %s interface %d '%s'\n",
2664                        clazz->descriptor, interfaceIdx, classDescriptor);
2665                }
2666                goto bail_during_resolve;
2667            }
2668
2669            /* are we allowed to implement this interface? */
2670            if (!dvmCheckClassAccess(clazz, clazz->interfaces[i])) {
2671                dvmLinearReadOnly(clazz->classLoader, clazz->interfaces);
2672                LOGW("Interface '%s' is not accessible to '%s'\n",
2673                    clazz->interfaces[i]->descriptor, clazz->descriptor);
2674                dvmThrowException("Ljava/lang/IllegalAccessError;",
2675                    "interface not accessible");
2676                goto bail_during_resolve;
2677            }
2678
2679            /* Don't let the GC reclaim the interface class.
2680             * TODO: shouldn't be needed; remove when things stabilize
2681             */
2682            dvmAddTrackedAlloc((Object *)clazz->interfaces[i], NULL);
2683            numInterfacesResolved++;
2684
2685            LOGVV("+++  found interface '%s'\n",
2686                clazz->interfaces[i]->descriptor);
2687        }
2688        dvmLinearReadOnly(clazz->classLoader, clazz->interfaces);
2689    }
2690
2691    /*
2692     * The ClassObject is now in a GC-able state.  We let the GC
2693     * realize this by punching in the real class type, which is
2694     * always java.lang.Class.
2695     *
2696     * After this line, clazz will be fair game for the GC.
2697     * Every field that the GC will look at must now be valid:
2698     * - clazz->super
2699     * - class->classLoader
2700     * - clazz->sfields
2701     * - clazz->interfaces
2702     */
2703    clazz->obj.clazz = gDvm.classJavaLangClass;
2704
2705    if (false) {
2706bail_during_resolve:
2707        resolve_okay = false;
2708    } else {
2709        resolve_okay = true;
2710    }
2711
2712    /*
2713     * Now that the GC can scan the ClassObject, we can let
2714     * go of the explicit references we were holding onto.
2715     *
2716     * Either that or we failed, in which case we need to
2717     * release the references so we don't leak memory.
2718     */
2719    if (clazz->super != NULL) {
2720        dvmReleaseTrackedAlloc((Object *)clazz->super, NULL);
2721    }
2722    for (i = 0; i < numInterfacesResolved; i++) {
2723        dvmReleaseTrackedAlloc((Object *)clazz->interfaces[i], NULL);
2724    }
2725
2726    if (!resolve_okay) {
2727        //LOGW("resolve_okay is false\n");
2728        goto bail;
2729    }
2730
2731    /*
2732     * Populate vtable.
2733     */
2734    if (dvmIsInterfaceClass(clazz)) {
2735        /* no vtable; just set the method indices */
2736        int count = clazz->virtualMethodCount;
2737
2738        if (count != (u2) count) {
2739            LOGE("Too many methods (%d) in interface '%s'\n", count,
2740                 clazz->descriptor);
2741            goto bail;
2742        }
2743
2744        dvmLinearReadWrite(clazz->classLoader, clazz->virtualMethods);
2745
2746        for (i = 0; i < count; i++)
2747            clazz->virtualMethods[i].methodIndex = (u2) i;
2748
2749        dvmLinearReadOnly(clazz->classLoader, clazz->virtualMethods);
2750    } else {
2751        if (!createVtable(clazz)) {
2752            LOGW("failed creating vtable\n");
2753            goto bail;
2754        }
2755    }
2756
2757    /*
2758     * Populate interface method tables.  Can alter the vtable.
2759     */
2760    if (!createIftable(clazz))
2761        goto bail;
2762
2763    /*
2764     * Insert special-purpose "stub" method implementations.
2765     */
2766    if (!insertMethodStubs(clazz))
2767        goto bail;
2768
2769    /*
2770     * Compute instance field offsets and, hence, the size of the object.
2771     */
2772    if (!computeFieldOffsets(clazz))
2773        goto bail;
2774
2775    /*
2776     * Cache fields and methods from java/lang/ref/Reference and
2777     * java/lang/Class.  This has to happen after computeFieldOffsets().
2778     */
2779    if (clazz->classLoader == NULL) {
2780        if (strcmp(clazz->descriptor, "Ljava/lang/ref/Reference;") == 0) {
2781            if (!precacheReferenceOffsets(clazz)) {
2782                LOGE("failed pre-caching Reference offsets\n");
2783                dvmThrowException("Ljava/lang/InternalError;", NULL);
2784                goto bail;
2785            }
2786        } else if (clazz == gDvm.classJavaLangClass) {
2787            gDvm.offJavaLangClass_pd = dvmFindFieldOffset(clazz, "pd",
2788                "Ljava/security/ProtectionDomain;");
2789            if (gDvm.offJavaLangClass_pd <= 0) {
2790                LOGE("ERROR: unable to find 'pd' field in Class\n");
2791                dvmAbort();     /* we're not going to get much farther */
2792                //goto bail;
2793            }
2794        }
2795    }
2796
2797    /*
2798     * Compact the offsets the GC has to examine into a bitmap, if
2799     * possible.  (This has to happen after Reference.referent is
2800     * massaged in precacheReferenceOffsets.)
2801     */
2802    computeRefOffsets(clazz);
2803
2804    /*
2805     * Done!
2806     */
2807    if (IS_CLASS_FLAG_SET(clazz, CLASS_ISPREVERIFIED))
2808        clazz->status = CLASS_VERIFIED;
2809    else
2810        clazz->status = CLASS_RESOLVED;
2811    okay = true;
2812    if (gDvm.verboseClass)
2813        LOGV("CLASS: linked '%s'\n", clazz->descriptor);
2814
2815    /*
2816     * We send CLASS_PREPARE events to the debugger from here.  The
2817     * definition of "preparation" is creating the static fields for a
2818     * class and initializing them to the standard default values, but not
2819     * executing any code (that comes later, during "initialization").
2820     *
2821     * We did the static prep in loadSFieldFromDex() while loading the class.
2822     *
2823     * The class has been prepared and resolved but possibly not yet verified
2824     * at this point.
2825     */
2826    if (gDvm.debuggerActive) {
2827        dvmDbgPostClassPrepare(clazz);
2828    }
2829
2830bail:
2831    if (!okay) {
2832        clazz->status = CLASS_ERROR;
2833        if (!dvmCheckException(dvmThreadSelf())) {
2834            dvmThrowException("Ljava/lang/VirtualMachineError;", NULL);
2835        }
2836    }
2837    return okay;
2838}
2839
2840/*
2841 * Create the virtual method table.
2842 *
2843 * The top part of the table is a copy of the table from our superclass,
2844 * with our local methods overriding theirs.  The bottom part of the table
2845 * has any new methods we defined.
2846 */
2847static bool createVtable(ClassObject* clazz)
2848{
2849    bool result = false;
2850    int maxCount;
2851    int i;
2852
2853    if (clazz->super != NULL) {
2854        //LOGI("SUPER METHODS %d %s->%s\n", clazz->super->vtableCount,
2855        //    clazz->descriptor, clazz->super->descriptor);
2856    }
2857
2858    /* the virtual methods we define, plus the superclass vtable size */
2859    maxCount = clazz->virtualMethodCount;
2860    if (clazz->super != NULL) {
2861        maxCount += clazz->super->vtableCount;
2862    } else {
2863        /* TODO: is this invariant true for all java/lang/Objects,
2864         * regardless of the class loader?  For now, assume it is.
2865         */
2866        assert(strcmp(clazz->descriptor, "Ljava/lang/Object;") == 0);
2867    }
2868    //LOGD("+++ max vmethods for '%s' is %d\n", clazz->descriptor, maxCount);
2869
2870    /*
2871     * Over-allocate the table, then realloc it down if necessary.  So
2872     * long as we don't allocate anything in between we won't cause
2873     * fragmentation, and reducing the size should be unlikely to cause
2874     * a buffer copy.
2875     */
2876    dvmLinearReadWrite(clazz->classLoader, clazz->virtualMethods);
2877    clazz->vtable = (Method**) dvmLinearAlloc(clazz->classLoader,
2878                        sizeof(Method*) * maxCount);
2879    if (clazz->vtable == NULL)
2880        goto bail;
2881
2882    if (clazz->super != NULL) {
2883        int actualCount;
2884
2885        memcpy(clazz->vtable, clazz->super->vtable,
2886            sizeof(*(clazz->vtable)) * clazz->super->vtableCount);
2887        actualCount = clazz->super->vtableCount;
2888
2889        /*
2890         * See if any of our virtual methods override the superclass.
2891         */
2892        for (i = 0; i < clazz->virtualMethodCount; i++) {
2893            Method* localMeth = &clazz->virtualMethods[i];
2894            int si;
2895
2896            for (si = 0; si < clazz->super->vtableCount; si++) {
2897                Method* superMeth = clazz->vtable[si];
2898
2899                if (dvmCompareMethodNamesAndProtos(localMeth, superMeth) == 0)
2900                {
2901                    /* verify */
2902                    if (dvmIsFinalMethod(superMeth)) {
2903                        LOGW("Method %s.%s overrides final %s.%s\n",
2904                            localMeth->clazz->descriptor, localMeth->name,
2905                            superMeth->clazz->descriptor, superMeth->name);
2906                        goto bail;
2907                    }
2908                    clazz->vtable[si] = localMeth;
2909                    localMeth->methodIndex = (u2) si;
2910                    //LOGV("+++   override %s.%s (slot %d)\n",
2911                    //    clazz->descriptor, localMeth->name, si);
2912                    break;
2913                }
2914            }
2915
2916            if (si == clazz->super->vtableCount) {
2917                /* not an override, add to end */
2918                clazz->vtable[actualCount] = localMeth;
2919                localMeth->methodIndex = (u2) actualCount;
2920                actualCount++;
2921
2922                //LOGV("+++   add method %s.%s\n",
2923                //    clazz->descriptor, localMeth->name);
2924            }
2925        }
2926
2927        if (actualCount != (u2) actualCount) {
2928            LOGE("Too many methods (%d) in class '%s'\n", actualCount,
2929                 clazz->descriptor);
2930            goto bail;
2931        }
2932
2933        assert(actualCount <= maxCount);
2934
2935        if (actualCount < maxCount) {
2936            assert(clazz->vtable != NULL);
2937            dvmLinearReadOnly(clazz->classLoader, clazz->vtable);
2938            clazz->vtable = dvmLinearRealloc(clazz->classLoader, clazz->vtable,
2939                sizeof(*(clazz->vtable)) * actualCount);
2940            if (clazz->vtable == NULL) {
2941                LOGE("vtable realloc failed\n");
2942                goto bail;
2943            } else {
2944                LOGVV("+++  reduced vtable from %d to %d\n",
2945                    maxCount, actualCount);
2946            }
2947        }
2948
2949        clazz->vtableCount = actualCount;
2950    } else {
2951        /* java/lang/Object case */
2952        int count = clazz->virtualMethodCount;
2953        if (count != (u2) count) {
2954            LOGE("Too many methods (%d) in base class '%s'\n", count,
2955                 clazz->descriptor);
2956            goto bail;
2957        }
2958
2959        for (i = 0; i < count; i++) {
2960            clazz->vtable[i] = &clazz->virtualMethods[i];
2961            clazz->virtualMethods[i].methodIndex = (u2) i;
2962        }
2963        clazz->vtableCount = clazz->virtualMethodCount;
2964    }
2965
2966    result = true;
2967
2968bail:
2969    dvmLinearReadOnly(clazz->classLoader, clazz->vtable);
2970    dvmLinearReadOnly(clazz->classLoader, clazz->virtualMethods);
2971    return result;
2972}
2973
2974/*
2975 * Create and populate "iftable".
2976 *
2977 * The set of interfaces we support is the combination of the interfaces
2978 * we implement directly and those implemented by our superclass.  Each
2979 * interface can have one or more "superinterfaces", which we must also
2980 * support.  For speed we flatten the tree out.
2981 *
2982 * We might be able to speed this up when there are lots of interfaces
2983 * by merge-sorting the class pointers and binary-searching when removing
2984 * duplicates.  We could also drop the duplicate removal -- it's only
2985 * there to reduce the memory footprint.
2986 *
2987 * Because of "Miranda methods", this may reallocate clazz->virtualMethods.
2988 *
2989 * Returns "true" on success.
2990 */
2991static bool createIftable(ClassObject* clazz)
2992{
2993    bool result = false;
2994    bool zapIftable = false;
2995    bool zapVtable = false;
2996    bool zapIfvipool = false;
2997    int ifCount, superIfCount, idx;
2998    int i;
2999
3000    if (clazz->super != NULL)
3001        superIfCount = clazz->super->iftableCount;
3002    else
3003        superIfCount = 0;
3004
3005    ifCount = superIfCount;
3006    ifCount += clazz->interfaceCount;
3007    for (i = 0; i < clazz->interfaceCount; i++)
3008        ifCount += clazz->interfaces[i]->iftableCount;
3009
3010    LOGVV("INTF: class '%s' direct w/supra=%d super=%d total=%d\n",
3011        clazz->descriptor, ifCount - superIfCount, superIfCount, ifCount);
3012
3013    if (ifCount == 0) {
3014        assert(clazz->iftableCount == 0);
3015        assert(clazz->iftable == NULL);
3016        result = true;
3017        goto bail;
3018    }
3019
3020    /*
3021     * Create a table with enough space for all interfaces, and copy the
3022     * superclass' table in.
3023     */
3024    clazz->iftable = (InterfaceEntry*) dvmLinearAlloc(clazz->classLoader,
3025                        sizeof(InterfaceEntry) * ifCount);
3026    zapIftable = true;
3027    memset(clazz->iftable, 0x00, sizeof(InterfaceEntry) * ifCount);
3028    if (superIfCount != 0) {
3029        memcpy(clazz->iftable, clazz->super->iftable,
3030            sizeof(InterfaceEntry) * superIfCount);
3031    }
3032
3033    /*
3034     * Create a flattened interface hierarchy of our immediate interfaces.
3035     */
3036    idx = superIfCount;
3037
3038    for (i = 0; i < clazz->interfaceCount; i++) {
3039        ClassObject* interf;
3040        int j;
3041
3042        interf = clazz->interfaces[i];
3043        assert(interf != NULL);
3044
3045        /* make sure this is still an interface class */
3046        if (!dvmIsInterfaceClass(interf)) {
3047            LOGW("Class '%s' implements non-interface '%s'\n",
3048                clazz->descriptor, interf->descriptor);
3049            dvmThrowExceptionWithClassMessage(
3050                "Ljava/lang/IncompatibleClassChangeError;",
3051                clazz->descriptor);
3052            goto bail;
3053        }
3054
3055        /* add entry for this interface */
3056        clazz->iftable[idx++].clazz = interf;
3057
3058        /* add entries for the interface's superinterfaces */
3059        for (j = 0; j < interf->iftableCount; j++) {
3060            clazz->iftable[idx++].clazz = interf->iftable[j].clazz;
3061        }
3062    }
3063
3064    assert(idx == ifCount);
3065
3066    if (false) {
3067        /*
3068         * Remove anything redundant from our recent additions.  Note we have
3069         * to traverse the recent adds when looking for duplicates, because
3070         * it's possible the recent additions are self-redundant.  This
3071         * reduces the memory footprint of classes with lots of inherited
3072         * interfaces.
3073         *
3074         * (I don't know if this will cause problems later on when we're trying
3075         * to find a static field.  It looks like the proper search order is
3076         * (1) current class, (2) interfaces implemented by current class,
3077         * (3) repeat with superclass.  A field implemented by an interface
3078         * and by a superclass might come out wrong if the superclass also
3079         * implements the interface.  The javac compiler will reject the
3080         * situation as ambiguous, so the concern is somewhat artificial.)
3081         *
3082         * UPDATE: this makes ReferenceType.Interfaces difficult to implement,
3083         * because it wants to return just the interfaces declared to be
3084         * implemented directly by the class.  I'm excluding this code for now.
3085         */
3086        for (i = superIfCount; i < ifCount; i++) {
3087            int j;
3088
3089            for (j = 0; j < ifCount; j++) {
3090                if (i == j)
3091                    continue;
3092                if (clazz->iftable[i].clazz == clazz->iftable[j].clazz) {
3093                    LOGVV("INTF: redundant interface %s in %s\n",
3094                        clazz->iftable[i].clazz->descriptor,
3095                        clazz->descriptor);
3096
3097                    if (i != ifCount-1)
3098                        memmove(&clazz->iftable[i], &clazz->iftable[i+1],
3099                            (ifCount - i -1) * sizeof(InterfaceEntry));
3100                    ifCount--;
3101                    i--;        // adjust for i++ above
3102                    break;
3103                }
3104            }
3105        }
3106        LOGVV("INTF: class '%s' nodupes=%d\n", clazz->descriptor, ifCount);
3107    } // if (false)
3108
3109    clazz->iftableCount = ifCount;
3110
3111    /*
3112     * If we're an interface, we don't need the vtable pointers, so
3113     * we're done.  If this class doesn't implement an interface that our
3114     * superclass doesn't have, then we again have nothing to do.
3115     */
3116    if (dvmIsInterfaceClass(clazz) || superIfCount == ifCount) {
3117        //dvmDumpClass(clazz, kDumpClassFullDetail);
3118        result = true;
3119        goto bail;
3120    }
3121
3122    /*
3123     * When we're handling invokeinterface, we probably have an object
3124     * whose type is an interface class rather than a concrete class.  We
3125     * need to convert the method reference into a vtable index.  So, for
3126     * every entry in "iftable", we create a list of vtable indices.
3127     *
3128     * Because our vtable encompasses the superclass vtable, we can use
3129     * the vtable indices from our superclass for all of the interfaces
3130     * that weren't directly implemented by us.
3131     *
3132     * Each entry in "iftable" has a pointer to the start of its set of
3133     * vtable offsets.  The iftable entries in the superclass point to
3134     * storage allocated in the superclass, and the iftable entries added
3135     * for this class point to storage allocated in this class.  "iftable"
3136     * is flat for fast access in a class and all of its subclasses, but
3137     * "ifviPool" is only created for the topmost implementor.
3138     */
3139    int poolSize = 0;
3140    for (i = superIfCount; i < ifCount; i++) {
3141        /*
3142         * Note it's valid for an interface to have no methods (e.g.
3143         * java/io/Serializable).
3144         */
3145        LOGVV("INTF: pool: %d from %s\n",
3146            clazz->iftable[i].clazz->virtualMethodCount,
3147            clazz->iftable[i].clazz->descriptor);
3148        poolSize += clazz->iftable[i].clazz->virtualMethodCount;
3149    }
3150
3151    if (poolSize == 0) {
3152        LOGVV("INTF: didn't find any new interfaces with methods\n");
3153        result = true;
3154        goto bail;
3155    }
3156
3157    clazz->ifviPoolCount = poolSize;
3158    clazz->ifviPool = (int*) dvmLinearAlloc(clazz->classLoader,
3159                        poolSize * sizeof(int*));
3160    zapIfvipool = true;
3161
3162    /*
3163     * Fill in the vtable offsets for the interfaces that weren't part of
3164     * our superclass.
3165     */
3166    int poolOffset = 0;
3167    Method** mirandaList = NULL;
3168    int mirandaCount = 0, mirandaAlloc = 0;
3169
3170    for (i = superIfCount; i < ifCount; i++) {
3171        ClassObject* interface;
3172        int methIdx;
3173
3174        clazz->iftable[i].methodIndexArray = clazz->ifviPool + poolOffset;
3175        interface = clazz->iftable[i].clazz;
3176        poolOffset += interface->virtualMethodCount;    // end here
3177
3178        /*
3179         * For each method listed in the interface's method list, find the
3180         * matching method in our class's method list.  We want to favor the
3181         * subclass over the superclass, which just requires walking
3182         * back from the end of the vtable.  (This only matters if the
3183         * superclass defines a private method and this class redefines
3184         * it -- otherwise it would use the same vtable slot.  In Dalvik
3185         * those don't end up in the virtual method table, so it shouldn't
3186         * matter which direction we go.  We walk it backward anyway.)
3187         *
3188         *
3189         * Suppose we have the following arrangement:
3190         *   public interface MyInterface
3191         *     public boolean inInterface();
3192         *   public abstract class MirandaAbstract implements MirandaInterface
3193         *     //public abstract boolean inInterface(); // not declared!
3194         *     public boolean inAbstract() { stuff }    // in vtable
3195         *   public class MirandClass extends MirandaAbstract
3196         *     public boolean inInterface() { stuff }
3197         *     public boolean inAbstract() { stuff }    // in vtable
3198         *
3199         * The javac compiler happily compiles MirandaAbstract even though
3200         * it doesn't declare all methods from its interface.  When we try
3201         * to set up a vtable for MirandaAbstract, we find that we don't
3202         * have an slot for inInterface.  To prevent this, we synthesize
3203         * abstract method declarations in MirandaAbstract.
3204         *
3205         * We have to expand vtable and update some things that point at it,
3206         * so we accumulate the method list and do it all at once below.
3207         */
3208        for (methIdx = 0; methIdx < interface->virtualMethodCount; methIdx++) {
3209            Method* imeth = &interface->virtualMethods[methIdx];
3210            int j;
3211
3212            IF_LOGVV() {
3213                char* desc = dexProtoCopyMethodDescriptor(&imeth->prototype);
3214                LOGVV("INTF:  matching '%s' '%s'\n", imeth->name, desc);
3215                free(desc);
3216            }
3217
3218            for (j = clazz->vtableCount-1; j >= 0; j--) {
3219                if (dvmCompareMethodNamesAndProtos(imeth, clazz->vtable[j])
3220                    == 0)
3221                {
3222                    LOGVV("INTF:   matched at %d\n", j);
3223                    if (!dvmIsPublicMethod(clazz->vtable[j])) {
3224                        LOGW("Implementation of %s.%s is not public\n",
3225                            clazz->descriptor, clazz->vtable[j]->name);
3226                        dvmThrowException("Ljava/lang/IllegalAccessError;",
3227                            "interface implementation not public");
3228                        goto bail;
3229                    }
3230                    clazz->iftable[i].methodIndexArray[methIdx] = j;
3231                    break;
3232                }
3233            }
3234            if (j < 0) {
3235                IF_LOGV() {
3236                    char* desc =
3237                        dexProtoCopyMethodDescriptor(&imeth->prototype);
3238                    LOGV("No match for '%s' '%s' in '%s' (creating miranda)\n",
3239                            imeth->name, desc, clazz->descriptor);
3240                    free(desc);
3241                }
3242                //dvmThrowException("Ljava/lang/RuntimeException;", "Miranda!");
3243                //return false;
3244
3245                if (mirandaCount == mirandaAlloc) {
3246                    mirandaAlloc += 8;
3247                    if (mirandaList == NULL) {
3248                        mirandaList = dvmLinearAlloc(clazz->classLoader,
3249                                        mirandaAlloc * sizeof(Method*));
3250                    } else {
3251                        dvmLinearReadOnly(clazz->classLoader, mirandaList);
3252                        mirandaList = dvmLinearRealloc(clazz->classLoader,
3253                                mirandaList, mirandaAlloc * sizeof(Method*));
3254                    }
3255                    assert(mirandaList != NULL);    // mem failed + we leaked
3256                }
3257
3258                /*
3259                 * These may be redundant (e.g. method with same name and
3260                 * signature declared in two interfaces implemented by the
3261                 * same abstract class).  We can squeeze the duplicates
3262                 * out here.
3263                 */
3264                int mir;
3265                for (mir = 0; mir < mirandaCount; mir++) {
3266                    if (dvmCompareMethodNamesAndProtos(
3267                            mirandaList[mir], imeth) == 0)
3268                    {
3269                        IF_LOGVV() {
3270                            char* desc = dexProtoCopyMethodDescriptor(
3271                                    &imeth->prototype);
3272                            LOGVV("MIRANDA dupe: %s and %s %s%s\n",
3273                                mirandaList[mir]->clazz->descriptor,
3274                                imeth->clazz->descriptor,
3275                                imeth->name, desc);
3276                            free(desc);
3277                        }
3278                        break;
3279                    }
3280                }
3281
3282                /* point the iftable at a phantom slot index */
3283                clazz->iftable[i].methodIndexArray[methIdx] =
3284                    clazz->vtableCount + mir;
3285                LOGVV("MIRANDA: %s points at slot %d\n",
3286                    imeth->name, clazz->vtableCount + mir);
3287
3288                /* if non-duplicate among Mirandas, add to Miranda list */
3289                if (mir == mirandaCount) {
3290                    //LOGV("MIRANDA: holding '%s' in slot %d\n",
3291                    //    imeth->name, mir);
3292                    mirandaList[mirandaCount++] = imeth;
3293                }
3294            }
3295        }
3296    }
3297
3298    if (mirandaCount != 0) {
3299        static const int kManyMirandas = 150;   /* arbitrary */
3300        Method* newVirtualMethods;
3301        Method* meth;
3302        int oldMethodCount, oldVtableCount;
3303
3304        for (i = 0; i < mirandaCount; i++) {
3305            LOGVV("MIRANDA %d: %s.%s\n", i,
3306                mirandaList[i]->clazz->descriptor, mirandaList[i]->name);
3307        }
3308        if (mirandaCount > kManyMirandas) {
3309            /*
3310             * Some obfuscators like to create an interface with a huge
3311             * pile of methods, declare classes as implementing it, and then
3312             * only define a couple of methods.  This leads to a rather
3313             * massive collection of Miranda methods and a lot of wasted
3314             * space, sometimes enough to blow out the LinearAlloc cap.
3315             */
3316            LOGD("Note: class %s has %d unimplemented (abstract) methods\n",
3317                clazz->descriptor, mirandaCount);
3318        }
3319
3320        /*
3321         * We found methods in one or more interfaces for which we do not
3322         * have vtable entries.  We have to expand our virtualMethods
3323         * table (which might be empty) to hold some new entries.
3324         */
3325        if (clazz->virtualMethods == NULL) {
3326            newVirtualMethods = (Method*) dvmLinearAlloc(clazz->classLoader,
3327                sizeof(Method) * (clazz->virtualMethodCount + mirandaCount));
3328        } else {
3329            //dvmLinearReadOnly(clazz->classLoader, clazz->virtualMethods);
3330            newVirtualMethods = (Method*) dvmLinearRealloc(clazz->classLoader,
3331                clazz->virtualMethods,
3332                sizeof(Method) * (clazz->virtualMethodCount + mirandaCount));
3333        }
3334        if (newVirtualMethods != clazz->virtualMethods) {
3335            /*
3336             * Table was moved in memory.  We have to run through the
3337             * vtable and fix the pointers.  The vtable entries might be
3338             * pointing at superclasses, so we flip it around: run through
3339             * all locally-defined virtual methods, and fix their entries
3340             * in the vtable.  (This would get really messy if sub-classes
3341             * had already been loaded.)
3342             *
3343             * Reminder: clazz->virtualMethods and clazz->virtualMethodCount
3344             * hold the virtual methods declared by this class.  The
3345             * method's methodIndex is the vtable index, and is the same
3346             * for all sub-classes (and all super classes in which it is
3347             * defined).  We're messing with these because the Miranda
3348             * stuff makes it look like the class actually has an abstract
3349             * method declaration in it.
3350             */
3351            LOGVV("MIRANDA fixing vtable pointers\n");
3352            dvmLinearReadWrite(clazz->classLoader, clazz->vtable);
3353            Method* meth = newVirtualMethods;
3354            for (i = 0; i < clazz->virtualMethodCount; i++, meth++)
3355                clazz->vtable[meth->methodIndex] = meth;
3356            dvmLinearReadOnly(clazz->classLoader, clazz->vtable);
3357        }
3358
3359        oldMethodCount = clazz->virtualMethodCount;
3360        clazz->virtualMethods = newVirtualMethods;
3361        clazz->virtualMethodCount += mirandaCount;
3362
3363        dvmLinearReadOnly(clazz->classLoader, clazz->virtualMethods);
3364
3365        /*
3366         * We also have to expand the vtable.
3367         */
3368        assert(clazz->vtable != NULL);
3369        clazz->vtable = (Method**) dvmLinearRealloc(clazz->classLoader,
3370                        clazz->vtable,
3371                        sizeof(Method*) * (clazz->vtableCount + mirandaCount));
3372        if (clazz->vtable == NULL) {
3373            assert(false);
3374            goto bail;
3375        }
3376        zapVtable = true;
3377
3378        oldVtableCount = clazz->vtableCount;
3379        clazz->vtableCount += mirandaCount;
3380
3381        /*
3382         * Now we need to create the fake methods.  We clone the abstract
3383         * method definition from the interface and then replace a few
3384         * things.
3385         *
3386         * The Method will be an "abstract native", with nativeFunc set to
3387         * dvmAbstractMethodStub().
3388         */
3389        meth = clazz->virtualMethods + oldMethodCount;
3390        for (i = 0; i < mirandaCount; i++, meth++) {
3391            dvmLinearReadWrite(clazz->classLoader, clazz->virtualMethods);
3392            cloneMethod(meth, mirandaList[i]);
3393            meth->clazz = clazz;
3394            meth->accessFlags |= ACC_MIRANDA;
3395            meth->methodIndex = (u2) (oldVtableCount + i);
3396            dvmLinearReadOnly(clazz->classLoader, clazz->virtualMethods);
3397
3398            /* point the new vtable entry at the new method */
3399            clazz->vtable[oldVtableCount + i] = meth;
3400        }
3401
3402        dvmLinearReadOnly(clazz->classLoader, mirandaList);
3403        dvmLinearFree(clazz->classLoader, mirandaList);
3404
3405    }
3406
3407    /*
3408     * TODO?
3409     * Sort the interfaces by number of declared methods.  All we really
3410     * want is to get the interfaces with zero methods at the end of the
3411     * list, so that when we walk through the list during invoke-interface
3412     * we don't examine interfaces that can't possibly be useful.
3413     *
3414     * The set will usually be small, so a simple insertion sort works.
3415     *
3416     * We have to be careful not to change the order of two interfaces
3417     * that define the same method.  (Not a problem if we only move the
3418     * zero-method interfaces to the end.)
3419     *
3420     * PROBLEM:
3421     * If we do this, we will no longer be able to identify super vs.
3422     * current class interfaces by comparing clazz->super->iftableCount.  This
3423     * breaks anything that only wants to find interfaces declared directly
3424     * by the class (dvmFindStaticFieldHier, ReferenceType.Interfaces,
3425     * dvmDbgOutputAllInterfaces, etc).  Need to provide a workaround.
3426     *
3427     * We can sort just the interfaces implemented directly by this class,
3428     * but that doesn't seem like it would provide much of an advantage.  I'm
3429     * not sure this is worthwhile.
3430     *
3431     * (This has been made largely obsolete by the interface cache mechanism.)
3432     */
3433
3434    //dvmDumpClass(clazz);
3435
3436    result = true;
3437
3438bail:
3439    if (zapIftable)
3440        dvmLinearReadOnly(clazz->classLoader, clazz->iftable);
3441    if (zapVtable)
3442        dvmLinearReadOnly(clazz->classLoader, clazz->vtable);
3443    if (zapIfvipool)
3444        dvmLinearReadOnly(clazz->classLoader, clazz->ifviPool);
3445    return result;
3446}
3447
3448
3449/*
3450 * Provide "stub" implementations for methods without them.
3451 *
3452 * Currently we provide an implementation for all abstract methods that
3453 * throws an AbstractMethodError exception.  This allows us to avoid an
3454 * explicit check for abstract methods in every virtual call.
3455 *
3456 * NOTE: for Miranda methods, the method declaration is a clone of what
3457 * was found in the interface class.  That copy may already have had the
3458 * function pointer filled in, so don't be surprised if it's not NULL.
3459 *
3460 * NOTE: this sets the "native" flag, giving us an "abstract native" method,
3461 * which is nonsensical.  Need to make sure that this doesn't escape the
3462 * VM.  We can either mask it out in reflection calls, or copy "native"
3463 * into the high 16 bits of accessFlags and check that internally.
3464 */
3465static bool insertMethodStubs(ClassObject* clazz)
3466{
3467    dvmLinearReadWrite(clazz->classLoader, clazz->virtualMethods);
3468
3469    Method* meth;
3470    int i;
3471
3472    meth = clazz->virtualMethods;
3473    for (i = 0; i < clazz->virtualMethodCount; i++, meth++) {
3474        if (dvmIsAbstractMethod(meth)) {
3475            assert(meth->insns == NULL);
3476            assert(meth->nativeFunc == NULL ||
3477                meth->nativeFunc == (DalvikBridgeFunc)dvmAbstractMethodStub);
3478
3479            meth->accessFlags |= ACC_NATIVE;
3480            meth->nativeFunc = (DalvikBridgeFunc) dvmAbstractMethodStub;
3481        }
3482    }
3483
3484    dvmLinearReadOnly(clazz->classLoader, clazz->virtualMethods);
3485    return true;
3486}
3487
3488
3489/*
3490 * Swap two instance fields.
3491 */
3492static inline void swapField(InstField* pOne, InstField* pTwo)
3493{
3494    InstField swap;
3495
3496    LOGVV("  --- swap '%s' and '%s'\n", pOne->field.name, pTwo->field.name);
3497    swap = *pOne;
3498    *pOne = *pTwo;
3499    *pTwo = swap;
3500}
3501
3502/*
3503 * Assign instance fields to u4 slots.
3504 *
3505 * The top portion of the instance field area is occupied by the superclass
3506 * fields, the bottom by the fields for this class.
3507 *
3508 * "long" and "double" fields occupy two adjacent slots.  On some
3509 * architectures, 64-bit quantities must be 64-bit aligned, so we need to
3510 * arrange fields (or introduce padding) to ensure this.  We assume the
3511 * fields of the topmost superclass (i.e. Object) are 64-bit aligned, so
3512 * we can just ensure that the offset is "even".  To avoid wasting space,
3513 * we want to move non-reference 32-bit fields into gaps rather than
3514 * creating pad words.
3515 *
3516 * In the worst case we will waste 4 bytes, but because objects are
3517 * allocated on >= 64-bit boundaries, those bytes may well be wasted anyway
3518 * (assuming this is the most-derived class).
3519 *
3520 * Pad words are not represented in the field table, so the field table
3521 * itself does not change size.
3522 *
3523 * The number of field slots determines the size of the object, so we
3524 * set that here too.
3525 *
3526 * This function feels a little more complicated than I'd like, but it
3527 * has the property of moving the smallest possible set of fields, which
3528 * should reduce the time required to load a class.
3529 *
3530 * NOTE: reference fields *must* come first, or precacheReferenceOffsets()
3531 * will break.
3532 */
3533static bool computeFieldOffsets(ClassObject* clazz)
3534{
3535    int fieldOffset;
3536    int i, j;
3537
3538    dvmLinearReadWrite(clazz->classLoader, clazz->ifields);
3539
3540    if (clazz->super != NULL)
3541        fieldOffset = clazz->super->objectSize;
3542    else
3543        fieldOffset = offsetof(DataObject, instanceData);
3544
3545    LOGVV("--- computeFieldOffsets '%s'\n", clazz->descriptor);
3546
3547    //LOGI("OFFSETS fieldCount=%d\n", clazz->ifieldCount);
3548    //LOGI("dataobj, instance: %d\n", offsetof(DataObject, instanceData));
3549    //LOGI("classobj, access: %d\n", offsetof(ClassObject, accessFlags));
3550    //LOGI("super=%p, fieldOffset=%d\n", clazz->super, fieldOffset);
3551
3552    /*
3553     * Start by moving all reference fields to the front.
3554     */
3555    clazz->ifieldRefCount = 0;
3556    j = clazz->ifieldCount - 1;
3557    for (i = 0; i < clazz->ifieldCount; i++) {
3558        InstField* pField = &clazz->ifields[i];
3559        char c = pField->field.signature[0];
3560
3561        if (c != '[' && c != 'L') {
3562            /* This isn't a reference field; see if any reference fields
3563             * follow this one.  If so, we'll move it to this position.
3564             * (quicksort-style partitioning)
3565             */
3566            while (j > i) {
3567                InstField* refField = &clazz->ifields[j--];
3568                char rc = refField->field.signature[0];
3569
3570                if (rc == '[' || rc == 'L') {
3571                    /* Here's a reference field that follows at least one
3572                     * non-reference field.  Swap it with the current field.
3573                     * (When this returns, "pField" points to the reference
3574                     * field, and "refField" points to the non-ref field.)
3575                     */
3576                    swapField(pField, refField);
3577
3578                    /* Fix the signature.
3579                     */
3580                    c = rc;
3581
3582                    clazz->ifieldRefCount++;
3583                    break;
3584                }
3585            }
3586            /* We may or may not have swapped a field.
3587             */
3588        } else {
3589            /* This is a reference field.
3590             */
3591            clazz->ifieldRefCount++;
3592        }
3593
3594        /*
3595         * If we've hit the end of the reference fields, break.
3596         */
3597        if (c != '[' && c != 'L')
3598            break;
3599
3600        pField->byteOffset = fieldOffset;
3601        fieldOffset += sizeof(u4);
3602        LOGVV("  --- offset1 '%s'=%d\n", pField->field.name,pField->byteOffset);
3603    }
3604
3605    /*
3606     * Now we want to pack all of the double-wide fields together.  If we're
3607     * not aligned, though, we want to shuffle one 32-bit field into place.
3608     * If we can't find one, we'll have to pad it.
3609     */
3610    if (i != clazz->ifieldCount && (fieldOffset & 0x04) != 0) {
3611        LOGVV("  +++ not aligned\n");
3612
3613        InstField* pField = &clazz->ifields[i];
3614        char c = pField->field.signature[0];
3615
3616        if (c != 'J' && c != 'D') {
3617            /*
3618             * The field that comes next is 32-bit, so just advance past it.
3619             */
3620            assert(c != '[' && c != 'L');
3621            pField->byteOffset = fieldOffset;
3622            fieldOffset += sizeof(u4);
3623            i++;
3624            LOGVV("  --- offset2 '%s'=%d\n",
3625                pField->field.name, pField->byteOffset);
3626        } else {
3627            /*
3628             * Next field is 64-bit, so search for a 32-bit field we can
3629             * swap into it.
3630             */
3631            bool found = false;
3632            j = clazz->ifieldCount - 1;
3633            while (j > i) {
3634                InstField* singleField = &clazz->ifields[j--];
3635                char rc = singleField->field.signature[0];
3636
3637                if (rc != 'J' && rc != 'D') {
3638                    swapField(pField, singleField);
3639                    //c = rc;
3640                    LOGVV("  +++ swapped '%s' for alignment\n",
3641                        pField->field.name);
3642                    pField->byteOffset = fieldOffset;
3643                    fieldOffset += sizeof(u4);
3644                    LOGVV("  --- offset3 '%s'=%d\n",
3645                        pField->field.name, pField->byteOffset);
3646                    found = true;
3647                    i++;
3648                    break;
3649                }
3650            }
3651            if (!found) {
3652                LOGV("  +++ inserting pad field in '%s'\n", clazz->descriptor);
3653                fieldOffset += sizeof(u4);
3654            }
3655        }
3656    }
3657
3658    /*
3659     * Alignment is good, shuffle any double-wide fields forward, and
3660     * finish assigning field offsets to all fields.
3661     */
3662    assert(i == clazz->ifieldCount || (fieldOffset & 0x04) == 0);
3663    j = clazz->ifieldCount - 1;
3664    for ( ; i < clazz->ifieldCount; i++) {
3665        InstField* pField = &clazz->ifields[i];
3666        char c = pField->field.signature[0];
3667
3668        if (c != 'D' && c != 'J') {
3669            /* This isn't a double-wide field; see if any double fields
3670             * follow this one.  If so, we'll move it to this position.
3671             * (quicksort-style partitioning)
3672             */
3673            while (j > i) {
3674                InstField* doubleField = &clazz->ifields[j--];
3675                char rc = doubleField->field.signature[0];
3676
3677                if (rc == 'D' || rc == 'J') {
3678                    /* Here's a double-wide field that follows at least one
3679                     * non-double field.  Swap it with the current field.
3680                     * (When this returns, "pField" points to the reference
3681                     * field, and "doubleField" points to the non-double field.)
3682                     */
3683                    swapField(pField, doubleField);
3684                    c = rc;
3685
3686                    break;
3687                }
3688            }
3689            /* We may or may not have swapped a field.
3690             */
3691        } else {
3692            /* This is a double-wide field, leave it be.
3693             */
3694        }
3695
3696        pField->byteOffset = fieldOffset;
3697        LOGVV("  --- offset4 '%s'=%d\n", pField->field.name,pField->byteOffset);
3698        fieldOffset += sizeof(u4);
3699        if (c == 'J' || c == 'D')
3700            fieldOffset += sizeof(u4);
3701    }
3702
3703#ifndef NDEBUG
3704    /* Make sure that all reference fields appear before
3705     * non-reference fields, and all double-wide fields are aligned.
3706     */
3707    j = 0;  // seen non-ref
3708    for (i = 0; i < clazz->ifieldCount; i++) {
3709        InstField *pField = &clazz->ifields[i];
3710        char c = pField->field.signature[0];
3711
3712        if (c == 'D' || c == 'J') {
3713            assert((pField->byteOffset & 0x07) == 0);
3714        }
3715
3716        if (c != '[' && c != 'L') {
3717            if (!j) {
3718                assert(i == clazz->ifieldRefCount);
3719                j = 1;
3720            }
3721        } else if (j) {
3722            assert(false);
3723        }
3724    }
3725    if (!j) {
3726        assert(clazz->ifieldRefCount == clazz->ifieldCount);
3727    }
3728#endif
3729
3730    /*
3731     * We map a C struct directly on top of java/lang/Class objects.  Make
3732     * sure we left enough room for the instance fields.
3733     */
3734    assert(clazz != gDvm.classJavaLangClass || (size_t)fieldOffset <
3735        offsetof(ClassObject, instanceData) + sizeof(clazz->instanceData));
3736
3737    clazz->objectSize = fieldOffset;
3738
3739    dvmLinearReadOnly(clazz->classLoader, clazz->ifields);
3740    return true;
3741}
3742
3743/*
3744 * Throw the VM-spec-mandated error when an exception is thrown during
3745 * class initialization.
3746 *
3747 * The safest way to do this is to call the ExceptionInInitializerError
3748 * constructor that takes a Throwable.
3749 *
3750 * [Do we want to wrap it if the original is an Error rather than
3751 * an Exception?]
3752 */
3753static void throwClinitError(void)
3754{
3755    Thread* self = dvmThreadSelf();
3756    Object* exception;
3757    Object* eiie;
3758
3759    exception = dvmGetException(self);
3760    dvmAddTrackedAlloc(exception, self);
3761    dvmClearException(self);
3762
3763    if (gDvm.classJavaLangExceptionInInitializerError == NULL) {
3764        /*
3765         * Always resolves to same thing -- no race condition.
3766         */
3767        gDvm.classJavaLangExceptionInInitializerError =
3768            dvmFindSystemClass(
3769                    "Ljava/lang/ExceptionInInitializerError;");
3770        if (gDvm.classJavaLangExceptionInInitializerError == NULL) {
3771            LOGE("Unable to prep java/lang/ExceptionInInitializerError\n");
3772            goto fail;
3773        }
3774
3775        gDvm.methJavaLangExceptionInInitializerError_init =
3776            dvmFindDirectMethodByDescriptor(gDvm.classJavaLangExceptionInInitializerError,
3777            "<init>", "(Ljava/lang/Throwable;)V");
3778        if (gDvm.methJavaLangExceptionInInitializerError_init == NULL) {
3779            LOGE("Unable to prep java/lang/ExceptionInInitializerError\n");
3780            goto fail;
3781        }
3782    }
3783
3784    eiie = dvmAllocObject(gDvm.classJavaLangExceptionInInitializerError,
3785                ALLOC_DEFAULT);
3786    if (eiie == NULL)
3787        goto fail;
3788
3789    /*
3790     * Construct the new object, and replace the exception with it.
3791     */
3792    JValue unused;
3793    dvmCallMethod(self, gDvm.methJavaLangExceptionInInitializerError_init,
3794        eiie, &unused, exception);
3795    dvmSetException(self, eiie);
3796    dvmReleaseTrackedAlloc(eiie, NULL);
3797    dvmReleaseTrackedAlloc(exception, self);
3798    return;
3799
3800fail:       /* restore original exception */
3801    dvmSetException(self, exception);
3802    dvmReleaseTrackedAlloc(exception, self);
3803    return;
3804}
3805
3806/*
3807 * The class failed to initialize on a previous attempt, so we want to throw
3808 * a NoClassDefFoundError (v2 2.17.5).  The exception to this rule is if we
3809 * failed in verification, in which case v2 5.4.1 says we need to re-throw
3810 * the previous error.
3811 */
3812static void throwEarlierClassFailure(ClassObject* clazz)
3813{
3814    LOGI("Rejecting re-init on previously-failed class %s v=%p\n",
3815        clazz->descriptor, clazz->verifyErrorClass);
3816
3817    if (clazz->verifyErrorClass == NULL) {
3818        dvmThrowExceptionWithClassMessage("Ljava/lang/NoClassDefFoundError;",
3819            clazz->descriptor);
3820    } else {
3821        dvmThrowExceptionByClassWithClassMessage(clazz->verifyErrorClass,
3822            clazz->descriptor);
3823    }
3824}
3825
3826/*
3827 * Initialize any static fields whose values are stored in
3828 * the DEX file.  This must be done during class initialization.
3829 */
3830static void initSFields(ClassObject* clazz)
3831{
3832    Thread* self = dvmThreadSelf(); /* for dvmReleaseTrackedAlloc() */
3833    DexFile* pDexFile;
3834    const DexClassDef* pClassDef;
3835    const DexEncodedArray* pValueList;
3836    EncodedArrayIterator iterator;
3837    int i;
3838
3839    if (clazz->sfieldCount == 0) {
3840        return;
3841    }
3842    if (clazz->pDvmDex == NULL) {
3843        /* generated class; any static fields should already be set up */
3844        LOGV("Not initializing static fields in %s\n", clazz->descriptor);
3845        return;
3846    }
3847    pDexFile = clazz->pDvmDex->pDexFile;
3848
3849    pClassDef = dexFindClass(pDexFile, clazz->descriptor);
3850    assert(pClassDef != NULL);
3851
3852    pValueList = dexGetStaticValuesList(pDexFile, pClassDef);
3853    if (pValueList == NULL) {
3854        return;
3855    }
3856
3857    dvmEncodedArrayIteratorInitialize(&iterator, pValueList, clazz);
3858
3859    /*
3860     * Iterate over the initial values array, setting the corresponding
3861     * static field for each array element.
3862     */
3863
3864    for (i = 0; dvmEncodedArrayIteratorHasNext(&iterator); i++) {
3865        AnnotationValue value;
3866        bool parsed = dvmEncodedArrayIteratorGetNext(&iterator, &value);
3867        StaticField* sfield = &clazz->sfields[i];
3868        const char* descriptor = sfield->field.signature;
3869        bool needRelease = false;
3870
3871        if (! parsed) {
3872            /*
3873             * TODO: Eventually verification should attempt to ensure
3874             * that this can't happen at least due to a data integrity
3875             * problem.
3876             */
3877            LOGE("Static initializer parse failed for %s at index %d",
3878                    clazz->descriptor, i);
3879            dvmAbort();
3880        }
3881
3882        /* Verify that the value we got was of a valid type. */
3883
3884        switch (descriptor[0]) {
3885            case 'Z': parsed = (value.type == kDexAnnotationBoolean); break;
3886            case 'B': parsed = (value.type == kDexAnnotationByte);    break;
3887            case 'C': parsed = (value.type == kDexAnnotationChar);    break;
3888            case 'S': parsed = (value.type == kDexAnnotationShort);   break;
3889            case 'I': parsed = (value.type == kDexAnnotationInt);     break;
3890            case 'J': parsed = (value.type == kDexAnnotationLong);    break;
3891            case 'F': parsed = (value.type == kDexAnnotationFloat);   break;
3892            case 'D': parsed = (value.type == kDexAnnotationDouble);  break;
3893            case '[': parsed = (value.type == kDexAnnotationNull);    break;
3894            case 'L': {
3895                switch (value.type) {
3896                    case kDexAnnotationNull: {
3897                        /* No need for further tests. */
3898                        break;
3899                    }
3900                    case kDexAnnotationString: {
3901                        parsed =
3902                            (strcmp(descriptor, "Ljava/lang/String;") == 0);
3903                        needRelease = true;
3904                        break;
3905                    }
3906                    case kDexAnnotationType: {
3907                        parsed =
3908                            (strcmp(descriptor, "Ljava/lang/Class;") == 0);
3909                        needRelease = true;
3910                        break;
3911                    }
3912                    default: {
3913                        parsed = false;
3914                        break;
3915                    }
3916                }
3917                break;
3918            }
3919            default: {
3920                parsed = false;
3921                break;
3922            }
3923        }
3924
3925        if (parsed) {
3926            /*
3927             * All's well, so store the value. Note: This always
3928             * stores the full width of a JValue, even though most of
3929             * the time only the first word is needed.
3930             */
3931            sfield->value = value.value;
3932            if (needRelease) {
3933                dvmReleaseTrackedAlloc(value.value.l, self);
3934            }
3935        } else {
3936            /*
3937             * Something up above had a problem. TODO: See comment
3938             * above the switch about verfication.
3939             */
3940            LOGE("Bogus static initialization: value type %d in field type "
3941                    "%s for %s at index %d",
3942                value.type, descriptor, clazz->descriptor, i);
3943            dvmAbort();
3944        }
3945    }
3946}
3947
3948
3949/*
3950 * Determine whether "descriptor" yields the same class object in the
3951 * context of clazz1 and clazz2.
3952 *
3953 * The caller must hold gDvm.loadedClasses.
3954 *
3955 * Returns "true" if they match.
3956 */
3957static bool compareDescriptorClasses(const char* descriptor,
3958    const ClassObject* clazz1, const ClassObject* clazz2)
3959{
3960    ClassObject* result1;
3961    ClassObject* result2;
3962
3963    /*
3964     * Do the first lookup by name.
3965     */
3966    result1 = dvmFindClassNoInit(descriptor, clazz1->classLoader);
3967
3968    /*
3969     * We can skip a second lookup by name if the second class loader is
3970     * in the initiating loader list of the class object we retrieved.
3971     * (This means that somebody already did a lookup of this class through
3972     * the second loader, and it resolved to the same class.)  If it's not
3973     * there, we may simply not have had an opportunity to add it yet, so
3974     * we do the full lookup.
3975     *
3976     * The initiating loader test should catch the majority of cases
3977     * (in particular, the zillions of references to String/Object).
3978     *
3979     * Unfortunately we're still stuck grabbing a mutex to do the lookup.
3980     *
3981     * For this to work, the superclass/interface should be the first
3982     * argument, so that way if it's from the bootstrap loader this test
3983     * will work.  (The bootstrap loader, by definition, never shows up
3984     * as the initiating loader of a class defined by some other loader.)
3985     */
3986    dvmHashTableLock(gDvm.loadedClasses);
3987    bool isInit = dvmLoaderInInitiatingList(result1, clazz2->classLoader);
3988    dvmHashTableUnlock(gDvm.loadedClasses);
3989
3990    if (isInit) {
3991        //printf("%s(obj=%p) / %s(cl=%p): initiating\n",
3992        //    result1->descriptor, result1,
3993        //    clazz2->descriptor, clazz2->classLoader);
3994        return true;
3995    } else {
3996        //printf("%s(obj=%p) / %s(cl=%p): RAW\n",
3997        //    result1->descriptor, result1,
3998        //    clazz2->descriptor, clazz2->classLoader);
3999        result2 = dvmFindClassNoInit(descriptor, clazz2->classLoader);
4000    }
4001
4002    if (result1 == NULL || result2 == NULL) {
4003        dvmClearException(dvmThreadSelf());
4004        if (result1 == result2) {
4005            /*
4006             * Neither class loader could find this class.  Apparently it
4007             * doesn't exist.
4008             *
4009             * We can either throw some sort of exception now, or just
4010             * assume that it'll fail later when something actually tries
4011             * to use the class.  For strict handling we should throw now,
4012             * because a "tricky" class loader could start returning
4013             * something later, and a pair of "tricky" loaders could set
4014             * us up for confusion.
4015             *
4016             * I'm not sure if we're allowed to complain about nonexistent
4017             * classes in method signatures during class init, so for now
4018             * this will just return "true" and let nature take its course.
4019             */
4020            return true;
4021        } else {
4022            /* only one was found, so clearly they're not the same */
4023            return false;
4024        }
4025    }
4026
4027    return result1 == result2;
4028}
4029
4030/*
4031 * For every component in the method descriptor, resolve the class in the
4032 * context of the two classes and compare the results.
4033 *
4034 * For best results, the "superclass" class should be first.
4035 *
4036 * Returns "true" if the classes match, "false" otherwise.
4037 */
4038static bool checkMethodDescriptorClasses(const Method* meth,
4039    const ClassObject* clazz1, const ClassObject* clazz2)
4040{
4041    DexParameterIterator iterator;
4042    const char* descriptor;
4043
4044    /* walk through the list of parameters */
4045    dexParameterIteratorInit(&iterator, &meth->prototype);
4046    while (true) {
4047        descriptor = dexParameterIteratorNextDescriptor(&iterator);
4048
4049        if (descriptor == NULL)
4050            break;
4051
4052        if (descriptor[0] == 'L' || descriptor[0] == '[') {
4053            /* non-primitive type */
4054            if (!compareDescriptorClasses(descriptor, clazz1, clazz2))
4055                return false;
4056        }
4057    }
4058
4059    /* check the return type */
4060    descriptor = dexProtoGetReturnType(&meth->prototype);
4061    if (descriptor[0] == 'L' || descriptor[0] == '[') {
4062        if (!compareDescriptorClasses(descriptor, clazz1, clazz2))
4063            return false;
4064    }
4065    return true;
4066}
4067
4068/*
4069 * Validate the descriptors in the superclass and interfaces.
4070 *
4071 * What we need to do is ensure that the classes named in the method
4072 * descriptors in our ancestors and ourselves resolve to the same class
4073 * objects.  We can get conflicts when the classes come from different
4074 * class loaders, and the resolver comes up with different results for
4075 * the same class name in different contexts.
4076 *
4077 * An easy way to cause the problem is to declare a base class that uses
4078 * class Foo in a method signature (e.g. as the return type).  Then,
4079 * define a subclass and a different version of Foo, and load them from a
4080 * different class loader.  If the subclass overrides the method, it will
4081 * have a different concept of what Foo is than its parent does, so even
4082 * though the method signature strings are identical, they actually mean
4083 * different things.
4084 *
4085 * A call to the method through a base-class reference would be treated
4086 * differently than a call to the method through a subclass reference, which
4087 * isn't the way polymorphism works, so we have to reject the subclass.
4088 * If the subclass doesn't override the base method, then there's no
4089 * problem, because calls through base-class references and subclass
4090 * references end up in the same place.
4091 *
4092 * We don't need to check to see if an interface's methods match with its
4093 * superinterface's methods, because you can't instantiate an interface
4094 * and do something inappropriate with it.  If interface I1 extends I2
4095 * and is implemented by C, and I1 and I2 are in separate class loaders
4096 * and have conflicting views of other classes, we will catch the conflict
4097 * when we process C.  Anything that implements I1 is doomed to failure,
4098 * but we don't need to catch that while processing I1.
4099 *
4100 * On failure, throws an exception and returns "false".
4101 */
4102static bool validateSuperDescriptors(const ClassObject* clazz)
4103{
4104    int i;
4105
4106    if (dvmIsInterfaceClass(clazz))
4107        return true;
4108
4109    /*
4110     * Start with the superclass-declared methods.
4111     */
4112    if (clazz->super != NULL &&
4113        clazz->classLoader != clazz->super->classLoader)
4114    {
4115        /*
4116         * Walk through every overridden method and compare resolved
4117         * descriptor components.  We pull the Method structs out of
4118         * the vtable.  It doesn't matter whether we get the struct from
4119         * the parent or child, since we just need the UTF-8 descriptor,
4120         * which must match.
4121         *
4122         * We need to do this even for the stuff inherited from Object,
4123         * because it's possible that the new class loader has redefined
4124         * a basic class like String.
4125         *
4126         * We don't need to check stuff defined in a superclass because
4127         * it was checked when the superclass was loaded.
4128         */
4129        const Method* meth;
4130
4131        //printf("Checking %s %p vs %s %p\n",
4132        //    clazz->descriptor, clazz->classLoader,
4133        //    clazz->super->descriptor, clazz->super->classLoader);
4134        for (i = clazz->super->vtableCount - 1; i >= 0; i--) {
4135            meth = clazz->vtable[i];
4136            if (meth != clazz->super->vtable[i] &&
4137                !checkMethodDescriptorClasses(meth, clazz->super, clazz))
4138            {
4139                LOGW("Method mismatch: %s in %s (cl=%p) and super %s (cl=%p)\n",
4140                    meth->name, clazz->descriptor, clazz->classLoader,
4141                    clazz->super->descriptor, clazz->super->classLoader);
4142                dvmThrowException("Ljava/lang/LinkageError;",
4143                    "Classes resolve differently in superclass");
4144                return false;
4145            }
4146        }
4147    }
4148
4149    /*
4150     * Check the methods defined by this class against the interfaces it
4151     * implements.  If we inherited the implementation from a superclass,
4152     * we have to check it against the superclass (which might be in a
4153     * different class loader).  If the superclass also implements the
4154     * interface, we could skip the check since by definition it was
4155     * performed when the class was loaded.
4156     */
4157    for (i = 0; i < clazz->iftableCount; i++) {
4158        const InterfaceEntry* iftable = &clazz->iftable[i];
4159
4160        if (clazz->classLoader != iftable->clazz->classLoader) {
4161            const ClassObject* iface = iftable->clazz;
4162            int j;
4163
4164            for (j = 0; j < iface->virtualMethodCount; j++) {
4165                const Method* meth;
4166                int vtableIndex;
4167
4168                vtableIndex = iftable->methodIndexArray[j];
4169                meth = clazz->vtable[vtableIndex];
4170
4171                if (!checkMethodDescriptorClasses(meth, iface, meth->clazz)) {
4172                    LOGW("Method mismatch: %s in %s (cl=%p) and "
4173                            "iface %s (cl=%p)\n",
4174                        meth->name, clazz->descriptor, clazz->classLoader,
4175                        iface->descriptor, iface->classLoader);
4176                    dvmThrowException("Ljava/lang/LinkageError;",
4177                        "Classes resolve differently in interface");
4178                    return false;
4179                }
4180            }
4181        }
4182    }
4183
4184    return true;
4185}
4186
4187/*
4188 * Returns true if the class is being initialized by us (which means that
4189 * calling dvmInitClass will return immediately after fiddling with locks).
4190 *
4191 * There isn't a race here, because either clazz->initThreadId won't match
4192 * us, or it will and it was set in the same thread.
4193 */
4194bool dvmIsClassInitializing(const ClassObject* clazz)
4195{
4196    return (clazz->status == CLASS_INITIALIZING &&
4197            clazz->initThreadId == dvmThreadSelf()->threadId);
4198}
4199
4200/*
4201 * If a class has not been initialized, do so by executing the code in
4202 * <clinit>.  The sequence is described in the VM spec v2 2.17.5.
4203 *
4204 * It is possible for multiple threads to arrive here simultaneously, so
4205 * we need to lock the class while we check stuff.  We know that no
4206 * interpreted code has access to the class yet, so we can use the class's
4207 * monitor lock.
4208 *
4209 * We will often be called recursively, e.g. when the <clinit> code resolves
4210 * one of its fields, the field resolution will try to initialize the class.
4211 * In that case we will return "true" even though the class isn't actually
4212 * ready to go.  The ambiguity can be resolved with dvmIsClassInitializing().
4213 * (TODO: consider having this return an enum to avoid the extra call --
4214 * return -1 on failure, 0 on success, 1 on still-initializing.  Looks like
4215 * dvmIsClassInitializing() is always paired with *Initialized())
4216 *
4217 * This can get very interesting if a class has a static field initialized
4218 * to a new instance of itself.  <clinit> will end up calling <init> on
4219 * the members it is initializing, which is fine unless it uses the contents
4220 * of static fields to initialize instance fields.  This will leave the
4221 * static-referenced objects in a partially initialized state.  This is
4222 * reasonably rare and can sometimes be cured with proper field ordering.
4223 *
4224 * On failure, returns "false" with an exception raised.
4225 *
4226 * -----
4227 *
4228 * It is possible to cause a deadlock by having a situation like this:
4229 *   class A { static { sleep(10000); new B(); } }
4230 *   class B { static { sleep(10000); new A(); } }
4231 *   new Thread() { public void run() { new A(); } }.start();
4232 *   new Thread() { public void run() { new B(); } }.start();
4233 * This appears to be expected under the spec.
4234 *
4235 * The interesting question is what to do if somebody calls Thread.interrupt()
4236 * on one of the deadlocked threads.  According to the VM spec, they're both
4237 * sitting in "wait".  Should the interrupt code quietly raise the
4238 * "interrupted" flag, or should the "wait" return immediately with an
4239 * exception raised?
4240 *
4241 * This gets a little murky.  The VM spec says we call "wait", and the
4242 * spec for Thread.interrupt says Object.wait is interruptible.  So it
4243 * seems that, if we get unlucky and interrupt class initialization, we
4244 * are expected to throw (which gets converted to ExceptionInInitializerError
4245 * since InterruptedException is checked).
4246 *
4247 * There are a couple of problems here.  First, all threads are expected to
4248 * present a consistent view of class initialization, so we can't have it
4249 * fail in one thread and succeed in another.  Second, once a class fails
4250 * to initialize, it must *always* fail.  This means that a stray interrupt()
4251 * call could render a class unusable for the lifetime of the VM.
4252 *
4253 * In most cases -- the deadlock example above being a counter-example --
4254 * the interrupting thread can't tell whether the target thread handled
4255 * the initialization itself or had to wait while another thread did the
4256 * work.  Refusing to interrupt class initialization is, in most cases,
4257 * not something that a program can reliably detect.
4258 *
4259 * On the assumption that interrupting class initialization is highly
4260 * undesirable in most circumstances, and that failing to do so does not
4261 * deviate from the spec in a meaningful way, we don't allow class init
4262 * to be interrupted by Thread.interrupt().
4263 */
4264bool dvmInitClass(ClassObject* clazz)
4265{
4266#if LOG_CLASS_LOADING
4267    bool initializedByUs = false;
4268#endif
4269
4270    Thread* self = dvmThreadSelf();
4271    const Method* method;
4272
4273    dvmLockObject(self, (Object*) clazz);
4274    assert(dvmIsClassLinked(clazz) || clazz->status == CLASS_ERROR);
4275
4276    /*
4277     * If the class hasn't been verified yet, do so now.
4278     */
4279    if (clazz->status < CLASS_VERIFIED) {
4280        /*
4281         * If we're in an "erroneous" state, throw an exception and bail.
4282         */
4283        if (clazz->status == CLASS_ERROR) {
4284            throwEarlierClassFailure(clazz);
4285            goto bail_unlock;
4286        }
4287
4288        assert(clazz->status == CLASS_RESOLVED);
4289        assert(!IS_CLASS_FLAG_SET(clazz, CLASS_ISPREVERIFIED));
4290
4291        if (gDvm.classVerifyMode == VERIFY_MODE_NONE ||
4292            (gDvm.classVerifyMode == VERIFY_MODE_REMOTE &&
4293             clazz->classLoader == NULL))
4294        {
4295            /* advance to "verified" state */
4296            LOGV("+++ not verifying class %s (cl=%p)\n",
4297                clazz->descriptor, clazz->classLoader);
4298            clazz->status = CLASS_VERIFIED;
4299            goto noverify;
4300        }
4301
4302        if (!gDvm.optimizing)
4303            LOGV("+++ late verify on %s\n", clazz->descriptor);
4304
4305        /*
4306         * We're not supposed to optimize an unverified class, but during
4307         * development this mode was useful.  We can't verify an optimized
4308         * class because the optimization process discards information.
4309         */
4310        if (IS_CLASS_FLAG_SET(clazz, CLASS_ISOPTIMIZED)) {
4311            LOGW("Class '%s' was optimized without verification; "
4312                 "not verifying now\n",
4313                clazz->descriptor);
4314            LOGW("  ('rm /data/dalvik-cache/*' and restart to fix this)");
4315            goto verify_failed;
4316        }
4317
4318        clazz->status = CLASS_VERIFYING;
4319        if (!dvmVerifyClass(clazz, VERIFY_DEFAULT)) {
4320verify_failed:
4321            dvmThrowExceptionWithClassMessage("Ljava/lang/VerifyError;",
4322                clazz->descriptor);
4323            clazz->verifyErrorClass = dvmGetException(self)->clazz;
4324            clazz->status = CLASS_ERROR;
4325            goto bail_unlock;
4326        }
4327
4328        clazz->status = CLASS_VERIFIED;
4329    }
4330noverify:
4331
4332#ifdef WITH_DEBUGGER
4333    /* update instruction stream now that the verifier is done */
4334    dvmFlushBreakpoints(clazz);
4335#endif
4336
4337    if (clazz->status == CLASS_INITIALIZED)
4338        goto bail_unlock;
4339
4340    while (clazz->status == CLASS_INITIALIZING) {
4341        /* we caught somebody else in the act; was it us? */
4342        if (clazz->initThreadId == self->threadId) {
4343            //LOGV("HEY: found a recursive <clinit>\n");
4344            goto bail_unlock;
4345        }
4346
4347        if (dvmCheckException(self)) {
4348            LOGW("GLITCH: exception pending at start of class init\n");
4349            dvmAbort();
4350        }
4351
4352        /*
4353         * Wait for the other thread to finish initialization.  We pass
4354         * "false" for the "interruptShouldThrow" arg so it doesn't throw
4355         * an exception on interrupt.
4356         */
4357        dvmObjectWait(self, (Object*) clazz, 0, 0, false);
4358
4359        /*
4360         * When we wake up, repeat the test for init-in-progress.  If there's
4361         * an exception pending (only possible if "interruptShouldThrow"
4362         * was set), bail out.
4363         */
4364        if (dvmCheckException(self)) {
4365            LOGI("Class init of '%s' failing with wait() exception\n",
4366                clazz->descriptor);
4367            /*
4368             * TODO: this is bogus, because it means the two threads have a
4369             * different idea of the class status.  We need to flag the
4370             * class as bad and ensure that the initializer thread respects
4371             * our notice.  If we get lucky and wake up after the class has
4372             * finished initialization but before being woken, we have to
4373             * swallow the exception, perhaps raising thread->interrupted
4374             * to preserve semantics.
4375             *
4376             * Since we're not currently allowing interrupts, this should
4377             * never happen and we don't need to fix this.
4378             */
4379            assert(false);
4380            throwClinitError();
4381            clazz->status = CLASS_ERROR;
4382            goto bail_unlock;
4383        }
4384        if (clazz->status == CLASS_INITIALIZING) {
4385            LOGI("Waiting again for class init\n");
4386            continue;
4387        }
4388        assert(clazz->status == CLASS_INITIALIZED ||
4389               clazz->status == CLASS_ERROR);
4390        if (clazz->status == CLASS_ERROR) {
4391            /*
4392             * The caller wants an exception, but it was thrown in a
4393             * different thread.  Synthesize one here.
4394             */
4395            dvmThrowException("Ljava/lang/UnsatisfiedLinkError;",
4396                "(<clinit> failed, see exception in other thread)");
4397        }
4398        goto bail_unlock;
4399    }
4400
4401    /* see if we failed previously */
4402    if (clazz->status == CLASS_ERROR) {
4403        // might be wise to unlock before throwing; depends on which class
4404        // it is that we have locked
4405        dvmUnlockObject(self, (Object*) clazz);
4406        throwEarlierClassFailure(clazz);
4407        return false;
4408    }
4409
4410#ifdef WITH_PROFILER
4411    u8 startWhen = 0;
4412    if (gDvm.allocProf.enabled) {
4413        startWhen = dvmGetRelativeTimeNsec();
4414    }
4415#endif
4416
4417    /*
4418     * We're ready to go, and have exclusive access to the class.
4419     *
4420     * Before we start initialization, we need to do one extra bit of
4421     * validation: make sure that the methods declared here match up
4422     * with our superclass and interfaces.  We know that the UTF-8
4423     * descriptors match, but classes from different class loaders can
4424     * have the same name.
4425     *
4426     * We do this now, rather than at load/link time, for the same reason
4427     * that we defer verification.
4428     *
4429     * It's unfortunate that we need to do this at all, but we risk
4430     * mixing reference types with identical names (see Dalvik test 068).
4431     */
4432    if (!validateSuperDescriptors(clazz)) {
4433        assert(dvmCheckException(self));
4434        clazz->status = CLASS_ERROR;
4435        goto bail_unlock;
4436    }
4437
4438    /*
4439     * Let's initialize this thing.
4440     *
4441     * We unlock the object so that other threads can politely sleep on
4442     * our mutex with Object.wait(), instead of hanging or spinning trying
4443     * to grab our mutex.
4444     */
4445    assert(clazz->status < CLASS_INITIALIZING);
4446
4447#if LOG_CLASS_LOADING
4448    // We started initializing.
4449    logClassLoad('+', clazz);
4450    initializedByUs = true;
4451#endif
4452
4453    clazz->status = CLASS_INITIALIZING;
4454    clazz->initThreadId = self->threadId;
4455    dvmUnlockObject(self, (Object*) clazz);
4456
4457    /* init our superclass */
4458    if (clazz->super != NULL && clazz->super->status != CLASS_INITIALIZED) {
4459        assert(!dvmIsInterfaceClass(clazz));
4460        if (!dvmInitClass(clazz->super)) {
4461            assert(dvmCheckException(self));
4462            clazz->status = CLASS_ERROR;
4463            /* wake up anybody who started waiting while we were unlocked */
4464            dvmLockObject(self, (Object*) clazz);
4465            goto bail_notify;
4466        }
4467    }
4468
4469    /* Initialize any static fields whose values are
4470     * stored in the Dex file.  This should include all of the
4471     * simple "final static" fields, which are required to
4472     * be initialized first. (vmspec 2 sec 2.17.5 item 8)
4473     * More-complicated final static fields should be set
4474     * at the beginning of <clinit>;  all we can do is trust
4475     * that the compiler did the right thing.
4476     */
4477    initSFields(clazz);
4478
4479    /* Execute any static initialization code.
4480     */
4481    method = dvmFindDirectMethodByDescriptor(clazz, "<clinit>", "()V");
4482    if (method == NULL) {
4483        LOGVV("No <clinit> found for %s\n", clazz->descriptor);
4484    } else {
4485        LOGVV("Invoking %s.<clinit>\n", clazz->descriptor);
4486        JValue unused;
4487        dvmCallMethod(self, method, NULL, &unused);
4488    }
4489
4490    if (dvmCheckException(self)) {
4491        /*
4492         * We've had an exception thrown during static initialization.  We
4493         * need to throw an ExceptionInInitializerError, but we want to
4494         * tuck the original exception into the "cause" field.
4495         */
4496        LOGW("Exception %s thrown during %s.<clinit>\n",
4497            (dvmGetException(self)->clazz)->descriptor, clazz->descriptor);
4498        throwClinitError();
4499        //LOGW("+++ replaced\n");
4500
4501        dvmLockObject(self, (Object*) clazz);
4502        clazz->status = CLASS_ERROR;
4503    } else {
4504        /* success! */
4505        dvmLockObject(self, (Object*) clazz);
4506        clazz->status = CLASS_INITIALIZED;
4507        LOGVV("Initialized class: %s\n", clazz->descriptor);
4508
4509#ifdef WITH_PROFILER
4510        /*
4511         * Update alloc counters.  TODO: guard with mutex.
4512         */
4513        if (gDvm.allocProf.enabled && startWhen != 0) {
4514            u8 initDuration = dvmGetRelativeTimeNsec() - startWhen;
4515            gDvm.allocProf.classInitTime += initDuration;
4516            self->allocProf.classInitTime += initDuration;
4517            gDvm.allocProf.classInitCount++;
4518            self->allocProf.classInitCount++;
4519        }
4520#endif
4521    }
4522
4523bail_notify:
4524    /*
4525     * Notify anybody waiting on the object.
4526     */
4527    dvmObjectNotifyAll(self, (Object*) clazz);
4528
4529bail_unlock:
4530
4531#if LOG_CLASS_LOADING
4532    if (initializedByUs) {
4533        // We finished initializing.
4534        logClassLoad('-', clazz);
4535    }
4536#endif
4537
4538    dvmUnlockObject(self, (Object*) clazz);
4539
4540    return (clazz->status != CLASS_ERROR);
4541}
4542
4543/*
4544 * Replace method->nativeFunc and method->insns with new values.  This is
4545 * performed on resolution of a native method.
4546 */
4547void dvmSetNativeFunc(const Method* method, DalvikBridgeFunc func,
4548    const u2* insns)
4549{
4550    ClassObject* clazz = method->clazz;
4551
4552    /* just open up both; easier that way */
4553    dvmLinearReadWrite(clazz->classLoader, clazz->virtualMethods);
4554    dvmLinearReadWrite(clazz->classLoader, clazz->directMethods);
4555
4556    ((Method*)method)->nativeFunc = func;
4557    ((Method*)method)->insns = insns;
4558
4559    dvmLinearReadOnly(clazz->classLoader, clazz->virtualMethods);
4560    dvmLinearReadOnly(clazz->classLoader, clazz->directMethods);
4561}
4562
4563/*
4564 * Add a RegisterMap to a Method.  This is done when we verify the class
4565 * and compute the register maps at class initialization time (i.e. when
4566 * we don't have a pre-generated map).  This means "pMap" is on the heap
4567 * and should be freed when the Method is discarded.
4568 */
4569void dvmSetRegisterMap(Method* method, const RegisterMap* pMap)
4570{
4571    ClassObject* clazz = method->clazz;
4572
4573    if (method->registerMap != NULL) {
4574        /* unexpected during class loading, okay on first use (uncompress) */
4575        LOGV("NOTE: registerMap already set for %s.%s\n",
4576            method->clazz->descriptor, method->name);
4577        /* keep going */
4578    }
4579    assert(!dvmIsNativeMethod(method) && !dvmIsAbstractMethod(method));
4580
4581    /* might be virtual or direct */
4582    dvmLinearReadWrite(clazz->classLoader, clazz->virtualMethods);
4583    dvmLinearReadWrite(clazz->classLoader, clazz->directMethods);
4584
4585    method->registerMap = pMap;
4586
4587    dvmLinearReadOnly(clazz->classLoader, clazz->virtualMethods);
4588    dvmLinearReadOnly(clazz->classLoader, clazz->directMethods);
4589}
4590
4591/*
4592 * dvmHashForeach callback.  A nonzero return value causes foreach to
4593 * bail out.
4594 */
4595static int findClassCallback(void* vclazz, void* arg)
4596{
4597    ClassObject* clazz = vclazz;
4598    const char* descriptor = (const char*) arg;
4599
4600    if (strcmp(clazz->descriptor, descriptor) == 0)
4601        return (int) clazz;
4602    return 0;
4603}
4604
4605/*
4606 * Find a loaded class by descriptor. Returns the first one found.
4607 * Because there can be more than one if class loaders are involved,
4608 * this is not an especially good API. (Currently only used by the
4609 * debugger and "checking" JNI.)
4610 *
4611 * "descriptor" should have the form "Ljava/lang/Class;" or
4612 * "[Ljava/lang/Class;", i.e. a descriptor and not an internal-form
4613 * class name.
4614 */
4615ClassObject* dvmFindLoadedClass(const char* descriptor)
4616{
4617    int result;
4618
4619    dvmHashTableLock(gDvm.loadedClasses);
4620    result = dvmHashForeach(gDvm.loadedClasses, findClassCallback,
4621            (void*) descriptor);
4622    dvmHashTableUnlock(gDvm.loadedClasses);
4623
4624    return (ClassObject*) result;
4625}
4626
4627/*
4628 * Retrieve the system (a/k/a application) class loader.
4629 */
4630Object* dvmGetSystemClassLoader(void)
4631{
4632    ClassObject* clazz;
4633    Method* getSysMeth;
4634    Object* loader;
4635
4636    clazz = dvmFindSystemClass("Ljava/lang/ClassLoader;");
4637    if (clazz == NULL)
4638        return NULL;
4639
4640    getSysMeth = dvmFindDirectMethodByDescriptor(clazz, "getSystemClassLoader",
4641        "()Ljava/lang/ClassLoader;");
4642    if (getSysMeth == NULL)
4643        return NULL;
4644
4645    JValue result;
4646    dvmCallMethod(dvmThreadSelf(), getSysMeth, NULL, &result);
4647    loader = (Object*)result.l;
4648    return loader;
4649}
4650
4651
4652/*
4653 * This is a dvmHashForeach callback.
4654 */
4655static int dumpClass(void* vclazz, void* varg)
4656{
4657    const ClassObject* clazz = (const ClassObject*) vclazz;
4658    const ClassObject* super;
4659    int flags = (int) varg;
4660    char* desc;
4661    int i;
4662
4663    if (clazz == NULL) {
4664        LOGI("dumpClass: ignoring request to dump null class\n");
4665        return 0;
4666    }
4667
4668    if ((flags & kDumpClassFullDetail) == 0) {
4669        bool showInit = (flags & kDumpClassInitialized) != 0;
4670        bool showLoader = (flags & kDumpClassClassLoader) != 0;
4671        const char* initStr;
4672
4673        initStr = dvmIsClassInitialized(clazz) ? "true" : "false";
4674
4675        if (showInit && showLoader)
4676            LOGI("%s %p %s\n", clazz->descriptor, clazz->classLoader, initStr);
4677        else if (showInit)
4678            LOGI("%s %s\n", clazz->descriptor, initStr);
4679        else if (showLoader)
4680            LOGI("%s %p\n", clazz->descriptor, clazz->classLoader);
4681        else
4682            LOGI("%s\n", clazz->descriptor);
4683
4684        return 0;
4685    }
4686
4687    /* clazz->super briefly holds the superclass index during class prep */
4688    if ((u4)clazz->super > 0x10000 && (u4) clazz->super != (u4)-1)
4689        super = clazz->super;
4690    else
4691        super = NULL;
4692
4693    LOGI("----- %s '%s' cl=%p ser=0x%08x -----\n",
4694        dvmIsInterfaceClass(clazz) ? "interface" : "class",
4695        clazz->descriptor, clazz->classLoader, clazz->serialNumber);
4696    LOGI("  objectSize=%d (%d from super)\n", (int) clazz->objectSize,
4697        super != NULL ? (int) super->objectSize : -1);
4698    LOGI("  access=0x%04x.%04x\n", clazz->accessFlags >> 16,
4699        clazz->accessFlags & JAVA_FLAGS_MASK);
4700    if (super != NULL)
4701        LOGI("  super='%s' (cl=%p)\n", super->descriptor, super->classLoader);
4702    if (dvmIsArrayClass(clazz)) {
4703        LOGI("  dimensions=%d elementClass=%s\n",
4704            clazz->arrayDim, clazz->elementClass->descriptor);
4705    }
4706    if (clazz->iftableCount > 0) {
4707        LOGI("  interfaces (%d):\n", clazz->iftableCount);
4708        for (i = 0; i < clazz->iftableCount; i++) {
4709            InterfaceEntry* ent = &clazz->iftable[i];
4710            int j;
4711
4712            LOGI("    %2d: %s (cl=%p)\n",
4713                i, ent->clazz->descriptor, ent->clazz->classLoader);
4714
4715            /* enable when needed */
4716            if (false && ent->methodIndexArray != NULL) {
4717                for (j = 0; j < ent->clazz->virtualMethodCount; j++)
4718                    LOGI("      %2d: %d %s %s\n",
4719                        j, ent->methodIndexArray[j],
4720                        ent->clazz->virtualMethods[j].name,
4721                        clazz->vtable[ent->methodIndexArray[j]]->name);
4722            }
4723        }
4724    }
4725    if (!dvmIsInterfaceClass(clazz)) {
4726        LOGI("  vtable (%d entries, %d in super):\n", clazz->vtableCount,
4727            super != NULL ? super->vtableCount : 0);
4728        for (i = 0; i < clazz->vtableCount; i++) {
4729            desc = dexProtoCopyMethodDescriptor(&clazz->vtable[i]->prototype);
4730            LOGI("    %s%2d: %p %20s %s\n",
4731                (i != clazz->vtable[i]->methodIndex) ? "*** " : "",
4732                (u4) clazz->vtable[i]->methodIndex, clazz->vtable[i],
4733                clazz->vtable[i]->name, desc);
4734            free(desc);
4735        }
4736        LOGI("  direct methods (%d entries):\n", clazz->directMethodCount);
4737        for (i = 0; i < clazz->directMethodCount; i++) {
4738            desc = dexProtoCopyMethodDescriptor(
4739                    &clazz->directMethods[i].prototype);
4740            LOGI("    %2d: %20s %s\n", i, clazz->directMethods[i].name,
4741                desc);
4742            free(desc);
4743        }
4744    } else {
4745        LOGI("  interface methods (%d):\n", clazz->virtualMethodCount);
4746        for (i = 0; i < clazz->virtualMethodCount; i++) {
4747            desc = dexProtoCopyMethodDescriptor(
4748                    &clazz->virtualMethods[i].prototype);
4749            LOGI("    %2d: %2d %20s %s\n", i,
4750                (u4) clazz->virtualMethods[i].methodIndex,
4751                clazz->virtualMethods[i].name,
4752                desc);
4753            free(desc);
4754        }
4755    }
4756    if (clazz->sfieldCount > 0) {
4757        LOGI("  static fields (%d entries):\n", clazz->sfieldCount);
4758        for (i = 0; i < clazz->sfieldCount; i++) {
4759            LOGI("    %2d: %20s %s\n", i, clazz->sfields[i].field.name,
4760                clazz->sfields[i].field.signature);
4761        }
4762    }
4763    if (clazz->ifieldCount > 0) {
4764        LOGI("  instance fields (%d entries):\n", clazz->ifieldCount);
4765        for (i = 0; i < clazz->ifieldCount; i++) {
4766            LOGI("    %2d: %20s %s\n", i, clazz->ifields[i].field.name,
4767                clazz->ifields[i].field.signature);
4768        }
4769    }
4770    return 0;
4771}
4772
4773/*
4774 * Dump the contents of a single class.
4775 *
4776 * Pass kDumpClassFullDetail into "flags" to get lots of detail.
4777 */
4778void dvmDumpClass(const ClassObject* clazz, int flags)
4779{
4780    dumpClass((void*) clazz, (void*) flags);
4781}
4782
4783/*
4784 * Dump the contents of all classes.
4785 */
4786void dvmDumpAllClasses(int flags)
4787{
4788    dvmHashTableLock(gDvm.loadedClasses);
4789    dvmHashForeach(gDvm.loadedClasses, dumpClass, (void*) flags);
4790    dvmHashTableUnlock(gDvm.loadedClasses);
4791}
4792
4793/*
4794 * Get the number of loaded classes
4795 */
4796int dvmGetNumLoadedClasses()
4797{
4798    int count;
4799    dvmHashTableLock(gDvm.loadedClasses);
4800    count = dvmHashTableNumEntries(gDvm.loadedClasses);
4801    dvmHashTableUnlock(gDvm.loadedClasses);
4802    return count;
4803}
4804
4805/*
4806 * Write some statistics to the log file.
4807 */
4808void dvmDumpLoaderStats(const char* msg)
4809{
4810    LOGV("VM stats (%s): cls=%d/%d meth=%d ifld=%d sfld=%d linear=%d\n",
4811        msg, gDvm.numLoadedClasses, dvmHashTableNumEntries(gDvm.loadedClasses),
4812        gDvm.numDeclaredMethods, gDvm.numDeclaredInstFields,
4813        gDvm.numDeclaredStaticFields, gDvm.pBootLoaderAlloc->curOffset);
4814#ifdef COUNT_PRECISE_METHODS
4815    LOGI("GC precise methods: %d\n",
4816        dvmPointerSetGetCount(gDvm.preciseMethods));
4817#endif
4818}
4819
4820#ifdef PROFILE_FIELD_ACCESS
4821/*
4822 * Dump the field access counts for all fields in this method.
4823 */
4824static int dumpAccessCounts(void* vclazz, void* varg)
4825{
4826    const ClassObject* clazz = (const ClassObject*) vclazz;
4827    int i;
4828
4829    for (i = 0; i < clazz->ifieldCount; i++) {
4830        Field* field = &clazz->ifields[i].field;
4831
4832        if (field->gets != 0)
4833            printf("GI %d %s.%s\n", field->gets,
4834                field->clazz->descriptor, field->name);
4835        if (field->puts != 0)
4836            printf("PI %d %s.%s\n", field->puts,
4837                field->clazz->descriptor, field->name);
4838    }
4839    for (i = 0; i < clazz->sfieldCount; i++) {
4840        Field* field = &clazz->sfields[i].field;
4841
4842        if (field->gets != 0)
4843            printf("GS %d %s.%s\n", field->gets,
4844                field->clazz->descriptor, field->name);
4845        if (field->puts != 0)
4846            printf("PS %d %s.%s\n", field->puts,
4847                field->clazz->descriptor, field->name);
4848    }
4849
4850    return 0;
4851}
4852
4853/*
4854 * Dump the field access counts for all loaded classes.
4855 */
4856void dvmDumpFieldAccessCounts(void)
4857{
4858    dvmHashTableLock(gDvm.loadedClasses);
4859    dvmHashForeach(gDvm.loadedClasses, dumpAccessCounts, NULL);
4860    dvmHashTableUnlock(gDvm.loadedClasses);
4861}
4862#endif
4863
4864
4865/*
4866 * Mark all classes associated with the built-in loader.
4867 */
4868static int markClassObject(void *clazz, void *arg)
4869{
4870    UNUSED_PARAMETER(arg);
4871
4872    dvmMarkObjectNonNull((Object *)clazz);
4873    return 0;
4874}
4875
4876/*
4877 * The garbage collector calls this to mark the class objects for all
4878 * loaded classes.
4879 */
4880void dvmGcScanRootClassLoader()
4881{
4882    /* dvmClassStartup() may not have been called before the first GC.
4883     */
4884    if (gDvm.unlinkedJavaLangClass != NULL) {
4885        dvmMarkObjectNonNull((Object *)gDvm.unlinkedJavaLangClass);
4886    }
4887    if (gDvm.loadedClasses != NULL) {
4888        dvmHashTableLock(gDvm.loadedClasses);
4889        dvmHashForeach(gDvm.loadedClasses, markClassObject, NULL);
4890        dvmHashTableUnlock(gDvm.loadedClasses);
4891    }
4892}
4893
4894
4895/*
4896 * ===========================================================================
4897 *      Method Prototypes and Descriptors
4898 * ===========================================================================
4899 */
4900
4901/*
4902 * Compare the two method names and prototypes, a la strcmp(). The
4903 * name is considered the "major" order and the prototype the "minor"
4904 * order. The prototypes are compared as if by dvmCompareMethodProtos().
4905 */
4906int dvmCompareMethodNamesAndProtos(const Method* method1,
4907        const Method* method2)
4908{
4909    int result = strcmp(method1->name, method2->name);
4910
4911    if (result != 0) {
4912        return result;
4913    }
4914
4915    return dvmCompareMethodProtos(method1, method2);
4916}
4917
4918/*
4919 * Compare the two method names and prototypes, a la strcmp(), ignoring
4920 * the return value. The name is considered the "major" order and the
4921 * prototype the "minor" order. The prototypes are compared as if by
4922 * dvmCompareMethodArgProtos().
4923 */
4924int dvmCompareMethodNamesAndParameterProtos(const Method* method1,
4925        const Method* method2)
4926{
4927    int result = strcmp(method1->name, method2->name);
4928
4929    if (result != 0) {
4930        return result;
4931    }
4932
4933    return dvmCompareMethodParameterProtos(method1, method2);
4934}
4935
4936/*
4937 * Compare a (name, prototype) pair with the (name, prototype) of
4938 * a method, a la strcmp(). The name is considered the "major" order and
4939 * the prototype the "minor" order. The descriptor and prototype are
4940 * compared as if by dvmCompareDescriptorAndMethodProto().
4941 */
4942int dvmCompareNameProtoAndMethod(const char* name,
4943    const DexProto* proto, const Method* method)
4944{
4945    int result = strcmp(name, method->name);
4946
4947    if (result != 0) {
4948        return result;
4949    }
4950
4951    return dexProtoCompare(proto, &method->prototype);
4952}
4953
4954/*
4955 * Compare a (name, method descriptor) pair with the (name, prototype) of
4956 * a method, a la strcmp(). The name is considered the "major" order and
4957 * the prototype the "minor" order. The descriptor and prototype are
4958 * compared as if by dvmCompareDescriptorAndMethodProto().
4959 */
4960int dvmCompareNameDescriptorAndMethod(const char* name,
4961    const char* descriptor, const Method* method)
4962{
4963    int result = strcmp(name, method->name);
4964
4965    if (result != 0) {
4966        return result;
4967    }
4968
4969    return dvmCompareDescriptorAndMethodProto(descriptor, method);
4970}
4971
4972size_t dvmClassObjectSize(const ClassObject *clazz)
4973{
4974    size_t size;
4975
4976    assert(clazz != NULL);
4977    size = offsetof(ClassObject, sfields);
4978    size += sizeof(StaticField) * clazz->sfieldCount;
4979    return size;
4980}
4981