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 #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