Home | History | Annotate | Download | only in runtime
      1 /*
      2  * Copyright (C) 2011 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 #ifndef ART_RUNTIME_DEX_INSTRUCTION_H_
     18 #define ART_RUNTIME_DEX_INSTRUCTION_H_
     19 
     20 #include "base/logging.h"
     21 #include "base/macros.h"
     22 #include "globals.h"
     23 
     24 typedef uint8_t uint4_t;
     25 typedef int8_t int4_t;
     26 
     27 namespace art {
     28 
     29 class DexFile;
     30 
     31 enum {
     32   kNumPackedOpcodes = 0x100
     33 };
     34 
     35 class Instruction {
     36  public:
     37   // NOP-encoded switch-statement signatures.
     38   enum {
     39     kPackedSwitchSignature = 0x0100,
     40     kSparseSwitchSignature = 0x0200,
     41     kArrayDataSignature = 0x0300,
     42   };
     43 
     44   struct PACKED(4) PackedSwitchPayload {
     45     const uint16_t ident;
     46     const uint16_t case_count;
     47     const int32_t first_key;
     48     const int32_t targets[];
     49 
     50    private:
     51     DISALLOW_COPY_AND_ASSIGN(PackedSwitchPayload);
     52   };
     53 
     54   struct PACKED(4) SparseSwitchPayload {
     55     const uint16_t ident;
     56     const uint16_t case_count;
     57     const int32_t keys_and_targets[];
     58 
     59    public:
     60     const int32_t* GetKeys() const {
     61       return keys_and_targets;
     62     }
     63 
     64     const int32_t* GetTargets() const {
     65       return keys_and_targets + case_count;
     66     }
     67 
     68    private:
     69     DISALLOW_COPY_AND_ASSIGN(SparseSwitchPayload);
     70   };
     71 
     72   struct PACKED(4) ArrayDataPayload {
     73     const uint16_t ident;
     74     const uint16_t element_width;
     75     const uint32_t element_count;
     76     const uint8_t data[];
     77 
     78    private:
     79     DISALLOW_COPY_AND_ASSIGN(ArrayDataPayload);
     80   };
     81 
     82   // TODO: the code layout below is deliberate to avoid this enum being picked up by
     83   //       generate-operator-out.py.
     84   enum Code
     85   {  // NOLINT(whitespace/braces)
     86 #define INSTRUCTION_ENUM(opcode, cname, p, f, r, i, a, v) cname = opcode,
     87 #include "dex_instruction_list.h"
     88     DEX_INSTRUCTION_LIST(INSTRUCTION_ENUM)
     89 #undef DEX_INSTRUCTION_LIST
     90 #undef INSTRUCTION_ENUM
     91   };
     92 
     93   enum Format {
     94     k10x,  // op
     95     k12x,  // op vA, vB
     96     k11n,  // op vA, #+B
     97     k11x,  // op vAA
     98     k10t,  // op +AA
     99     k20t,  // op +AAAA
    100     k22x,  // op vAA, vBBBB
    101     k21t,  // op vAA, +BBBB
    102     k21s,  // op vAA, #+BBBB
    103     k21h,  // op vAA, #+BBBB00000[00000000]
    104     k21c,  // op vAA, thing@BBBB
    105     k23x,  // op vAA, vBB, vCC
    106     k22b,  // op vAA, vBB, #+CC
    107     k22t,  // op vA, vB, +CCCC
    108     k22s,  // op vA, vB, #+CCCC
    109     k22c,  // op vA, vB, thing@CCCC
    110     k32x,  // op vAAAA, vBBBB
    111     k30t,  // op +AAAAAAAA
    112     k31t,  // op vAA, +BBBBBBBB
    113     k31i,  // op vAA, #+BBBBBBBB
    114     k31c,  // op vAA, thing@BBBBBBBB
    115     k35c,  // op {vC, vD, vE, vF, vG}, thing@BBBB (B: count, A: vG)
    116     k3rc,  // op {vCCCC .. v(CCCC+AA-1)}, meth@BBBB
    117     k51l,  // op vAA, #+BBBBBBBBBBBBBBBB
    118   };
    119 
    120   enum Flags {
    121     kBranch              = 0x000001,  // conditional or unconditional branch
    122     kContinue            = 0x000002,  // flow can continue to next statement
    123     kSwitch              = 0x000004,  // switch statement
    124     kThrow               = 0x000008,  // could cause an exception to be thrown
    125     kReturn              = 0x000010,  // returns, no additional statements
    126     kInvoke              = 0x000020,  // a flavor of invoke
    127     kUnconditional       = 0x000040,  // unconditional branch
    128     kAdd                 = 0x000080,  // addition
    129     kSubtract            = 0x000100,  // subtract
    130     kMultiply            = 0x000200,  // multiply
    131     kDivide              = 0x000400,  // division
    132     kRemainder           = 0x000800,  // remainder
    133     kAnd                 = 0x001000,  // and
    134     kOr                  = 0x002000,  // or
    135     kXor                 = 0x004000,  // xor
    136     kShl                 = 0x008000,  // shl
    137     kShr                 = 0x010000,  // shr
    138     kUshr                = 0x020000,  // ushr
    139     kCast                = 0x040000,  // cast
    140     kStore               = 0x080000,  // store opcode
    141     kLoad                = 0x100000,  // load opcode
    142     kClobber             = 0x200000,  // clobbers memory in a big way (not just a write)
    143     kRegCFieldOrConstant = 0x400000,  // is the third virtual register a field or literal constant (vC)
    144     kRegBFieldOrConstant = 0x800000,  // is the second virtual register a field or literal constant (vB)
    145   };
    146 
    147   enum VerifyFlag {
    148     kVerifyNone               = 0x000000,
    149     kVerifyRegA               = 0x000001,
    150     kVerifyRegAWide           = 0x000002,
    151     kVerifyRegB               = 0x000004,
    152     kVerifyRegBField          = 0x000008,
    153     kVerifyRegBMethod         = 0x000010,
    154     kVerifyRegBNewInstance    = 0x000020,
    155     kVerifyRegBString         = 0x000040,
    156     kVerifyRegBType           = 0x000080,
    157     kVerifyRegBWide           = 0x000100,
    158     kVerifyRegC               = 0x000200,
    159     kVerifyRegCField          = 0x000400,
    160     kVerifyRegCNewArray       = 0x000800,
    161     kVerifyRegCType           = 0x001000,
    162     kVerifyRegCWide           = 0x002000,
    163     kVerifyArrayData          = 0x004000,
    164     kVerifyBranchTarget       = 0x008000,
    165     kVerifySwitchTargets      = 0x010000,
    166     kVerifyVarArg             = 0x020000,
    167     kVerifyVarArgNonZero      = 0x040000,
    168     kVerifyVarArgRange        = 0x080000,
    169     kVerifyVarArgRangeNonZero = 0x100000,
    170     kVerifyRuntimeOnly        = 0x200000,
    171     kVerifyError              = 0x400000,
    172   };
    173 
    174   static constexpr uint32_t kMaxVarArgRegs = 5;
    175 
    176   // Returns the size (in 2 byte code units) of this instruction.
    177   size_t SizeInCodeUnits() const {
    178     int result = kInstructionSizeInCodeUnits[Opcode()];
    179     if (UNLIKELY(result < 0)) {
    180       return SizeInCodeUnitsComplexOpcode();
    181     } else {
    182       return static_cast<size_t>(result);
    183     }
    184   }
    185 
    186   // Reads an instruction out of the stream at the specified address.
    187   static const Instruction* At(const uint16_t* code) {
    188     DCHECK(code != NULL);
    189     return reinterpret_cast<const Instruction*>(code);
    190   }
    191 
    192   // Reads an instruction out of the stream from the current address plus an offset.
    193   const Instruction* RelativeAt(int32_t offset) const {
    194     return At(reinterpret_cast<const uint16_t*>(this) + offset);
    195   }
    196 
    197   // Returns a pointer to the next instruction in the stream.
    198   const Instruction* Next() const {
    199     return RelativeAt(SizeInCodeUnits());
    200   }
    201 
    202   // Returns a pointer to the instruction after this 1xx instruction in the stream.
    203   const Instruction* Next_1xx() const {
    204     DCHECK(FormatOf(Opcode()) >= k10x && FormatOf(Opcode()) <= k10t);
    205     return RelativeAt(1);
    206   }
    207 
    208   // Returns a pointer to the instruction after this 2xx instruction in the stream.
    209   const Instruction* Next_2xx() const {
    210     DCHECK(FormatOf(Opcode()) >= k20t && FormatOf(Opcode()) <= k22c);
    211     return RelativeAt(2);
    212   }
    213 
    214   // Returns a pointer to the instruction after this 3xx instruction in the stream.
    215   const Instruction* Next_3xx() const {
    216     DCHECK(FormatOf(Opcode()) >= k32x && FormatOf(Opcode()) <= k3rc);
    217     return RelativeAt(3);
    218   }
    219 
    220   // Returns a pointer to the instruction after this 51l instruction in the stream.
    221   const Instruction* Next_51l() const {
    222     DCHECK(FormatOf(Opcode()) == k51l);
    223     return RelativeAt(5);
    224   }
    225 
    226   // Returns the name of this instruction's opcode.
    227   const char* Name() const {
    228     return Instruction::Name(Opcode());
    229   }
    230 
    231   // Returns the name of the given opcode.
    232   static const char* Name(Code opcode) {
    233     return kInstructionNames[opcode];
    234   }
    235 
    236   // VRegA
    237   bool HasVRegA() const;
    238   int32_t VRegA() const;
    239 
    240   int8_t VRegA_10t() const {
    241     return VRegA_10t(Fetch16(0));
    242   }
    243   uint8_t VRegA_10x() const {
    244     return VRegA_10x(Fetch16(0));
    245   }
    246   uint4_t VRegA_11n() const {
    247     return VRegA_11n(Fetch16(0));
    248   }
    249   uint8_t VRegA_11x() const {
    250     return VRegA_11x(Fetch16(0));
    251   }
    252   uint4_t VRegA_12x() const {
    253     return VRegA_12x(Fetch16(0));
    254   }
    255   int16_t VRegA_20t() const;
    256   uint8_t VRegA_21c() const {
    257     return VRegA_21c(Fetch16(0));
    258   }
    259   uint8_t VRegA_21h() const {
    260     return VRegA_21h(Fetch16(0));
    261   }
    262   uint8_t VRegA_21s() const {
    263     return VRegA_21s(Fetch16(0));
    264   }
    265   uint8_t VRegA_21t() const {
    266     return VRegA_21t(Fetch16(0));
    267   }
    268   uint8_t VRegA_22b() const {
    269     return VRegA_22b(Fetch16(0));
    270   }
    271   uint4_t VRegA_22c() const {
    272     return VRegA_22c(Fetch16(0));
    273   }
    274   uint4_t VRegA_22s() const {
    275     return VRegA_22s(Fetch16(0));
    276   }
    277   uint4_t VRegA_22t() const {
    278     return VRegA_22t(Fetch16(0));
    279   }
    280   uint8_t VRegA_22x() const {
    281     return VRegA_22x(Fetch16(0));
    282   }
    283   uint8_t VRegA_23x() const {
    284     return VRegA_23x(Fetch16(0));
    285   }
    286   int32_t VRegA_30t() const;
    287   uint8_t VRegA_31c() const {
    288     return VRegA_31c(Fetch16(0));
    289   }
    290   uint8_t VRegA_31i() const {
    291     return VRegA_31i(Fetch16(0));
    292   }
    293   uint8_t VRegA_31t() const {
    294     return VRegA_31t(Fetch16(0));
    295   }
    296   uint16_t VRegA_32x() const;
    297   uint4_t VRegA_35c() const {
    298     return VRegA_35c(Fetch16(0));
    299   }
    300   uint8_t VRegA_3rc() const {
    301     return VRegA_3rc(Fetch16(0));
    302   }
    303   uint8_t VRegA_51l() const {
    304     return VRegA_51l(Fetch16(0));
    305   }
    306 
    307   // The following methods return the vA operand for various instruction formats. The "inst_data"
    308   // parameter holds the first 16 bits of instruction which the returned value is decoded from.
    309   int8_t VRegA_10t(uint16_t inst_data) const;
    310   uint8_t VRegA_10x(uint16_t inst_data) const;
    311   uint4_t VRegA_11n(uint16_t inst_data) const;
    312   uint8_t VRegA_11x(uint16_t inst_data) const;
    313   uint4_t VRegA_12x(uint16_t inst_data) const;
    314   uint8_t VRegA_21c(uint16_t inst_data) const;
    315   uint8_t VRegA_21h(uint16_t inst_data) const;
    316   uint8_t VRegA_21s(uint16_t inst_data) const;
    317   uint8_t VRegA_21t(uint16_t inst_data) const;
    318   uint8_t VRegA_22b(uint16_t inst_data) const;
    319   uint4_t VRegA_22c(uint16_t inst_data) const;
    320   uint4_t VRegA_22s(uint16_t inst_data) const;
    321   uint4_t VRegA_22t(uint16_t inst_data) const;
    322   uint8_t VRegA_22x(uint16_t inst_data) const;
    323   uint8_t VRegA_23x(uint16_t inst_data) const;
    324   uint8_t VRegA_31c(uint16_t inst_data) const;
    325   uint8_t VRegA_31i(uint16_t inst_data) const;
    326   uint8_t VRegA_31t(uint16_t inst_data) const;
    327   uint4_t VRegA_35c(uint16_t inst_data) const;
    328   uint8_t VRegA_3rc(uint16_t inst_data) const;
    329   uint8_t VRegA_51l(uint16_t inst_data) const;
    330 
    331   // VRegB
    332   bool HasVRegB() const;
    333   int32_t VRegB() const;
    334 
    335   bool HasWideVRegB() const;
    336   uint64_t WideVRegB() const;
    337 
    338   int4_t VRegB_11n() const {
    339     return VRegB_11n(Fetch16(0));
    340   }
    341   uint4_t VRegB_12x() const {
    342     return VRegB_12x(Fetch16(0));
    343   }
    344   uint16_t VRegB_21c() const;
    345   uint16_t VRegB_21h() const;
    346   int16_t VRegB_21s() const;
    347   int16_t VRegB_21t() const;
    348   uint8_t VRegB_22b() const;
    349   uint4_t VRegB_22c() const {
    350     return VRegB_22c(Fetch16(0));
    351   }
    352   uint4_t VRegB_22s() const {
    353     return VRegB_22s(Fetch16(0));
    354   }
    355   uint4_t VRegB_22t() const {
    356     return VRegB_22t(Fetch16(0));
    357   }
    358   uint16_t VRegB_22x() const;
    359   uint8_t VRegB_23x() const;
    360   uint32_t VRegB_31c() const;
    361   int32_t VRegB_31i() const;
    362   int32_t VRegB_31t() const;
    363   uint16_t VRegB_32x() const;
    364   uint16_t VRegB_35c() const;
    365   uint16_t VRegB_3rc() const;
    366   uint64_t VRegB_51l() const;  // vB_wide
    367 
    368   // The following methods return the vB operand for all instruction formats where it is encoded in
    369   // the first 16 bits of instruction. The "inst_data" parameter holds these 16 bits. The returned
    370   // value is decoded from it.
    371   int4_t VRegB_11n(uint16_t inst_data) const;
    372   uint4_t VRegB_12x(uint16_t inst_data) const;
    373   uint4_t VRegB_22c(uint16_t inst_data) const;
    374   uint4_t VRegB_22s(uint16_t inst_data) const;
    375   uint4_t VRegB_22t(uint16_t inst_data) const;
    376 
    377   // VRegC
    378   bool HasVRegC() const;
    379   int32_t VRegC() const;
    380 
    381   int8_t VRegC_22b() const;
    382   uint16_t VRegC_22c() const;
    383   int16_t VRegC_22s() const;
    384   int16_t VRegC_22t() const;
    385   uint8_t VRegC_23x() const;
    386   uint4_t VRegC_35c() const;
    387   uint16_t VRegC_3rc() const;
    388 
    389   // Fills the given array with the 'arg' array of the instruction.
    390   bool HasVarArgs() const;
    391   void GetVarArgs(uint32_t args[kMaxVarArgRegs], uint16_t inst_data) const;
    392   void GetVarArgs(uint32_t args[kMaxVarArgRegs]) const {
    393     return GetVarArgs(args, Fetch16(0));
    394   }
    395 
    396   // Returns the opcode field of the instruction. The given "inst_data" parameter must be the first
    397   // 16 bits of instruction.
    398   Code Opcode(uint16_t inst_data) const {
    399     DCHECK_EQ(inst_data, Fetch16(0));
    400     return static_cast<Code>(inst_data & 0xFF);
    401   }
    402 
    403   // Returns the opcode field of the instruction from the first 16 bits of instruction.
    404   Code Opcode() const {
    405     return Opcode(Fetch16(0));
    406   }
    407 
    408   void SetOpcode(Code opcode) {
    409     DCHECK_LT(static_cast<uint16_t>(opcode), 256u);
    410     uint16_t* insns = reinterpret_cast<uint16_t*>(this);
    411     insns[0] = (insns[0] & 0xff00) | static_cast<uint16_t>(opcode);
    412   }
    413 
    414   void SetVRegA_10x(uint8_t val) {
    415     DCHECK(FormatOf(Opcode()) == k10x);
    416     uint16_t* insns = reinterpret_cast<uint16_t*>(this);
    417     insns[0] = (val << 8) | (insns[0] & 0x00ff);
    418   }
    419 
    420   void SetVRegB_3rc(uint16_t val) {
    421     DCHECK(FormatOf(Opcode()) == k3rc);
    422     uint16_t* insns = reinterpret_cast<uint16_t*>(this);
    423     insns[1] = val;
    424   }
    425 
    426   void SetVRegB_35c(uint16_t val) {
    427     DCHECK(FormatOf(Opcode()) == k35c);
    428     uint16_t* insns = reinterpret_cast<uint16_t*>(this);
    429     insns[1] = val;
    430   }
    431 
    432   void SetVRegC_22c(uint16_t val) {
    433     DCHECK(FormatOf(Opcode()) == k22c);
    434     uint16_t* insns = reinterpret_cast<uint16_t*>(this);
    435     insns[1] = val;
    436   }
    437 
    438   // Returns the format of the given opcode.
    439   static Format FormatOf(Code opcode) {
    440     return kInstructionFormats[opcode];
    441   }
    442 
    443   // Returns the flags for the given opcode.
    444   static int FlagsOf(Code opcode) {
    445     return kInstructionFlags[opcode];
    446   }
    447 
    448   // Return the verify flags for the given opcode.
    449   static int VerifyFlagsOf(Code opcode) {
    450     return kInstructionVerifyFlags[opcode];
    451   }
    452 
    453   // Returns true if this instruction is a branch.
    454   bool IsBranch() const {
    455     return (kInstructionFlags[Opcode()] & kBranch) != 0;
    456   }
    457 
    458   // Returns true if this instruction is a unconditional branch.
    459   bool IsUnconditional() const {
    460     return (kInstructionFlags[Opcode()] & kUnconditional) != 0;
    461   }
    462 
    463   // Returns the branch offset if this instruction is a branch.
    464   int32_t GetTargetOffset() const;
    465 
    466   // Returns true if the instruction allows control flow to go to the following instruction.
    467   bool CanFlowThrough() const;
    468 
    469   // Returns true if this instruction is a switch.
    470   bool IsSwitch() const {
    471     return (kInstructionFlags[Opcode()] & kSwitch) != 0;
    472   }
    473 
    474   // Returns true if this instruction can throw.
    475   bool IsThrow() const {
    476     return (kInstructionFlags[Opcode()] & kThrow) != 0;
    477   }
    478 
    479   // Determine if the instruction is any of 'return' instructions.
    480   bool IsReturn() const {
    481     return (kInstructionFlags[Opcode()] & kReturn) != 0;
    482   }
    483 
    484   // Determine if this instruction ends execution of its basic block.
    485   bool IsBasicBlockEnd() const {
    486     return IsBranch() || IsReturn() || Opcode() == THROW;
    487   }
    488 
    489   // Determine if this instruction is an invoke.
    490   bool IsInvoke() const {
    491     return (kInstructionFlags[Opcode()] & kInvoke) != 0;
    492   }
    493 
    494   int GetVerifyTypeArgumentA() const {
    495     return (kInstructionVerifyFlags[Opcode()] & (kVerifyRegA | kVerifyRegAWide));
    496   }
    497 
    498   int GetVerifyTypeArgumentB() const {
    499     return (kInstructionVerifyFlags[Opcode()] & (kVerifyRegB | kVerifyRegBField |
    500         kVerifyRegBMethod | kVerifyRegBNewInstance | kVerifyRegBString | kVerifyRegBType |
    501         kVerifyRegBWide));
    502   }
    503 
    504   int GetVerifyTypeArgumentC() const {
    505     return (kInstructionVerifyFlags[Opcode()] & (kVerifyRegC | kVerifyRegCField |
    506         kVerifyRegCNewArray | kVerifyRegCType | kVerifyRegCWide));
    507   }
    508 
    509   int GetVerifyExtraFlags() const {
    510     return (kInstructionVerifyFlags[Opcode()] & (kVerifyArrayData | kVerifyBranchTarget |
    511         kVerifySwitchTargets | kVerifyVarArg | kVerifyVarArgNonZero | kVerifyVarArgRange |
    512         kVerifyVarArgRangeNonZero | kVerifyError));
    513   }
    514 
    515   bool GetVerifyIsRuntimeOnly() const {
    516     return (kInstructionVerifyFlags[Opcode()] & kVerifyRuntimeOnly) != 0;
    517   }
    518 
    519   // Get the dex PC of this instruction as a offset in code units from the beginning of insns.
    520   uint32_t GetDexPc(const uint16_t* insns) const {
    521     return (reinterpret_cast<const uint16_t*>(this) - insns);
    522   }
    523 
    524   // Dump decoded version of instruction
    525   std::string DumpString(const DexFile*) const;
    526 
    527   // Dump code_units worth of this instruction, padding to code_units for shorter instructions
    528   std::string DumpHex(size_t code_units) const;
    529 
    530   uint16_t Fetch16(size_t offset) const {
    531     const uint16_t* insns = reinterpret_cast<const uint16_t*>(this);
    532     return insns[offset];
    533   }
    534 
    535  private:
    536   size_t SizeInCodeUnitsComplexOpcode() const;
    537 
    538   uint32_t Fetch32(size_t offset) const {
    539     return (Fetch16(offset) | ((uint32_t) Fetch16(offset + 1) << 16));
    540   }
    541 
    542   uint4_t InstA() const {
    543     return InstA(Fetch16(0));
    544   }
    545 
    546   uint4_t InstB() const {
    547     return InstB(Fetch16(0));
    548   }
    549 
    550   uint8_t InstAA() const {
    551     return InstAA(Fetch16(0));
    552   }
    553 
    554   uint4_t InstA(uint16_t inst_data) const {
    555     DCHECK_EQ(inst_data, Fetch16(0));
    556     return static_cast<uint4_t>((inst_data >> 8) & 0x0f);
    557   }
    558 
    559   uint4_t InstB(uint16_t inst_data) const {
    560     DCHECK_EQ(inst_data, Fetch16(0));
    561     return static_cast<uint4_t>(inst_data >> 12);
    562   }
    563 
    564   uint8_t InstAA(uint16_t inst_data) const {
    565     DCHECK_EQ(inst_data, Fetch16(0));
    566     return static_cast<uint8_t>(inst_data >> 8);
    567   }
    568 
    569   static const char* const kInstructionNames[];
    570   static Format const kInstructionFormats[];
    571   static int const kInstructionFlags[];
    572   static int const kInstructionVerifyFlags[];
    573   static int const kInstructionSizeInCodeUnits[];
    574   DISALLOW_IMPLICIT_CONSTRUCTORS(Instruction);
    575 };
    576 std::ostream& operator<<(std::ostream& os, const Instruction::Code& code);
    577 std::ostream& operator<<(std::ostream& os, const Instruction::Format& format);
    578 std::ostream& operator<<(std::ostream& os, const Instruction::Flags& flags);
    579 std::ostream& operator<<(std::ostream& os, const Instruction::VerifyFlag& vflags);
    580 
    581 }  // namespace art
    582 
    583 #endif  // ART_RUNTIME_DEX_INSTRUCTION_H_
    584