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 #include "Dalvik.h" 19 #include "NcgHelper.h" 20 #include "interp/InterpDefs.h" 21 22 23 /* 24 * Find the matching case. Returns the offset to the handler instructions. 25 * 26 * Returns 3 if we don't find a match (it's the size of the packed-switch 27 * instruction). 28 */ 29 s4 dvmNcgHandlePackedSwitch(const s4* entries, s4 firstKey, u2 size, s4 testVal) 30 { 31 //skip add_reg_reg (ADD_REG_REG_SIZE) and jump_reg (JUMP_REG_SIZE) 32 const int kInstrLen = 4; //default to next bytecode 33 if (testVal < firstKey || testVal >= firstKey + size) { 34 LOGVV("Value %d not found in switch (%d-%d)", 35 testVal, firstKey, firstKey+size-1); 36 return kInstrLen; 37 } 38 39 assert(testVal - firstKey >= 0 && testVal - firstKey < size); 40 LOGVV("Value %d found in slot %d (goto 0x%02x)", 41 testVal, testVal - firstKey, 42 s4FromSwitchData(&entries[testVal - firstKey])); 43 return s4FromSwitchData(&entries[testVal - firstKey]); 44 45 } 46 /* return the number of bytes to increase the bytecode pointer by */ 47 s4 dvmJitHandlePackedSwitch(const s4* entries, s4 firstKey, u2 size, s4 testVal) 48 { 49 if (testVal < firstKey || testVal >= firstKey + size) { 50 LOGVV("Value %d not found in switch (%d-%d)", 51 testVal, firstKey, firstKey+size-1); 52 return 2*3;//bytecode packed_switch is 6(2*3) bytes long 53 } 54 55 LOGVV("Value %d found in slot %d (goto 0x%02x)", 56 testVal, testVal - firstKey, 57 s4FromSwitchData(&entries[testVal - firstKey])); 58 return 2*s4FromSwitchData(&entries[testVal - firstKey]); //convert from u2 to byte 59 60 } 61 /* 62 * Find the matching case. Returns the offset to the handler instructions. 63 * 64 * Returns 3 if we don't find a match (it's the size of the sparse-switch 65 * instruction). 66 */ 67 s4 dvmNcgHandleSparseSwitch(const s4* keys, u2 size, s4 testVal) 68 { 69 const int kInstrLen = 4; //CHECK 70 const s4* entries = keys + size; 71 int i; 72 for (i = 0; i < size; i++) { 73 s4 k = s4FromSwitchData(&keys[i]); 74 if (k == testVal) { 75 LOGVV("Value %d found in entry %d (goto 0x%02x)", 76 testVal, i, s4FromSwitchData(&entries[i])); 77 return s4FromSwitchData(&entries[i]); 78 } else if (k > testVal) { 79 break; 80 } 81 } 82 83 LOGVV("Value %d not found in switch", testVal); 84 return kInstrLen; 85 } 86 /* return the number of bytes to increase the bytecode pointer by */ 87 s4 dvmJitHandleSparseSwitch(const s4* keys, u2 size, s4 testVal) 88 { 89 const s4* entries = keys + size; 90 int i; 91 for (i = 0; i < size; i++) { 92 s4 k = s4FromSwitchData(&keys[i]); 93 if (k == testVal) { 94 LOGVV("Value %d found in entry %d (goto 0x%02x)", 95 testVal, i, s4FromSwitchData(&entries[i])); 96 return 2*s4FromSwitchData(&entries[i]); //convert from u2 to byte 97 } else if (k > testVal) { 98 break; 99 } 100 } 101 102 LOGVV("Value %d not found in switch", testVal); 103 return 2*3; //bytecode sparse_switch is 6(2*3) bytes long 104 } 105