summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSebastien Hertz <shertz@google.com>2013-06-05 12:29:44 +0000
committerAndroid (Google) Code Review <android-gerrit@google.com>2013-06-05 12:29:44 +0000
commit1b1e8da7287e199533bf63d72f16fdff99fe7f8e (patch)
treebc212f567422d957895a64911a59f395d638c24b
parent980d16b81f3dd78eb491b80bed9cd184016878c6 (diff)
parent92c607f614484ed091cfb1f73fab5c736eed78de (diff)
downloadandroid_art-1b1e8da7287e199533bf63d72f16fdff99fe7f8e.tar.gz
android_art-1b1e8da7287e199533bf63d72f16fdff99fe7f8e.tar.bz2
android_art-1b1e8da7287e199533bf63d72f16fdff99fe7f8e.zip
Merge "Optimize branch instructions in interpreter." into dalvik-dev
-rw-r--r--src/dex_instruction-inl.h7
-rw-r--r--src/dex_instruction.h38
-rw-r--r--src/interpreter/interpreter.cc56
3 files changed, 47 insertions, 54 deletions
diff --git a/src/dex_instruction-inl.h b/src/dex_instruction-inl.h
index 519b3cf859..b426e66a1c 100644
--- a/src/dex_instruction-inl.h
+++ b/src/dex_instruction-inl.h
@@ -21,13 +21,6 @@
namespace art {
-inline const Instruction* Instruction::Next_51l() const {
- DCHECK_EQ(FormatOf(Opcode()), k51l);
- size_t current_size_in_bytes = 5 * sizeof(uint16_t);
- const uint8_t* ptr = reinterpret_cast<const uint8_t*>(this);
- return reinterpret_cast<const Instruction*>(ptr + current_size_in_bytes);
-}
-
//------------------------------------------------------------------------------
// VRegA
//------------------------------------------------------------------------------
diff --git a/src/dex_instruction.h b/src/dex_instruction.h
index ae469d0fe3..adaada7f87 100644
--- a/src/dex_instruction.h
+++ b/src/dex_instruction.h
@@ -162,39 +162,45 @@ class Instruction {
}
}
+ // Reads an instruction out of the stream at the specified address.
+ static const Instruction* At(const uint16_t* code) {
+ DCHECK(code != NULL);
+ return reinterpret_cast<const Instruction*>(code);
+ }
+
+ // Reads an instruction out of the stream from the current address plus an offset.
+ const Instruction* RelativeAt(int32_t offset) const {
+ return At(reinterpret_cast<const uint16_t*>(this) + offset);
+ }
+
// Returns a pointer to the next instruction in the stream.
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);
+ return RelativeAt(SizeInCodeUnits());
}
// Returns a pointer to the instruction after this 1xx instruction in the stream.
const Instruction* Next_1xx() const {
DCHECK(FormatOf(Opcode()) >= k10x && FormatOf(Opcode()) <= k10t);
- size_t current_size_in_bytes = 1 * sizeof(uint16_t);
- const uint8_t* ptr = reinterpret_cast<const uint8_t*>(this);
- return reinterpret_cast<const Instruction*>(ptr + current_size_in_bytes);
+ return RelativeAt(1);
}
// Returns a pointer to the instruction after this 2xx instruction in the stream.
const Instruction* Next_2xx() const {
DCHECK(FormatOf(Opcode()) >= k20t && FormatOf(Opcode()) <= k22c);
- size_t current_size_in_bytes = 2 * sizeof(uint16_t);
- const uint8_t* ptr = reinterpret_cast<const uint8_t*>(this);
- return reinterpret_cast<const Instruction*>(ptr + current_size_in_bytes);
+ return RelativeAt(2);
}
// Returns a pointer to the instruction after this 3xx instruction in the stream.
const Instruction* Next_3xx() const {
DCHECK(FormatOf(Opcode()) >= k32x && FormatOf(Opcode()) <= k3rc);
- size_t current_size_in_bytes = 3 * sizeof(uint16_t);
- const uint8_t* ptr = reinterpret_cast<const uint8_t*>(this);
- return reinterpret_cast<const Instruction*>(ptr + current_size_in_bytes);
+ return RelativeAt(3);
}
// Returns a pointer to the instruction after this 51l instruction in the stream.
- const Instruction* Next_51l() const;
+ const Instruction* Next_51l() const {
+ DCHECK(FormatOf(Opcode()) == k51l);
+ return RelativeAt(5);
+ }
// Returns the name of this instruction's opcode.
const char* Name() const {
@@ -272,12 +278,6 @@ class Instruction {
return static_cast<Code>(opcode);
}
- // Reads an instruction out of the stream at the specified address.
- static const Instruction* At(const uint16_t* code) {
- CHECK(code != NULL);
- return reinterpret_cast<const Instruction*>(code);
- }
-
// Returns the format of the given opcode.
static Format FormatOf(Code opcode) {
return kInstructionFormats[opcode];
diff --git a/src/interpreter/interpreter.cc b/src/interpreter/interpreter.cc
index 2e87dfdd98..705e265090 100644
--- a/src/interpreter/interpreter.cc
+++ b/src/interpreter/interpreter.cc
@@ -1202,22 +1202,22 @@ static JValue Execute(Thread* self, MethodHelper& mh, const DexFile::CodeItem* c
}
case Instruction::GOTO: {
PREAMBLE();
- inst = Instruction::At(insns + inst->GetDexPc(insns) + inst->VRegA_10t());
+ inst = inst->RelativeAt(inst->VRegA_10t());
break;
}
case Instruction::GOTO_16: {
PREAMBLE();
- inst = Instruction::At(insns + inst->GetDexPc(insns) + inst->VRegA_20t());
+ inst = inst->RelativeAt(inst->VRegA_20t());
break;
}
case Instruction::GOTO_32: {
PREAMBLE();
- inst = Instruction::At(insns + inst->GetDexPc(insns) + inst->VRegA_30t());
+ inst = inst->RelativeAt(inst->VRegA_30t());
break;
}
case Instruction::PACKED_SWITCH: {
PREAMBLE();
- const uint16_t* switch_data = insns + inst->GetDexPc(insns) + inst->VRegB_31t();
+ const uint16_t* switch_data = reinterpret_cast<const uint16_t*>(inst) + inst->VRegB_31t();
int32_t test_val = shadow_frame.GetVReg(inst->VRegA_31t());
DCHECK_EQ(switch_data[0], static_cast<uint16_t>(Instruction::kPackedSwitchSignature));
uint16_t size = switch_data[1];
@@ -1229,7 +1229,7 @@ static JValue Execute(Thread* self, MethodHelper& mh, const DexFile::CodeItem* c
DCHECK(IsAligned<4>(targets));
int32_t index = test_val - first_key;
if (index >= 0 && index < size) {
- inst = Instruction::At(insns + inst->GetDexPc(insns) + targets[index]);
+ inst = inst->RelativeAt(targets[index]);
} else {
inst = inst->Next_3xx();
}
@@ -1237,8 +1237,7 @@ static JValue Execute(Thread* self, MethodHelper& mh, const DexFile::CodeItem* c
}
case Instruction::SPARSE_SWITCH: {
PREAMBLE();
- uint32_t dex_pc = inst->GetDexPc(insns);
- const uint16_t* switch_data = insns + dex_pc + inst->VRegB_31t();
+ const uint16_t* switch_data = reinterpret_cast<const uint16_t*>(inst) + inst->VRegB_31t();
int32_t test_val = shadow_frame.GetVReg(inst->VRegA_31t());
CHECK_EQ(switch_data[0], static_cast<uint16_t>(Instruction::kSparseSwitchSignature));
uint16_t size = switch_data[1];
@@ -1249,6 +1248,7 @@ static JValue Execute(Thread* self, MethodHelper& mh, const DexFile::CodeItem* c
CHECK(IsAligned<4>(entries));
int lo = 0;
int hi = size - 1;
+ const Instruction* current_inst = inst;
inst = inst->Next_3xx();
while (lo <= hi) {
int mid = (lo + hi) / 2;
@@ -1258,7 +1258,7 @@ static JValue Execute(Thread* self, MethodHelper& mh, const DexFile::CodeItem* c
} else if (test_val > foundVal) {
lo = mid + 1;
} else {
- inst = Instruction::At(insns + dex_pc + entries[mid]);
+ inst = current_inst->RelativeAt(entries[mid]);
break;
}
}
@@ -1348,7 +1348,7 @@ static JValue Execute(Thread* self, MethodHelper& mh, const DexFile::CodeItem* c
case Instruction::IF_EQ: {
PREAMBLE();
if (shadow_frame.GetVReg(inst->VRegA_22t()) == shadow_frame.GetVReg(inst->VRegB_22t())) {
- inst = Instruction::At(insns + inst->GetDexPc(insns) + inst->VRegC_22t());
+ inst = inst->RelativeAt(inst->VRegC_22t());
} else {
inst = inst->Next_2xx();
}
@@ -1357,7 +1357,7 @@ static JValue Execute(Thread* self, MethodHelper& mh, const DexFile::CodeItem* c
case Instruction::IF_NE: {
PREAMBLE();
if (shadow_frame.GetVReg(inst->VRegA_22t()) != shadow_frame.GetVReg(inst->VRegB_22t())) {
- inst = Instruction::At(insns + inst->GetDexPc(insns) + inst->VRegC_22t());
+ inst = inst->RelativeAt(inst->VRegC_22t());
} else {
inst = inst->Next_2xx();
}
@@ -1366,7 +1366,7 @@ static JValue Execute(Thread* self, MethodHelper& mh, const DexFile::CodeItem* c
case Instruction::IF_LT: {
PREAMBLE();
if (shadow_frame.GetVReg(inst->VRegA_22t()) < shadow_frame.GetVReg(inst->VRegB_22t())) {
- inst = Instruction::At(insns + inst->GetDexPc(insns) + inst->VRegC_22t());
+ inst = inst->RelativeAt(inst->VRegC_22t());
} else {
inst = inst->Next_2xx();
}
@@ -1375,7 +1375,7 @@ static JValue Execute(Thread* self, MethodHelper& mh, const DexFile::CodeItem* c
case Instruction::IF_GE: {
PREAMBLE();
if (shadow_frame.GetVReg(inst->VRegA_22t()) >= shadow_frame.GetVReg(inst->VRegB_22t())) {
- inst = Instruction::At(insns + inst->GetDexPc(insns) + inst->VRegC_22t());
+ inst = inst->RelativeAt(inst->VRegC_22t());
} else {
inst = inst->Next_2xx();
}
@@ -1384,7 +1384,7 @@ static JValue Execute(Thread* self, MethodHelper& mh, const DexFile::CodeItem* c
case Instruction::IF_GT: {
PREAMBLE();
if (shadow_frame.GetVReg(inst->VRegA_22t()) > shadow_frame.GetVReg(inst->VRegB_22t())) {
- inst = Instruction::At(insns + inst->GetDexPc(insns) + inst->VRegC_22t());
+ inst = inst->RelativeAt(inst->VRegC_22t());
} else {
inst = inst->Next_2xx();
}
@@ -1393,7 +1393,7 @@ static JValue Execute(Thread* self, MethodHelper& mh, const DexFile::CodeItem* c
case Instruction::IF_LE: {
PREAMBLE();
if (shadow_frame.GetVReg(inst->VRegA_22t()) <= shadow_frame.GetVReg(inst->VRegB_22t())) {
- inst = Instruction::At(insns + inst->GetDexPc(insns) + inst->VRegC_22t());
+ inst = inst->RelativeAt(inst->VRegC_22t());
} else {
inst = inst->Next_2xx();
}
@@ -1402,7 +1402,7 @@ static JValue Execute(Thread* self, MethodHelper& mh, const DexFile::CodeItem* c
case Instruction::IF_EQZ: {
PREAMBLE();
if (shadow_frame.GetVReg(inst->VRegA_21t()) == 0) {
- inst = Instruction::At(insns + inst->GetDexPc(insns) + inst->VRegB_21t());
+ inst = inst->RelativeAt(inst->VRegB_21t());
} else {
inst = inst->Next_2xx();
}
@@ -1411,7 +1411,7 @@ static JValue Execute(Thread* self, MethodHelper& mh, const DexFile::CodeItem* c
case Instruction::IF_NEZ: {
PREAMBLE();
if (shadow_frame.GetVReg(inst->VRegA_21t()) != 0) {
- inst = Instruction::At(insns + inst->GetDexPc(insns) + inst->VRegB_21t());
+ inst = inst->RelativeAt(inst->VRegB_21t());
} else {
inst = inst->Next_2xx();
}
@@ -1420,7 +1420,7 @@ static JValue Execute(Thread* self, MethodHelper& mh, const DexFile::CodeItem* c
case Instruction::IF_LTZ: {
PREAMBLE();
if (shadow_frame.GetVReg(inst->VRegA_21t()) < 0) {
- inst = Instruction::At(insns + inst->GetDexPc(insns) + inst->VRegB_21t());
+ inst = inst->RelativeAt(inst->VRegB_21t());
} else {
inst = inst->Next_2xx();
}
@@ -1429,7 +1429,7 @@ static JValue Execute(Thread* self, MethodHelper& mh, const DexFile::CodeItem* c
case Instruction::IF_GEZ: {
PREAMBLE();
if (shadow_frame.GetVReg(inst->VRegA_21t()) >= 0) {
- inst = Instruction::At(insns + inst->GetDexPc(insns) + inst->VRegB_21t());
+ inst = inst->RelativeAt(inst->VRegB_21t());
} else {
inst = inst->Next_2xx();
}
@@ -1438,7 +1438,7 @@ static JValue Execute(Thread* self, MethodHelper& mh, const DexFile::CodeItem* c
case Instruction::IF_GTZ: {
PREAMBLE();
if (shadow_frame.GetVReg(inst->VRegA_21t()) > 0) {
- inst = Instruction::At(insns + inst->GetDexPc(insns) + inst->VRegB_21t());
+ inst = inst->RelativeAt(inst->VRegB_21t());
} else {
inst = inst->Next_2xx();
}
@@ -1447,7 +1447,7 @@ static JValue Execute(Thread* self, MethodHelper& mh, const DexFile::CodeItem* c
case Instruction::IF_LEZ: {
PREAMBLE();
if (shadow_frame.GetVReg(inst->VRegA_21t()) <= 0) {
- inst = Instruction::At(insns + inst->GetDexPc(insns) + inst->VRegB_21t());
+ inst = inst->RelativeAt(inst->VRegB_21t());
} else {
inst = inst->Next_2xx();
}
@@ -2305,6 +2305,14 @@ static JValue Execute(Thread* self, MethodHelper& mh, const DexFile::CodeItem* c
inst = inst->Next_1xx();
break;
}
+ case Instruction::DIV_INT_2ADDR: {
+ PREAMBLE();
+ uint32_t vregA = inst->VRegA_12x();
+ DoIntDivide(self, shadow_frame, vregA, shadow_frame.GetVReg(vregA),
+ shadow_frame.GetVReg(inst->VRegB_12x()));
+ inst = inst->Next_1xx();
+ break;
+ }
case Instruction::REM_INT_2ADDR: {
PREAMBLE();
uint32_t vregA = inst->VRegA_12x();
@@ -2367,14 +2375,6 @@ static JValue Execute(Thread* self, MethodHelper& mh, const DexFile::CodeItem* c
inst = inst->Next_1xx();
break;
}
- case Instruction::DIV_INT_2ADDR: {
- PREAMBLE();
- uint32_t vregA = inst->VRegA_12x();
- DoIntDivide(self, shadow_frame, vregA, shadow_frame.GetVReg(vregA),
- shadow_frame.GetVReg(inst->VRegB_12x()));
- inst = inst->Next_1xx();
- break;
- }
case Instruction::ADD_LONG_2ADDR: {
PREAMBLE();
uint32_t vregA = inst->VRegA_12x();