Make dex instruction size a lookup.
Add ostream operators for dex instruction enums.
Move simple methods to header file.
Change-Id: I9644bfb975896a491ee73ef9a8ef13c062c5fcbd
diff --git a/src/dex_instruction.h b/src/dex_instruction.h
index 91aa042..90dca69 100644
--- a/src/dex_instruction.h
+++ b/src/dex_instruction.h
@@ -74,13 +74,16 @@
DISALLOW_COPY_AND_ASSIGN(ArrayDataPayload);
};
- enum Code {
+ // TODO: the code layout below is deliberate to avoid this enum being picked up by
+ // generate-operator-out.py.
+ enum Code
+ {
#define INSTRUCTION_ENUM(opcode, cname, p, f, r, i, a, v) cname = opcode,
#include "dex_instruction_list.h"
DEX_INSTRUCTION_LIST(INSTRUCTION_ENUM)
#undef DEX_INSTRUCTION_LIST
#undef INSTRUCTION_ENUM
- };
+ } ;
enum Format {
k10x, // op
@@ -147,10 +150,21 @@
void Decode(uint32_t &vA, uint32_t &vB, uint64_t &vB_wide, uint32_t &vC, uint32_t arg[]) const;
// Returns the size (in 2 byte code units) of this instruction.
- size_t SizeInCodeUnits() const;
+ size_t SizeInCodeUnits() const {
+ int result = kInstructionSizeInCodeUnits[Opcode()];
+ if (UNLIKELY(result < 0)) {
+ return SizeInCodeUnitsComplexOpcode();
+ } else {
+ return static_cast<size_t>(result);
+ }
+ }
// Returns a pointer to the next instruction in the stream.
- const Instruction* Next() const;
+ const Instruction* Next() const {
+ size_t current_size_in_bytes = SizeInCodeUnits() * sizeof(uint16_t);
+ const uint8_t* ptr = reinterpret_cast<const uint8_t*>(this);
+ return reinterpret_cast<const Instruction*>(ptr + current_size_in_bytes);
+ }
// Returns the name of this instruction's opcode.
const char* Name() const {
@@ -163,7 +177,11 @@
}
// Returns the opcode field of the instruction.
- Code Opcode() const;
+ Code Opcode() const {
+ const uint16_t* insns = reinterpret_cast<const uint16_t*>(this);
+ int opcode = *insns & 0xFF;
+ return static_cast<Code>(opcode);
+ }
// Reads an instruction out of the stream at the specified address.
static const Instruction* At(const uint16_t* code) {
@@ -177,7 +195,7 @@
}
// Returns the flags for the given opcode.
- static int Flags(Code opcode) {
+ static int FlagsOf(Code opcode) {
return kInstructionFlags[opcode];
}
@@ -242,12 +260,19 @@
std::string DumpHex(size_t code_units) const;
private:
+ size_t SizeInCodeUnitsComplexOpcode() const;
+
static const char* const kInstructionNames[];
static Format const kInstructionFormats[];
static int const kInstructionFlags[];
static int const kInstructionVerifyFlags[];
+ static int const kInstructionSizeInCodeUnits[];
DISALLOW_IMPLICIT_CONSTRUCTORS(Instruction);
};
+std::ostream& operator<<(std::ostream& os, const Instruction::Code& code);
+std::ostream& operator<<(std::ostream& os, const Instruction::Format& format);
+std::ostream& operator<<(std::ostream& os, const Instruction::Flags& flags);
+std::ostream& operator<<(std::ostream& os, const Instruction::VerifyFlag& vflags);
/*
* Holds the contents of a decoded instruction.
@@ -260,7 +285,10 @@
uint32_t arg[5]; /* vC/D/E/F/G in invoke or filled-new-array */
Instruction::Code opcode;
- explicit DecodedInstruction(const Instruction* inst);
+ explicit DecodedInstruction(const Instruction* inst) {
+ inst->Decode(vA, vB, vB_wide, vC, arg);
+ opcode = inst->Opcode();
+ }
};
} // namespace art