OSDN Git Service

auto import from //branches/cupcake/...@125939
[android-x86/dalvik.git] / vm / mterp / Mterp.c
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  * Mterp entry point and support functions.
19  */
20 #include "mterp/Mterp.h"
21
22 #include <stddef.h>
23
24
25 /*
26  * Verify some constants used by the mterp interpreter.
27  */
28 bool dvmCheckAsmConstants(void)
29 {
30     extern char dvmAsmInstructionStart[];
31     extern char dvmAsmInstructionEnd[];
32     extern char dvmAsmSisterStart[];
33     extern char dvmAsmSisterEnd[];
34
35     bool failed = false;
36
37 #define ASM_DEF_VERIFY
38 #include "mterp/common/asm-constants.h"
39
40     if (failed) {
41         LOGE("Please correct the values in mterp/common/asm-constants.h\n");
42         dvmAbort();
43     }
44
45     /*
46      * If an instruction overflows the 64-byte handler size limit, it will
47      * push everything up and alter the total size.  Check it here.
48      */
49     const int width = 64;
50     int interpSize = dvmAsmInstructionEnd - dvmAsmInstructionStart;
51     if (interpSize != 0 && interpSize != 256*width) {
52         LOGE("ERROR: unexpected asm interp size %d\n", interpSize);
53         LOGE("(did an instruction handler exceed %d bytes?)\n", width);
54         dvmAbort();
55     }
56     int sisterSize = dvmAsmSisterEnd - dvmAsmSisterStart;
57     LOGV("mterp: interp is %d bytes, sisters are %d bytes\n",
58         interpSize, sisterSize);
59
60     return !failed;
61 }
62
63
64 /*
65  * "Standard" mterp entry point.  This sets up a "glue" structure and then
66  * calls into the assembly interpreter implementation.
67  *
68  * (There is presently no "debug" entry point.)
69  */
70 bool dvmMterpStd(Thread* self, InterpState* glue)
71 {
72     int changeInterp;
73
74     /* configure mterp items */
75     glue->self = self;
76     glue->methodClassDex = glue->method->clazz->pDvmDex;
77
78     glue->interpStackEnd = self->interpStackEnd;
79     glue->pSelfSuspendCount = &self->suspendCount;
80 #if defined(WITH_DEBUGGER)
81     glue->pDebuggerActive = &gDvm.debuggerActive;
82 #endif
83 #if defined(WITH_PROFILER)
84     glue->pActiveProfilers = &gDvm.activeProfilers;
85 #endif
86
87     IF_LOGVV() {
88         char* desc = dexProtoCopyMethodDescriptor(&glue->method->prototype);
89         LOGVV("mterp threadid=%d entry %d: %s.%s %s\n",
90             dvmThreadSelf()->threadId,
91             glue->entryPoint,
92             glue->method->clazz->descriptor,
93             glue->method->name,
94             desc);
95         free(desc);
96     }
97     //LOGI("glue is %p, pc=%p, fp=%p\n", glue, glue->pc, glue->fp);
98     //LOGI("first instruction is 0x%04x\n", glue->pc[0]);
99
100     changeInterp = dvmMterpStdRun(glue);
101     if (!changeInterp) {
102         /* this is a "normal" exit; we're not coming back */
103 #ifdef LOG_INSTR
104         LOGD("|-- Leaving interpreter loop");
105 #endif
106         return false;
107     } else {
108         /* we're "standard", so switch to "debug" */
109         LOGVV("  mterp returned, changeInterp=%d\n", changeInterp);
110         glue->nextMode = INTERP_DBG;
111         return true;
112     }
113 }
114