diff options
author | Sebastien Hertz <shertz@google.com> | 2013-06-05 12:29:44 +0000 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2013-06-05 12:29:44 +0000 |
commit | 1b1e8da7287e199533bf63d72f16fdff99fe7f8e (patch) | |
tree | bc212f567422d957895a64911a59f395d638c24b | |
parent | 980d16b81f3dd78eb491b80bed9cd184016878c6 (diff) | |
parent | 92c607f614484ed091cfb1f73fab5c736eed78de (diff) | |
download | android_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.h | 7 | ||||
-rw-r--r-- | src/dex_instruction.h | 38 | ||||
-rw-r--r-- | src/interpreter/interpreter.cc | 56 |
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(); |