diff options
-rw-r--r-- | runtime/dex_instruction.cc | 42 | ||||
-rw-r--r-- | runtime/dex_instruction_test.cc | 37 |
2 files changed, 52 insertions, 27 deletions
diff --git a/runtime/dex_instruction.cc b/runtime/dex_instruction.cc index b2267e5573..99fe53bb71 100644 --- a/runtime/dex_instruction.cc +++ b/runtime/dex_instruction.cc @@ -349,17 +349,19 @@ std::string Instruction::DumpString(const DexFile* file) const { case k35c: { uint32_t arg[kMaxVarArgRegs]; GetVarArgs(arg); + auto DumpArgs = [&](size_t count) { + for (size_t i = 0; i < count; ++i) { + if (i != 0) { + os << ", "; + } + os << "v" << arg[i]; + } + }; switch (Opcode()) { case FILLED_NEW_ARRAY: { - const int32_t a = VRegA_35c(); os << opcode << " {"; - for (int i = 0; i < a; ++i) { - if (i > 0) { - os << ", "; - } - os << "v" << arg[i]; - } + DumpArgs(VRegA_35c()); os << "}, type@" << VRegB_35c(); } break; @@ -372,12 +374,7 @@ std::string Instruction::DumpString(const DexFile* file) const { if (file != nullptr) { os << opcode << " {"; uint32_t method_idx = VRegB_35c(); - for (size_t i = 0; i < VRegA_35c(); ++i) { - if (i != 0) { - os << ", "; - } - os << "v" << arg[i]; - } + DumpArgs(VRegA_35c()); os << "}, " << file->PrettyMethod(method_idx) << " // method@" << method_idx; break; } @@ -386,12 +383,7 @@ std::string Instruction::DumpString(const DexFile* file) const { if (file != nullptr) { os << opcode << " {"; uint32_t method_idx = VRegB_35c(); - for (size_t i = 0; i < VRegA_35c(); ++i) { - if (i != 0) { - os << ", "; - } - os << "v" << arg[i]; - } + DumpArgs(VRegA_35c()); os << "}, // vtable@" << method_idx; break; } @@ -400,19 +392,15 @@ std::string Instruction::DumpString(const DexFile* file) const { if (file != nullptr) { os << opcode << " {"; uint32_t call_site_idx = VRegB_35c(); - for (size_t i = 0; i < VRegA_35c(); ++i) { - if (i != 0) { - os << ", "; - } - os << "v" << arg[i]; - } + DumpArgs(VRegA_35c()); os << "}, // call_site@" << call_site_idx; break; } FALLTHROUGH_INTENDED; default: - os << opcode << " {v" << arg[0] << ", v" << arg[1] << ", v" << arg[2] - << ", v" << arg[3] << ", v" << arg[4] << "}, thing@" << VRegB_35c(); + os << opcode << " {"; + DumpArgs(VRegA_35c()); + os << "}, thing@" << VRegB_35c(); break; } break; diff --git a/runtime/dex_instruction_test.cc b/runtime/dex_instruction_test.cc index 95e4181a8e..3f7ac57cef 100644 --- a/runtime/dex_instruction_test.cc +++ b/runtime/dex_instruction_test.cc @@ -131,4 +131,41 @@ TEST(Instruction, PropertiesOf4rcc) { ASSERT_FALSE(ins->HasVarArgs()); } +static void Build35c(uint16_t* out, + Instruction::Code code, + uint16_t method_idx, + std::vector<uint16_t> args) { + out[0] = 0; + out[0] |= (args.size() << 12); + out[0] |= static_cast<uint16_t>(code); + out[1] = method_idx; + size_t i = 0; + out[2] = 0; + for (; i < 4 && i < args.size(); ++i) { + out[2] |= args[i] << (i * 4); + } + if (args.size() == 5) { + out[0] |= args[4] << 8; + } +} + +static std::string DumpInst35c(Instruction::Code code, + uint16_t method_idx, + std::vector<uint16_t> args) { + uint16_t inst[6] = {}; + Build35c(inst, code, method_idx, args); + return Instruction::At(inst)->DumpString(nullptr); +} + +TEST(Instruction, DumpString) { + EXPECT_EQ(DumpInst35c(Instruction::FILLED_NEW_ARRAY, 1234, {3, 2}), + "filled-new-array {v3, v2}, type@1234"); + EXPECT_EQ(DumpInst35c(Instruction::INVOKE_VIRTUAL, 1234, {3, 2, 1, 5, 6}), + "invoke-virtual {v3, v2, v1, v5, v6}, thing@1234"); + EXPECT_EQ(DumpInst35c(Instruction::INVOKE_VIRTUAL_QUICK, 1234, {3, 2, 1, 5}), + "invoke-virtual-quick {v3, v2, v1, v5}, thing@1234"); + EXPECT_EQ(DumpInst35c(Instruction::INVOKE_CUSTOM, 1234, {3, 2, 1}), + "invoke-custom {v3, v2, v1}, thing@1234"); +} + } // namespace art |