Home | History | Annotate | Download | only in x86
      1 /*
      2  * Copyright (C) 2012 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 /*! \file Lower.cpp
     19     \brief This file implements the high-level wrapper for lowering
     20 
     21 */
     22 
     23 //#include "uthash.h"
     24 #include "libdex/DexOpcodes.h"
     25 #include "libdex/DexFile.h"
     26 #include <math.h>
     27 #include <sys/mman.h>
     28 #include "Translator.h"
     29 #include "Lower.h"
     30 #include "enc_wrapper.h"
     31 #include "vm/mterp/Mterp.h"
     32 #include "NcgHelper.h"
     33 #include "libdex/DexCatch.h"
     34 #include "compiler/CompilerIR.h"
     35 
     36 //statistics for optimization
     37 int num_removed_nullCheck;
     38 
     39 PhysicalReg scratchRegs[4];
     40 
     41 LowOp* ops[BUFFER_SIZE];
     42 LowOp* op;
     43 u2* rPC; //PC pointer to bytecode
     44 u2 inst; //current bytecode
     45 int offsetPC/*offset in bytecode*/, offsetNCG/*byte offset in native code*/;
     46 int ncg_rPC;
     47 //! map from PC in bytecode to PC in native code
     48 int mapFromBCtoNCG[BYTECODE_SIZE_PER_METHOD]; //initially mapped to -1
     49 char* streamStart = NULL; //start of the Pure CodeItem?, not include the global symbols
     50 char* streamCode = NULL; //start of the Pure CodeItem?, not include the global symbols
     51 char* streamMethodStart; //start of the method
     52 char* stream; //current stream pointer
     53 int lowOpTimeStamp = 0;
     54 Method* currentMethod = NULL;
     55 int currentExceptionBlockIdx = -1;
     56 LowOpBlockLabel* traceLabelList = NULL;
     57 BasicBlock* traceCurrentBB = NULL;
     58 MIR* traceCurrentMIR = NULL;
     59 bool scheduling_is_on = false;
     60 
     61 int common_invokeMethodNoRange();
     62 int common_invokeMethodRange();
     63 int common_invokeArgsDone(ArgsDoneType, bool);
     64 
     65 //data section of .ia32:
     66 char globalData[128];
     67 
     68 char strClassCastException[] = "Ljava/lang/ClassCastException;";
     69 char strInstantiationError[] = "Ljava/lang/InstantiationError;";
     70 char strInternalError[] = "Ljava/lang/InternalError;";
     71 char strFilledNewArrayNotImpl[] = "filled-new-array only implemented for 'int'";
     72 char strArithmeticException[] = "Ljava/lang/ArithmeticException;";
     73 char strArrayIndexException[] = "Ljava/lang/ArrayIndexOutOfBoundsException;";
     74 char strArrayStoreException[] = "Ljava/lang/ArrayStoreException;";
     75 char strDivideByZero[] = "divide by zero";
     76 char strNegativeArraySizeException[] = "Ljava/lang/NegativeArraySizeException;";
     77 char strNoSuchMethodError[] = "Ljava/lang/NoSuchMethodError;";
     78 char strNullPointerException[] = "Ljava/lang/NullPointerException;";
     79 char strStringIndexOutOfBoundsException[] = "Ljava/lang/StringIndexOutOfBoundsException;";
     80 
     81 int LstrClassCastExceptionPtr, LstrInstantiationErrorPtr, LstrInternalError, LstrFilledNewArrayNotImpl;
     82 int LstrArithmeticException, LstrArrayIndexException, LstrArrayStoreException, LstrStringIndexOutOfBoundsException;
     83 int LstrDivideByZero, LstrNegativeArraySizeException, LstrNoSuchMethodError, LstrNullPointerException;
     84 int LdoubNeg, LvaluePosInfLong, LvalueNegInfLong, LvalueNanLong, LshiftMask, Lvalue64, L64bits, LintMax, LintMin;
     85 
     86 void initConstDataSec() {
     87     char* tmpPtr = globalData;
     88 
     89     LdoubNeg = (int)tmpPtr;
     90     *((u4*)tmpPtr) = 0x00000000;
     91     tmpPtr += sizeof(u4);
     92     *((u4*)tmpPtr) = 0x80000000;
     93     tmpPtr += sizeof(u4);
     94 
     95     LvaluePosInfLong = (int)tmpPtr;
     96     *((u4*)tmpPtr) = 0xFFFFFFFF;
     97     tmpPtr += sizeof(u4);
     98     *((u4*)tmpPtr) = 0x7FFFFFFF;
     99     tmpPtr += sizeof(u4);
    100 
    101     LvalueNegInfLong = (int)tmpPtr;
    102     *((u4*)tmpPtr) = 0x00000000;
    103     tmpPtr += sizeof(u4);
    104     *((u4*)tmpPtr) = 0x80000000;
    105     tmpPtr += sizeof(u4);
    106 
    107     LvalueNanLong = (int)tmpPtr;
    108     *((u4*)tmpPtr) = 0;
    109     tmpPtr += sizeof(u4);
    110     *((u4*)tmpPtr) = 0;
    111     tmpPtr += sizeof(u4);
    112 
    113     LshiftMask = (int)tmpPtr;
    114     *((u4*)tmpPtr) = 0x3f;
    115     tmpPtr += sizeof(u4);
    116     *((u4*)tmpPtr) = 0;
    117     tmpPtr += sizeof(u4);
    118 
    119     Lvalue64 = (int)tmpPtr;
    120     *((u4*)tmpPtr) = 0x40;
    121     tmpPtr += sizeof(u4);
    122     *((u4*)tmpPtr) = 0;
    123     tmpPtr += sizeof(u4);
    124 
    125     L64bits = (int)tmpPtr;
    126     *((u4*)tmpPtr) = 0xFFFFFFFF;
    127     tmpPtr += sizeof(u4);
    128     *((u4*)tmpPtr) = 0xFFFFFFFF;
    129     tmpPtr += sizeof(u4);
    130 
    131     LintMin = (int)tmpPtr;
    132     *((u4*)tmpPtr) = 0x80000000;
    133     tmpPtr += sizeof(u4);
    134 
    135     LintMax = (int)tmpPtr;
    136     *((u4*)tmpPtr) = 0x7FFFFFFF;
    137     tmpPtr += sizeof(u4);
    138 
    139     LstrClassCastExceptionPtr = (int)strClassCastException;
    140     LstrInstantiationErrorPtr = (int)strInstantiationError;
    141     LstrInternalError = (int)strInternalError;
    142     LstrFilledNewArrayNotImpl = (int)strFilledNewArrayNotImpl;
    143     LstrArithmeticException = (int)strArithmeticException;
    144     LstrArrayIndexException = (int)strArrayIndexException;
    145     LstrArrayStoreException = (int)strArrayStoreException;
    146     LstrDivideByZero = (int)strDivideByZero;
    147     LstrNegativeArraySizeException = (int)strNegativeArraySizeException;
    148     LstrNoSuchMethodError = (int)strNoSuchMethodError;
    149     LstrNullPointerException = (int)strNullPointerException;
    150     LstrStringIndexOutOfBoundsException = (int)strStringIndexOutOfBoundsException;
    151 }
    152 
    153 //declarations of functions used in this file
    154 int spill_reg(int reg, bool isPhysical);
    155 int unspill_reg(int reg, bool isPhysical);
    156 
    157 int const_string_resolve();
    158 int sget_sput_resolve();
    159 int new_instance_needinit();
    160 int new_instance_abstract();
    161 int invoke_virtual_resolve();
    162 int invoke_direct_resolve();
    163 int invoke_static_resolve();
    164 int filled_new_array_notimpl();
    165 int resolve_class2(
    166                    int startLR/*logical register index*/, bool isPhysical, int indexReg/*const pool index*/,
    167                    bool indexPhysical,
    168                    int thirdArg);
    169 int resolve_method2(
    170                     int startLR/*logical register index*/, bool isPhysical, int indexReg/*const pool index*/,
    171                     bool indexPhysical,
    172                     int thirdArg/*VIRTUAL*/);
    173 int resolve_inst_field2(
    174                         int startLR/*logical register index*/, bool isPhysical,
    175                         int indexReg/*const pool index*/,
    176                         bool indexPhysical);
    177 int resolve_static_field2(
    178                           int startLR/*logical register index*/, bool isPhysical,
    179                           int indexReg/*const pool index*/,
    180                           bool indexPhysical);
    181 
    182 int invokeMethodNoRange_1_helper();
    183 int invokeMethodNoRange_2_helper();
    184 int invokeMethodNoRange_3_helper();
    185 int invokeMethodNoRange_4_helper();
    186 int invokeMethodNoRange_5_helper();
    187 int invokeMethodRange_helper();
    188 
    189 int invoke_virtual_helper();
    190 int invoke_virtual_quick_helper();
    191 int invoke_static_helper();
    192 int invoke_direct_helper();
    193 int new_instance_helper();
    194 int sget_sput_helper(int flag);
    195 int aput_obj_helper();
    196 int aget_helper(int flag);
    197 int aput_helper(int flag);
    198 int monitor_enter_helper();
    199 int monitor_exit_helper();
    200 int throw_helper();
    201 int const_string_helper();
    202 int array_length_helper();
    203 int invoke_super_helper();
    204 int invoke_interface_helper();
    205 int iget_iput_helper(int flag);
    206 int check_cast_helper(bool instance);
    207 int new_array_helper();
    208 
    209 int common_returnFromMethod();
    210 
    211 /*!
    212 \brief dump helper functions
    213 
    214 */
    215 int performCGWorklist() {
    216     filled_new_array_notimpl();
    217     freeShortMap();
    218     const_string_resolve();
    219     freeShortMap();
    220 
    221     resolve_class2(PhysicalReg_EAX, true, PhysicalReg_EAX, true, 0);
    222     freeShortMap();
    223     resolve_method2(PhysicalReg_EAX, true, PhysicalReg_EAX, true, METHOD_VIRTUAL);
    224     freeShortMap();
    225     resolve_method2(PhysicalReg_EAX, true, PhysicalReg_EAX, true, METHOD_DIRECT);
    226     freeShortMap();
    227     resolve_method2(PhysicalReg_EAX, true, PhysicalReg_EAX, true, METHOD_STATIC);
    228     freeShortMap();
    229     resolve_inst_field2(PhysicalReg_EAX, true, PhysicalReg_EAX, true);
    230     freeShortMap();
    231     resolve_static_field2(PhysicalReg_EAX, true, PhysicalReg_EAX, true);
    232     freeShortMap();
    233     throw_exception_message(PhysicalReg_ECX, PhysicalReg_EAX, true, PhysicalReg_Null, true);
    234     freeShortMap();
    235     throw_exception(PhysicalReg_ECX, PhysicalReg_EAX, PhysicalReg_Null, true);
    236     freeShortMap();
    237     new_instance_needinit();
    238     freeShortMap();
    239     return 0;
    240 }
    241 
    242 int aput_object_count;
    243 int common_periodicChecks_entry();
    244 int common_periodicChecks4();
    245 /*!
    246 \brief for debugging purpose, dump the sequence of native code for each bytecode
    247 
    248 */
    249 int ncgMethodFake(Method* method) {
    250     //to measure code size expansion, no need to patch up labels
    251     methodDataWorklist = NULL;
    252     globalShortWorklist = NULL;
    253     globalNCGWorklist = NULL;
    254     streamMethodStart = stream;
    255 
    256     //initialize mapFromBCtoNCG
    257     memset(&mapFromBCtoNCG[0], -1, BYTECODE_SIZE_PER_METHOD * sizeof(mapFromBCtoNCG[0]));
    258     unsigned int i;
    259     u2* rStart = (u2*)malloc(5*sizeof(u2));
    260     if(rStart == NULL) {
    261         ALOGE("Memory allocation failed");
    262         return -1;
    263     }
    264     rPC = rStart;
    265     method->insns = rStart;
    266     for(i = 0; i < 5; i++) *rPC++ = 0;
    267     for(i = 0; i < 256; i++) {
    268         rPC = rStart;
    269         //modify the opcode
    270         char* tmp = (char*)rStart;
    271         *tmp++ = i;
    272         *tmp = i;
    273         inst = FETCH(0);
    274         char* tmpStart = stream;
    275         lowerByteCode(method); //use inst, rPC, method, modify rPC
    276         int size_in_u2 = rPC - rStart;
    277         if(stream - tmpStart  > 0)
    278             ALOGI("LOWER bytecode %x size in u2: %d ncg size in byte: %d", i, size_in_u2, stream - tmpStart);
    279     }
    280     exit(0);
    281 }
    282 
    283 bool existATryBlock(Method* method, int startPC, int endPC) {
    284     const DexCode* pCode = dvmGetMethodCode(method);
    285     u4 triesSize = pCode->triesSize;
    286     const DexTry* pTries = dexGetTries(pCode);
    287     unsigned int i;
    288     for (i = 0; i < triesSize; i++) {
    289         const DexTry* pTry = &pTries[i];
    290         u4 start = pTry->startAddr; //offsetPC
    291         u4 end = start + pTry->insnCount;
    292         //if [start, end] overlaps with [startPC, endPC] returns true
    293         if((int)end < startPC || (int)start > endPC) { //no overlap
    294         } else {
    295             return true;
    296         }
    297     }
    298     return false;
    299 }
    300 
    301 int mm_bytecode_size = 0;
    302 int mm_ncg_size = 0;
    303 int mm_relocation_size = 0;
    304 int mm_map_size = 0;
    305 void resetCodeSize() {
    306     mm_bytecode_size = 0;
    307     mm_ncg_size = 0;
    308     mm_relocation_size = 0;
    309     mm_map_size = 0;
    310 }
    311 
    312 bool bytecodeIsRemoved(const Method* method, u4 bytecodeOffset) {
    313     if(gDvm.executionMode == kExecutionModeNcgO0) return false;
    314     u4 ncgOff = mapFromBCtoNCG[bytecodeOffset];
    315     int k = bytecodeOffset+1;
    316     u2 insnsSize = dvmGetMethodInsnsSize(method);
    317     while(k < insnsSize) {
    318         if(mapFromBCtoNCG[k] < 0) {
    319             k++;
    320             continue;
    321         }
    322         if(mapFromBCtoNCG[k] == (int)ncgOff) return true;
    323         return false;
    324     }
    325     return false;
    326 }
    327 
    328 int invoke_super_nsm();
    329 void init_common(const char* curFileName, DvmDex *pDvmDex, bool forNCG); //forward declaration
    330 void initGlobalMethods(); //forward declaration
    331 
    332 //called once when compiler thread starts up
    333 void initJIT(const char* curFileName, DvmDex *pDvmDex) {
    334     init_common(curFileName, pDvmDex, false);
    335 }
    336 
    337 void init_common(const char* curFileName, DvmDex *pDvmDex, bool forNCG) {
    338     if(!gDvm.constInit) {
    339         globalMapNum = 0;
    340         globalMap = NULL;
    341         initConstDataSec();
    342         gDvm.constInit = true;
    343     }
    344 
    345     //for initJIT: stream is already set
    346     if(!gDvm.commonInit) {
    347         initGlobalMethods();
    348         gDvm.commonInit = true;
    349     }
    350 }
    351 
    352 void initGlobalMethods() {
    353     dump_x86_inst = false; /* DEBUG */
    354     // generate native code for function ncgGetEIP
    355     insertLabel("ncgGetEIP", false);
    356     move_mem_to_reg(OpndSize_32, 0, PhysicalReg_ESP, true, PhysicalReg_EDX, true);
    357     x86_return();
    358 
    359     //generate code for common labels
    360     //jumps within a helper function is treated as short labels
    361     globalShortMap = NULL;
    362     common_periodicChecks_entry();
    363     freeShortMap();
    364     common_periodicChecks4();
    365     freeShortMap();
    366     //common_invokeMethodNoRange();
    367     //common_invokeMethodRange();
    368 
    369     if(dump_x86_inst) ALOGI("ArgsDone_Normal start");
    370     common_invokeArgsDone(ArgsDone_Normal, false);
    371     freeShortMap();
    372     if(dump_x86_inst) ALOGI("ArgsDone_Native start");
    373     common_invokeArgsDone(ArgsDone_Native, false);
    374     freeShortMap();
    375     if(dump_x86_inst) ALOGI("ArgsDone_Full start");
    376     common_invokeArgsDone(ArgsDone_Full, true/*isJitFull*/);
    377     if(dump_x86_inst) ALOGI("ArgsDone_Full end");
    378     freeShortMap();
    379 
    380     common_backwardBranch();
    381     freeShortMap();
    382     common_exceptionThrown();
    383     freeShortMap();
    384     common_errNullObject();
    385     freeShortMap();
    386     common_errArrayIndex();
    387     freeShortMap();
    388     common_errArrayStore();
    389     freeShortMap();
    390     common_errNegArraySize();
    391     freeShortMap();
    392     common_errNoSuchMethod();
    393     freeShortMap();
    394     common_errDivideByZero();
    395     freeShortMap();
    396     common_gotoBail();
    397     freeShortMap();
    398     common_gotoBail_0();
    399     freeShortMap();
    400     invoke_super_nsm();
    401     freeShortMap();
    402 
    403     performCGWorklist(); //generate code for helper functions
    404     performLabelWorklist(); //it is likely that the common labels will jump to other common labels
    405 
    406     dump_x86_inst = false;
    407 }
    408 
    409 ExecutionMode origMode;
    410 //when to update streamMethodStart
    411 bool lowerByteCodeJit(const Method* method, const u2* codePtr, MIR* mir) {
    412     rPC = (u2*)codePtr;
    413     inst = FETCH(0);
    414     traceCurrentMIR = mir;
    415     int retCode = lowerByteCode(method);
    416     traceCurrentMIR = NULL;
    417     freeShortMap();
    418     if(retCode >= 0) return false; //handled
    419     return true; //not handled
    420 }
    421 
    422 void startOfBasicBlock(BasicBlock* bb) {
    423     traceCurrentBB = bb;
    424     if(gDvm.executionMode == kExecutionModeNcgO0) {
    425         isScratchPhysical = true;
    426     } else {
    427         isScratchPhysical = false;
    428     }
    429 }
    430 
    431 void startOfTrace(const Method* method, LowOpBlockLabel* labelList, int exceptionBlockId,
    432                   CompilationUnit *cUnit) {
    433     origMode = gDvm.executionMode;
    434     gDvm.executionMode = kExecutionModeNcgO1;
    435     if(gDvm.executionMode == kExecutionModeNcgO0) {
    436         isScratchPhysical = true;
    437     } else {
    438         isScratchPhysical = false;
    439     }
    440     currentMethod = (Method*)method;
    441     currentExceptionBlockIdx = exceptionBlockId;
    442     methodDataWorklist = NULL;
    443     globalShortWorklist = NULL;
    444     globalNCGWorklist = NULL;
    445 
    446     streamMethodStart = stream;
    447     //initialize mapFromBCtoNCG
    448     memset(&mapFromBCtoNCG[0], -1, BYTECODE_SIZE_PER_METHOD * sizeof(mapFromBCtoNCG[0]));
    449     traceLabelList = labelList;
    450     if(gDvm.executionMode == kExecutionModeNcgO1)
    451         startOfTraceO1(method, labelList, exceptionBlockId, cUnit);
    452 }
    453 
    454 void endOfTrace(bool freeOnly) {
    455     if(freeOnly) {
    456         freeLabelWorklist();
    457         freeNCGWorklist();
    458         freeDataWorklist();
    459         freeChainingWorklist();
    460     }
    461     else {
    462         performLabelWorklist();
    463         performNCGWorklist(); //handle forward jump (GOTO, IF)
    464         performDataWorklist(); //handle SWITCH & FILL_ARRAY_DATA
    465         performChainingWorklist();
    466     }
    467     if(gDvm.executionMode == kExecutionModeNcgO1) {
    468         endOfTraceO1();
    469     }
    470     gDvm.executionMode = origMode;
    471 }
    472 
    473 ///////////////////////////////////////////////////////////////////
    474 //!
    475 //! each bytecode is translated to a sequence of machine codes
    476 int lowerByteCode(const Method* method) { //inputs: rPC & inst & stream & streamMethodStart
    477     /* offsetPC is used in O1 code generator, where it is defined as the sequence number
    478        use a local version to avoid overwriting */
    479     int offsetPC = rPC - (u2*)method->insns;
    480 
    481     if(dump_x86_inst)
    482         ALOGI("LOWER bytecode %x at offsetPC %x offsetNCG %x @%p",
    483               INST_INST(inst), offsetPC, stream - streamMethodStart, stream);
    484 
    485     //update mapFromBCtoNCG
    486     offsetNCG = stream - streamMethodStart;
    487     if(offsetPC >= BYTECODE_SIZE_PER_METHOD) ALOGE("offsetPC %d exceeds BYTECODE_SIZE_PER_METHOD", offsetPC);
    488     mapFromBCtoNCG[offsetPC] = offsetNCG;
    489 #if defined(ENABLE_TRACING) && defined(TRACING_OPTION2)
    490     insertMapWorklist(offsetPC, mapFromBCtoNCG[offsetPC], 1);
    491 #endif
    492     //return number of LowOps generated
    493     switch (INST_INST(inst)) {
    494     case OP_NOP:
    495         return op_nop();
    496     case OP_MOVE:
    497     case OP_MOVE_OBJECT:
    498         return op_move();
    499     case OP_MOVE_FROM16:
    500     case OP_MOVE_OBJECT_FROM16:
    501         return op_move_from16();
    502     case OP_MOVE_16:
    503     case OP_MOVE_OBJECT_16:
    504         return op_move_16();
    505     case OP_MOVE_WIDE:
    506         return op_move_wide();
    507     case OP_MOVE_WIDE_FROM16:
    508         return op_move_wide_from16();
    509     case OP_MOVE_WIDE_16:
    510         return op_move_wide_16();
    511     case OP_MOVE_RESULT:
    512     case OP_MOVE_RESULT_OBJECT:
    513         return op_move_result();
    514     case OP_MOVE_RESULT_WIDE:
    515         return op_move_result_wide();
    516     case OP_MOVE_EXCEPTION:
    517         return op_move_exception();
    518     case OP_RETURN_VOID:
    519     case OP_RETURN_VOID_BARRIER:
    520         return op_return_void();
    521     case OP_RETURN:
    522     case OP_RETURN_OBJECT:
    523         return op_return();
    524     case OP_RETURN_WIDE:
    525         return op_return_wide();
    526     case OP_CONST_4:
    527         return op_const_4();
    528     case OP_CONST_16:
    529         return op_const_16();
    530     case OP_CONST:
    531         return op_const();
    532     case OP_CONST_HIGH16:
    533         return op_const_high16();
    534     case OP_CONST_WIDE_16:
    535         return op_const_wide_16();
    536     case OP_CONST_WIDE_32:
    537         return op_const_wide_32();
    538     case OP_CONST_WIDE:
    539         return op_const_wide();
    540     case OP_CONST_WIDE_HIGH16:
    541         return op_const_wide_high16();
    542     case OP_CONST_STRING:
    543         return op_const_string();
    544     case OP_CONST_STRING_JUMBO:
    545         return op_const_string_jumbo();
    546     case OP_CONST_CLASS:
    547         return op_const_class();
    548     case OP_MONITOR_ENTER:
    549         return op_monitor_enter();
    550     case OP_MONITOR_EXIT:
    551         return op_monitor_exit();
    552     case OP_CHECK_CAST:
    553         return op_check_cast();
    554     case OP_INSTANCE_OF:
    555         return op_instance_of();
    556     case OP_ARRAY_LENGTH:
    557         return op_array_length();
    558     case OP_NEW_INSTANCE:
    559         return op_new_instance();
    560     case OP_NEW_ARRAY:
    561         return op_new_array();
    562     case OP_FILLED_NEW_ARRAY:
    563         return op_filled_new_array();
    564     case OP_FILLED_NEW_ARRAY_RANGE:
    565         return op_filled_new_array_range();
    566     case OP_FILL_ARRAY_DATA:
    567         return op_fill_array_data();
    568     case OP_THROW:
    569         return op_throw();
    570     case OP_THROW_VERIFICATION_ERROR:
    571         return op_throw_verification_error();
    572     case OP_GOTO:
    573         return op_goto();
    574     case OP_GOTO_16:
    575         return op_goto_16();
    576     case OP_GOTO_32:
    577         return op_goto_32();
    578     case OP_PACKED_SWITCH:
    579         return op_packed_switch();
    580     case OP_SPARSE_SWITCH:
    581         return op_sparse_switch();
    582     case OP_CMPL_FLOAT:
    583         return op_cmpl_float();
    584     case OP_CMPG_FLOAT:
    585         return op_cmpg_float();
    586     case OP_CMPL_DOUBLE:
    587         return op_cmpl_double();
    588     case OP_CMPG_DOUBLE:
    589         return op_cmpg_double();
    590     case OP_CMP_LONG:
    591         return op_cmp_long();
    592     case OP_IF_EQ:
    593         return op_if_eq();
    594     case OP_IF_NE:
    595         return op_if_ne();
    596     case OP_IF_LT:
    597         return op_if_lt();
    598     case OP_IF_GE:
    599         return op_if_ge();
    600     case OP_IF_GT:
    601         return op_if_gt();
    602     case OP_IF_LE:
    603         return op_if_le();
    604     case OP_IF_EQZ:
    605         return op_if_eqz();
    606     case OP_IF_NEZ:
    607         return op_if_nez();
    608     case OP_IF_LTZ:
    609         return op_if_ltz();
    610     case OP_IF_GEZ:
    611         return op_if_gez();
    612     case OP_IF_GTZ:
    613         return op_if_gtz();
    614     case OP_IF_LEZ:
    615         return op_if_lez();
    616     case OP_AGET:
    617         return op_aget();
    618     case OP_AGET_WIDE:
    619         return op_aget_wide();
    620     case OP_AGET_OBJECT:
    621         return op_aget_object();
    622     case OP_AGET_BOOLEAN:
    623         return op_aget_boolean();
    624     case OP_AGET_BYTE:
    625         return op_aget_byte();
    626     case OP_AGET_CHAR:
    627         return op_aget_char();
    628     case OP_AGET_SHORT:
    629         return op_aget_short();
    630     case OP_APUT:
    631         return op_aput();
    632     case OP_APUT_WIDE:
    633         return op_aput_wide();
    634     case OP_APUT_OBJECT:
    635         return op_aput_object();
    636     case OP_APUT_BOOLEAN:
    637         return op_aput_boolean();
    638     case OP_APUT_BYTE:
    639         return op_aput_byte();
    640     case OP_APUT_CHAR:
    641         return op_aput_char();
    642     case OP_APUT_SHORT:
    643         return op_aput_short();
    644     case OP_IGET:
    645     case OP_IGET_VOLATILE:
    646         return op_iget();
    647     case OP_IGET_WIDE:
    648         return op_iget_wide(false); // isVolatile==false
    649     case OP_IGET_WIDE_VOLATILE:
    650         return op_iget_wide(true);  // isVolatile==true
    651     case OP_IGET_OBJECT:
    652     case OP_IGET_OBJECT_VOLATILE:
    653         return op_iget_object();
    654     case OP_IGET_BOOLEAN:
    655         return op_iget_boolean();
    656     case OP_IGET_BYTE:
    657         return op_iget_byte();
    658     case OP_IGET_CHAR:
    659         return op_iget_char();
    660     case OP_IGET_SHORT:
    661         return op_iget_short();
    662     case OP_IPUT:
    663     case OP_IPUT_VOLATILE:
    664         return op_iput();
    665     case OP_IPUT_WIDE:
    666         return op_iput_wide(false); // isVolatile==false
    667     case OP_IPUT_WIDE_VOLATILE:
    668         return op_iput_wide(true);  // isVolatile==true
    669     case OP_IPUT_OBJECT:
    670     case OP_IPUT_OBJECT_VOLATILE:
    671         return op_iput_object();
    672     case OP_IPUT_BOOLEAN:
    673         return op_iput_boolean();
    674     case OP_IPUT_BYTE:
    675         return op_iput_byte();
    676     case OP_IPUT_CHAR:
    677         return op_iput_char();
    678     case OP_IPUT_SHORT:
    679         return op_iput_short();
    680     case OP_SGET:
    681     case OP_SGET_VOLATILE:
    682         return op_sget();
    683     case OP_SGET_WIDE:
    684         return op_sget_wide(false); // isVolatile==false
    685     case OP_SGET_WIDE_VOLATILE:
    686         return op_sget_wide(true);  // isVolatile==true
    687     case OP_SGET_OBJECT:
    688     case OP_SGET_OBJECT_VOLATILE:
    689         return op_sget_object();
    690     case OP_SGET_BOOLEAN:
    691         return op_sget_boolean();
    692     case OP_SGET_BYTE:
    693         return op_sget_byte();
    694     case OP_SGET_CHAR:
    695         return op_sget_char();
    696     case OP_SGET_SHORT:
    697         return op_sget_short();
    698     case OP_SPUT:
    699     case OP_SPUT_VOLATILE:
    700         return op_sput(false);
    701     case OP_SPUT_WIDE:
    702         return op_sput_wide(false); // isVolatile==false
    703     case OP_SPUT_WIDE_VOLATILE:
    704         return op_sput_wide(true);  // isVolatile==true
    705     case OP_SPUT_OBJECT:
    706     case OP_SPUT_OBJECT_VOLATILE:
    707         return op_sput_object();
    708     case OP_SPUT_BOOLEAN:
    709         return op_sput_boolean();
    710     case OP_SPUT_BYTE:
    711         return op_sput_byte();
    712     case OP_SPUT_CHAR:
    713         return op_sput_char();
    714     case OP_SPUT_SHORT:
    715         return op_sput_short();
    716     case OP_INVOKE_VIRTUAL:
    717         return op_invoke_virtual();
    718     case OP_INVOKE_SUPER:
    719         return op_invoke_super();
    720     case OP_INVOKE_DIRECT:
    721         return op_invoke_direct();
    722     case OP_INVOKE_STATIC:
    723         return op_invoke_static();
    724     case OP_INVOKE_INTERFACE:
    725         return op_invoke_interface();
    726     case OP_INVOKE_VIRTUAL_RANGE:
    727         return op_invoke_virtual_range();
    728     case OP_INVOKE_SUPER_RANGE:
    729         return op_invoke_super_range();
    730     case OP_INVOKE_DIRECT_RANGE:
    731         return op_invoke_direct_range();
    732     case OP_INVOKE_STATIC_RANGE:
    733         return op_invoke_static_range();
    734     case OP_INVOKE_INTERFACE_RANGE:
    735         return op_invoke_interface_range();
    736     case OP_NEG_INT:
    737         return op_neg_int();
    738     case OP_NOT_INT:
    739         return op_not_int();
    740     case OP_NEG_LONG:
    741         return op_neg_long();
    742     case OP_NOT_LONG:
    743         return op_not_long();
    744     case OP_NEG_FLOAT:
    745         return op_neg_float();
    746     case OP_NEG_DOUBLE:
    747         return op_neg_double();
    748     case OP_INT_TO_LONG:
    749         return op_int_to_long();
    750     case OP_INT_TO_FLOAT:
    751         return op_int_to_float();
    752     case OP_INT_TO_DOUBLE:
    753         return op_int_to_double();
    754     case OP_LONG_TO_INT:
    755         return op_long_to_int();
    756     case OP_LONG_TO_FLOAT:
    757         return op_long_to_float();
    758     case OP_LONG_TO_DOUBLE:
    759         return op_long_to_double();
    760     case OP_FLOAT_TO_INT:
    761         return op_float_to_int();
    762     case OP_FLOAT_TO_LONG:
    763         return op_float_to_long();
    764     case OP_FLOAT_TO_DOUBLE:
    765         return op_float_to_double();
    766     case OP_DOUBLE_TO_INT:
    767         return op_double_to_int();
    768     case OP_DOUBLE_TO_LONG:
    769         return op_double_to_long();
    770     case OP_DOUBLE_TO_FLOAT:
    771         return op_double_to_float();
    772     case OP_INT_TO_BYTE:
    773         return op_int_to_byte();
    774     case OP_INT_TO_CHAR:
    775         return op_int_to_char();
    776     case OP_INT_TO_SHORT:
    777         return op_int_to_short();
    778     case OP_ADD_INT:
    779         return op_add_int();
    780     case OP_SUB_INT:
    781         return op_sub_int();
    782     case OP_MUL_INT:
    783         return op_mul_int();
    784     case OP_DIV_INT:
    785         return op_div_int();
    786     case OP_REM_INT:
    787         return op_rem_int();
    788     case OP_AND_INT:
    789         return op_and_int();
    790     case OP_OR_INT:
    791         return op_or_int();
    792     case OP_XOR_INT:
    793         return op_xor_int();
    794     case OP_SHL_INT:
    795         return op_shl_int();
    796     case OP_SHR_INT:
    797         return op_shr_int();
    798     case OP_USHR_INT:
    799         return op_ushr_int();
    800     case OP_ADD_LONG:
    801         return op_add_long();
    802     case OP_SUB_LONG:
    803         return op_sub_long();
    804     case OP_MUL_LONG:
    805         return op_mul_long();
    806     case OP_DIV_LONG:
    807         return op_div_long();
    808     case OP_REM_LONG:
    809         return op_rem_long();
    810     case OP_AND_LONG:
    811         return op_and_long();
    812     case OP_OR_LONG:
    813         return op_or_long();
    814     case OP_XOR_LONG:
    815         return op_xor_long();
    816     case OP_SHL_LONG:
    817         return op_shl_long();
    818     case OP_SHR_LONG:
    819         return op_shr_long();
    820     case OP_USHR_LONG:
    821         return op_ushr_long();
    822     case OP_ADD_FLOAT:
    823         return op_add_float();
    824     case OP_SUB_FLOAT:
    825         return op_sub_float();
    826     case OP_MUL_FLOAT:
    827         return op_mul_float();
    828     case OP_DIV_FLOAT:
    829         return op_div_float();
    830     case OP_REM_FLOAT:
    831         return op_rem_float();
    832     case OP_ADD_DOUBLE:
    833         return op_add_double();
    834     case OP_SUB_DOUBLE:
    835         return op_sub_double();
    836     case OP_MUL_DOUBLE:
    837         return op_mul_double();
    838     case OP_DIV_DOUBLE:
    839         return op_div_double();
    840     case OP_REM_DOUBLE:
    841         return op_rem_double();
    842     case OP_ADD_INT_2ADDR:
    843         return op_add_int_2addr();
    844     case OP_SUB_INT_2ADDR:
    845         return op_sub_int_2addr();
    846     case OP_MUL_INT_2ADDR:
    847         return op_mul_int_2addr();
    848     case OP_DIV_INT_2ADDR:
    849         return op_div_int_2addr();
    850     case OP_REM_INT_2ADDR:
    851         return op_rem_int_2addr();
    852     case OP_AND_INT_2ADDR:
    853         return op_and_int_2addr();
    854     case OP_OR_INT_2ADDR:
    855         return op_or_int_2addr();
    856     case OP_XOR_INT_2ADDR:
    857         return op_xor_int_2addr();
    858     case OP_SHL_INT_2ADDR:
    859         return op_shl_int_2addr();
    860     case OP_SHR_INT_2ADDR:
    861         return op_shr_int_2addr();
    862     case OP_USHR_INT_2ADDR:
    863         return op_ushr_int_2addr();
    864     case OP_ADD_LONG_2ADDR:
    865         return op_add_long_2addr();
    866     case OP_SUB_LONG_2ADDR:
    867         return op_sub_long_2addr();
    868     case OP_MUL_LONG_2ADDR:
    869         return op_mul_long_2addr();
    870     case OP_DIV_LONG_2ADDR:
    871         return op_div_long_2addr();
    872     case OP_REM_LONG_2ADDR:
    873         return op_rem_long_2addr();
    874     case OP_AND_LONG_2ADDR:
    875         return op_and_long_2addr();
    876     case OP_OR_LONG_2ADDR:
    877         return op_or_long_2addr();
    878     case OP_XOR_LONG_2ADDR:
    879         return op_xor_long_2addr();
    880     case OP_SHL_LONG_2ADDR:
    881         return op_shl_long_2addr();
    882     case OP_SHR_LONG_2ADDR:
    883         return op_shr_long_2addr();
    884     case OP_USHR_LONG_2ADDR:
    885         return op_ushr_long_2addr();
    886     case OP_ADD_FLOAT_2ADDR:
    887         return op_add_float_2addr();
    888     case OP_SUB_FLOAT_2ADDR:
    889         return op_sub_float_2addr();
    890     case OP_MUL_FLOAT_2ADDR:
    891         return op_mul_float_2addr();
    892     case OP_DIV_FLOAT_2ADDR:
    893         return op_div_float_2addr();
    894     case OP_REM_FLOAT_2ADDR:
    895         return op_rem_float_2addr();
    896     case OP_ADD_DOUBLE_2ADDR:
    897         return op_add_double_2addr();
    898     case OP_SUB_DOUBLE_2ADDR:
    899         return op_sub_double_2addr();
    900     case OP_MUL_DOUBLE_2ADDR:
    901         return op_mul_double_2addr();
    902     case OP_DIV_DOUBLE_2ADDR:
    903         return op_div_double_2addr();
    904     case OP_REM_DOUBLE_2ADDR:
    905         return op_rem_double_2addr();
    906     case OP_ADD_INT_LIT16:
    907         return op_add_int_lit16();
    908     case OP_RSUB_INT:
    909         return op_rsub_int();
    910     case OP_MUL_INT_LIT16:
    911         return op_mul_int_lit16();
    912     case OP_DIV_INT_LIT16:
    913         return op_div_int_lit16();
    914     case OP_REM_INT_LIT16:
    915         return op_rem_int_lit16();
    916     case OP_AND_INT_LIT16:
    917         return op_and_int_lit16();
    918     case OP_OR_INT_LIT16:
    919         return op_or_int_lit16();
    920     case OP_XOR_INT_LIT16:
    921         return op_xor_int_lit16();
    922     case OP_ADD_INT_LIT8:
    923         return op_add_int_lit8();
    924     case OP_RSUB_INT_LIT8:
    925         return op_rsub_int_lit8();
    926     case OP_MUL_INT_LIT8:
    927         return op_mul_int_lit8();
    928     case OP_DIV_INT_LIT8:
    929         return op_div_int_lit8();
    930     case OP_REM_INT_LIT8:
    931         return op_rem_int_lit8();
    932     case OP_AND_INT_LIT8:
    933         return op_and_int_lit8();
    934     case OP_OR_INT_LIT8:
    935         return op_or_int_lit8();
    936     case OP_XOR_INT_LIT8:
    937         return op_xor_int_lit8();
    938     case OP_SHL_INT_LIT8:
    939         return op_shl_int_lit8();
    940     case OP_SHR_INT_LIT8:
    941         return op_shr_int_lit8();
    942     case OP_USHR_INT_LIT8:
    943         return op_ushr_int_lit8();
    944     case OP_EXECUTE_INLINE:
    945         return op_execute_inline(false);
    946     case OP_EXECUTE_INLINE_RANGE:
    947         return op_execute_inline(true);
    948     case OP_BREAKPOINT:
    949         ALOGE("found bytecode OP_BREAKPOINT");
    950         dvmAbort();
    951     case OP_INVOKE_OBJECT_INIT_RANGE:
    952         return op_invoke_object_init_range();
    953     case OP_IGET_QUICK:
    954         return op_iget_quick();
    955     case OP_IGET_WIDE_QUICK:
    956         return op_iget_wide_quick();
    957     case OP_IGET_OBJECT_QUICK:
    958         return op_iget_object_quick();
    959     case OP_IPUT_QUICK:
    960         return op_iput_quick();
    961     case OP_IPUT_WIDE_QUICK:
    962         return op_iput_wide_quick();
    963     case OP_IPUT_OBJECT_QUICK:
    964         return op_iput_object_quick();
    965     case OP_INVOKE_VIRTUAL_QUICK:
    966         return op_invoke_virtual_quick();
    967     case OP_INVOKE_VIRTUAL_QUICK_RANGE:
    968         return op_invoke_virtual_quick_range();
    969     case OP_INVOKE_SUPER_QUICK:
    970         return op_invoke_super_quick();
    971     case OP_INVOKE_SUPER_QUICK_RANGE:
    972         return op_invoke_super_quick_range();
    973     }
    974 
    975     ALOGE("No JIT support for bytecode %x at offsetPC %x",
    976           INST_INST(inst), offsetPC);
    977     return -1;
    978 }
    979 int op_nop() {
    980     rPC++;
    981     return 0;
    982 }
    983