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