entry.cpp revision 60fc806b679a3655c228b4093058c59941a49cfe
1/*
2 * Handler function table, one entry per opcode.
3 */
4#undef H
5#define H(_op) dvmMterp_##_op
6DEFINE_GOTO_TABLE(gDvmMterpHandlers)
7
8#undef H
9#define H(_op) #_op
10DEFINE_GOTO_TABLE(gDvmMterpHandlerNames)
11
12#include <setjmp.h>
13
14/*
15 * C mterp entry point.  This just calls the various C fallbacks, making
16 * this a slow but portable interpeter.
17 *
18 * This is only used for the "allstubs" variant.
19 */
20void dvmMterpStdRun(Thread* self)
21{
22    jmp_buf jmpBuf;
23
24    self->bailPtr = &jmpBuf;
25
26    /* We exit via a longjmp */
27    if (setjmp(jmpBuf)) {
28        LOGVV("mterp threadid=%d returning", dvmThreadSelf()->threadId);
29        return
30    }
31
32    /* run until somebody longjmp()s out */
33    while (true) {
34        typedef void (*Handler)(Thread* self);
35
36        u2 inst = /*self->interpSave.*/pc[0];
37        /*
38         * In mterp, dvmCheckBefore is handled via the altHandlerTable,
39         * while in the portable interpreter it is part of the handler
40         * FINISH code.  For allstubs, we must do an explicit check
41         * in the interpretation loop.
42         */
43        if (self-interpBreak.ctl.subMode) {
44            dvmCheckBefore(pc, fp, self, curMethod);
45        }
46        Handler handler = (Handler) gDvmMterpHandlers[inst & 0xff];
47        (void) gDvmMterpHandlerNames;   /* avoid gcc "defined but not used" */
48        LOGVV("handler %p %s",
49            handler, (const char*) gDvmMterpHandlerNames[inst & 0xff]);
50        (*handler)(self);
51    }
52}
53
54/*
55 * C mterp exit point.  Call here to bail out of the interpreter.
56 */
57void dvmMterpStdBail(Thread* self)
58{
59    jmp_buf* pJmpBuf = self->bailPtr;
60    longjmp(*pJmpBuf, 1);
61}
62