1f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 2f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Copyright (C) 2008 The Android Open Source Project 3f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 4f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 5f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * you may not use this file except in compliance with the License. 6f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * You may obtain a copy of the License at 7f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 8f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 9f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 10f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 11f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 12f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * See the License for the specific language governing permissions and 14f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * limitations under the License. 15f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 16f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 17f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* common includes */ 18f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include "Dalvik.h" 19f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include "interp/InterpDefs.h" 20f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include "mterp/Mterp.h" 21f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include <math.h> // needed for fmod, fmodf 22ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng#include "mterp/common/FindInterface.h" 23f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 24f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 25f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Configuration defines. These affect the C implementations, i.e. the 26f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * portable interpreter(s) and C stubs. 27f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 28f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Some defines are controlled by the Makefile, e.g.: 29f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * WITH_INSTR_CHECKS 30f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * WITH_TRACKREF_CHECKS 31f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * EASY_GDB 32f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * NDEBUG 33f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 34f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project#ifdef WITH_INSTR_CHECKS /* instruction-level paranoia (slow!) */ 36f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project# define CHECK_BRANCH_OFFSETS 37f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project# define CHECK_REGISTER_INDICES 38f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#endif 39f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 40f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 41529d6b8112a06daca3bf4a89dec9fbad95efe46bAndy McFadden * Some architectures require 64-bit alignment for access to 64-bit data 42529d6b8112a06daca3bf4a89dec9fbad95efe46bAndy McFadden * types. We can't just use pointers to copy 64-bit values out of our 43529d6b8112a06daca3bf4a89dec9fbad95efe46bAndy McFadden * interpreted register set, because gcc may assume the pointer target is 44529d6b8112a06daca3bf4a89dec9fbad95efe46bAndy McFadden * aligned and generate invalid code. 45f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 46529d6b8112a06daca3bf4a89dec9fbad95efe46bAndy McFadden * There are two common approaches: 47529d6b8112a06daca3bf4a89dec9fbad95efe46bAndy McFadden * (1) Use a union that defines a 32-bit pair and a 64-bit value. 48529d6b8112a06daca3bf4a89dec9fbad95efe46bAndy McFadden * (2) Call memcpy(). 49529d6b8112a06daca3bf4a89dec9fbad95efe46bAndy McFadden * 50529d6b8112a06daca3bf4a89dec9fbad95efe46bAndy McFadden * Depending upon what compiler you're using and what options are specified, 51529d6b8112a06daca3bf4a89dec9fbad95efe46bAndy McFadden * one may be faster than the other. For example, the compiler might 52529d6b8112a06daca3bf4a89dec9fbad95efe46bAndy McFadden * convert a memcpy() of 8 bytes into a series of instructions and omit 53529d6b8112a06daca3bf4a89dec9fbad95efe46bAndy McFadden * the call. The union version could cause some strange side-effects, 54529d6b8112a06daca3bf4a89dec9fbad95efe46bAndy McFadden * e.g. for a while ARM gcc thought it needed separate storage for each 55529d6b8112a06daca3bf4a89dec9fbad95efe46bAndy McFadden * inlined instance, and generated instructions to zero out ~700 bytes of 56529d6b8112a06daca3bf4a89dec9fbad95efe46bAndy McFadden * stack space at the top of the interpreter. 57529d6b8112a06daca3bf4a89dec9fbad95efe46bAndy McFadden * 58529d6b8112a06daca3bf4a89dec9fbad95efe46bAndy McFadden * The default is to use memcpy(). The current gcc for ARM seems to do 59529d6b8112a06daca3bf4a89dec9fbad95efe46bAndy McFadden * better with the union. 60f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 61f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#if defined(__ARM_EABI__) 62529d6b8112a06daca3bf4a89dec9fbad95efe46bAndy McFadden# define NO_UNALIGN_64__UNION 63f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#endif 64f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 65529d6b8112a06daca3bf4a89dec9fbad95efe46bAndy McFadden 66f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project//#define LOG_INSTR /* verbose debugging */ 67f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* set and adjust ANDROID_LOG_TAGS='*:i jdwp:i dalvikvm:i dalvikvmi:i' */ 68f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 69f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 7099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * Export another copy of the PC on every instruction; this is largely 7199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * redundant with EXPORT_PC and the debugger code. This value can be 7299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * compared against what we have stored on the stack with EXPORT_PC to 7399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * help ensure that we aren't missing any export calls. 7499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project */ 7599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project#if WITH_EXTRA_GC_CHECKS > 1 7699409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project# define EXPORT_EXTRA_PC() (self->currentPc2 = pc) 7799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project#else 7899409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project# define EXPORT_EXTRA_PC() 7999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project#endif 8099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project 8199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project/* 82f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Adjust the program counter. "_offset" is a signed int, in 16-bit units. 83f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 84f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Assumes the existence of "const u2* pc" and "const u2* curMethod->insns". 85f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 86f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * We don't advance the program counter until we finish an instruction or 87f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * branch, because we do want to have to unroll the PC if there's an 88f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * exception. 89f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 90f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#ifdef CHECK_BRANCH_OFFSETS 91f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project# define ADJUST_PC(_offset) do { \ 92f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int myoff = _offset; /* deref only once */ \ 93f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (pc + myoff < curMethod->insns || \ 94f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pc + myoff >= curMethod->insns + dvmGetMethodInsnsSize(curMethod)) \ 95f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { \ 96f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char* desc; \ 97f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project desc = dexProtoCopyMethodDescriptor(&curMethod->prototype); \ 98c1a4ab9c313d8a3d12007f2dbef7b5a6fa4ac2efSteve Block ALOGE("Invalid branch %d at 0x%04x in %s.%s %s", \ 99f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project myoff, (int) (pc - curMethod->insns), \ 100f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project curMethod->clazz->descriptor, curMethod->name, desc); \ 101f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project free(desc); \ 102f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmAbort(); \ 103f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } \ 104f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pc += myoff; \ 10599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project EXPORT_EXTRA_PC(); \ 106f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } while (false) 107f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#else 10899409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project# define ADJUST_PC(_offset) do { \ 10999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project pc += _offset; \ 11099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project EXPORT_EXTRA_PC(); \ 11199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project } while (false) 112f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#endif 113f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 114f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 115f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * If enabled, log instructions as we execute them. 116f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 117f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#ifdef LOG_INSTR 118f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project# define ILOGD(...) ILOG(LOG_DEBUG, __VA_ARGS__) 119f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project# define ILOGV(...) ILOG(LOG_VERBOSE, __VA_ARGS__) 120f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project# define ILOG(_level, ...) do { \ 121f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char debugStrBuf[128]; \ 122f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project snprintf(debugStrBuf, sizeof(debugStrBuf), __VA_ARGS__); \ 12360fc806b679a3655c228b4093058c59941a49cfeDan Bornstein if (curMethod != NULL) \ 1241663a6c12fdf4732d7ea0a0406af6085b3c408e4Steve Block ALOG(_level, LOG_TAG"i", "%-2d|%04x%s", \ 125f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project self->threadId, (int)(pc - curMethod->insns), debugStrBuf); \ 126f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project else \ 1271663a6c12fdf4732d7ea0a0406af6085b3c408e4Steve Block ALOG(_level, LOG_TAG"i", "%-2d|####%s", \ 128f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project self->threadId, debugStrBuf); \ 129f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } while(false) 130f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid dvmDumpRegs(const Method* method, const u4* framePtr, bool inOnly); 131f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project# define DUMP_REGS(_meth, _frame, _inOnly) dvmDumpRegs(_meth, _frame, _inOnly) 132f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic const char kSpacing[] = " "; 133f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#else 134f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project# define ILOGD(...) ((void)0) 135f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project# define ILOGV(...) ((void)0) 136f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project# define DUMP_REGS(_meth, _frame, _inOnly) ((void)0) 137f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#endif 138f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 139f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* get a long from an array of u4 */ 140f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic inline s8 getLongFromArray(const u4* ptr, int idx) 141f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 142f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#if defined(NO_UNALIGN_64__UNION) 143f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project union { s8 ll; u4 parts[2]; } conv; 144f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 145f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ptr += idx; 146f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project conv.parts[0] = ptr[0]; 147f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project conv.parts[1] = ptr[1]; 148f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return conv.ll; 149529d6b8112a06daca3bf4a89dec9fbad95efe46bAndy McFadden#else 150f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project s8 val; 151f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project memcpy(&val, &ptr[idx], 8); 152f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return val; 153f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#endif 154f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 155f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 156f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* store a long into an array of u4 */ 157f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic inline void putLongToArray(u4* ptr, int idx, s8 val) 158f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 159f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#if defined(NO_UNALIGN_64__UNION) 160f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project union { s8 ll; u4 parts[2]; } conv; 161f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 162f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ptr += idx; 163f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project conv.ll = val; 164f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ptr[0] = conv.parts[0]; 165f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ptr[1] = conv.parts[1]; 166f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#else 167529d6b8112a06daca3bf4a89dec9fbad95efe46bAndy McFadden memcpy(&ptr[idx], &val, 8); 168f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#endif 169f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 170f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 171f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* get a double from an array of u4 */ 172f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic inline double getDoubleFromArray(const u4* ptr, int idx) 173f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 174f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#if defined(NO_UNALIGN_64__UNION) 175f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project union { double d; u4 parts[2]; } conv; 176f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 177f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ptr += idx; 178f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project conv.parts[0] = ptr[0]; 179f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project conv.parts[1] = ptr[1]; 180f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return conv.d; 181529d6b8112a06daca3bf4a89dec9fbad95efe46bAndy McFadden#else 182f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project double dval; 183f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project memcpy(&dval, &ptr[idx], 8); 184f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return dval; 185f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#endif 186f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 187f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 188f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* store a double into an array of u4 */ 189f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic inline void putDoubleToArray(u4* ptr, int idx, double dval) 190f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 191f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#if defined(NO_UNALIGN_64__UNION) 192f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project union { double d; u4 parts[2]; } conv; 193f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 194f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ptr += idx; 195f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project conv.d = dval; 196f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ptr[0] = conv.parts[0]; 197f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ptr[1] = conv.parts[1]; 198f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#else 199529d6b8112a06daca3bf4a89dec9fbad95efe46bAndy McFadden memcpy(&ptr[idx], &dval, 8); 200f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#endif 201f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 202f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 203f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 204f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * If enabled, validate the register number on every access. Otherwise, 205f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * just do an array access. 206f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 207f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Assumes the existence of "u4* fp". 208f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 209f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * "_idx" may be referenced more than once. 210f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 211f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#ifdef CHECK_REGISTER_INDICES 212f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project# define GET_REGISTER(_idx) \ 213f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ( (_idx) < curMethod->registersSize ? \ 214f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project (fp[(_idx)]) : (assert(!"bad reg"),1969) ) 215f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project# define SET_REGISTER(_idx, _val) \ 216f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ( (_idx) < curMethod->registersSize ? \ 217f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project (fp[(_idx)] = (u4)(_val)) : (assert(!"bad reg"),1969) ) 218f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project# define GET_REGISTER_AS_OBJECT(_idx) ((Object *)GET_REGISTER(_idx)) 219f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project# define SET_REGISTER_AS_OBJECT(_idx, _val) SET_REGISTER(_idx, (s4)_val) 220f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project# define GET_REGISTER_INT(_idx) ((s4) GET_REGISTER(_idx)) 221f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project# define SET_REGISTER_INT(_idx, _val) SET_REGISTER(_idx, (s4)_val) 222f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project# define GET_REGISTER_WIDE(_idx) \ 223f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ( (_idx) < curMethod->registersSize-1 ? \ 224f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project getLongFromArray(fp, (_idx)) : (assert(!"bad reg"),1969) ) 225f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project# define SET_REGISTER_WIDE(_idx, _val) \ 226f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ( (_idx) < curMethod->registersSize-1 ? \ 2279c6f0a6a36fcce4a55e3764db45c6c7cced077a5Carl Shapiro (void)putLongToArray(fp, (_idx), (_val)) : assert(!"bad reg") ) 228f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project# define GET_REGISTER_FLOAT(_idx) \ 229f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ( (_idx) < curMethod->registersSize ? \ 230f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project (*((float*) &fp[(_idx)])) : (assert(!"bad reg"),1969.0f) ) 231f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project# define SET_REGISTER_FLOAT(_idx, _val) \ 232f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ( (_idx) < curMethod->registersSize ? \ 233f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project (*((float*) &fp[(_idx)]) = (_val)) : (assert(!"bad reg"),1969.0f) ) 234f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project# define GET_REGISTER_DOUBLE(_idx) \ 235f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ( (_idx) < curMethod->registersSize-1 ? \ 236f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project getDoubleFromArray(fp, (_idx)) : (assert(!"bad reg"),1969.0) ) 237f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project# define SET_REGISTER_DOUBLE(_idx, _val) \ 238f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ( (_idx) < curMethod->registersSize-1 ? \ 2399c6f0a6a36fcce4a55e3764db45c6c7cced077a5Carl Shapiro (void)putDoubleToArray(fp, (_idx), (_val)) : assert(!"bad reg") ) 240f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#else 241f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project# define GET_REGISTER(_idx) (fp[(_idx)]) 242f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project# define SET_REGISTER(_idx, _val) (fp[(_idx)] = (_val)) 243f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project# define GET_REGISTER_AS_OBJECT(_idx) ((Object*) fp[(_idx)]) 244f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project# define SET_REGISTER_AS_OBJECT(_idx, _val) (fp[(_idx)] = (u4)(_val)) 245f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project# define GET_REGISTER_INT(_idx) ((s4)GET_REGISTER(_idx)) 246f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project# define SET_REGISTER_INT(_idx, _val) SET_REGISTER(_idx, (s4)_val) 247f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project# define GET_REGISTER_WIDE(_idx) getLongFromArray(fp, (_idx)) 248f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project# define SET_REGISTER_WIDE(_idx, _val) putLongToArray(fp, (_idx), (_val)) 249f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project# define GET_REGISTER_FLOAT(_idx) (*((float*) &fp[(_idx)])) 250f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project# define SET_REGISTER_FLOAT(_idx, _val) (*((float*) &fp[(_idx)]) = (_val)) 251f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project# define GET_REGISTER_DOUBLE(_idx) getDoubleFromArray(fp, (_idx)) 252f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project# define SET_REGISTER_DOUBLE(_idx, _val) putDoubleToArray(fp, (_idx), (_val)) 253f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#endif 254f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 255f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 256f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Get 16 bits from the specified offset of the program counter. We always 257f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * want to load 16 bits at a time from the instruction stream -- it's more 258f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * efficient than 8 and won't have the alignment problems that 32 might. 259f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 260f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Assumes existence of "const u2* pc". 261f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 262f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define FETCH(_offset) (pc[(_offset)]) 263f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 264f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 265f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Extract instruction byte from 16-bit fetch (_inst is a u2). 266f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 267f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define INST_INST(_inst) ((_inst) & 0xff) 268f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 269f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 27096516932f1557d8f48a8b2dbbb885af01a11ef6eAndy McFadden * Replace the opcode (used when handling breakpoints). _opcode is a u1. 27196516932f1557d8f48a8b2dbbb885af01a11ef6eAndy McFadden */ 27296516932f1557d8f48a8b2dbbb885af01a11ef6eAndy McFadden#define INST_REPLACE_OP(_inst, _opcode) (((_inst) & 0xff00) | _opcode) 27396516932f1557d8f48a8b2dbbb885af01a11ef6eAndy McFadden 27496516932f1557d8f48a8b2dbbb885af01a11ef6eAndy McFadden/* 275f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Extract the "vA, vB" 4-bit registers from the instruction word (_inst is u2). 276f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 277f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define INST_A(_inst) (((_inst) >> 8) & 0x0f) 278f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define INST_B(_inst) ((_inst) >> 12) 279f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 280f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 281f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Get the 8-bit "vAA" 8-bit register index from the instruction word. 282f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * (_inst is u2) 283f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 284f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define INST_AA(_inst) ((_inst) >> 8) 285f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 286f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 287f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * The current PC must be available to Throwable constructors, e.g. 28898f3eb12bf2a33c49712e093d5cc2aa713a93aa5buzbee * those created by the various exception throw routines, so that the 28998f3eb12bf2a33c49712e093d5cc2aa713a93aa5buzbee * exception stack trace can be generated correctly. If we don't do this, 29098f3eb12bf2a33c49712e093d5cc2aa713a93aa5buzbee * the offset within the current method won't be shown correctly. See the 29198f3eb12bf2a33c49712e093d5cc2aa713a93aa5buzbee * notes in Exception.c. 292f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 29399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * This is also used to determine the address for precise GC. 29499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * 295f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Assumes existence of "u4* fp" and "const u2* pc". 296f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 297f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define EXPORT_PC() (SAVEAREA_FROM_FP(fp)->xtra.currentPc = pc) 298f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 299f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 300f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Check to see if "obj" is NULL. If so, throw an exception. Assumes the 301f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * pc has already been exported to the stack. 302f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 303f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Perform additional checks on debug builds. 304f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 305f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Use this to check for NULL when the instruction handler calls into 306f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * something that could throw an exception (so we have already called 307f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * EXPORT_PC at the top). 308f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 309f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic inline bool checkForNull(Object* obj) 310f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 311f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (obj == NULL) { 312d27f3cf3e7b373487f39e035fc4b55168d55c454Dan Bornstein dvmThrowNullPointerException(NULL); 313f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return false; 314f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 315f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#ifdef WITH_EXTRA_OBJECT_VALIDATION 31634987b48d216786454aca59474cb76015af48bd9Jeff Brown if (!dvmIsHeapAddress(obj)) { 317c1a4ab9c313d8a3d12007f2dbef7b5a6fa4ac2efSteve Block ALOGE("Invalid object %p", obj); 318f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmAbort(); 319f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 320f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#endif 321f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#ifndef NDEBUG 322f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (obj->clazz == NULL || ((u4) obj->clazz) <= 65536) { 323f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* probable heap corruption */ 324c1a4ab9c313d8a3d12007f2dbef7b5a6fa4ac2efSteve Block ALOGE("Invalid object class %p (in %p)", obj->clazz, obj); 325f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmAbort(); 326f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 327f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#endif 328f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return true; 329f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 330f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 331f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 332f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Check to see if "obj" is NULL. If so, export the PC into the stack 333f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * frame and throw an exception. 334f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 335f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Perform additional checks on debug builds. 336f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 337f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Use this to check for NULL when the instruction handler doesn't do 338f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * anything else that can throw an exception. 339f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 340f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic inline bool checkForNullExportPC(Object* obj, u4* fp, const u2* pc) 341f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 342f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (obj == NULL) { 343f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project EXPORT_PC(); 344d27f3cf3e7b373487f39e035fc4b55168d55c454Dan Bornstein dvmThrowNullPointerException(NULL); 345f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return false; 346f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 347f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#ifdef WITH_EXTRA_OBJECT_VALIDATION 3488bc8bf71a52e17d483021b4c9dc8e735d9bce3edElliott Hughes if (!dvmIsHeapAddress(obj)) { 349c1a4ab9c313d8a3d12007f2dbef7b5a6fa4ac2efSteve Block ALOGE("Invalid object %p", obj); 350f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmAbort(); 351f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 352f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#endif 353f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#ifndef NDEBUG 354f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (obj->clazz == NULL || ((u4) obj->clazz) <= 65536) { 355f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* probable heap corruption */ 356c1a4ab9c313d8a3d12007f2dbef7b5a6fa4ac2efSteve Block ALOGE("Invalid object class %p (in %p)", obj->clazz, obj); 357f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmAbort(); 358f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 359f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#endif 360f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return true; 361f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 362