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