• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Handler function table, one entry per opcode.
3  */
4 #undef H
5 #define H(_op) (const void*) dvmMterp_##_op
6 DEFINE_GOTO_TABLE(gDvmMterpHandlers)
7 
8 #undef H
9 #define H(_op) #_op
DEFINE_GOTO_TABLE(gDvmMterpHandlerNames)10 DEFINE_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  */
20 void dvmMterpStdRun(Thread* self)
21 {
22     jmp_buf jmpBuf;
23 
24     self->interpSave.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);
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  */
dvmMterpStdBail(Thread * self)57 void dvmMterpStdBail(Thread* self)
58 {
59     jmp_buf* pJmpBuf = (jmp_buf*) self->interpSave.bailPtr;
60     longjmp(*pJmpBuf, 1);
61 }
62