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 37int num_removed_nullCheck; 38 39PhysicalReg scratchRegs[4]; 40 41LowOp* ops[BUFFER_SIZE]; 42LowOp* op; 43u2* rPC; //PC pointer to bytecode 44u2 inst; //current bytecode 45int offsetPC/*offset in bytecode*/, offsetNCG/*byte offset in native code*/; 46int ncg_rPC; 47//! map from PC in bytecode to PC in native code 48int mapFromBCtoNCG[BYTECODE_SIZE_PER_METHOD]; //initially mapped to -1 49char* streamStart = NULL; //start of the Pure CodeItem?, not include the global symbols 50char* streamCode = NULL; //start of the Pure CodeItem?, not include the global symbols 51char* streamMethodStart; //start of the method 52char* stream; //current stream pointer 53int lowOpTimeStamp = 0; 54Method* currentMethod = NULL; 55int currentExceptionBlockIdx = -1; 56LowOpBlockLabel* traceLabelList = NULL; 57BasicBlock* traceCurrentBB = NULL; 58MIR* traceCurrentMIR = NULL; 59bool scheduling_is_on = false; 60 61int common_invokeMethodNoRange(); 62int common_invokeMethodRange(); 63int common_invokeArgsDone(ArgsDoneType, bool); 64 65//data section of .ia32: 66char globalData[128]; 67 68char strClassCastException[] = "Ljava/lang/ClassCastException;"; 69char strInstantiationError[] = "Ljava/lang/InstantiationError;"; 70char strInternalError[] = "Ljava/lang/InternalError;"; 71char strFilledNewArrayNotImpl[] = "filled-new-array only implemented for 'int'"; 72char strArithmeticException[] = "Ljava/lang/ArithmeticException;"; 73char strArrayIndexException[] = "Ljava/lang/ArrayIndexOutOfBoundsException;"; 74char strArrayStoreException[] = "Ljava/lang/ArrayStoreException;"; 75char strDivideByZero[] = "divide by zero"; 76char strNegativeArraySizeException[] = "Ljava/lang/NegativeArraySizeException;"; 77char strNoSuchMethodError[] = "Ljava/lang/NoSuchMethodError;"; 78char strNullPointerException[] = "Ljava/lang/NullPointerException;"; 79char strStringIndexOutOfBoundsException[] = "Ljava/lang/StringIndexOutOfBoundsException;"; 80 81int LstrClassCastExceptionPtr, LstrInstantiationErrorPtr, LstrInternalError, LstrFilledNewArrayNotImpl; 82int LstrArithmeticException, LstrArrayIndexException, LstrArrayStoreException, LstrStringIndexOutOfBoundsException; 83int LstrDivideByZero, LstrNegativeArraySizeException, LstrNoSuchMethodError, LstrNullPointerException; 84int LdoubNeg, LvaluePosInfLong, LvalueNegInfLong, LvalueNanLong, LshiftMask, Lvalue64, L64bits, LintMax, LintMin; 85 86void 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 154int spill_reg(int reg, bool isPhysical); 155int unspill_reg(int reg, bool isPhysical); 156 157int const_string_resolve(); 158int sget_sput_resolve(); 159int new_instance_needinit(); 160int new_instance_abstract(); 161int invoke_virtual_resolve(); 162int invoke_direct_resolve(); 163int invoke_static_resolve(); 164int filled_new_array_notimpl(); 165int resolve_class2( 166 int startLR/*logical register index*/, bool isPhysical, int indexReg/*const pool index*/, 167 bool indexPhysical, 168 int thirdArg); 169int resolve_method2( 170 int startLR/*logical register index*/, bool isPhysical, int indexReg/*const pool index*/, 171 bool indexPhysical, 172 int thirdArg/*VIRTUAL*/); 173int resolve_inst_field2( 174 int startLR/*logical register index*/, bool isPhysical, 175 int indexReg/*const pool index*/, 176 bool indexPhysical); 177int resolve_static_field2( 178 int startLR/*logical register index*/, bool isPhysical, 179 int indexReg/*const pool index*/, 180 bool indexPhysical); 181 182int invokeMethodNoRange_1_helper(); 183int invokeMethodNoRange_2_helper(); 184int invokeMethodNoRange_3_helper(); 185int invokeMethodNoRange_4_helper(); 186int invokeMethodNoRange_5_helper(); 187int invokeMethodRange_helper(); 188 189int invoke_virtual_helper(); 190int invoke_virtual_quick_helper(); 191int invoke_static_helper(); 192int invoke_direct_helper(); 193int new_instance_helper(); 194int sget_sput_helper(int flag); 195int aput_obj_helper(); 196int aget_helper(int flag); 197int aput_helper(int flag); 198int monitor_enter_helper(); 199int monitor_exit_helper(); 200int throw_helper(); 201int const_string_helper(); 202int array_length_helper(); 203int invoke_super_helper(); 204int invoke_interface_helper(); 205int iget_iput_helper(int flag); 206int check_cast_helper(bool instance); 207int new_array_helper(); 208 209int common_returnFromMethod(); 210 211/*! 212\brief dump helper functions 213 214*/ 215int 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 242int aput_object_count; 243int common_periodicChecks_entry(); 244int common_periodicChecks4(); 245/*! 246\brief for debugging purpose, dump the sequence of native code for each bytecode 247 248*/ 249int 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 283bool 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 301int mm_bytecode_size = 0; 302int mm_ncg_size = 0; 303int mm_relocation_size = 0; 304int mm_map_size = 0; 305void resetCodeSize() { 306 mm_bytecode_size = 0; 307 mm_ncg_size = 0; 308 mm_relocation_size = 0; 309 mm_map_size = 0; 310} 311 312bool 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 328int invoke_super_nsm(); 329void init_common(const char* curFileName, DvmDex *pDvmDex, bool forNCG); //forward declaration 330void initGlobalMethods(); //forward declaration 331 332//called once when compiler thread starts up 333void initJIT(const char* curFileName, DvmDex *pDvmDex) { 334 init_common(curFileName, pDvmDex, false); 335} 336 337void 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 352void 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 409ExecutionMode origMode; 410//when to update streamMethodStart 411bool 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 422void startOfBasicBlock(BasicBlock* bb) { 423 traceCurrentBB = bb; 424 if(gDvm.executionMode == kExecutionModeNcgO0) { 425 isScratchPhysical = true; 426 } else { 427 isScratchPhysical = false; 428 } 429} 430 431void 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 454void 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 476int 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} 979int op_nop() { 980 rPC++; 981 return 0; 982} 983