summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMathieu Chartier <mathieuc@google.com>2014-12-10 10:35:44 -0800
committerMathieu Chartier <mathieuc@google.com>2014-12-10 11:45:44 -0800
commitffc605cd817e79d6c7602a87543bb31f24d3a99f (patch)
tree84e4e68b11fe2d9c8c2e901b858026c1ebe88973
parentb1a38e246cfbfb21100d9c9e57f33970e824f075 (diff)
downloadart-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.cc16
-rw-r--r--compiler/dex/quick/quick_compiler.cc8
-rw-r--r--runtime/common_throws.cc4
-rw-r--r--runtime/dex_instruction_list.h8
-rw-r--r--runtime/interpreter/interpreter_common.cc22
-rw-r--r--runtime/interpreter/interpreter_goto_table_impl.cc40
-rw-r--r--runtime/interpreter/interpreter_switch_impl.cc26
-rw-r--r--runtime/verifier/method_verifier.cc41
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 ||