Home | History | Annotate | Download | only in 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 /* common includes */
     18 #include "Dalvik.h"
     19 #include "interp/InterpDefs.h"
     20 #include "mterp/Mterp.h"
     21 #include <math.h>                   // needed for fmod, fmodf
     22 #include "mterp/common/FindInterface.h"
     23 
     24 /*
     25  * Configuration defines.  These affect the C implementations, i.e. the
     26  * portable interpreter(s) and C stubs.
     27  *
     28  * Some defines are controlled by the Makefile, e.g.:
     29  *   WITH_INSTR_CHECKS
     30  *   WITH_TRACKREF_CHECKS
     31  *   EASY_GDB
     32  *   NDEBUG
     33  *
     34  * If THREADED_INTERP is not defined, we use a classic "while true / switch"
     35  * interpreter.  If it is defined, then the tail end of each instruction
     36  * handler fetches the next instruction and jumps directly to the handler.
     37  * This increases the size of the "Std" interpreter by about 10%, but
     38  * provides a speedup of about the same magnitude.
     39  *
     40  * There's a "hybrid" approach that uses a goto table instead of a switch
     41  * statement, avoiding the "is the opcode in range" tests required for switch.
     42  * The performance is close to the threaded version, and without the 10%
     43  * size increase, but the benchmark results are off enough that it's not
     44  * worth adding as a third option.
     45  */
     46 #define THREADED_INTERP             /* threaded vs. while-loop interpreter */
     47 
     48 #ifdef WITH_INSTR_CHECKS            /* instruction-level paranoia (slow!) */
     49 # define CHECK_BRANCH_OFFSETS
     50 # define CHECK_REGISTER_INDICES
     51 #endif
     52 
     53 /*
     54  * ARM EABI requires 64-bit alignment for access to 64-bit data types.  We
     55  * can't just use pointers to copy 64-bit values out of our interpreted
     56  * register set, because gcc will generate ldrd/strd.
     57  *
     58  * The __UNION version copies data in and out of a union.  The __MEMCPY
     59  * version uses a memcpy() call to do the transfer; gcc is smart enough to
     60  * not actually call memcpy().  The __UNION version is very bad on ARM;
     61  * it only uses one more instruction than __MEMCPY, but for some reason
     62  * gcc thinks it needs separate storage for every instance of the union.
     63  * On top of that, it feels the need to zero them out at the start of the
     64  * method.  Net result is we zero out ~700 bytes of stack space at the top
     65  * of the interpreter using ARM STM instructions.
     66  */
     67 #if defined(__ARM_EABI__)
     68 //# define NO_UNALIGN_64__UNION
     69 # define NO_UNALIGN_64__MEMCPY
     70 #endif
     71 
     72 //#define LOG_INSTR                   /* verbose debugging */
     73 /* set and adjust ANDROID_LOG_TAGS='*:i jdwp:i dalvikvm:i dalvikvmi:i' */
     74 
     75 /*
     76  * Keep a tally of accesses to fields.  Currently only works if full DEX
     77  * optimization is disabled.
     78  */
     79 #ifdef PROFILE_FIELD_ACCESS
     80 # define UPDATE_FIELD_GET(_field) { (_field)->gets++; }
     81 # define UPDATE_FIELD_PUT(_field) { (_field)->puts++; }
     82 #else
     83 # define UPDATE_FIELD_GET(_field) ((void)0)
     84 # define UPDATE_FIELD_PUT(_field) ((void)0)
     85 #endif
     86 
     87 /*
     88  * Export another copy of the PC on every instruction; this is largely
     89  * redundant with EXPORT_PC and the debugger code.  This value can be
     90  * compared against what we have stored on the stack with EXPORT_PC to
     91  * help ensure that we aren't missing any export calls.
     92  */
     93 #if WITH_EXTRA_GC_CHECKS > 1
     94 # define EXPORT_EXTRA_PC() (self->currentPc2 = pc)
     95 #else
     96 # define EXPORT_EXTRA_PC()
     97 #endif
     98 
     99 /*
    100  * Adjust the program counter.  "_offset" is a signed int, in 16-bit units.
    101  *
    102  * Assumes the existence of "const u2* pc" and "const u2* curMethod->insns".
    103  *
    104  * We don't advance the program counter until we finish an instruction or
    105  * branch, because we do want to have to unroll the PC if there's an
    106  * exception.
    107  */
    108 #ifdef CHECK_BRANCH_OFFSETS
    109 # define ADJUST_PC(_offset) do {                                            \
    110         int myoff = _offset;        /* deref only once */                   \
    111         if (pc + myoff < curMethod->insns ||                                \
    112             pc + myoff >= curMethod->insns + dvmGetMethodInsnsSize(curMethod)) \
    113         {                                                                   \
    114             char* desc;                                                     \
    115             desc = dexProtoCopyMethodDescriptor(&curMethod->prototype);     \
    116             LOGE("Invalid branch %d at 0x%04x in %s.%s %s\n",               \
    117                 myoff, (int) (pc - curMethod->insns),                       \
    118                 curMethod->clazz->descriptor, curMethod->name, desc);       \
    119             free(desc);                                                     \
    120             dvmAbort();                                                     \
    121         }                                                                   \
    122         pc += myoff;                                                        \
    123         EXPORT_EXTRA_PC();                                                  \
    124     } while (false)
    125 #else
    126 # define ADJUST_PC(_offset) do {                                            \
    127         pc += _offset;                                                      \
    128         EXPORT_EXTRA_PC();                                                  \
    129     } while (false)
    130 #endif
    131 
    132 /*
    133  * If enabled, log instructions as we execute them.
    134  */
    135 #ifdef LOG_INSTR
    136 # define ILOGD(...) ILOG(LOG_DEBUG, __VA_ARGS__)
    137 # define ILOGV(...) ILOG(LOG_VERBOSE, __VA_ARGS__)
    138 # define ILOG(_level, ...) do {                                             \
    139         char debugStrBuf[128];                                              \
    140         snprintf(debugStrBuf, sizeof(debugStrBuf), __VA_ARGS__);            \
    141         if (curMethod != NULL)                                                 \
    142             LOG(_level, LOG_TAG"i", "%-2d|%04x%s\n",                        \
    143                 self->threadId, (int)(pc - curMethod->insns), debugStrBuf); \
    144         else                                                                \
    145             LOG(_level, LOG_TAG"i", "%-2d|####%s\n",                        \
    146                 self->threadId, debugStrBuf);                               \
    147     } while(false)
    148 void dvmDumpRegs(const Method* method, const u4* framePtr, bool inOnly);
    149 # define DUMP_REGS(_meth, _frame, _inOnly) dvmDumpRegs(_meth, _frame, _inOnly)
    150 static const char kSpacing[] = "            ";
    151 #else
    152 # define ILOGD(...) ((void)0)
    153 # define ILOGV(...) ((void)0)
    154 # define DUMP_REGS(_meth, _frame, _inOnly) ((void)0)
    155 #endif
    156 
    157 /* get a long from an array of u4 */
    158 static inline s8 getLongFromArray(const u4* ptr, int idx)
    159 {
    160 #if defined(NO_UNALIGN_64__UNION)
    161     union { s8 ll; u4 parts[2]; } conv;
    162 
    163     ptr += idx;
    164     conv.parts[0] = ptr[0];
    165     conv.parts[1] = ptr[1];
    166     return conv.ll;
    167 #elif defined(NO_UNALIGN_64__MEMCPY)
    168     s8 val;
    169     memcpy(&val, &ptr[idx], 8);
    170     return val;
    171 #else
    172     return *((s8*) &ptr[idx]);
    173 #endif
    174 }
    175 
    176 /* store a long into an array of u4 */
    177 static inline void putLongToArray(u4* ptr, int idx, s8 val)
    178 {
    179 #if defined(NO_UNALIGN_64__UNION)
    180     union { s8 ll; u4 parts[2]; } conv;
    181 
    182     ptr += idx;
    183     conv.ll = val;
    184     ptr[0] = conv.parts[0];
    185     ptr[1] = conv.parts[1];
    186 #elif defined(NO_UNALIGN_64__MEMCPY)
    187     memcpy(&ptr[idx], &val, 8);
    188 #else
    189     *((s8*) &ptr[idx]) = val;
    190 #endif
    191 }
    192 
    193 /* get a double from an array of u4 */
    194 static inline double getDoubleFromArray(const u4* ptr, int idx)
    195 {
    196 #if defined(NO_UNALIGN_64__UNION)
    197     union { double d; u4 parts[2]; } conv;
    198 
    199     ptr += idx;
    200     conv.parts[0] = ptr[0];
    201     conv.parts[1] = ptr[1];
    202     return conv.d;
    203 #elif defined(NO_UNALIGN_64__MEMCPY)
    204     double dval;
    205     memcpy(&dval, &ptr[idx], 8);
    206     return dval;
    207 #else
    208     return *((double*) &ptr[idx]);
    209 #endif
    210 }
    211 
    212 /* store a double into an array of u4 */
    213 static inline void putDoubleToArray(u4* ptr, int idx, double dval)
    214 {
    215 #if defined(NO_UNALIGN_64__UNION)
    216     union { double d; u4 parts[2]; } conv;
    217 
    218     ptr += idx;
    219     conv.d = dval;
    220     ptr[0] = conv.parts[0];
    221     ptr[1] = conv.parts[1];
    222 #elif defined(NO_UNALIGN_64__MEMCPY)
    223     memcpy(&ptr[idx], &dval, 8);
    224 #else
    225     *((double*) &ptr[idx]) = dval;
    226 #endif
    227 }
    228 
    229 /*
    230  * If enabled, validate the register number on every access.  Otherwise,
    231  * just do an array access.
    232  *
    233  * Assumes the existence of "u4* fp".
    234  *
    235  * "_idx" may be referenced more than once.
    236  */
    237 #ifdef CHECK_REGISTER_INDICES
    238 # define GET_REGISTER(_idx) \
    239     ( (_idx) < curMethod->registersSize ? \
    240         (fp[(_idx)]) : (assert(!"bad reg"),1969) )
    241 # define SET_REGISTER(_idx, _val) \
    242     ( (_idx) < curMethod->registersSize ? \
    243         (fp[(_idx)] = (u4)(_val)) : (assert(!"bad reg"),1969) )
    244 # define GET_REGISTER_AS_OBJECT(_idx)       ((Object *)GET_REGISTER(_idx))
    245 # define SET_REGISTER_AS_OBJECT(_idx, _val) SET_REGISTER(_idx, (s4)_val)
    246 # define GET_REGISTER_INT(_idx) ((s4) GET_REGISTER(_idx))
    247 # define SET_REGISTER_INT(_idx, _val) SET_REGISTER(_idx, (s4)_val)
    248 # define GET_REGISTER_WIDE(_idx) \
    249     ( (_idx) < curMethod->registersSize-1 ? \
    250         getLongFromArray(fp, (_idx)) : (assert(!"bad reg"),1969) )
    251 # define SET_REGISTER_WIDE(_idx, _val) \
    252     ( (_idx) < curMethod->registersSize-1 ? \
    253         putLongToArray(fp, (_idx), (_val)) : (assert(!"bad reg"),1969) )
    254 # define GET_REGISTER_FLOAT(_idx) \
    255     ( (_idx) < curMethod->registersSize ? \
    256         (*((float*) &fp[(_idx)])) : (assert(!"bad reg"),1969.0f) )
    257 # define SET_REGISTER_FLOAT(_idx, _val) \
    258     ( (_idx) < curMethod->registersSize ? \
    259         (*((float*) &fp[(_idx)]) = (_val)) : (assert(!"bad reg"),1969.0f) )
    260 # define GET_REGISTER_DOUBLE(_idx) \
    261     ( (_idx) < curMethod->registersSize-1 ? \
    262         getDoubleFromArray(fp, (_idx)) : (assert(!"bad reg"),1969.0) )
    263 # define SET_REGISTER_DOUBLE(_idx, _val) \
    264     ( (_idx) < curMethod->registersSize-1 ? \
    265         putDoubleToArray(fp, (_idx), (_val)) : (assert(!"bad reg"),1969.0) )
    266 #else
    267 # define GET_REGISTER(_idx)                 (fp[(_idx)])
    268 # define SET_REGISTER(_idx, _val)           (fp[(_idx)] = (_val))
    269 # define GET_REGISTER_AS_OBJECT(_idx)       ((Object*) fp[(_idx)])
    270 # define SET_REGISTER_AS_OBJECT(_idx, _val) (fp[(_idx)] = (u4)(_val))
    271 # define GET_REGISTER_INT(_idx)             ((s4)GET_REGISTER(_idx))
    272 # define SET_REGISTER_INT(_idx, _val)       SET_REGISTER(_idx, (s4)_val)
    273 # define GET_REGISTER_WIDE(_idx)            getLongFromArray(fp, (_idx))
    274 # define SET_REGISTER_WIDE(_idx, _val)      putLongToArray(fp, (_idx), (_val))
    275 # define GET_REGISTER_FLOAT(_idx)           (*((float*) &fp[(_idx)]))
    276 # define SET_REGISTER_FLOAT(_idx, _val)     (*((float*) &fp[(_idx)]) = (_val))
    277 # define GET_REGISTER_DOUBLE(_idx)          getDoubleFromArray(fp, (_idx))
    278 # define SET_REGISTER_DOUBLE(_idx, _val)    putDoubleToArray(fp, (_idx), (_val))
    279 #endif
    280 
    281 /*
    282  * Get 16 bits from the specified offset of the program counter.  We always
    283  * want to load 16 bits at a time from the instruction stream -- it's more
    284  * efficient than 8 and won't have the alignment problems that 32 might.
    285  *
    286  * Assumes existence of "const u2* pc".
    287  */
    288 #define FETCH(_offset)     (pc[(_offset)])
    289 
    290 /*
    291  * Extract instruction byte from 16-bit fetch (_inst is a u2).
    292  */
    293 #define INST_INST(_inst)    ((_inst) & 0xff)
    294 
    295 /*
    296  * Replace the opcode (used when handling breakpoints).  _opcode is a u1.
    297  */
    298 #define INST_REPLACE_OP(_inst, _opcode) (((_inst) & 0xff00) | _opcode)
    299 
    300 /*
    301  * Extract the "vA, vB" 4-bit registers from the instruction word (_inst is u2).
    302  */
    303 #define INST_A(_inst)       (((_inst) >> 8) & 0x0f)
    304 #define INST_B(_inst)       ((_inst) >> 12)
    305 
    306 /*
    307  * Get the 8-bit "vAA" 8-bit register index from the instruction word.
    308  * (_inst is u2)
    309  */
    310 #define INST_AA(_inst)      ((_inst) >> 8)
    311 
    312 /*
    313  * The current PC must be available to Throwable constructors, e.g.
    314  * those created by dvmThrowException(), so that the exception stack
    315  * trace can be generated correctly.  If we don't do this, the offset
    316  * within the current method won't be shown correctly.  See the notes
    317  * in Exception.c.
    318  *
    319  * This is also used to determine the address for precise GC.
    320  *
    321  * Assumes existence of "u4* fp" and "const u2* pc".
    322  */
    323 #define EXPORT_PC()         (SAVEAREA_FROM_FP(fp)->xtra.currentPc = pc)
    324 
    325 /*
    326  * Determine if we need to switch to a different interpreter.  "_current"
    327  * is either INTERP_STD or INTERP_DBG.  It should be fixed for a given
    328  * interpreter generation file, which should remove the outer conditional
    329  * from the following.
    330  *
    331  * If we're building without debug and profiling support, we never switch.
    332  */
    333 #if defined(WITH_JIT)
    334 # define NEED_INTERP_SWITCH(_current) (                                     \
    335     (_current == INTERP_STD) ?                                              \
    336         dvmJitDebuggerOrProfilerActive() : !dvmJitDebuggerOrProfilerActive() )
    337 #else
    338 # define NEED_INTERP_SWITCH(_current) (                                     \
    339     (_current == INTERP_STD) ?                                              \
    340         dvmDebuggerOrProfilerActive() : !dvmDebuggerOrProfilerActive() )
    341 #endif
    342 
    343 /*
    344  * Check to see if "obj" is NULL.  If so, throw an exception.  Assumes the
    345  * pc has already been exported to the stack.
    346  *
    347  * Perform additional checks on debug builds.
    348  *
    349  * Use this to check for NULL when the instruction handler calls into
    350  * something that could throw an exception (so we have already called
    351  * EXPORT_PC at the top).
    352  */
    353 static inline bool checkForNull(Object* obj)
    354 {
    355     if (obj == NULL) {
    356         dvmThrowException("Ljava/lang/NullPointerException;", NULL);
    357         return false;
    358     }
    359 #ifdef WITH_EXTRA_OBJECT_VALIDATION
    360     if (!dvmIsValidObject(obj)) {
    361         LOGE("Invalid object %p\n", obj);
    362         dvmAbort();
    363     }
    364 #endif
    365 #ifndef NDEBUG
    366     if (obj->clazz == NULL || ((u4) obj->clazz) <= 65536) {
    367         /* probable heap corruption */
    368         LOGE("Invalid object class %p (in %p)\n", obj->clazz, obj);
    369         dvmAbort();
    370     }
    371 #endif
    372     return true;
    373 }
    374 
    375 /*
    376  * Check to see if "obj" is NULL.  If so, export the PC into the stack
    377  * frame and throw an exception.
    378  *
    379  * Perform additional checks on debug builds.
    380  *
    381  * Use this to check for NULL when the instruction handler doesn't do
    382  * anything else that can throw an exception.
    383  */
    384 static inline bool checkForNullExportPC(Object* obj, u4* fp, const u2* pc)
    385 {
    386     if (obj == NULL) {
    387         EXPORT_PC();
    388         dvmThrowException("Ljava/lang/NullPointerException;", NULL);
    389         return false;
    390     }
    391 #ifdef WITH_EXTRA_OBJECT_VALIDATION
    392     if (!dvmIsValidObject(obj)) {
    393         LOGE("Invalid object %p\n", obj);
    394         dvmAbort();
    395     }
    396 #endif
    397 #ifndef NDEBUG
    398     if (obj->clazz == NULL || ((u4) obj->clazz) <= 65536) {
    399         /* probable heap corruption */
    400         LOGE("Invalid object class %p (in %p)\n", obj->clazz, obj);
    401         dvmAbort();
    402     }
    403 #endif
    404     return true;
    405 }
    406