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