diff options
author | Mathieu Chartier <mathieuc@google.com> | 2014-12-10 10:35:44 -0800 |
---|---|---|
committer | Mathieu Chartier <mathieuc@google.com> | 2014-12-10 11:45:44 -0800 |
commit | ffc605cd817e79d6c7602a87543bb31f24d3a99f (patch) | |
tree | 84e4e68b11fe2d9c8c2e901b858026c1ebe88973 | |
parent | b1a38e246cfbfb21100d9c9e57f33970e824f075 (diff) | |
download | art-ffc605cd817e79d6c7602a87543bb31f24d3a99f.zip art-ffc605cd817e79d6c7602a87543bb31f24d3a99f.tar.gz art-ffc605cd817e79d6c7602a87543bb31f24d3a99f.tar.bz2 |
Add missing iget quick for bool, byte, char, short
Bug: 17791557
Bug: 17671806
Change-Id: Ifac4fbfba6c3a3f97131e85914b24756fb7f9722
-rw-r--r-- | compiler/dex/dex_to_dex_compiler.cc | 16 | ||||
-rw-r--r-- | compiler/dex/quick/quick_compiler.cc | 8 | ||||
-rw-r--r-- | runtime/common_throws.cc | 4 | ||||
-rw-r--r-- | runtime/dex_instruction_list.h | 8 | ||||
-rw-r--r-- | runtime/interpreter/interpreter_common.cc | 22 | ||||
-rw-r--r-- | runtime/interpreter/interpreter_goto_table_impl.cc | 40 | ||||
-rw-r--r-- | runtime/interpreter/interpreter_switch_impl.cc | 26 | ||||
-rw-r--r-- | runtime/verifier/method_verifier.cc | 41 |
8 files changed, 114 insertions, 51 deletions
diff --git a/compiler/dex/dex_to_dex_compiler.cc b/compiler/dex/dex_to_dex_compiler.cc index 205a521..f7968c2 100644 --- a/compiler/dex/dex_to_dex_compiler.cc +++ b/compiler/dex/dex_to_dex_compiler.cc @@ -120,6 +120,22 @@ void DexCompiler::Compile() { CompileInstanceFieldAccess(inst, dex_pc, Instruction::IGET_OBJECT_QUICK, false); break; + case Instruction::IGET_BOOLEAN: + CompileInstanceFieldAccess(inst, dex_pc, Instruction::IGET_BOOLEAN_QUICK, false); + break; + + case Instruction::IGET_BYTE: + CompileInstanceFieldAccess(inst, dex_pc, Instruction::IGET_BYTE_QUICK, false); + break; + + case Instruction::IGET_CHAR: + CompileInstanceFieldAccess(inst, dex_pc, Instruction::IGET_CHAR_QUICK, false); + break; + + case Instruction::IGET_SHORT: + CompileInstanceFieldAccess(inst, dex_pc, Instruction::IGET_SHORT_QUICK, false); + break; + case Instruction::IPUT: CompileInstanceFieldAccess(inst, dex_pc, Instruction::IPUT_QUICK, true); break; diff --git a/compiler/dex/quick/quick_compiler.cc b/compiler/dex/quick/quick_compiler.cc index 8d4cb3c..fb098c3 100644 --- a/compiler/dex/quick/quick_compiler.cc +++ b/compiler/dex/quick/quick_compiler.cc @@ -392,10 +392,10 @@ static int kAllOpcodes[] = { Instruction::IPUT_BYTE_QUICK, Instruction::IPUT_CHAR_QUICK, Instruction::IPUT_SHORT_QUICK, - Instruction::UNUSED_EF, - Instruction::UNUSED_F0, - Instruction::UNUSED_F1, - Instruction::UNUSED_F2, + Instruction::IGET_BOOLEAN_QUICK, + Instruction::IGET_BYTE_QUICK, + Instruction::IGET_CHAR_QUICK, + Instruction::IGET_SHORT_QUICK, Instruction::UNUSED_F3, Instruction::UNUSED_F4, Instruction::UNUSED_F5, diff --git a/runtime/common_throws.cc b/runtime/common_throws.cc index 846216c..f5b4354 100644 --- a/runtime/common_throws.cc +++ b/runtime/common_throws.cc @@ -418,6 +418,10 @@ void ThrowNullPointerExceptionFromDexPC(const ThrowLocation& throw_location) { break; } case Instruction::IGET_QUICK: + case Instruction::IGET_BOOLEAN_QUICK: + case Instruction::IGET_BYTE_QUICK: + case Instruction::IGET_CHAR_QUICK: + case Instruction::IGET_SHORT_QUICK: case Instruction::IGET_WIDE_QUICK: case Instruction::IGET_OBJECT_QUICK: { // Since we replaced the field index, we ask the verifier to tell us which diff --git a/runtime/dex_instruction_list.h b/runtime/dex_instruction_list.h index 05214a4..a90f424 100644 --- a/runtime/dex_instruction_list.h +++ b/runtime/dex_instruction_list.h @@ -257,10 +257,10 @@ V(0xEC, IPUT_BYTE_QUICK, "iput-byte-quick", k22c, false, kFieldRef, kContinue | kThrow | kStore | kRegCFieldOrConstant, kVerifyRegA | kVerifyRegB | kVerifyRuntimeOnly) \ V(0xED, IPUT_CHAR_QUICK, "iput-char-quick", k22c, false, kFieldRef, kContinue | kThrow | kStore | kRegCFieldOrConstant, kVerifyRegA | kVerifyRegB | kVerifyRuntimeOnly) \ V(0xEE, IPUT_SHORT_QUICK, "iput-short-quick", k22c, false, kFieldRef, kContinue | kThrow | kStore | kRegCFieldOrConstant, kVerifyRegA | kVerifyRegB | kVerifyRuntimeOnly) \ - V(0xEF, UNUSED_EF, "unused-ef", k10x, false, kUnknown, 0, kVerifyError) \ - V(0xF0, UNUSED_F0, "unused-f0", k10x, false, kUnknown, 0, kVerifyError) \ - V(0xF1, UNUSED_F1, "unused-f1", k10x, false, kUnknown, 0, kVerifyError) \ - V(0xF2, UNUSED_F2, "unused-f2", k10x, false, kUnknown, 0, kVerifyError) \ + V(0xEF, IGET_BOOLEAN_QUICK, "iget-boolean-quick", k22c, true, kFieldRef, kContinue | kThrow | kLoad | kRegCFieldOrConstant, kVerifyRegA | kVerifyRegB | kVerifyRuntimeOnly) \ + V(0xF0, IGET_BYTE_QUICK, "iget-byte-quick", k22c, true, kFieldRef, kContinue | kThrow | kLoad | kRegCFieldOrConstant, kVerifyRegA | kVerifyRegB | kVerifyRuntimeOnly) \ + V(0xF1, IGET_CHAR_QUICK, "iget-char-quick", k22c, true, kFieldRef, kContinue | kThrow | kLoad | kRegCFieldOrConstant, kVerifyRegA | kVerifyRegB | kVerifyRuntimeOnly) \ + V(0xF2, IGET_SHORT_QUICK, "iget-short-quick", k22c, true, kFieldRef, kContinue | kThrow | kLoad | kRegCFieldOrConstant, kVerifyRegA | kVerifyRegB | kVerifyRuntimeOnly) \ V(0xF3, UNUSED_F3, "unused-f3", k10x, false, kUnknown, 0, kVerifyError) \ V(0xF4, UNUSED_F4, "unused-f4", k10x, false, kUnknown, 0, kVerifyError) \ V(0xF5, UNUSED_F5, "unused-f5", k10x, false, kUnknown, 0, kVerifyError) \ diff --git a/runtime/interpreter/interpreter_common.cc b/runtime/interpreter/interpreter_common.cc index 3c7db85..2a63456 100644 --- a/runtime/interpreter/interpreter_common.cc +++ b/runtime/interpreter/interpreter_common.cc @@ -145,6 +145,18 @@ bool DoIGetQuick(ShadowFrame& shadow_frame, const Instruction* inst, uint16_t in case Primitive::kPrimInt: shadow_frame.SetVReg(vregA, static_cast<int32_t>(obj->GetField32(field_offset))); break; + case Primitive::kPrimBoolean: + shadow_frame.SetVReg(vregA, static_cast<int32_t>(obj->GetFieldBoolean(field_offset))); + break; + case Primitive::kPrimByte: + shadow_frame.SetVReg(vregA, static_cast<int32_t>(obj->GetFieldByte(field_offset))); + break; + case Primitive::kPrimChar: + shadow_frame.SetVReg(vregA, static_cast<int32_t>(obj->GetFieldChar(field_offset))); + break; + case Primitive::kPrimShort: + shadow_frame.SetVReg(vregA, static_cast<int32_t>(obj->GetFieldShort(field_offset))); + break; case Primitive::kPrimLong: shadow_frame.SetVRegLong(vregA, static_cast<int64_t>(obj->GetField64(field_offset))); break; @@ -163,9 +175,13 @@ bool DoIGetQuick(ShadowFrame& shadow_frame, const Instruction* inst, uint16_t in template bool DoIGetQuick<_field_type>(ShadowFrame& shadow_frame, const Instruction* inst, \ uint16_t inst_data) -EXPLICIT_DO_IGET_QUICK_TEMPLATE_DECL(Primitive::kPrimInt); // iget-quick. -EXPLICIT_DO_IGET_QUICK_TEMPLATE_DECL(Primitive::kPrimLong); // iget-wide-quick. -EXPLICIT_DO_IGET_QUICK_TEMPLATE_DECL(Primitive::kPrimNot); // iget-object-quick. +EXPLICIT_DO_IGET_QUICK_TEMPLATE_DECL(Primitive::kPrimInt); // iget-quick. +EXPLICIT_DO_IGET_QUICK_TEMPLATE_DECL(Primitive::kPrimBoolean); // iget-boolean-quick. +EXPLICIT_DO_IGET_QUICK_TEMPLATE_DECL(Primitive::kPrimByte); // iget-byte-quick. +EXPLICIT_DO_IGET_QUICK_TEMPLATE_DECL(Primitive::kPrimChar); // iget-char-quick. +EXPLICIT_DO_IGET_QUICK_TEMPLATE_DECL(Primitive::kPrimShort); // iget-short-quick. +EXPLICIT_DO_IGET_QUICK_TEMPLATE_DECL(Primitive::kPrimLong); // iget-wide-quick. +EXPLICIT_DO_IGET_QUICK_TEMPLATE_DECL(Primitive::kPrimNot); // iget-object-quick. #undef EXPLICIT_DO_IGET_QUICK_TEMPLATE_DECL template<Primitive::Type field_type> diff --git a/runtime/interpreter/interpreter_goto_table_impl.cc b/runtime/interpreter/interpreter_goto_table_impl.cc index c332a7b..c610263 100644 --- a/runtime/interpreter/interpreter_goto_table_impl.cc +++ b/runtime/interpreter/interpreter_goto_table_impl.cc @@ -1249,6 +1249,30 @@ JValue ExecuteGotoImpl(Thread* self, const DexFile::CodeItem* code_item, ShadowF } HANDLE_INSTRUCTION_END(); + HANDLE_INSTRUCTION_START(IGET_BOOLEAN_QUICK) { + bool success = DoIGetQuick<Primitive::kPrimBoolean>(shadow_frame, inst, inst_data); + POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2); + } + HANDLE_INSTRUCTION_END(); + + HANDLE_INSTRUCTION_START(IGET_BYTE_QUICK) { + bool success = DoIGetQuick<Primitive::kPrimByte>(shadow_frame, inst, inst_data); + POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2); + } + HANDLE_INSTRUCTION_END(); + + HANDLE_INSTRUCTION_START(IGET_CHAR_QUICK) { + bool success = DoIGetQuick<Primitive::kPrimChar>(shadow_frame, inst, inst_data); + POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2); + } + HANDLE_INSTRUCTION_END(); + + HANDLE_INSTRUCTION_START(IGET_SHORT_QUICK) { + bool success = DoIGetQuick<Primitive::kPrimShort>(shadow_frame, inst, inst_data); + POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2); + } + HANDLE_INSTRUCTION_END(); + HANDLE_INSTRUCTION_START(IGET_WIDE_QUICK) { bool success = DoIGetQuick<Primitive::kPrimLong>(shadow_frame, inst, inst_data); POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2); @@ -2310,22 +2334,6 @@ JValue ExecuteGotoImpl(Thread* self, const DexFile::CodeItem* code_item, ShadowF UnexpectedOpcode(inst, shadow_frame); HANDLE_INSTRUCTION_END(); - HANDLE_INSTRUCTION_START(UNUSED_EF) - UnexpectedOpcode(inst, shadow_frame); - HANDLE_INSTRUCTION_END(); - - HANDLE_INSTRUCTION_START(UNUSED_F0) - UnexpectedOpcode(inst, shadow_frame); - HANDLE_INSTRUCTION_END(); - - HANDLE_INSTRUCTION_START(UNUSED_F1) - UnexpectedOpcode(inst, shadow_frame); - HANDLE_INSTRUCTION_END(); - - HANDLE_INSTRUCTION_START(UNUSED_F2) - UnexpectedOpcode(inst, shadow_frame); - HANDLE_INSTRUCTION_END(); - HANDLE_INSTRUCTION_START(UNUSED_F3) UnexpectedOpcode(inst, shadow_frame); HANDLE_INSTRUCTION_END(); diff --git a/runtime/interpreter/interpreter_switch_impl.cc b/runtime/interpreter/interpreter_switch_impl.cc index f9bbfa1..8bbc694 100644 --- a/runtime/interpreter/interpreter_switch_impl.cc +++ b/runtime/interpreter/interpreter_switch_impl.cc @@ -1128,6 +1128,30 @@ JValue ExecuteSwitchImpl(Thread* self, const DexFile::CodeItem* code_item, POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx); break; } + case Instruction::IGET_BOOLEAN_QUICK: { + PREAMBLE(); + bool success = DoIGetQuick<Primitive::kPrimBoolean>(shadow_frame, inst, inst_data); + POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx); + break; + } + case Instruction::IGET_BYTE_QUICK: { + PREAMBLE(); + bool success = DoIGetQuick<Primitive::kPrimByte>(shadow_frame, inst, inst_data); + POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx); + break; + } + case Instruction::IGET_CHAR_QUICK: { + PREAMBLE(); + bool success = DoIGetQuick<Primitive::kPrimChar>(shadow_frame, inst, inst_data); + POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx); + break; + } + case Instruction::IGET_SHORT_QUICK: { + PREAMBLE(); + bool success = DoIGetQuick<Primitive::kPrimShort>(shadow_frame, inst, inst_data); + POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx); + break; + } case Instruction::SGET_BOOLEAN: { PREAMBLE(); bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimBoolean, do_access_check>(self, shadow_frame, inst, inst_data); @@ -2137,7 +2161,7 @@ JValue ExecuteSwitchImpl(Thread* self, const DexFile::CodeItem* code_item, inst = inst->Next_2xx(); break; case Instruction::UNUSED_3E ... Instruction::UNUSED_43: - case Instruction::UNUSED_EF ... Instruction::UNUSED_FF: + case Instruction::UNUSED_F3 ... Instruction::UNUSED_FF: case Instruction::UNUSED_79: case Instruction::UNUSED_7A: UnexpectedOpcode(inst, shadow_frame); diff --git a/runtime/verifier/method_verifier.cc b/runtime/verifier/method_verifier.cc index c206b94..b2aede1 100644 --- a/runtime/verifier/method_verifier.cc +++ b/runtime/verifier/method_verifier.cc @@ -2705,6 +2705,18 @@ bool MethodVerifier::CodeFlowVerifyInstruction(uint32_t* start_guess) { case Instruction::IGET_OBJECT_QUICK: VerifyQuickFieldAccess<FieldAccessType::kAccGet>(inst, reg_types_.JavaLangObject(false), false); break; + case Instruction::IGET_BOOLEAN_QUICK: + VerifyQuickFieldAccess<FieldAccessType::kAccGet>(inst, reg_types_.Boolean(), true); + break; + case Instruction::IGET_BYTE_QUICK: + VerifyQuickFieldAccess<FieldAccessType::kAccGet>(inst, reg_types_.Byte(), true); + break; + case Instruction::IGET_CHAR_QUICK: + VerifyQuickFieldAccess<FieldAccessType::kAccGet>(inst, reg_types_.Char(), true); + break; + case Instruction::IGET_SHORT_QUICK: + VerifyQuickFieldAccess<FieldAccessType::kAccGet>(inst, reg_types_.Short(), true); + break; case Instruction::IPUT_QUICK: VerifyQuickFieldAccess<FieldAccessType::kAccPut>(inst, reg_types_.Integer(), true); break; @@ -2744,31 +2756,10 @@ bool MethodVerifier::CodeFlowVerifyInstruction(uint32_t* start_guess) { } /* These should never appear during verification. */ - case Instruction::UNUSED_3E: - case Instruction::UNUSED_3F: - case Instruction::UNUSED_40: - case Instruction::UNUSED_41: - case Instruction::UNUSED_42: - case Instruction::UNUSED_43: + case Instruction::UNUSED_3E ... Instruction::UNUSED_43: + case Instruction::UNUSED_F3 ... Instruction::UNUSED_FF: case Instruction::UNUSED_79: case Instruction::UNUSED_7A: - case Instruction::UNUSED_EF: - case Instruction::UNUSED_F0: - case Instruction::UNUSED_F1: - case Instruction::UNUSED_F2: - case Instruction::UNUSED_F3: - case Instruction::UNUSED_F4: - case Instruction::UNUSED_F5: - case Instruction::UNUSED_F6: - case Instruction::UNUSED_F7: - case Instruction::UNUSED_F8: - case Instruction::UNUSED_F9: - case Instruction::UNUSED_FA: - case Instruction::UNUSED_FB: - case Instruction::UNUSED_FC: - case Instruction::UNUSED_FD: - case Instruction::UNUSED_FE: - case Instruction::UNUSED_FF: Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "Unexpected opcode " << inst->DumpString(dex_file_); break; @@ -3909,6 +3900,10 @@ mirror::ArtField* MethodVerifier::GetQuickFieldAccess(const Instruction* inst, DCHECK(inst->Opcode() == Instruction::IGET_QUICK || inst->Opcode() == Instruction::IGET_WIDE_QUICK || inst->Opcode() == Instruction::IGET_OBJECT_QUICK || + inst->Opcode() == Instruction::IGET_BOOLEAN_QUICK || + inst->Opcode() == Instruction::IGET_BYTE_QUICK || + inst->Opcode() == Instruction::IGET_CHAR_QUICK || + inst->Opcode() == Instruction::IGET_SHORT_QUICK || inst->Opcode() == Instruction::IPUT_QUICK || inst->Opcode() == Instruction::IPUT_WIDE_QUICK || inst->Opcode() == Instruction::IPUT_OBJECT_QUICK || |