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 "Dalvik.h" 21 #include "mterp/Mterp.h" 22 23 #include <stddef.h> 24 25 26 /* 27 * Verify some constants used by the mterp interpreter. 28 */ 29 bool dvmCheckAsmConstants() 30 { 31 bool failed = false; 32 33 #ifndef DVM_NO_ASM_INTERP 34 35 #ifndef DVM_JMP_TABLE_MTERP 36 extern void* dvmAsmInstructionStart[]; 37 extern void* dvmAsmInstructionEnd[]; 38 #endif 39 40 #define ASM_DEF_VERIFY 41 #include "mterp/common/asm-constants.h" 42 43 if (failed) { 44 LOGE("Please correct the values in mterp/common/asm-constants.h"); 45 dvmAbort(); 46 } 47 48 #ifndef DVM_JMP_TABLE_MTERP 49 /* 50 * If we're using computed goto instruction transitions, make sure 51 * none of the handlers overflows the 64-byte limit. This won't tell 52 * which one did, but if any one is too big the total size will 53 * overflow. 54 */ 55 const int width = 64; 56 int interpSize = (uintptr_t) dvmAsmInstructionEnd - 57 (uintptr_t) dvmAsmInstructionStart; 58 if (interpSize != 0 && interpSize != kNumPackedOpcodes*width) { 59 LOGE("ERROR: unexpected asm interp size %d", interpSize); 60 LOGE("(did an instruction handler exceed %d bytes?)", width); 61 dvmAbort(); 62 } 63 #endif 64 65 #endif // ndef DVM_NO_ASM_INTERP 66 67 return !failed; 68 } 69 70 71 /* 72 * "Mterp entry point. 73 */ 74 void dvmMterpStd(Thread* self) 75 { 76 /* configure mterp items */ 77 self->interpSave.methodClassDex = self->interpSave.method->clazz->pDvmDex; 78 79 IF_LOGVV() { 80 char* desc = dexProtoCopyMethodDescriptor( 81 &self->interpSave.method->prototype); 82 LOGVV("mterp threadid=%d : %s.%s %s", 83 dvmThreadSelf()->threadId, 84 self->interpSave.method->clazz->descriptor, 85 self->interpSave.method->name, 86 desc); 87 free(desc); 88 } 89 //LOGI("self is %p, pc=%p, fp=%p", self, self->interpSave.pc, 90 // self->interpSave.curFrame); 91 //LOGI("first instruction is 0x%04x", self->interpSave.pc[0]); 92 93 /* 94 * Handle any ongoing profiling and prep for debugging 95 */ 96 if (self->interpBreak.ctl.subMode != 0) { 97 TRACE_METHOD_ENTER(self, self->interpSave.method); 98 self->debugIsMethodEntry = true; // Always true on startup 99 } 100 101 dvmMterpStdRun(self); 102 103 #ifdef LOG_INSTR 104 LOGD("|-- Leaving interpreter loop"); 105 #endif 106 } 107