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