From: Mathieu Chartier Date: Wed, 10 Dec 2014 18:35:44 +0000 (-0800) Subject: Add missing iget quick for bool, byte, char, short X-Git-Tag: android-x86-7.1-r1~889^2~2371^2 X-Git-Url: http://git.osdn.net/view?a=commitdiff_plain;h=ffc605cd817e79d6c7602a87543bb31f24d3a99f;p=android-x86%2Fart.git Add missing iget quick for bool, byte, char, short Bug: 17791557 Bug: 17671806 Change-Id: Ifac4fbfba6c3a3f97131e85914b24756fb7f9722 --- diff --git a/compiler/dex/dex_to_dex_compiler.cc b/compiler/dex/dex_to_dex_compiler.cc index 205a5218f..f7968c225 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 8d4cb3c5e..fb098c397 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 846216c52..f5b435400 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 05214a460..a90f42432 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 3c7db8539..2a63456c0 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(obj->GetField32(field_offset))); break; + case Primitive::kPrimBoolean: + shadow_frame.SetVReg(vregA, static_cast(obj->GetFieldBoolean(field_offset))); + break; + case Primitive::kPrimByte: + shadow_frame.SetVReg(vregA, static_cast(obj->GetFieldByte(field_offset))); + break; + case Primitive::kPrimChar: + shadow_frame.SetVReg(vregA, static_cast(obj->GetFieldChar(field_offset))); + break; + case Primitive::kPrimShort: + shadow_frame.SetVReg(vregA, static_cast(obj->GetFieldShort(field_offset))); + break; case Primitive::kPrimLong: shadow_frame.SetVRegLong(vregA, static_cast(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 diff --git a/runtime/interpreter/interpreter_goto_table_impl.cc b/runtime/interpreter/interpreter_goto_table_impl.cc index c332a7b59..c6102633b 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(shadow_frame, inst, inst_data); + POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2); + } + HANDLE_INSTRUCTION_END(); + + HANDLE_INSTRUCTION_START(IGET_BYTE_QUICK) { + bool success = DoIGetQuick(shadow_frame, inst, inst_data); + POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2); + } + HANDLE_INSTRUCTION_END(); + + HANDLE_INSTRUCTION_START(IGET_CHAR_QUICK) { + bool success = DoIGetQuick(shadow_frame, inst, inst_data); + POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2); + } + HANDLE_INSTRUCTION_END(); + + HANDLE_INSTRUCTION_START(IGET_SHORT_QUICK) { + bool success = DoIGetQuick(shadow_frame, inst, inst_data); + POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2); + } + HANDLE_INSTRUCTION_END(); + HANDLE_INSTRUCTION_START(IGET_WIDE_QUICK) { bool success = DoIGetQuick(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 f9bbfa17b..8bbc69481 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(shadow_frame, inst, inst_data); + POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx); + break; + } + case Instruction::IGET_BYTE_QUICK: { + PREAMBLE(); + bool success = DoIGetQuick(shadow_frame, inst, inst_data); + POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx); + break; + } + case Instruction::IGET_CHAR_QUICK: { + PREAMBLE(); + bool success = DoIGetQuick(shadow_frame, inst, inst_data); + POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx); + break; + } + case Instruction::IGET_SHORT_QUICK: { + PREAMBLE(); + bool success = DoIGetQuick(shadow_frame, inst, inst_data); + POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx); + break; + } case Instruction::SGET_BOOLEAN: { PREAMBLE(); bool success = DoFieldGet(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 c206b94ec..b2aede1cc 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(inst, reg_types_.JavaLangObject(false), false); break; + case Instruction::IGET_BOOLEAN_QUICK: + VerifyQuickFieldAccess(inst, reg_types_.Boolean(), true); + break; + case Instruction::IGET_BYTE_QUICK: + VerifyQuickFieldAccess(inst, reg_types_.Byte(), true); + break; + case Instruction::IGET_CHAR_QUICK: + VerifyQuickFieldAccess(inst, reg_types_.Char(), true); + break; + case Instruction::IGET_SHORT_QUICK: + VerifyQuickFieldAccess(inst, reg_types_.Short(), true); + break; case Instruction::IPUT_QUICK: VerifyQuickFieldAccess(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 ||