• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
initConstDataSec()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 */
performCGWorklist()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 */
ncgMethodFake(Method * method)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 
existATryBlock(Method * method,int startPC,int endPC)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;
resetCodeSize()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 
bytecodeIsRemoved(const Method * method,u4 bytecodeOffset)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
initJIT(const char * curFileName,DvmDex * pDvmDex)333 void initJIT(const char* curFileName, DvmDex *pDvmDex) {
334     init_common(curFileName, pDvmDex, false);
335 }
336 
init_common(const char * curFileName,DvmDex * pDvmDex,bool forNCG)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 
initGlobalMethods()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
lowerByteCodeJit(const Method * method,const u2 * codePtr,MIR * mir)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 
startOfBasicBlock(BasicBlock * bb)422 void startOfBasicBlock(BasicBlock* bb) {
423     traceCurrentBB = bb;
424     if(gDvm.executionMode == kExecutionModeNcgO0) {
425         isScratchPhysical = true;
426     } else {
427         isScratchPhysical = false;
428     }
429 }
430 
startOfTrace(const Method * method,LowOpBlockLabel * labelList,int exceptionBlockId,CompilationUnit * cUnit)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 
endOfTrace(bool freeOnly)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
lowerByteCode(const Method * method)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 }
op_nop()979 int op_nop() {
980     rPC++;
981     return 0;
982 }
983