Improve interpreter performance.
Bug: 8196227
This CL removes the use of DecodedInstruction to read instruction opcode and
operands. It now directly access to each operand according to instruction
format (like VRegA_11x for accessing register vA with format 11x).
It also caches some information used for instrumentation like 'this' object
and current method and add missing check about pending exception.
Change-Id: I8c03c0aea9d75068b89e3cb2c8c12383d7928281
diff --git a/src/dex_instruction-inl.h b/src/dex_instruction-inl.h
new file mode 100644
index 0000000..66fbd29
--- /dev/null
+++ b/src/dex_instruction-inl.h
@@ -0,0 +1,317 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ART_SRC_DEX_INSTRUCTION_INL_H_
+#define ART_SRC_DEX_INSTRUCTION_INL_H_
+
+#include "dex_instruction.h"
+
+namespace art {
+
+//------------------------------------------------------------------------------
+// VRegA
+//------------------------------------------------------------------------------
+inline int8_t Instruction::VRegA_10t() const {
+ DCHECK_EQ(FormatOf(Opcode()), k10t);
+ return static_cast<int8_t>(InstAA());
+}
+
+inline uint4_t Instruction::VRegA_11n() const {
+ DCHECK_EQ(FormatOf(Opcode()), k11n);
+ return InstA();
+}
+
+inline uint8_t Instruction::VRegA_11x() const {
+ DCHECK_EQ(FormatOf(Opcode()), k11x);
+ return InstAA();
+}
+
+inline uint4_t Instruction::VRegA_12x() const {
+ DCHECK_EQ(FormatOf(Opcode()), k12x);
+ return InstA();
+}
+
+inline int16_t Instruction::VRegA_20t() const {
+ DCHECK_EQ(FormatOf(Opcode()), k20t);
+ return static_cast<int16_t>(Fetch16(1));
+}
+
+inline uint8_t Instruction::VRegA_21c() const {
+ DCHECK_EQ(FormatOf(Opcode()), k21c);
+ return InstAA();
+}
+
+inline uint8_t Instruction::VRegA_21h() const {
+ DCHECK_EQ(FormatOf(Opcode()), k21h);
+ return InstAA();
+}
+
+inline uint8_t Instruction::VRegA_21s() const {
+ DCHECK_EQ(FormatOf(Opcode()), k21s);
+ return InstAA();
+}
+
+inline uint8_t Instruction::VRegA_21t() const {
+ DCHECK_EQ(FormatOf(Opcode()), k21t);
+ return InstAA();
+}
+
+inline uint8_t Instruction::VRegA_22b() const {
+ DCHECK_EQ(FormatOf(Opcode()), k22b);
+ return InstAA();
+}
+
+inline uint4_t Instruction::VRegA_22c() const {
+ DCHECK_EQ(FormatOf(Opcode()), k22c);
+ return InstA();
+}
+
+inline uint4_t Instruction::VRegA_22s() const {
+ DCHECK_EQ(FormatOf(Opcode()), k22s);
+ return InstA();
+}
+
+inline uint4_t Instruction::VRegA_22t() const {
+ DCHECK_EQ(FormatOf(Opcode()), k22t);
+ return InstA();
+}
+
+inline uint8_t Instruction::VRegA_22x() const {
+ DCHECK_EQ(FormatOf(Opcode()), k22x);
+ return InstAA();
+}
+
+inline uint8_t Instruction::VRegA_23x() const {
+ DCHECK_EQ(FormatOf(Opcode()), k23x);
+ return InstAA();
+}
+
+inline int32_t Instruction::VRegA_30t() const {
+ DCHECK_EQ(FormatOf(Opcode()), k30t);
+ return static_cast<int32_t>(Fetch32(1));
+}
+
+inline uint8_t Instruction::VRegA_31c() const {
+ DCHECK_EQ(FormatOf(Opcode()), k31c);
+ return InstAA();
+}
+
+inline uint8_t Instruction::VRegA_31i() const {
+ DCHECK_EQ(FormatOf(Opcode()), k31i);
+ return InstAA();
+}
+
+inline uint8_t Instruction::VRegA_31t() const {
+ DCHECK_EQ(FormatOf(Opcode()), k31t);
+ return InstAA();
+}
+
+inline uint16_t Instruction::VRegA_32x() const {
+ DCHECK_EQ(FormatOf(Opcode()), k32x);
+ return Fetch16(1);
+}
+
+inline uint4_t Instruction::VRegA_35c() const {
+ DCHECK_EQ(FormatOf(Opcode()), k35c);
+ return InstB(); // This is labeled A in the spec.
+}
+
+inline uint8_t Instruction::VRegA_3rc() const {
+ DCHECK_EQ(FormatOf(Opcode()), k3rc);
+ return InstAA();
+}
+
+inline uint8_t Instruction::VRegA_51l() const {
+ DCHECK_EQ(FormatOf(Opcode()), k51l);
+ return InstAA();
+}
+
+//------------------------------------------------------------------------------
+// VRegB
+//------------------------------------------------------------------------------
+inline int4_t Instruction::VRegB_11n() const {
+ DCHECK_EQ(FormatOf(Opcode()), k11n);
+ return static_cast<int4_t>((InstB() << 28) >> 28);
+}
+
+inline uint4_t Instruction::VRegB_12x() const {
+ DCHECK_EQ(FormatOf(Opcode()), k12x);
+ return InstB();
+}
+
+inline uint16_t Instruction::VRegB_21c() const {
+ DCHECK_EQ(FormatOf(Opcode()), k21c);
+ return Fetch16(1);
+}
+
+inline uint16_t Instruction::VRegB_21h() const {
+ DCHECK_EQ(FormatOf(Opcode()), k21h);
+ return Fetch16(1);
+}
+
+inline int16_t Instruction::VRegB_21s() const {
+ DCHECK_EQ(FormatOf(Opcode()), k21s);
+ return static_cast<int16_t>(Fetch16(1));
+}
+
+inline int16_t Instruction::VRegB_21t() const {
+ DCHECK_EQ(FormatOf(Opcode()), k21t);
+ return static_cast<int16_t>(Fetch16(1));
+}
+
+inline uint8_t Instruction::VRegB_22b() const {
+ DCHECK_EQ(FormatOf(Opcode()), k22b);
+ return static_cast<uint8_t>(Fetch16(1) & 0xff);
+}
+
+inline uint4_t Instruction::VRegB_22c() const {
+ DCHECK_EQ(FormatOf(Opcode()), k22c);
+ return InstB();
+}
+
+inline uint4_t Instruction::VRegB_22s() const {
+ DCHECK_EQ(FormatOf(Opcode()), k22s);
+ return InstB();
+}
+
+inline uint4_t Instruction::VRegB_22t() const {
+ DCHECK_EQ(FormatOf(Opcode()), k22t);
+ return InstB();
+}
+
+inline uint16_t Instruction::VRegB_22x() const {
+ DCHECK_EQ(FormatOf(Opcode()), k22x);
+ return Fetch16(1);
+}
+
+inline uint8_t Instruction::VRegB_23x() const {
+ DCHECK_EQ(FormatOf(Opcode()), k23x);
+ return static_cast<uint8_t>(Fetch16(1) & 0xff);
+}
+
+inline uint32_t Instruction::VRegB_31c() const {
+ DCHECK_EQ(FormatOf(Opcode()), k31c);
+ return Fetch32(1);
+}
+
+inline int32_t Instruction::VRegB_31i() const {
+ DCHECK_EQ(FormatOf(Opcode()), k31i);
+ return static_cast<int32_t>(Fetch32(1));
+}
+
+inline int32_t Instruction::VRegB_31t() const {
+ DCHECK_EQ(FormatOf(Opcode()), k31t);
+ return static_cast<int32_t>(Fetch32(1));
+}
+
+inline uint16_t Instruction::VRegB_32x() const {
+ DCHECK_EQ(FormatOf(Opcode()), k32x);
+ return Fetch16(2);
+}
+
+inline uint16_t Instruction::VRegB_35c() const {
+ DCHECK_EQ(FormatOf(Opcode()), k35c);
+ return Fetch16(1);
+}
+
+inline uint16_t Instruction::VRegB_3rc() const {
+ DCHECK_EQ(FormatOf(Opcode()), k3rc);
+ return Fetch16(1);
+}
+
+inline uint64_t Instruction::VRegB_51l() const {
+ DCHECK_EQ(FormatOf(Opcode()), k51l);
+ uint64_t vB_wide = Fetch32(1) | ((uint64_t) Fetch32(3) << 32);
+ return vB_wide;
+}
+
+//------------------------------------------------------------------------------
+// VRegC
+//------------------------------------------------------------------------------
+inline int8_t Instruction::VRegC_22b() const {
+ DCHECK_EQ(FormatOf(Opcode()), k22b);
+ return static_cast<int8_t>(Fetch16(1) >> 8);
+}
+
+inline uint16_t Instruction::VRegC_22c() const {
+ DCHECK_EQ(FormatOf(Opcode()), k22c);
+ return Fetch16(1);
+}
+
+inline int16_t Instruction::VRegC_22s() const {
+ DCHECK_EQ(FormatOf(Opcode()), k22s);
+ return static_cast<int16_t>(Fetch16(1));
+}
+
+inline int16_t Instruction::VRegC_22t() const {
+ DCHECK_EQ(FormatOf(Opcode()), k22t);
+ return static_cast<int16_t>(Fetch16(1));
+}
+
+inline uint8_t Instruction::VRegC_23x() const {
+ DCHECK_EQ(FormatOf(Opcode()), k23x);
+ return static_cast<uint8_t>(Fetch16(1) >> 8);
+}
+
+inline uint4_t Instruction::VRegC_35c() const {
+ DCHECK_EQ(FormatOf(Opcode()), k35c);
+ return static_cast<uint4_t>(Fetch16(2) & 0x0f);
+}
+
+inline uint16_t Instruction::VRegC_3rc() const {
+ DCHECK_EQ(FormatOf(Opcode()), k3rc);
+ return Fetch16(2);
+}
+
+inline void Instruction::GetArgs(uint32_t arg[5]) const {
+ DCHECK_EQ(FormatOf(Opcode()), k35c);
+
+ /*
+ * Note that the fields mentioned in the spec don't appear in
+ * their "usual" positions here compared to most formats. This
+ * was done so that the field names for the argument count and
+ * reference index match between this format and the corresponding
+ * range formats (3rc and friends).
+ *
+ * Bottom line: The argument count is always in vA, and the
+ * method constant (or equivalent) is always in vB.
+ */
+ uint16_t regList = Fetch16(2);
+ uint4_t count = InstB(); // This is labeled A in the spec.
+
+ /*
+ * Copy the argument registers into the arg[] array, and
+ * also copy the first argument (if any) into vC. (The
+ * DecodedInstruction structure doesn't have separate
+ * fields for {vD, vE, vF, vG}, so there's no need to make
+ * copies of those.) Note that cases 5..2 fall through.
+ */
+ switch (count) {
+ case 5: arg[4] = InstA();
+ case 4: arg[3] = (regList >> 12) & 0x0f;
+ case 3: arg[2] = (regList >> 8) & 0x0f;
+ case 2: arg[1] = (regList >> 4) & 0x0f;
+ case 1: arg[0] = regList & 0x0f; break;
+ case 0: break; // Valid, but no need to do anything.
+ default:
+ LOG(ERROR) << "Invalid arg count in 35c (" << count << ")";
+ return;
+ }
+}
+
+} // namespace art
+
+#endif // ART_SRC_DEX_INSTRUCTION_INL_H_
diff --git a/src/dex_instruction.cc b/src/dex_instruction.cc
index 3224d77..414e78f 100644
--- a/src/dex_instruction.cc
+++ b/src/dex_instruction.cc
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-#include "dex_instruction.h"
+#include "dex_instruction-inl.h"
#include "dex_file-inl.h"
#include "utils.h"
@@ -72,13 +72,13 @@
* Handy macros for helping decode instructions.
*/
#define FETCH(_offset) (insns[(_offset)])
-#define FETCH_u4(_offset) (fetch_u4_impl((_offset), insns))
+#define FETCH_uint32(_offset) (fetch_uint32_impl((_offset), insns))
#define INST_A(_insn) (((uint16_t)(_insn) >> 8) & 0x0f)
#define INST_B(_insn) ((uint16_t)(_insn) >> 12)
#define INST_AA(_insn) ((_insn) >> 8)
-/* Helper for FETCH_u4, above. */
-static inline uint32_t fetch_u4_impl(uint32_t offset, const uint16_t* insns) {
+/* Helper for FETCH_uint32, above. */
+static inline uint32_t fetch_uint32_impl(uint32_t offset, const uint16_t* insns) {
return insns[offset] | ((uint32_t) insns[offset+1] << 16);
}
@@ -150,12 +150,12 @@
vC = FETCH(1);
break;
case k30t: // op +AAAAAAAA
- vA = FETCH_u4(1); // signed 32-bit value
+ vA = FETCH_uint32(1); // signed 32-bit value
break;
case k31t: // op vAA, +BBBBBBBB
case k31c: // op vAA, string@BBBBBBBB
vA = INST_AA(insn);
- vB = FETCH_u4(1); // 32-bit value
+ vB = FETCH_uint32(1); // 32-bit value
break;
case k32x: // op vAAAA, vBBBB
vA = FETCH(1);
@@ -163,7 +163,7 @@
break;
case k31i: // op vAA, #+BBBBBBBB
vA = INST_AA(insn);
- vB = FETCH_u4(1); // signed 32-bit value
+ vB = FETCH_uint32(1); // signed 32-bit value
break;
case k35c: // op {vC, vD, vE, vF, vG}, thing@BBBB
{
@@ -213,7 +213,7 @@
break;
case k51l: // op vAA, #+BBBBBBBBBBBBBBBB
vA = INST_AA(insn);
- vB_wide = FETCH_u4(1) | ((uint64_t) FETCH_u4(3) << 32);
+ vB_wide = FETCH_uint32(1) | ((uint64_t) FETCH_uint32(3) << 32);
break;
default:
LOG(ERROR) << "Can't decode unexpected format " << FormatOf(opcode) << " (op=" << opcode << ")";
diff --git a/src/dex_instruction.h b/src/dex_instruction.h
index 3921212..45c93ef 100644
--- a/src/dex_instruction.h
+++ b/src/dex_instruction.h
@@ -21,6 +21,9 @@
#include "base/macros.h"
#include "globals.h"
+typedef uint8_t uint4_t;
+typedef int8_t int4_t;
+
namespace art {
class DexFile;
@@ -176,6 +179,64 @@
return kInstructionNames[opcode];
}
+ // VRegA
+ int8_t VRegA_10t() const;
+ uint4_t VRegA_11n() const;
+ uint8_t VRegA_11x() const;
+ uint4_t VRegA_12x() const;
+ int16_t VRegA_20t() const;
+ uint8_t VRegA_21c() const;
+ uint8_t VRegA_21h() const;
+ uint8_t VRegA_21s() const;
+ uint8_t VRegA_21t() const;
+ uint8_t VRegA_22b() const;
+ uint4_t VRegA_22c() const;
+ uint4_t VRegA_22s() const;
+ uint4_t VRegA_22t() const;
+ uint8_t VRegA_22x() const;
+ uint8_t VRegA_23x() const;
+ int32_t VRegA_30t() const;
+ uint8_t VRegA_31c() const;
+ uint8_t VRegA_31i() const;
+ uint8_t VRegA_31t() const;
+ uint16_t VRegA_32x() const;
+ uint4_t VRegA_35c() const;
+ uint8_t VRegA_3rc() const;
+ uint8_t VRegA_51l() const;
+
+ // VRegB
+ int4_t VRegB_11n() const;
+ uint4_t VRegB_12x() const;
+ uint16_t VRegB_21c() const;
+ uint16_t VRegB_21h() const;
+ int16_t VRegB_21s() const;
+ int16_t VRegB_21t() const;
+ uint8_t VRegB_22b() const;
+ uint4_t VRegB_22c() const;
+ uint4_t VRegB_22s() const;
+ uint4_t VRegB_22t() const;
+ uint16_t VRegB_22x() const;
+ uint8_t VRegB_23x() const;
+ uint32_t VRegB_31c() const;
+ int32_t VRegB_31i() const;
+ int32_t VRegB_31t() const;
+ uint16_t VRegB_32x() const;
+ uint16_t VRegB_35c() const;
+ uint16_t VRegB_3rc() const;
+ uint64_t VRegB_51l() const; // vB_wide
+
+ // VRegC
+ int8_t VRegC_22b() const;
+ uint16_t VRegC_22c() const;
+ int16_t VRegC_22s() const;
+ int16_t VRegC_22t() const;
+ uint8_t VRegC_23x() const;
+ uint4_t VRegC_35c() const;
+ uint16_t VRegC_3rc() const;
+
+ // Fills the given array with the 'arg' array of the instruction.
+ void GetArgs(uint32_t args[5]) const;
+
// Returns the opcode field of the instruction.
Code Opcode() const {
const uint16_t* insns = reinterpret_cast<const uint16_t*>(this);
@@ -267,6 +328,27 @@
private:
size_t SizeInCodeUnitsComplexOpcode() const;
+ uint16_t Fetch16(size_t offset) const {
+ const uint16_t* insns = reinterpret_cast<const uint16_t*>(this);
+ return insns[offset];
+ }
+
+ uint32_t Fetch32(size_t offset) const {
+ return (Fetch16(offset) | ((uint32_t) Fetch16(offset + 1) << 16));
+ }
+
+ uint4_t InstA() const {
+ return static_cast<uint4_t>((Fetch16(0) >> 8) & 0x0f);
+ }
+
+ uint4_t InstB() const {
+ return static_cast<uint4_t>(Fetch16(0) >> 12);
+ }
+
+ uint8_t InstAA() const {
+ return static_cast<uint8_t>(Fetch16(0) >> 8);
+ }
+
static const char* const kInstructionNames[];
static Format const kInstructionFormats[];
static int const kInstructionFlags[];
diff --git a/src/interpreter/interpreter.cc b/src/interpreter/interpreter.cc
index 9f48e78..a3768c7 100644
--- a/src/interpreter/interpreter.cc
+++ b/src/interpreter/interpreter.cc
@@ -22,7 +22,7 @@
#include "class_linker-inl.h"
#include "common_throws.h"
#include "dex_file-inl.h"
-#include "dex_instruction.h"
+#include "dex_instruction-inl.h"
#include "gc/card_table-inl.h"
#include "invoke_arg_array_builder.h"
#include "nth_caller_visitor.h"
@@ -384,19 +384,20 @@
}
static void DoInvoke(Thread* self, MethodHelper& mh, ShadowFrame& shadow_frame,
- const DecodedInstruction& dec_insn, InvokeType type, bool is_range,
+ const Instruction* inst, InvokeType type, bool is_range,
JValue* result)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+ uint32_t vregC = (is_range) ? inst->VRegC_3rc() : inst->VRegC_35c();
Object* receiver;
if (type == kStatic) {
receiver = NULL;
} else {
- receiver = shadow_frame.GetVRegReference(dec_insn.vC);
+ receiver = shadow_frame.GetVRegReference(vregC);
}
- uint32_t method_idx = dec_insn.vB;
+ uint32_t method_idx = (is_range) ? inst->VRegB_3rc() : inst->VRegB_35c();
AbstractMethod* target_method = FindMethodFromCode(method_idx, receiver,
- shadow_frame.GetMethod(), self, true,
- type);
+ shadow_frame.GetMethod(),
+ self, true, type);
if (UNLIKELY(target_method == NULL)) {
CHECK(self->IsExceptionPending());
result->SetJ(0);
@@ -435,9 +436,13 @@
size_t arg_offset = (receiver == NULL) ? 0 : 1;
const char* shorty = mh.GetShorty();
+ uint32_t arg[5];
+ if (!is_range) {
+ inst->GetArgs(arg);
+ }
for (size_t shorty_pos = 0; cur_reg < num_regs; ++shorty_pos, cur_reg++, arg_offset++) {
DCHECK_LT(shorty_pos + 1, mh.GetShortyLength());
- size_t arg_pos = is_range ? dec_insn.vC + arg_offset : dec_insn.arg[arg_offset];
+ size_t arg_pos = is_range ? vregC + arg_offset : arg[arg_offset];
switch (shorty[shorty_pos + 1]) {
case 'L': {
Object* o = shadow_frame.GetVRegReference(arg_pos);
@@ -467,98 +472,117 @@
}
static void DoFieldGet(Thread* self, ShadowFrame& shadow_frame,
- const DecodedInstruction& dec_insn, FindFieldType find_type,
+ const Instruction* inst, FindFieldType find_type,
Primitive::Type field_type)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
bool is_static = (find_type == StaticObjectRead) || (find_type == StaticPrimitiveRead);
- uint32_t field_idx = is_static ? dec_insn.vB : dec_insn.vC;
+ uint32_t field_idx = is_static ? inst->VRegB_21c() : inst->VRegC_22c();
Field* f = FindFieldFromCode(field_idx, shadow_frame.GetMethod(), self,
find_type, Primitive::FieldSize(field_type));
- if (LIKELY(f != NULL)) {
- Object* obj;
- if (is_static) {
- obj = f->GetDeclaringClass();
- } else {
- obj = shadow_frame.GetVRegReference(dec_insn.vB);
- if (UNLIKELY(obj == NULL)) {
- ThrowNullPointerExceptionForFieldAccess(shadow_frame.GetCurrentLocationForThrow(), f, true);
- return;
- }
+ if (UNLIKELY(f == NULL)) {
+ CHECK(self->IsExceptionPending());
+ return;
+ }
+ Object* obj;
+ if (is_static) {
+ obj = f->GetDeclaringClass();
+ } else {
+ obj = shadow_frame.GetVRegReference(inst->VRegB_22c());
+ if (UNLIKELY(obj == NULL)) {
+ ThrowNullPointerExceptionForFieldAccess(shadow_frame.GetCurrentLocationForThrow(), f, true);
+ return;
}
- switch (field_type) {
- case Primitive::kPrimBoolean:
- shadow_frame.SetVReg(dec_insn.vA, f->GetBoolean(obj));
- break;
- case Primitive::kPrimByte:
- shadow_frame.SetVReg(dec_insn.vA, f->GetByte(obj));
- break;
- case Primitive::kPrimChar:
- shadow_frame.SetVReg(dec_insn.vA, f->GetChar(obj));
- break;
- case Primitive::kPrimShort:
- shadow_frame.SetVReg(dec_insn.vA, f->GetShort(obj));
- break;
- case Primitive::kPrimInt:
- shadow_frame.SetVReg(dec_insn.vA, f->GetInt(obj));
- break;
- case Primitive::kPrimLong:
- shadow_frame.SetVRegLong(dec_insn.vA, f->GetLong(obj));
- break;
- case Primitive::kPrimNot:
- shadow_frame.SetVRegReference(dec_insn.vA, f->GetObject(obj));
- break;
- default:
- LOG(FATAL) << "Unreachable: " << field_type;
- }
+ }
+ uint32_t vregA = is_static ? inst->VRegA_21c() : inst->VRegA_22c();
+ switch (field_type) {
+ case Primitive::kPrimBoolean:
+ shadow_frame.SetVReg(vregA, f->GetBoolean(obj));
+ break;
+ case Primitive::kPrimByte:
+ shadow_frame.SetVReg(vregA, f->GetByte(obj));
+ break;
+ case Primitive::kPrimChar:
+ shadow_frame.SetVReg(vregA, f->GetChar(obj));
+ break;
+ case Primitive::kPrimShort:
+ shadow_frame.SetVReg(vregA, f->GetShort(obj));
+ break;
+ case Primitive::kPrimInt:
+ shadow_frame.SetVReg(vregA, f->GetInt(obj));
+ break;
+ case Primitive::kPrimLong:
+ shadow_frame.SetVRegLong(vregA, f->GetLong(obj));
+ break;
+ case Primitive::kPrimNot:
+ shadow_frame.SetVRegReference(vregA, f->GetObject(obj));
+ break;
+ default:
+ LOG(FATAL) << "Unreachable: " << field_type;
}
}
static void DoFieldPut(Thread* self, ShadowFrame& shadow_frame,
- const DecodedInstruction& dec_insn, FindFieldType find_type,
+ const Instruction* inst, FindFieldType find_type,
Primitive::Type field_type)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
bool is_static = (find_type == StaticObjectWrite) || (find_type == StaticPrimitiveWrite);
- uint32_t field_idx = is_static ? dec_insn.vB : dec_insn.vC;
+ uint32_t field_idx = is_static ? inst->VRegB_21c() : inst->VRegC_22c();
Field* f = FindFieldFromCode(field_idx, shadow_frame.GetMethod(), self,
find_type, Primitive::FieldSize(field_type));
- if (LIKELY(f != NULL)) {
- Object* obj;
- if (is_static) {
- obj = f->GetDeclaringClass();
- } else {
- obj = shadow_frame.GetVRegReference(dec_insn.vB);
- if (UNLIKELY(obj == NULL)) {
- ThrowNullPointerExceptionForFieldAccess(shadow_frame.GetCurrentLocationForThrow(),
- f, false);
- return;
- }
- }
- switch (field_type) {
- case Primitive::kPrimBoolean:
- f->SetBoolean(obj, shadow_frame.GetVReg(dec_insn.vA));
- break;
- case Primitive::kPrimByte:
- f->SetByte(obj, shadow_frame.GetVReg(dec_insn.vA));
- break;
- case Primitive::kPrimChar:
- f->SetChar(obj, shadow_frame.GetVReg(dec_insn.vA));
- break;
- case Primitive::kPrimShort:
- f->SetShort(obj, shadow_frame.GetVReg(dec_insn.vA));
- break;
- case Primitive::kPrimInt:
- f->SetInt(obj, shadow_frame.GetVReg(dec_insn.vA));
- break;
- case Primitive::kPrimLong:
- f->SetLong(obj, shadow_frame.GetVRegLong(dec_insn.vA));
- break;
- case Primitive::kPrimNot:
- f->SetObj(obj, shadow_frame.GetVRegReference(dec_insn.vA));
- break;
- default:
- LOG(FATAL) << "Unreachable: " << field_type;
+ if (UNLIKELY(f == NULL)) {
+ CHECK(self->IsExceptionPending());
+ return;
+ }
+ Object* obj;
+ if (is_static) {
+ obj = f->GetDeclaringClass();
+ } else {
+ obj = shadow_frame.GetVRegReference(inst->VRegB_22c());
+ if (UNLIKELY(obj == NULL)) {
+ ThrowNullPointerExceptionForFieldAccess(shadow_frame.GetCurrentLocationForThrow(),
+ f, false);
+ return;
}
}
+ uint32_t vregA = is_static ? inst->VRegA_21c() : inst->VRegA_22c();
+ switch (field_type) {
+ case Primitive::kPrimBoolean:
+ f->SetBoolean(obj, shadow_frame.GetVReg(vregA));
+ break;
+ case Primitive::kPrimByte:
+ f->SetByte(obj, shadow_frame.GetVReg(vregA));
+ break;
+ case Primitive::kPrimChar:
+ f->SetChar(obj, shadow_frame.GetVReg(vregA));
+ break;
+ case Primitive::kPrimShort:
+ f->SetShort(obj, shadow_frame.GetVReg(vregA));
+ break;
+ case Primitive::kPrimInt:
+ f->SetInt(obj, shadow_frame.GetVReg(vregA));
+ break;
+ case Primitive::kPrimLong:
+ f->SetLong(obj, shadow_frame.GetVRegLong(vregA));
+ break;
+ case Primitive::kPrimNot:
+ f->SetObj(obj, shadow_frame.GetVRegReference(vregA));
+ break;
+ default:
+ LOG(FATAL) << "Unreachable: " << field_type;
+ }
+}
+
+static String* ResolveString(Thread* self, MethodHelper& mh, uint32_t string_idx) {
+ Class* java_lang_string_class = String::GetJavaLangString();
+ if (UNLIKELY(!java_lang_string_class->IsInitialized())) {
+ ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
+ if (UNLIKELY(!class_linker->EnsureInitialized(java_lang_string_class,
+ true, true))) {
+ DCHECK(self->IsExceptionPending());
+ return NULL;
+ }
+ }
+ return mh.ResolveString(string_idx);
}
static void DoIntDivide(Thread* self, ShadowFrame& shadow_frame, size_t result_reg,
@@ -614,24 +638,29 @@
}
self->VerifyStack();
instrumentation::Instrumentation* instrumentation = Runtime::Current()->GetInstrumentation();
- const uint16_t* insns = code_item->insns_;
+ const uint16_t* const insns = code_item->insns_;
+
+ // As the 'this' object won't change during the execution of current code, we
+ // want to cache it in local variables. Nevertheless, in order to let the
+ // garbage collector access it, we store it into sirt references.
+ SirtRef<Object> this_object_ref(self, shadow_frame.GetThisObject());
+
const Instruction* inst = Instruction::At(insns + shadow_frame.GetDexPC());
if (inst->GetDexPc(insns) == 0) { // We are entering the method as opposed to deoptimizing..
- instrumentation->MethodEnterEvent(self, shadow_frame.GetThisObject(), shadow_frame.GetMethod(),
- 0);
+ instrumentation->MethodEnterEvent(self, this_object_ref.get(),
+ shadow_frame.GetMethod(), 0);
}
while (true) {
CheckSuspend(self);
- uint32_t dex_pc = inst->GetDexPc(insns);
+ const uint32_t dex_pc = inst->GetDexPc(insns);
shadow_frame.SetDexPC(dex_pc);
- instrumentation->DexPcMovedEvent(self, shadow_frame.GetThisObject(), shadow_frame.GetMethod(),
- dex_pc);
- DecodedInstruction dec_insn(inst);
+ instrumentation->DexPcMovedEvent(self, this_object_ref.get(),
+ shadow_frame.GetMethod(), dex_pc);
const bool kTracing = false;
if (kTracing) {
#define TRACE_LOG std::cerr
TRACE_LOG << PrettyMethod(shadow_frame.GetMethod())
- << StringPrintf("\n0x%x: ", inst->GetDexPc(insns))
+ << StringPrintf("\n0x%x: ", dex_pc)
<< inst->DumpString(&mh.GetDexFile()) << "\n";
for (size_t i = 0; i < shadow_frame.NumberOfVRegs(); ++i) {
uint32_t raw_value = shadow_frame.GetVReg(i);
@@ -650,133 +679,170 @@
#undef TRACE_LOG
}
const Instruction* next_inst = inst->Next();
- switch (dec_insn.opcode) {
+ switch (inst->Opcode()) {
case Instruction::NOP:
break;
case Instruction::MOVE:
+ shadow_frame.SetVReg(inst->VRegA_12x(),
+ shadow_frame.GetVReg(inst->VRegB_12x()));
+ break;
case Instruction::MOVE_FROM16:
+ shadow_frame.SetVReg(inst->VRegA_22x(),
+ shadow_frame.GetVReg(inst->VRegB_22x()));
+ break;
case Instruction::MOVE_16:
- shadow_frame.SetVReg(dec_insn.vA, shadow_frame.GetVReg(dec_insn.vB));
+ shadow_frame.SetVReg(inst->VRegA_32x(),
+ shadow_frame.GetVReg(inst->VRegB_32x()));
break;
case Instruction::MOVE_WIDE:
+ shadow_frame.SetVRegLong(inst->VRegA_12x(),
+ shadow_frame.GetVRegLong(inst->VRegB_12x()));
+ break;
case Instruction::MOVE_WIDE_FROM16:
+ shadow_frame.SetVRegLong(inst->VRegA_22x(),
+ shadow_frame.GetVRegLong(inst->VRegB_22x()));
+ break;
case Instruction::MOVE_WIDE_16:
- shadow_frame.SetVRegLong(dec_insn.vA, shadow_frame.GetVRegLong(dec_insn.vB));
+ shadow_frame.SetVRegLong(inst->VRegA_32x(),
+ shadow_frame.GetVRegLong(inst->VRegB_32x()));
break;
case Instruction::MOVE_OBJECT:
+ shadow_frame.SetVRegReference(inst->VRegA_12x(),
+ shadow_frame.GetVRegReference(inst->VRegB_12x()));
+ break;
case Instruction::MOVE_OBJECT_FROM16:
+ shadow_frame.SetVRegReference(inst->VRegA_22x(),
+ shadow_frame.GetVRegReference(inst->VRegB_22x()));
+ break;
case Instruction::MOVE_OBJECT_16:
- shadow_frame.SetVRegReference(dec_insn.vA, shadow_frame.GetVRegReference(dec_insn.vB));
+ shadow_frame.SetVRegReference(inst->VRegA_32x(),
+ shadow_frame.GetVRegReference(inst->VRegB_32x()));
break;
case Instruction::MOVE_RESULT:
- shadow_frame.SetVReg(dec_insn.vA, result_register.GetI());
+ shadow_frame.SetVReg(inst->VRegA_11x(), result_register.GetI());
break;
case Instruction::MOVE_RESULT_WIDE:
- shadow_frame.SetVRegLong(dec_insn.vA, result_register.GetJ());
+ shadow_frame.SetVRegLong(inst->VRegA_11x(), result_register.GetJ());
break;
case Instruction::MOVE_RESULT_OBJECT:
- shadow_frame.SetVRegReference(dec_insn.vA, result_register.GetL());
+ shadow_frame.SetVRegReference(inst->VRegA_11x(), result_register.GetL());
break;
case Instruction::MOVE_EXCEPTION: {
Throwable* exception = self->GetException(NULL);
self->ClearException();
- shadow_frame.SetVRegReference(dec_insn.vA, exception);
+ shadow_frame.SetVRegReference(inst->VRegA_11x(), exception);
break;
}
case Instruction::RETURN_VOID: {
JValue result;
- instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(),
- shadow_frame.GetMethod(), shadow_frame.GetDexPC(),
- result);
+ instrumentation->MethodExitEvent(self, this_object_ref.get(),
+ shadow_frame.GetMethod(), dex_pc, result);
return result;
}
case Instruction::RETURN: {
JValue result;
result.SetJ(0);
- result.SetI(shadow_frame.GetVReg(dec_insn.vA));
- instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(),
- shadow_frame.GetMethod(), shadow_frame.GetDexPC(),
- result);
+ result.SetI(shadow_frame.GetVReg(inst->VRegA_11x()));
+ instrumentation->MethodExitEvent(self, this_object_ref.get(),
+ shadow_frame.GetMethod(), dex_pc, result);
return result;
}
case Instruction::RETURN_WIDE: {
JValue result;
- result.SetJ(shadow_frame.GetVRegLong(dec_insn.vA));
- instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(),
- shadow_frame.GetMethod(), shadow_frame.GetDexPC(),
- result);
+ result.SetJ(shadow_frame.GetVRegLong(inst->VRegA_11x()));
+ instrumentation->MethodExitEvent(self, this_object_ref.get(),
+ shadow_frame.GetMethod(), dex_pc, result);
return result;
}
case Instruction::RETURN_OBJECT: {
JValue result;
result.SetJ(0);
- result.SetL(shadow_frame.GetVRegReference(dec_insn.vA));
- instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(),
- shadow_frame.GetMethod(), shadow_frame.GetDexPC(),
- result);
+ result.SetL(shadow_frame.GetVRegReference(inst->VRegA_11x()));
+ instrumentation->MethodExitEvent(self, this_object_ref.get(),
+ shadow_frame.GetMethod(), dex_pc, result);
return result;
}
case Instruction::CONST_4: {
- int32_t val = static_cast<int32_t>(dec_insn.vB << 28) >> 28;
- shadow_frame.SetVReg(dec_insn.vA, val);
+ uint32_t dst = inst->VRegA_11n();
+ int32_t val = static_cast<int32_t>(inst->VRegB_11n() << 28) >> 28;
+ shadow_frame.SetVReg(dst, val);
if (val == 0) {
- shadow_frame.SetVRegReference(dec_insn.vA, NULL);
+ shadow_frame.SetVRegReference(dst, NULL);
}
break;
}
case Instruction::CONST_16: {
- int32_t val = static_cast<int16_t>(dec_insn.vB);
- shadow_frame.SetVReg(dec_insn.vA, val);
+ uint32_t dst = inst->VRegA_21s();
+ int32_t val = static_cast<int16_t>(inst->VRegB_21s());
+ shadow_frame.SetVReg(dst, val);
if (val == 0) {
- shadow_frame.SetVRegReference(dec_insn.vA, NULL);
+ shadow_frame.SetVRegReference(dst, NULL);
}
break;
}
case Instruction::CONST: {
- int32_t val = dec_insn.vB;
- shadow_frame.SetVReg(dec_insn.vA, val);
+ uint32_t dst = inst->VRegA_31i();
+ int32_t val = inst->VRegB_31i();
+ shadow_frame.SetVReg(dst, val);
if (val == 0) {
- shadow_frame.SetVRegReference(dec_insn.vA, NULL);
+ shadow_frame.SetVRegReference(dst, NULL);
}
break;
}
case Instruction::CONST_HIGH16: {
- int32_t val = dec_insn.vB << 16;
- shadow_frame.SetVReg(dec_insn.vA, val);
+ uint32_t dst = inst->VRegA_21h();
+ int32_t val = inst->VRegB_21h() << 16;
+ shadow_frame.SetVReg(dst, val);
if (val == 0) {
- shadow_frame.SetVRegReference(dec_insn.vA, NULL);
+ shadow_frame.SetVRegReference(dst, NULL);
}
break;
}
case Instruction::CONST_WIDE_16:
- shadow_frame.SetVRegLong(dec_insn.vA, static_cast<int16_t>(dec_insn.vB));
+ shadow_frame.SetVRegLong(inst->VRegA_21s(),
+ static_cast<int16_t>(inst->VRegB_21s()));
break;
case Instruction::CONST_WIDE_32:
- shadow_frame.SetVRegLong(dec_insn.vA, static_cast<int32_t>(dec_insn.vB));
+ shadow_frame.SetVRegLong(inst->VRegA_31i(),
+ static_cast<int32_t>(inst->VRegB_31i()));
break;
case Instruction::CONST_WIDE:
- shadow_frame.SetVRegLong(dec_insn.vA, dec_insn.vB_wide);
+ shadow_frame.SetVRegLong(inst->VRegA_51l(), inst->VRegB_51l());
break;
case Instruction::CONST_WIDE_HIGH16:
- shadow_frame.SetVRegLong(dec_insn.vA, static_cast<uint64_t>(dec_insn.vB) << 48);
+ shadow_frame.SetVRegLong(inst->VRegA_21h(),
+ static_cast<uint64_t>(inst->VRegB_21h()) << 48);
break;
- case Instruction::CONST_STRING:
- case Instruction::CONST_STRING_JUMBO: {
- if (UNLIKELY(!String::GetJavaLangString()->IsInitialized())) {
- Runtime::Current()->GetClassLinker()->EnsureInitialized(String::GetJavaLangString(),
- true, true);
+ case Instruction::CONST_STRING: {
+ String* s = ResolveString(self, mh, inst->VRegB_21c());
+ if (UNLIKELY(s == NULL)) {
+ CHECK(self->IsExceptionPending());
+ } else {
+ shadow_frame.SetVRegReference( inst->VRegA_21c(), s);
}
- String* s = mh.ResolveString(dec_insn.vB);
- shadow_frame.SetVRegReference(dec_insn.vA, s);
+ break;
+ }
+ case Instruction::CONST_STRING_JUMBO: {
+ String* s = ResolveString(self, mh, inst->VRegB_31c());
+ if (UNLIKELY(s == NULL)) {
+ CHECK(self->IsExceptionPending());
+ } else {
+ shadow_frame.SetVRegReference( inst->VRegA_31c(), s);
+ }
break;
}
case Instruction::CONST_CLASS: {
- Class* c = ResolveVerifyAndClinit(dec_insn.vB, shadow_frame.GetMethod(), self, false, true);
- shadow_frame.SetVRegReference(dec_insn.vA, c);
+ Class* c = ResolveVerifyAndClinit(inst->VRegB_21c(), shadow_frame.GetMethod(),
+ self, false, true);
+ if (UNLIKELY(c == NULL)) {
+ CHECK(self->IsExceptionPending());
+ } else {
+ shadow_frame.SetVRegReference(inst->VRegA_21c(), c);
+ }
break;
}
case Instruction::MONITOR_ENTER: {
- Object* obj = shadow_frame.GetVRegReference(dec_insn.vA);
+ Object* obj = shadow_frame.GetVRegReference(inst->VRegA_11x());
if (UNLIKELY(obj == NULL)) {
ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow());
} else {
@@ -785,7 +851,7 @@
break;
}
case Instruction::MONITOR_EXIT: {
- Object* obj = shadow_frame.GetVRegReference(dec_insn.vA);
+ Object* obj = shadow_frame.GetVRegReference(inst->VRegA_11x());
if (UNLIKELY(obj == NULL)) {
ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow());
} else {
@@ -794,11 +860,12 @@
break;
}
case Instruction::CHECK_CAST: {
- Class* c = ResolveVerifyAndClinit(dec_insn.vB, shadow_frame.GetMethod(), self, false, true);
+ Class* c = ResolveVerifyAndClinit(inst->VRegB_21c(), shadow_frame.GetMethod(),
+ self, false, true);
if (UNLIKELY(c == NULL)) {
CHECK(self->IsExceptionPending());
} else {
- Object* obj = shadow_frame.GetVRegReference(dec_insn.vA);
+ Object* obj = shadow_frame.GetVRegReference(inst->VRegA_21c());
if (UNLIKELY(obj != NULL && !obj->InstanceOf(c))) {
ThrowClassCastException(c, obj->GetClass());
}
@@ -806,45 +873,55 @@
break;
}
case Instruction::INSTANCE_OF: {
- Class* c = ResolveVerifyAndClinit(dec_insn.vC, shadow_frame.GetMethod(), self, false, true);
+ Class* c = ResolveVerifyAndClinit(inst->VRegC_22c(), shadow_frame.GetMethod(),
+ self, false, true);
if (UNLIKELY(c == NULL)) {
CHECK(self->IsExceptionPending());
} else {
- Object* obj = shadow_frame.GetVRegReference(dec_insn.vB);
- shadow_frame.SetVReg(dec_insn.vA, (obj != NULL && obj->InstanceOf(c)) ? 1 : 0);
+ Object* obj = shadow_frame.GetVRegReference(inst->VRegB_22c());
+ shadow_frame.SetVReg(inst->VRegA_22c(), (obj != NULL && obj->InstanceOf(c)) ? 1 : 0);
}
break;
}
case Instruction::ARRAY_LENGTH: {
- Object* array = shadow_frame.GetVRegReference(dec_insn.vB);
+ Object* array = shadow_frame.GetVRegReference(inst->VRegB_12x());
if (UNLIKELY(array == NULL)) {
ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow());
break;
}
- shadow_frame.SetVReg(dec_insn.vA, array->AsArray()->GetLength());
+ shadow_frame.SetVReg(inst->VRegA_12x(), array->AsArray()->GetLength());
break;
}
case Instruction::NEW_INSTANCE: {
- Object* obj = AllocObjectFromCode(dec_insn.vB, shadow_frame.GetMethod(), self, true);
- shadow_frame.SetVRegReference(dec_insn.vA, obj);
+ Object* obj = AllocObjectFromCode(inst->VRegB_21c(), shadow_frame.GetMethod(),
+ self, true);
+ if (UNLIKELY(obj == NULL)) {
+ CHECK(self->IsExceptionPending());
+ } else {
+ shadow_frame.SetVRegReference(inst->VRegA_21c(), obj);
+ }
break;
}
case Instruction::NEW_ARRAY: {
- int32_t length = shadow_frame.GetVReg(dec_insn.vB);
- Object* obj = AllocArrayFromCode(dec_insn.vC, shadow_frame.GetMethod(), length, self, true);
- shadow_frame.SetVRegReference(dec_insn.vA, obj);
+ int32_t length = shadow_frame.GetVReg(inst->VRegB_22c());
+ Object* obj = AllocArrayFromCode(inst->VRegC_22c(), shadow_frame.GetMethod(),
+ length, self, true);
+ if (UNLIKELY(obj == NULL)) {
+ CHECK(self->IsExceptionPending());
+ } else {
+ shadow_frame.SetVRegReference(inst->VRegA_22c(), obj);
+ }
break;
}
- case Instruction::FILLED_NEW_ARRAY:
- case Instruction::FILLED_NEW_ARRAY_RANGE: {
- bool is_range = (dec_insn.opcode == Instruction::FILLED_NEW_ARRAY_RANGE);
- int32_t length = dec_insn.vA;
- CHECK(is_range || length <= 5);
+ case Instruction::FILLED_NEW_ARRAY: {
+ const int32_t length = inst->VRegA_35c();
+ CHECK(length <= 5);
if (UNLIKELY(length < 0)) {
ThrowNegativeArraySizeException(length);
break;
}
- Class* arrayClass = ResolveVerifyAndClinit(dec_insn.vB, shadow_frame.GetMethod(), self, false, true);
+ Class* arrayClass = ResolveVerifyAndClinit(inst->VRegB_35c(), shadow_frame.GetMethod(),
+ self, false, true);
if (UNLIKELY(arrayClass == NULL)) {
CHECK(self->IsExceptionPending());
break;
@@ -864,117 +941,111 @@
break;
}
Object* newArray = Array::Alloc(self, arrayClass, length);
- if (newArray != NULL) {
+ if (UNLIKELY(newArray == NULL)) {
+ CHECK(self->IsExceptionPending());
+ } else {
+ uint32_t arg[5];
+ inst->GetArgs(arg);
+ const bool is_primitive_int_component = componentClass->IsPrimitiveInt();
for (int32_t i = 0; i < length; ++i) {
- if (is_range) {
- if (componentClass->IsPrimitiveInt()) {
- newArray->AsIntArray()->Set(i, shadow_frame.GetVReg(dec_insn.vC + i));
- } else {
- newArray->AsObjectArray<Object>()->Set(i, shadow_frame.GetVRegReference(dec_insn.vC + i));
- }
+ if (is_primitive_int_component) {
+ newArray->AsIntArray()->Set(i, shadow_frame.GetVReg(arg[i]));
} else {
- if (componentClass->IsPrimitiveInt()) {
- newArray->AsIntArray()->Set(i, shadow_frame.GetVReg(dec_insn.arg[i]));
- } else {
- newArray->AsObjectArray<Object>()->Set(i, shadow_frame.GetVRegReference(dec_insn.arg[i]));
- }
+ newArray->AsObjectArray<Object>()->Set(i, shadow_frame.GetVRegReference(arg[i]));
}
}
}
result_register.SetL(newArray);
break;
}
- case Instruction::CMPL_FLOAT: {
- float val1 = shadow_frame.GetVRegFloat(dec_insn.vB);
- float val2 = shadow_frame.GetVRegFloat(dec_insn.vC);
- int32_t result;
- if (val1 == val2) {
- result = 0;
- } else if (val1 > val2) {
- result = 1;
- } else {
- result = -1;
+ case Instruction::FILLED_NEW_ARRAY_RANGE: {
+ int32_t length = inst->VRegA_3rc();
+ if (UNLIKELY(length < 0)) {
+ ThrowNegativeArraySizeException(length);
+ break;
}
- shadow_frame.SetVReg(dec_insn.vA, result);
+ Class* arrayClass = ResolveVerifyAndClinit(inst->VRegB_3rc(), shadow_frame.GetMethod(),
+ self, false, true);
+ if (UNLIKELY(arrayClass == NULL)) {
+ CHECK(self->IsExceptionPending());
+ break;
+ }
+ CHECK(arrayClass->IsArrayClass());
+ Class* componentClass = arrayClass->GetComponentType();
+ if (UNLIKELY(componentClass->IsPrimitive() && !componentClass->IsPrimitiveInt())) {
+ if (componentClass->IsPrimitiveLong() || componentClass->IsPrimitiveDouble()) {
+ ThrowRuntimeException("Bad filled array request for type %s",
+ PrettyDescriptor(componentClass).c_str());
+ } else {
+ self->ThrowNewExceptionF(shadow_frame.GetCurrentLocationForThrow(),
+ "Ljava/lang/InternalError;",
+ "Found type %s; filled-new-array not implemented for anything but \'int\'",
+ PrettyDescriptor(componentClass).c_str());
+ }
+ break;
+ }
+ Object* newArray = Array::Alloc(self, arrayClass, length);
+ if (UNLIKELY(newArray == NULL)) {
+ CHECK(self->IsExceptionPending());
+ } else {
+ uint32_t vregC = inst->VRegC_3rc();
+ const bool is_primitive_int_component = componentClass->IsPrimitiveInt();
+ for (int32_t i = 0; i < length; ++i) {
+ if (is_primitive_int_component) {
+ newArray->AsIntArray()->Set(i, shadow_frame.GetVReg(vregC + i));
+ } else {
+ newArray->AsObjectArray<Object>()->Set(i, shadow_frame.GetVRegReference(vregC + i));
+ }
+ }
+ }
+ result_register.SetL(newArray);
break;
}
- case Instruction::CMPG_FLOAT: {
- float val1 = shadow_frame.GetVRegFloat(dec_insn.vB);
- float val2 = shadow_frame.GetVRegFloat(dec_insn.vC);
- int32_t result;
- if (val1 == val2) {
- result = 0;
- } else if (val1 < val2) {
- result = -1;
- } else {
- result = 1;
+ case Instruction::FILL_ARRAY_DATA: {
+ Object* obj = shadow_frame.GetVRegReference(inst->VRegA_31t());
+ if (UNLIKELY(obj == NULL)) {
+ ThrowNullPointerException(NULL, "null array in FILL_ARRAY_DATA");
+ break;
}
- shadow_frame.SetVReg(dec_insn.vA, result);
- break;
- }
- case Instruction::CMPL_DOUBLE: {
- double val1 = shadow_frame.GetVRegDouble(dec_insn.vB);
- double val2 = shadow_frame.GetVRegDouble(dec_insn.vC);
- int32_t result;
- if (val1 == val2) {
- result = 0;
- } else if (val1 > val2) {
- result = 1;
- } else {
- result = -1;
+ Array* array = obj->AsArray();
+ DCHECK(array->IsArrayInstance() && !array->IsObjectArray());
+ const Instruction::ArrayDataPayload* payload =
+ reinterpret_cast<const Instruction::ArrayDataPayload*>(insns + dex_pc + inst->VRegB_31t());
+ if (UNLIKELY(static_cast<int32_t>(payload->element_count) > array->GetLength())) {
+ self->ThrowNewExceptionF(shadow_frame.GetCurrentLocationForThrow(),
+ "Ljava/lang/ArrayIndexOutOfBoundsException;",
+ "failed FILL_ARRAY_DATA; length=%d, index=%d",
+ array->GetLength(), payload->element_count);
+ break;
}
- shadow_frame.SetVReg(dec_insn.vA, result);
- break;
- }
-
- case Instruction::CMPG_DOUBLE: {
- double val1 = shadow_frame.GetVRegDouble(dec_insn.vB);
- double val2 = shadow_frame.GetVRegDouble(dec_insn.vC);
- int32_t result;
- if (val1 == val2) {
- result = 0;
- } else if (val1 < val2) {
- result = -1;
- } else {
- result = 1;
- }
- shadow_frame.SetVReg(dec_insn.vA, result);
- break;
- }
- case Instruction::CMP_LONG: {
- int64_t val1 = shadow_frame.GetVRegLong(dec_insn.vB);
- int64_t val2 = shadow_frame.GetVRegLong(dec_insn.vC);
- int32_t result;
- if (val1 > val2) {
- result = 1;
- } else if (val1 == val2) {
- result = 0;
- } else {
- result = -1;
- }
- shadow_frame.SetVReg(dec_insn.vA, result);
+ uint32_t size_in_bytes = payload->element_count * payload->element_width;
+ memcpy(array->GetRawData(payload->element_width), payload->data, size_in_bytes);
break;
}
case Instruction::THROW: {
- Object* exception = shadow_frame.GetVRegReference(dec_insn.vA);
- if (exception == NULL) {
+ Object* exception = shadow_frame.GetVRegReference(inst->VRegA_11x());
+ if (UNLIKELY(exception == NULL)) {
ThrowNullPointerException(NULL, "throw with null exception");
} else {
self->SetException(shadow_frame.GetCurrentLocationForThrow(), exception->AsThrowable());
}
break;
}
- case Instruction::GOTO:
- case Instruction::GOTO_16:
+ case Instruction::GOTO: {
+ next_inst = Instruction::At(insns + dex_pc + inst->VRegA_10t());
+ break;
+ }
+ case Instruction::GOTO_16: {
+ next_inst = Instruction::At(insns + dex_pc + inst->VRegA_20t());
+ break;
+ }
case Instruction::GOTO_32: {
- uint32_t dex_pc = inst->GetDexPc(insns);
- next_inst = Instruction::At(insns + dex_pc + dec_insn.vA);
+ next_inst = Instruction::At(insns + dex_pc + inst->VRegA_30t());
break;
}
case Instruction::PACKED_SWITCH: {
- uint32_t dex_pc = inst->GetDexPc(insns);
- const uint16_t* switch_data = insns + dex_pc + dec_insn.vB;
- int32_t test_val = shadow_frame.GetVReg(dec_insn.vA);
+ const uint16_t* switch_data = insns + dex_pc + inst->VRegB_31t();
+ int32_t test_val = shadow_frame.GetVReg(inst->VRegA_31t());
CHECK_EQ(switch_data[0], static_cast<uint16_t>(Instruction::kPackedSwitchSignature));
uint16_t size = switch_data[1];
CHECK_GT(size, 0);
@@ -990,9 +1061,8 @@
break;
}
case Instruction::SPARSE_SWITCH: {
- uint32_t dex_pc = inst->GetDexPc(insns);
- const uint16_t* switch_data = insns + dex_pc + dec_insn.vB;
- int32_t test_val = shadow_frame.GetVReg(dec_insn.vA);
+ const uint16_t* switch_data = insns + dex_pc + 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];
CHECK_GT(size, 0);
@@ -1016,818 +1086,998 @@
}
break;
}
- case Instruction::FILL_ARRAY_DATA: {
- Object* obj = shadow_frame.GetVRegReference(dec_insn.vA);
- if (UNLIKELY(obj == NULL)) {
- ThrowNullPointerException(NULL, "null array in FILL_ARRAY_DATA");
- break;
+ case Instruction::CMPL_FLOAT: {
+ float val1 = shadow_frame.GetVRegFloat(inst->VRegB_23x());
+ float val2 = shadow_frame.GetVRegFloat(inst->VRegC_23x());
+ int32_t result;
+ // TODO: we should not test float equality like this. Reorder comparisons
+ // or use a different comparison mechanism.
+ if (val1 == val2) {
+ result = 0;
+ } else if (val1 > val2) {
+ result = 1;
+ } else {
+ result = -1;
}
- Array* array = obj->AsArray();
- DCHECK(array->IsArrayInstance() && !array->IsObjectArray());
- uint32_t dex_pc = inst->GetDexPc(insns);
- const Instruction::ArrayDataPayload* payload =
- reinterpret_cast<const Instruction::ArrayDataPayload*>(insns + dex_pc + dec_insn.vB);
- if (UNLIKELY(static_cast<int32_t>(payload->element_count) > array->GetLength())) {
- self->ThrowNewExceptionF(shadow_frame.GetCurrentLocationForThrow(),
- "Ljava/lang/ArrayIndexOutOfBoundsException;",
- "failed FILL_ARRAY_DATA; length=%d, index=%d",
- array->GetLength(), payload->element_count);
- break;
+ shadow_frame.SetVReg(inst->VRegA_23x(), result);
+ break;
+ }
+ case Instruction::CMPG_FLOAT: {
+ float val1 = shadow_frame.GetVRegFloat(inst->VRegB_23x());
+ float val2 = shadow_frame.GetVRegFloat(inst->VRegC_23x());
+ int32_t result;
+ // TODO: we should not test float equality like this. Reorder comparisons
+ // or use a different comparison mechanism.
+ if (val1 == val2) {
+ result = 0;
+ } else if (val1 < val2) {
+ result = -1;
+ } else {
+ result = 1;
}
- uint32_t size_in_bytes = payload->element_count * payload->element_width;
- memcpy(array->GetRawData(payload->element_width), payload->data, size_in_bytes);
+ shadow_frame.SetVReg(inst->VRegA_23x(), result);
+ break;
+ }
+ case Instruction::CMPL_DOUBLE: {
+ double val1 = shadow_frame.GetVRegDouble(inst->VRegB_23x());
+ double val2 = shadow_frame.GetVRegDouble(inst->VRegC_23x());
+ int32_t result;
+ // TODO: we should not test double equality like this. Reorder comparisons
+ // or use a different comparison mechanism.
+ if (val1 == val2) {
+ result = 0;
+ } else if (val1 > val2) {
+ result = 1;
+ } else {
+ result = -1;
+ }
+ shadow_frame.SetVReg(inst->VRegA_23x(), result);
+ break;
+ }
+
+ case Instruction::CMPG_DOUBLE: {
+ double val1 = shadow_frame.GetVRegDouble(inst->VRegB_23x());
+ double val2 = shadow_frame.GetVRegDouble(inst->VRegC_23x());
+ int32_t result;
+ // TODO: we should not test double equality like this. Reorder comparisons
+ // or use a different comparison mechanism.
+ if (val1 == val2) {
+ result = 0;
+ } else if (val1 < val2) {
+ result = -1;
+ } else {
+ result = 1;
+ }
+ shadow_frame.SetVReg(inst->VRegA_23x(), result);
+ break;
+ }
+ case Instruction::CMP_LONG: {
+ int64_t val1 = shadow_frame.GetVRegLong(inst->VRegB_23x());
+ int64_t val2 = shadow_frame.GetVRegLong(inst->VRegC_23x());
+ int32_t result;
+ if (val1 > val2) {
+ result = 1;
+ } else if (val1 == val2) {
+ result = 0;
+ } else {
+ result = -1;
+ }
+ shadow_frame.SetVReg(inst->VRegA_23x(), result);
break;
}
case Instruction::IF_EQ: {
- if (shadow_frame.GetVReg(dec_insn.vA) == shadow_frame.GetVReg(dec_insn.vB)) {
- uint32_t dex_pc = inst->GetDexPc(insns);
- next_inst = Instruction::At(insns + dex_pc + dec_insn.vC);
+ if (shadow_frame.GetVReg(inst->VRegA_22t()) == shadow_frame.GetVReg(inst->VRegB_22t())) {
+ next_inst = Instruction::At(insns + dex_pc + inst->VRegC_22t());
}
break;
}
case Instruction::IF_NE: {
- if (shadow_frame.GetVReg(dec_insn.vA) != shadow_frame.GetVReg(dec_insn.vB)) {
- uint32_t dex_pc = inst->GetDexPc(insns);
- next_inst = Instruction::At(insns + dex_pc + dec_insn.vC);
+ if (shadow_frame.GetVReg(inst->VRegA_22t()) != shadow_frame.GetVReg(inst->VRegB_22t())) {
+ next_inst = Instruction::At(insns + dex_pc + inst->VRegC_22t());
}
break;
}
case Instruction::IF_LT: {
- if (shadow_frame.GetVReg(dec_insn.vA) < shadow_frame.GetVReg(dec_insn.vB)) {
- uint32_t dex_pc = inst->GetDexPc(insns);
- next_inst = Instruction::At(insns + dex_pc + dec_insn.vC);
+ if (shadow_frame.GetVReg(inst->VRegA_22t()) < shadow_frame.GetVReg(inst->VRegB_22t())) {
+ next_inst = Instruction::At(insns + dex_pc + inst->VRegC_22t());
}
break;
}
case Instruction::IF_GE: {
- if (shadow_frame.GetVReg(dec_insn.vA) >= shadow_frame.GetVReg(dec_insn.vB)) {
- uint32_t dex_pc = inst->GetDexPc(insns);
- next_inst = Instruction::At(insns + dex_pc + dec_insn.vC);
+ if (shadow_frame.GetVReg(inst->VRegA_22t()) >= shadow_frame.GetVReg(inst->VRegB_22t())) {
+ next_inst = Instruction::At(insns + dex_pc + inst->VRegC_22t());
}
break;
}
case Instruction::IF_GT: {
- if (shadow_frame.GetVReg(dec_insn.vA) > shadow_frame.GetVReg(dec_insn.vB)) {
- uint32_t dex_pc = inst->GetDexPc(insns);
- next_inst = Instruction::At(insns + dex_pc + dec_insn.vC);
+ if (shadow_frame.GetVReg(inst->VRegA_22t()) > shadow_frame.GetVReg(inst->VRegB_22t())) {
+ next_inst = Instruction::At(insns + dex_pc + inst->VRegC_22t());
}
break;
}
case Instruction::IF_LE: {
- if (shadow_frame.GetVReg(dec_insn.vA) <= shadow_frame.GetVReg(dec_insn.vB)) {
- uint32_t dex_pc = inst->GetDexPc(insns);
- next_inst = Instruction::At(insns + dex_pc + dec_insn.vC);
+ if (shadow_frame.GetVReg(inst->VRegA_22t()) <= shadow_frame.GetVReg(inst->VRegB_22t())) {
+ next_inst = Instruction::At(insns + dex_pc + inst->VRegC_22t());
}
break;
}
case Instruction::IF_EQZ: {
- if (shadow_frame.GetVReg(dec_insn.vA) == 0) {
- uint32_t dex_pc = inst->GetDexPc(insns);
- next_inst = Instruction::At(insns + dex_pc + dec_insn.vB);
+ if (shadow_frame.GetVReg(inst->VRegA_21t()) == 0) {
+ next_inst = Instruction::At(insns + dex_pc + inst->VRegB_21t());
}
break;
}
case Instruction::IF_NEZ: {
- if (shadow_frame.GetVReg(dec_insn.vA) != 0) {
- uint32_t dex_pc = inst->GetDexPc(insns);
- next_inst = Instruction::At(insns + dex_pc + dec_insn.vB);
+ if (shadow_frame.GetVReg(inst->VRegA_21t()) != 0) {
+ next_inst = Instruction::At(insns + dex_pc + inst->VRegB_21t());
}
break;
}
case Instruction::IF_LTZ: {
- if (shadow_frame.GetVReg(dec_insn.vA) < 0) {
- uint32_t dex_pc = inst->GetDexPc(insns);
- next_inst = Instruction::At(insns + dex_pc + dec_insn.vB);
+ if (shadow_frame.GetVReg(inst->VRegA_21t()) < 0) {
+ next_inst = Instruction::At(insns + dex_pc + inst->VRegB_21t());
}
break;
}
case Instruction::IF_GEZ: {
- if (shadow_frame.GetVReg(dec_insn.vA) >= 0) {
- uint32_t dex_pc = inst->GetDexPc(insns);
- next_inst = Instruction::At(insns + dex_pc + dec_insn.vB);
+ if (shadow_frame.GetVReg(inst->VRegA_21t()) >= 0) {
+ next_inst = Instruction::At(insns + dex_pc + inst->VRegB_21t());
}
break;
}
case Instruction::IF_GTZ: {
- if (shadow_frame.GetVReg(dec_insn.vA) > 0) {
- uint32_t dex_pc = inst->GetDexPc(insns);
- next_inst = Instruction::At(insns + dex_pc + dec_insn.vB);
+ if (shadow_frame.GetVReg(inst->VRegA_21t()) > 0) {
+ next_inst = Instruction::At(insns + dex_pc + inst->VRegB_21t());
}
break;
}
case Instruction::IF_LEZ: {
- if (shadow_frame.GetVReg(dec_insn.vA) <= 0) {
- uint32_t dex_pc = inst->GetDexPc(insns);
- next_inst = Instruction::At(insns + dex_pc + dec_insn.vB);
+ if (shadow_frame.GetVReg(inst->VRegA_21t()) <= 0) {
+ next_inst = Instruction::At(insns + dex_pc + inst->VRegB_21t());
}
break;
}
case Instruction::AGET_BOOLEAN: {
- Object* a = shadow_frame.GetVRegReference(dec_insn.vB);
+ Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
if (UNLIKELY(a == NULL)) {
ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow());
break;
}
- int32_t index = shadow_frame.GetVReg(dec_insn.vC);
- shadow_frame.SetVReg(dec_insn.vA, a->AsBooleanArray()->Get(index));
+ int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
+ shadow_frame.SetVReg(inst->VRegA_23x(), a->AsBooleanArray()->Get(index));
break;
}
case Instruction::AGET_BYTE: {
- Object* a = shadow_frame.GetVRegReference(dec_insn.vB);
+ Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
if (UNLIKELY(a == NULL)) {
ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow());
break;
}
- int32_t index = shadow_frame.GetVReg(dec_insn.vC);
- shadow_frame.SetVReg(dec_insn.vA, a->AsByteArray()->Get(index));
+ int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
+ shadow_frame.SetVReg(inst->VRegA_23x(), a->AsByteArray()->Get(index));
break;
}
case Instruction::AGET_CHAR: {
- Object* a = shadow_frame.GetVRegReference(dec_insn.vB);
+ Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
if (UNLIKELY(a == NULL)) {
ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow());
break;
}
- int32_t index = shadow_frame.GetVReg(dec_insn.vC);
- shadow_frame.SetVReg(dec_insn.vA, a->AsCharArray()->Get(index));
+ int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
+ shadow_frame.SetVReg(inst->VRegA_23x(), a->AsCharArray()->Get(index));
break;
}
case Instruction::AGET_SHORT: {
- Object* a = shadow_frame.GetVRegReference(dec_insn.vB);
+ Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
if (UNLIKELY(a == NULL)) {
ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow());
break;
}
- int32_t index = shadow_frame.GetVReg(dec_insn.vC);
- shadow_frame.SetVReg(dec_insn.vA, a->AsShortArray()->Get(index));
+ int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
+ shadow_frame.SetVReg(inst->VRegA_23x(), a->AsShortArray()->Get(index));
break;
}
case Instruction::AGET: {
- Object* a = shadow_frame.GetVRegReference(dec_insn.vB);
+ Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
if (UNLIKELY(a == NULL)) {
ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow());
break;
}
- int32_t index = shadow_frame.GetVReg(dec_insn.vC);
- shadow_frame.SetVReg(dec_insn.vA, a->AsIntArray()->Get(index));
+ int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
+ shadow_frame.SetVReg(inst->VRegA_23x(), a->AsIntArray()->Get(index));
break;
}
case Instruction::AGET_WIDE: {
- Object* a = shadow_frame.GetVRegReference(dec_insn.vB);
+ Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
if (UNLIKELY(a == NULL)) {
ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow());
break;
}
- int32_t index = shadow_frame.GetVReg(dec_insn.vC);
- shadow_frame.SetVRegLong(dec_insn.vA, a->AsLongArray()->Get(index));
+ int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
+ shadow_frame.SetVRegLong(inst->VRegA_23x(), a->AsLongArray()->Get(index));
break;
}
case Instruction::AGET_OBJECT: {
- Object* a = shadow_frame.GetVRegReference(dec_insn.vB);
+ Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
if (UNLIKELY(a == NULL)) {
ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow());
break;
}
- int32_t index = shadow_frame.GetVReg(dec_insn.vC);
- shadow_frame.SetVRegReference(dec_insn.vA, a->AsObjectArray<Object>()->Get(index));
+ int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
+ shadow_frame.SetVRegReference(inst->VRegA_23x(), a->AsObjectArray<Object>()->Get(index));
break;
}
case Instruction::APUT_BOOLEAN: {
- uint8_t val = shadow_frame.GetVReg(dec_insn.vA);
- Object* a = shadow_frame.GetVRegReference(dec_insn.vB);
+ Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
if (UNLIKELY(a == NULL)) {
ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow());
break;
}
- int32_t index = shadow_frame.GetVReg(dec_insn.vC);
+ uint8_t val = shadow_frame.GetVReg(inst->VRegA_23x());
+ int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
a->AsBooleanArray()->Set(index, val);
break;
}
case Instruction::APUT_BYTE: {
- int8_t val = shadow_frame.GetVReg(dec_insn.vA);
- Object* a = shadow_frame.GetVRegReference(dec_insn.vB);
+ Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
if (UNLIKELY(a == NULL)) {
ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow());
break;
}
- int32_t index = shadow_frame.GetVReg(dec_insn.vC);
+ int8_t val = shadow_frame.GetVReg(inst->VRegA_23x());
+ int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
a->AsByteArray()->Set(index, val);
break;
}
case Instruction::APUT_CHAR: {
- uint16_t val = shadow_frame.GetVReg(dec_insn.vA);
- Object* a = shadow_frame.GetVRegReference(dec_insn.vB);
+ Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
if (UNLIKELY(a == NULL)) {
ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow());
break;
}
- int32_t index = shadow_frame.GetVReg(dec_insn.vC);
+ uint16_t val = shadow_frame.GetVReg(inst->VRegA_23x());
+ int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
a->AsCharArray()->Set(index, val);
break;
}
case Instruction::APUT_SHORT: {
- int16_t val = shadow_frame.GetVReg(dec_insn.vA);
- Object* a = shadow_frame.GetVRegReference(dec_insn.vB);
+ Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
if (UNLIKELY(a == NULL)) {
ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow());
break;
}
- int32_t index = shadow_frame.GetVReg(dec_insn.vC);
+ int16_t val = shadow_frame.GetVReg(inst->VRegA_23x());
+ int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
a->AsShortArray()->Set(index, val);
break;
}
case Instruction::APUT: {
- int32_t val = shadow_frame.GetVReg(dec_insn.vA);
- Object* a = shadow_frame.GetVRegReference(dec_insn.vB);
+ Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
if (UNLIKELY(a == NULL)) {
ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow());
break;
}
- int32_t index = shadow_frame.GetVReg(dec_insn.vC);
+ int32_t val = shadow_frame.GetVReg(inst->VRegA_23x());
+ int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
a->AsIntArray()->Set(index, val);
break;
}
case Instruction::APUT_WIDE: {
- int64_t val = shadow_frame.GetVRegLong(dec_insn.vA);
- Object* a = shadow_frame.GetVRegReference(dec_insn.vB);
+ Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
if (UNLIKELY(a == NULL)) {
ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow());
break;
}
- int32_t index = shadow_frame.GetVReg(dec_insn.vC);
+ int64_t val = shadow_frame.GetVRegLong(inst->VRegA_23x());
+ int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
a->AsLongArray()->Set(index, val);
break;
}
case Instruction::APUT_OBJECT: {
- Object* val = shadow_frame.GetVRegReference(dec_insn.vA);
- Object* a = shadow_frame.GetVRegReference(dec_insn.vB);
+ Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
if (UNLIKELY(a == NULL)) {
ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow());
break;
}
- int32_t index = shadow_frame.GetVReg(dec_insn.vC);
+ Object* val = shadow_frame.GetVRegReference(inst->VRegA_23x());
+ int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
a->AsObjectArray<Object>()->Set(index, val);
break;
}
case Instruction::IGET_BOOLEAN:
- DoFieldGet(self, shadow_frame, dec_insn, InstancePrimitiveRead, Primitive::kPrimBoolean);
+ DoFieldGet(self, shadow_frame, inst, InstancePrimitiveRead, Primitive::kPrimBoolean);
break;
case Instruction::IGET_BYTE:
- DoFieldGet(self, shadow_frame, dec_insn, InstancePrimitiveRead, Primitive::kPrimByte);
+ DoFieldGet(self, shadow_frame, inst, InstancePrimitiveRead, Primitive::kPrimByte);
break;
case Instruction::IGET_CHAR:
- DoFieldGet(self, shadow_frame, dec_insn, InstancePrimitiveRead, Primitive::kPrimChar);
+ DoFieldGet(self, shadow_frame, inst, InstancePrimitiveRead, Primitive::kPrimChar);
break;
case Instruction::IGET_SHORT:
- DoFieldGet(self, shadow_frame, dec_insn, InstancePrimitiveRead, Primitive::kPrimShort);
+ DoFieldGet(self, shadow_frame, inst, InstancePrimitiveRead, Primitive::kPrimShort);
break;
case Instruction::IGET:
- DoFieldGet(self, shadow_frame, dec_insn, InstancePrimitiveRead, Primitive::kPrimInt);
+ DoFieldGet(self, shadow_frame, inst, InstancePrimitiveRead, Primitive::kPrimInt);
break;
case Instruction::IGET_WIDE:
- DoFieldGet(self, shadow_frame, dec_insn, InstancePrimitiveRead, Primitive::kPrimLong);
+ DoFieldGet(self, shadow_frame, inst, InstancePrimitiveRead, Primitive::kPrimLong);
break;
case Instruction::IGET_OBJECT:
- DoFieldGet(self, shadow_frame, dec_insn, InstanceObjectRead, Primitive::kPrimNot);
+ DoFieldGet(self, shadow_frame, inst, InstanceObjectRead, Primitive::kPrimNot);
break;
case Instruction::SGET_BOOLEAN:
- DoFieldGet(self, shadow_frame, dec_insn, StaticPrimitiveRead, Primitive::kPrimBoolean);
+ DoFieldGet(self, shadow_frame, inst, StaticPrimitiveRead, Primitive::kPrimBoolean);
break;
case Instruction::SGET_BYTE:
- DoFieldGet(self, shadow_frame, dec_insn, StaticPrimitiveRead, Primitive::kPrimByte);
+ DoFieldGet(self, shadow_frame, inst, StaticPrimitiveRead, Primitive::kPrimByte);
break;
case Instruction::SGET_CHAR:
- DoFieldGet(self, shadow_frame, dec_insn, StaticPrimitiveRead, Primitive::kPrimChar);
+ DoFieldGet(self, shadow_frame, inst, StaticPrimitiveRead, Primitive::kPrimChar);
break;
case Instruction::SGET_SHORT:
- DoFieldGet(self, shadow_frame, dec_insn, StaticPrimitiveRead, Primitive::kPrimShort);
+ DoFieldGet(self, shadow_frame, inst, StaticPrimitiveRead, Primitive::kPrimShort);
break;
case Instruction::SGET:
- DoFieldGet(self, shadow_frame, dec_insn, StaticPrimitiveRead, Primitive::kPrimInt);
+ DoFieldGet(self, shadow_frame, inst, StaticPrimitiveRead, Primitive::kPrimInt);
break;
case Instruction::SGET_WIDE:
- DoFieldGet(self, shadow_frame, dec_insn, StaticPrimitiveRead, Primitive::kPrimLong);
+ DoFieldGet(self, shadow_frame, inst, StaticPrimitiveRead, Primitive::kPrimLong);
break;
case Instruction::SGET_OBJECT:
- DoFieldGet(self, shadow_frame, dec_insn, StaticObjectRead, Primitive::kPrimNot);
+ DoFieldGet(self, shadow_frame, inst, StaticObjectRead, Primitive::kPrimNot);
break;
case Instruction::IPUT_BOOLEAN:
- DoFieldPut(self, shadow_frame, dec_insn, InstancePrimitiveWrite, Primitive::kPrimBoolean);
+ DoFieldPut(self, shadow_frame, inst, InstancePrimitiveWrite, Primitive::kPrimBoolean);
break;
case Instruction::IPUT_BYTE:
- DoFieldPut(self, shadow_frame, dec_insn, InstancePrimitiveWrite, Primitive::kPrimByte);
+ DoFieldPut(self, shadow_frame, inst, InstancePrimitiveWrite, Primitive::kPrimByte);
break;
case Instruction::IPUT_CHAR:
- DoFieldPut(self, shadow_frame, dec_insn, InstancePrimitiveWrite, Primitive::kPrimChar);
+ DoFieldPut(self, shadow_frame, inst, InstancePrimitiveWrite, Primitive::kPrimChar);
break;
case Instruction::IPUT_SHORT:
- DoFieldPut(self, shadow_frame, dec_insn, InstancePrimitiveWrite, Primitive::kPrimShort);
+ DoFieldPut(self, shadow_frame, inst, InstancePrimitiveWrite, Primitive::kPrimShort);
break;
case Instruction::IPUT:
- DoFieldPut(self, shadow_frame, dec_insn, InstancePrimitiveWrite, Primitive::kPrimInt);
+ DoFieldPut(self, shadow_frame, inst, InstancePrimitiveWrite, Primitive::kPrimInt);
break;
case Instruction::IPUT_WIDE:
- DoFieldPut(self, shadow_frame, dec_insn, InstancePrimitiveWrite, Primitive::kPrimLong);
+ DoFieldPut(self, shadow_frame, inst, InstancePrimitiveWrite, Primitive::kPrimLong);
break;
case Instruction::IPUT_OBJECT:
- DoFieldPut(self, shadow_frame, dec_insn, InstanceObjectWrite, Primitive::kPrimNot);
+ DoFieldPut(self, shadow_frame, inst, InstanceObjectWrite, Primitive::kPrimNot);
break;
case Instruction::SPUT_BOOLEAN:
- DoFieldPut(self, shadow_frame, dec_insn, StaticPrimitiveWrite, Primitive::kPrimBoolean);
+ DoFieldPut(self, shadow_frame, inst, StaticPrimitiveWrite, Primitive::kPrimBoolean);
break;
case Instruction::SPUT_BYTE:
- DoFieldPut(self, shadow_frame, dec_insn, StaticPrimitiveWrite, Primitive::kPrimByte);
+ DoFieldPut(self, shadow_frame, inst, StaticPrimitiveWrite, Primitive::kPrimByte);
break;
case Instruction::SPUT_CHAR:
- DoFieldPut(self, shadow_frame, dec_insn, StaticPrimitiveWrite, Primitive::kPrimChar);
+ DoFieldPut(self, shadow_frame, inst, StaticPrimitiveWrite, Primitive::kPrimChar);
break;
case Instruction::SPUT_SHORT:
- DoFieldPut(self, shadow_frame, dec_insn, StaticPrimitiveWrite, Primitive::kPrimShort);
+ DoFieldPut(self, shadow_frame, inst, StaticPrimitiveWrite, Primitive::kPrimShort);
break;
case Instruction::SPUT:
- DoFieldPut(self, shadow_frame, dec_insn, StaticPrimitiveWrite, Primitive::kPrimInt);
+ DoFieldPut(self, shadow_frame, inst, StaticPrimitiveWrite, Primitive::kPrimInt);
break;
case Instruction::SPUT_WIDE:
- DoFieldPut(self, shadow_frame, dec_insn, StaticPrimitiveWrite, Primitive::kPrimLong);
+ DoFieldPut(self, shadow_frame, inst, StaticPrimitiveWrite, Primitive::kPrimLong);
break;
case Instruction::SPUT_OBJECT:
- DoFieldPut(self, shadow_frame, dec_insn, StaticObjectWrite, Primitive::kPrimNot);
+ DoFieldPut(self, shadow_frame, inst, StaticObjectWrite, Primitive::kPrimNot);
break;
case Instruction::INVOKE_VIRTUAL:
- DoInvoke(self, mh, shadow_frame, dec_insn, kVirtual, false, &result_register);
+ DoInvoke(self, mh, shadow_frame, inst, kVirtual, false, &result_register);
break;
case Instruction::INVOKE_VIRTUAL_RANGE:
- DoInvoke(self, mh, shadow_frame, dec_insn, kVirtual, true, &result_register);
+ DoInvoke(self, mh, shadow_frame, inst, kVirtual, true, &result_register);
break;
case Instruction::INVOKE_SUPER:
- DoInvoke(self, mh, shadow_frame, dec_insn, kSuper, false, &result_register);
+ DoInvoke(self, mh, shadow_frame, inst, kSuper, false, &result_register);
break;
case Instruction::INVOKE_SUPER_RANGE:
- DoInvoke(self, mh, shadow_frame, dec_insn, kSuper, true, &result_register);
+ DoInvoke(self, mh, shadow_frame, inst, kSuper, true, &result_register);
break;
case Instruction::INVOKE_DIRECT:
- DoInvoke(self, mh, shadow_frame, dec_insn, kDirect, false, &result_register);
+ DoInvoke(self, mh, shadow_frame, inst, kDirect, false, &result_register);
break;
case Instruction::INVOKE_DIRECT_RANGE:
- DoInvoke(self, mh, shadow_frame, dec_insn, kDirect, true, &result_register);
+ DoInvoke(self, mh, shadow_frame, inst, kDirect, true, &result_register);
break;
case Instruction::INVOKE_INTERFACE:
- DoInvoke(self, mh, shadow_frame, dec_insn, kInterface, false, &result_register);
+ DoInvoke(self, mh, shadow_frame, inst, kInterface, false, &result_register);
break;
case Instruction::INVOKE_INTERFACE_RANGE:
- DoInvoke(self, mh, shadow_frame, dec_insn, kInterface, true, &result_register);
+ DoInvoke(self, mh, shadow_frame, inst, kInterface, true, &result_register);
break;
case Instruction::INVOKE_STATIC:
- DoInvoke(self, mh, shadow_frame, dec_insn, kStatic, false, &result_register);
+ DoInvoke(self, mh, shadow_frame, inst, kStatic, false, &result_register);
break;
case Instruction::INVOKE_STATIC_RANGE:
- DoInvoke(self, mh, shadow_frame, dec_insn, kStatic, true, &result_register);
+ DoInvoke(self, mh, shadow_frame, inst, kStatic, true, &result_register);
break;
case Instruction::NEG_INT:
- shadow_frame.SetVReg(dec_insn.vA, -shadow_frame.GetVReg(dec_insn.vB));
+ shadow_frame.SetVReg(inst->VRegA_12x(), -shadow_frame.GetVReg(inst->VRegB_12x()));
break;
case Instruction::NOT_INT:
- shadow_frame.SetVReg(dec_insn.vA, ~shadow_frame.GetVReg(dec_insn.vB));
+ shadow_frame.SetVReg(inst->VRegA_12x(), ~shadow_frame.GetVReg(inst->VRegB_12x()));
break;
case Instruction::NEG_LONG:
- shadow_frame.SetVRegLong(dec_insn.vA, -shadow_frame.GetVRegLong(dec_insn.vB));
+ shadow_frame.SetVRegLong(inst->VRegA_12x(), -shadow_frame.GetVRegLong(inst->VRegB_12x()));
break;
case Instruction::NOT_LONG:
- shadow_frame.SetVRegLong(dec_insn.vA, ~shadow_frame.GetVRegLong(dec_insn.vB));
+ shadow_frame.SetVRegLong(inst->VRegA_12x(), ~shadow_frame.GetVRegLong(inst->VRegB_12x()));
break;
case Instruction::NEG_FLOAT:
- shadow_frame.SetVRegFloat(dec_insn.vA, -shadow_frame.GetVRegFloat(dec_insn.vB));
+ shadow_frame.SetVRegFloat(inst->VRegA_12x(), -shadow_frame.GetVRegFloat(inst->VRegB_12x()));
break;
case Instruction::NEG_DOUBLE:
- shadow_frame.SetVRegDouble(dec_insn.vA, -shadow_frame.GetVRegDouble(dec_insn.vB));
+ shadow_frame.SetVRegDouble(inst->VRegA_12x(), -shadow_frame.GetVRegDouble(inst->VRegB_12x()));
break;
case Instruction::INT_TO_LONG:
- shadow_frame.SetVRegLong(dec_insn.vA, shadow_frame.GetVReg(dec_insn.vB));
+ shadow_frame.SetVRegLong(inst->VRegA_12x(), shadow_frame.GetVReg(inst->VRegB_12x()));
break;
case Instruction::INT_TO_FLOAT:
- shadow_frame.SetVRegFloat(dec_insn.vA, shadow_frame.GetVReg(dec_insn.vB));
+ shadow_frame.SetVRegFloat(inst->VRegA_12x(), shadow_frame.GetVReg(inst->VRegB_12x()));
break;
case Instruction::INT_TO_DOUBLE:
- shadow_frame.SetVRegDouble(dec_insn.vA, shadow_frame.GetVReg(dec_insn.vB));
+ shadow_frame.SetVRegDouble(inst->VRegA_12x(), shadow_frame.GetVReg(inst->VRegB_12x()));
break;
case Instruction::LONG_TO_INT:
- shadow_frame.SetVReg(dec_insn.vA, shadow_frame.GetVRegLong(dec_insn.vB));
+ shadow_frame.SetVReg(inst->VRegA_12x(), shadow_frame.GetVRegLong(inst->VRegB_12x()));
break;
case Instruction::LONG_TO_FLOAT:
- shadow_frame.SetVRegFloat(dec_insn.vA, shadow_frame.GetVRegLong(dec_insn.vB));
+ shadow_frame.SetVRegFloat(inst->VRegA_12x(), shadow_frame.GetVRegLong(inst->VRegB_12x()));
break;
case Instruction::LONG_TO_DOUBLE:
- shadow_frame.SetVRegDouble(dec_insn.vA, shadow_frame.GetVRegLong(dec_insn.vB));
+ shadow_frame.SetVRegDouble(inst->VRegA_12x(), shadow_frame.GetVRegLong(inst->VRegB_12x()));
break;
case Instruction::FLOAT_TO_INT: {
- float val = shadow_frame.GetVRegFloat(dec_insn.vB);
+ uint32_t dst = inst->VRegA_12x();
+ float val = shadow_frame.GetVRegFloat(inst->VRegB_12x());
if (val != val) {
- shadow_frame.SetVReg(dec_insn.vA, 0);
+ shadow_frame.SetVReg(dst, 0);
} else if (val > static_cast<float>(kMaxInt)) {
- shadow_frame.SetVReg(dec_insn.vA, kMaxInt);
+ shadow_frame.SetVReg(dst, kMaxInt);
} else if (val < static_cast<float>(kMinInt)) {
- shadow_frame.SetVReg(dec_insn.vA, kMinInt);
+ shadow_frame.SetVReg(dst, kMinInt);
} else {
- shadow_frame.SetVReg(dec_insn.vA, val);
+ shadow_frame.SetVReg(dst, val);
}
break;
}
case Instruction::FLOAT_TO_LONG: {
- float val = shadow_frame.GetVRegFloat(dec_insn.vB);
+ uint32_t dst = inst->VRegA_12x();
+ float val = shadow_frame.GetVRegFloat(inst->VRegB_12x());
if (val != val) {
- shadow_frame.SetVRegLong(dec_insn.vA, 0);
+ shadow_frame.SetVRegLong(dst, 0);
} else if (val > static_cast<float>(kMaxLong)) {
- shadow_frame.SetVRegLong(dec_insn.vA, kMaxLong);
+ shadow_frame.SetVRegLong(dst, kMaxLong);
} else if (val < static_cast<float>(kMinLong)) {
- shadow_frame.SetVRegLong(dec_insn.vA, kMinLong);
+ shadow_frame.SetVRegLong(dst, kMinLong);
} else {
- shadow_frame.SetVRegLong(dec_insn.vA, val);
+ shadow_frame.SetVRegLong(dst, val);
}
break;
}
case Instruction::FLOAT_TO_DOUBLE:
- shadow_frame.SetVRegDouble(dec_insn.vA, shadow_frame.GetVRegFloat(dec_insn.vB));
+ shadow_frame.SetVRegDouble(inst->VRegA_12x(), shadow_frame.GetVRegFloat(inst->VRegB_12x()));
break;
case Instruction::DOUBLE_TO_INT: {
- double val = shadow_frame.GetVRegDouble(dec_insn.vB);
+ uint32_t dst = inst->VRegA_12x();
+ double val = shadow_frame.GetVRegDouble(inst->VRegB_12x());
if (val != val) {
- shadow_frame.SetVReg(dec_insn.vA, 0);
+ shadow_frame.SetVReg(dst, 0);
} else if (val > static_cast<double>(kMaxInt)) {
- shadow_frame.SetVReg(dec_insn.vA, kMaxInt);
+ shadow_frame.SetVReg(dst, kMaxInt);
} else if (val < static_cast<double>(kMinInt)) {
- shadow_frame.SetVReg(dec_insn.vA, kMinInt);
+ shadow_frame.SetVReg(dst, kMinInt);
} else {
- shadow_frame.SetVReg(dec_insn.vA, val);
+ shadow_frame.SetVReg(dst, val);
}
break;
}
case Instruction::DOUBLE_TO_LONG: {
- double val = shadow_frame.GetVRegDouble(dec_insn.vB);
+ uint32_t dst = inst->VRegA_12x();
+ double val = shadow_frame.GetVRegDouble(inst->VRegB_12x());
if (val != val) {
- shadow_frame.SetVRegLong(dec_insn.vA, 0);
+ shadow_frame.SetVRegLong(dst, 0);
} else if (val > static_cast<double>(kMaxLong)) {
- shadow_frame.SetVRegLong(dec_insn.vA, kMaxLong);
+ shadow_frame.SetVRegLong(dst, kMaxLong);
} else if (val < static_cast<double>(kMinLong)) {
- shadow_frame.SetVRegLong(dec_insn.vA, kMinLong);
+ shadow_frame.SetVRegLong(dst, kMinLong);
} else {
- shadow_frame.SetVRegLong(dec_insn.vA, val);
+ shadow_frame.SetVRegLong(dst, val);
}
break;
}
case Instruction::DOUBLE_TO_FLOAT:
- shadow_frame.SetVRegFloat(dec_insn.vA, shadow_frame.GetVRegDouble(dec_insn.vB));
+ shadow_frame.SetVRegFloat(inst->VRegA_12x(), shadow_frame.GetVRegDouble(inst->VRegB_12x()));
break;
case Instruction::INT_TO_BYTE:
- shadow_frame.SetVReg(dec_insn.vA, static_cast<int8_t>(shadow_frame.GetVReg(dec_insn.vB)));
+ shadow_frame.SetVReg(inst->VRegA_12x(),
+ static_cast<int8_t>(shadow_frame.GetVReg(inst->VRegB_12x())));
break;
case Instruction::INT_TO_CHAR:
- shadow_frame.SetVReg(dec_insn.vA, static_cast<uint16_t>(shadow_frame.GetVReg(dec_insn.vB)));
+ shadow_frame.SetVReg(inst->VRegA_12x(),
+ static_cast<uint16_t>(shadow_frame.GetVReg(inst->VRegB_12x())));
break;
case Instruction::INT_TO_SHORT:
- shadow_frame.SetVReg(dec_insn.vA, static_cast<int16_t>(shadow_frame.GetVReg(dec_insn.vB)));
+ shadow_frame.SetVReg(inst->VRegA_12x(),
+ static_cast<int16_t>(shadow_frame.GetVReg(inst->VRegB_12x())));
break;
case Instruction::ADD_INT:
- shadow_frame.SetVReg(dec_insn.vA,
- shadow_frame.GetVReg(dec_insn.vB) + shadow_frame.GetVReg(dec_insn.vC));
+ shadow_frame.SetVReg(inst->VRegA_23x(),
+ shadow_frame.GetVReg(inst->VRegB_23x()) +
+ shadow_frame.GetVReg(inst->VRegC_23x()));
break;
case Instruction::SUB_INT:
- shadow_frame.SetVReg(dec_insn.vA,
- shadow_frame.GetVReg(dec_insn.vB) - shadow_frame.GetVReg(dec_insn.vC));
+ shadow_frame.SetVReg(inst->VRegA_23x(),
+ shadow_frame.GetVReg(inst->VRegB_23x()) -
+ shadow_frame.GetVReg(inst->VRegC_23x()));
break;
case Instruction::MUL_INT:
- shadow_frame.SetVReg(dec_insn.vA,
- shadow_frame.GetVReg(dec_insn.vB) * shadow_frame.GetVReg(dec_insn.vC));
- break;
- case Instruction::REM_INT:
- DoIntRemainder(self, shadow_frame, dec_insn.vA, shadow_frame.GetVReg(dec_insn.vB),
- shadow_frame.GetVReg(dec_insn.vC));
+ shadow_frame.SetVReg(inst->VRegA_23x(),
+ shadow_frame.GetVReg(inst->VRegB_23x()) *
+ shadow_frame.GetVReg(inst->VRegC_23x()));
break;
case Instruction::DIV_INT:
- DoIntDivide(self, shadow_frame, dec_insn.vA, shadow_frame.GetVReg(dec_insn.vB),
- shadow_frame.GetVReg(dec_insn.vC));
+ DoIntDivide(self, shadow_frame, inst->VRegA_23x(),
+ shadow_frame.GetVReg(inst->VRegB_23x()),
+ shadow_frame.GetVReg(inst->VRegC_23x()));
+ break;
+ case Instruction::REM_INT:
+ DoIntRemainder(self, shadow_frame, inst->VRegA_23x(),
+ shadow_frame.GetVReg(inst->VRegB_23x()),
+ shadow_frame.GetVReg(inst->VRegC_23x()));
break;
case Instruction::SHL_INT:
- shadow_frame.SetVReg(dec_insn.vA, shadow_frame.GetVReg(dec_insn.vB) <<
- (shadow_frame.GetVReg(dec_insn.vC) & 0x1f));
+ shadow_frame.SetVReg(inst->VRegA_23x(),
+ shadow_frame.GetVReg(inst->VRegB_23x()) <<
+ (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x1f));
break;
case Instruction::SHR_INT:
- shadow_frame.SetVReg(dec_insn.vA, shadow_frame.GetVReg(dec_insn.vB) >>
- (shadow_frame.GetVReg(dec_insn.vC) & 0x1f));
+ shadow_frame.SetVReg(inst->VRegA_23x(),
+ shadow_frame.GetVReg(inst->VRegB_23x()) >>
+ (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x1f));
break;
case Instruction::USHR_INT:
- shadow_frame.SetVReg(dec_insn.vA,
- static_cast<uint32_t>(shadow_frame.GetVReg(dec_insn.vB)) >>
- (shadow_frame.GetVReg(dec_insn.vC) & 0x1f));
+ shadow_frame.SetVReg(inst->VRegA_23x(),
+ static_cast<uint32_t>(shadow_frame.GetVReg(inst->VRegB_23x())) >>
+ (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x1f));
break;
case Instruction::AND_INT:
- shadow_frame.SetVReg(dec_insn.vA,
- shadow_frame.GetVReg(dec_insn.vB) & shadow_frame.GetVReg(dec_insn.vC));
+ shadow_frame.SetVReg(inst->VRegA_23x(),
+ shadow_frame.GetVReg(inst->VRegB_23x()) &
+ shadow_frame.GetVReg(inst->VRegC_23x()));
break;
case Instruction::OR_INT:
- shadow_frame.SetVReg(dec_insn.vA,
- shadow_frame.GetVReg(dec_insn.vB) | shadow_frame.GetVReg(dec_insn.vC));
+ shadow_frame.SetVReg(inst->VRegA_23x(),
+ shadow_frame.GetVReg(inst->VRegB_23x()) |
+ shadow_frame.GetVReg(inst->VRegC_23x()));
break;
case Instruction::XOR_INT:
- shadow_frame.SetVReg(dec_insn.vA,
- shadow_frame.GetVReg(dec_insn.vB) ^ shadow_frame.GetVReg(dec_insn.vC));
+ shadow_frame.SetVReg(inst->VRegA_23x(),
+ shadow_frame.GetVReg(inst->VRegB_23x()) ^
+ shadow_frame.GetVReg(inst->VRegC_23x()));
break;
case Instruction::ADD_LONG:
- shadow_frame.SetVRegLong(dec_insn.vA,
- shadow_frame.GetVRegLong(dec_insn.vB) +
- shadow_frame.GetVRegLong(dec_insn.vC));
+ shadow_frame.SetVRegLong(inst->VRegA_23x(),
+ shadow_frame.GetVRegLong(inst->VRegB_23x()) +
+ shadow_frame.GetVRegLong(inst->VRegC_23x()));
break;
case Instruction::SUB_LONG:
- shadow_frame.SetVRegLong(dec_insn.vA,
- shadow_frame.GetVRegLong(dec_insn.vB) -
- shadow_frame.GetVRegLong(dec_insn.vC));
+ shadow_frame.SetVRegLong(inst->VRegA_23x(),
+ shadow_frame.GetVRegLong(inst->VRegB_23x()) -
+ shadow_frame.GetVRegLong(inst->VRegC_23x()));
break;
case Instruction::MUL_LONG:
- shadow_frame.SetVRegLong(dec_insn.vA,
- shadow_frame.GetVRegLong(dec_insn.vB) *
- shadow_frame.GetVRegLong(dec_insn.vC));
+ shadow_frame.SetVRegLong(inst->VRegA_23x(),
+ shadow_frame.GetVRegLong(inst->VRegB_23x()) *
+ shadow_frame.GetVRegLong(inst->VRegC_23x()));
break;
case Instruction::DIV_LONG:
- DoLongDivide(self, shadow_frame, dec_insn.vA, shadow_frame.GetVRegLong(dec_insn.vB),
- shadow_frame.GetVRegLong(dec_insn.vC));
+ DoLongDivide(self, shadow_frame, inst->VRegA_23x(),
+ shadow_frame.GetVRegLong(inst->VRegB_23x()),
+ shadow_frame.GetVRegLong(inst->VRegC_23x()));
break;
case Instruction::REM_LONG:
- DoLongRemainder(self, shadow_frame, dec_insn.vA, shadow_frame.GetVRegLong(dec_insn.vB),
- shadow_frame.GetVRegLong(dec_insn.vC));
+ DoLongRemainder(self, shadow_frame, inst->VRegA_23x(),
+ shadow_frame.GetVRegLong(inst->VRegB_23x()),
+ shadow_frame.GetVRegLong(inst->VRegC_23x()));
break;
case Instruction::AND_LONG:
- shadow_frame.SetVRegLong(dec_insn.vA,
- shadow_frame.GetVRegLong(dec_insn.vB) &
- shadow_frame.GetVRegLong(dec_insn.vC));
+ shadow_frame.SetVRegLong(inst->VRegA_23x(),
+ shadow_frame.GetVRegLong(inst->VRegB_23x()) &
+ shadow_frame.GetVRegLong(inst->VRegC_23x()));
break;
case Instruction::OR_LONG:
- shadow_frame.SetVRegLong(dec_insn.vA,
- shadow_frame.GetVRegLong(dec_insn.vB) |
- shadow_frame.GetVRegLong(dec_insn.vC));
+ shadow_frame.SetVRegLong(inst->VRegA_23x(),
+ shadow_frame.GetVRegLong(inst->VRegB_23x()) |
+ shadow_frame.GetVRegLong(inst->VRegC_23x()));
break;
case Instruction::XOR_LONG:
- shadow_frame.SetVRegLong(dec_insn.vA,
- shadow_frame.GetVRegLong(dec_insn.vB) ^
- shadow_frame.GetVRegLong(dec_insn.vC));
+ shadow_frame.SetVRegLong(inst->VRegA_23x(),
+ shadow_frame.GetVRegLong(inst->VRegB_23x()) ^
+ shadow_frame.GetVRegLong(inst->VRegC_23x()));
break;
case Instruction::SHL_LONG:
- shadow_frame.SetVRegLong(dec_insn.vA,
- shadow_frame.GetVRegLong(dec_insn.vB) <<
- (shadow_frame.GetVReg(dec_insn.vC) & 0x3f));
+ shadow_frame.SetVRegLong(inst->VRegA_23x(),
+ shadow_frame.GetVRegLong(inst->VRegB_23x()) <<
+ (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x3f));
break;
case Instruction::SHR_LONG:
- shadow_frame.SetVRegLong(dec_insn.vA,
- shadow_frame.GetVRegLong(dec_insn.vB) >>
- (shadow_frame.GetVReg(dec_insn.vC) & 0x3f));
+ shadow_frame.SetVRegLong(inst->VRegA_23x(),
+ shadow_frame.GetVRegLong(inst->VRegB_23x()) >>
+ (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x3f));
break;
case Instruction::USHR_LONG:
- shadow_frame.SetVRegLong(dec_insn.vA,
- static_cast<uint64_t>(shadow_frame.GetVRegLong(dec_insn.vB)) >>
- (shadow_frame.GetVReg(dec_insn.vC) & 0x3f));
+ shadow_frame.SetVRegLong(inst->VRegA_23x(),
+ static_cast<uint64_t>(shadow_frame.GetVRegLong(inst->VRegB_23x())) >>
+ (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x3f));
break;
case Instruction::ADD_FLOAT:
- shadow_frame.SetVRegFloat(dec_insn.vA,
- shadow_frame.GetVRegFloat(dec_insn.vB) +
- shadow_frame.GetVRegFloat(dec_insn.vC));
+ shadow_frame.SetVRegFloat(inst->VRegA_23x(),
+ shadow_frame.GetVRegFloat(inst->VRegB_23x()) +
+ shadow_frame.GetVRegFloat(inst->VRegC_23x()));
break;
case Instruction::SUB_FLOAT:
- shadow_frame.SetVRegFloat(dec_insn.vA,
- shadow_frame.GetVRegFloat(dec_insn.vB) -
- shadow_frame.GetVRegFloat(dec_insn.vC));
+ shadow_frame.SetVRegFloat(inst->VRegA_23x(),
+ shadow_frame.GetVRegFloat(inst->VRegB_23x()) -
+ shadow_frame.GetVRegFloat(inst->VRegC_23x()));
break;
case Instruction::MUL_FLOAT:
- shadow_frame.SetVRegFloat(dec_insn.vA,
- shadow_frame.GetVRegFloat(dec_insn.vB) *
- shadow_frame.GetVRegFloat(dec_insn.vC));
+ shadow_frame.SetVRegFloat(inst->VRegA_23x(),
+ shadow_frame.GetVRegFloat(inst->VRegB_23x()) *
+ shadow_frame.GetVRegFloat(inst->VRegC_23x()));
break;
case Instruction::DIV_FLOAT:
- shadow_frame.SetVRegFloat(dec_insn.vA,
- shadow_frame.GetVRegFloat(dec_insn.vB) /
- shadow_frame.GetVRegFloat(dec_insn.vC));
+ shadow_frame.SetVRegFloat(inst->VRegA_23x(),
+ shadow_frame.GetVRegFloat(inst->VRegB_23x()) /
+ shadow_frame.GetVRegFloat(inst->VRegC_23x()));
break;
case Instruction::REM_FLOAT:
- shadow_frame.SetVRegFloat(dec_insn.vA,
- fmodf(shadow_frame.GetVRegFloat(dec_insn.vB),
- shadow_frame.GetVRegFloat(dec_insn.vC)));
+ shadow_frame.SetVRegFloat(inst->VRegA_23x(),
+ fmodf(shadow_frame.GetVRegFloat(inst->VRegB_23x()),
+ shadow_frame.GetVRegFloat(inst->VRegC_23x())));
break;
case Instruction::ADD_DOUBLE:
- shadow_frame.SetVRegDouble(dec_insn.vA,
- shadow_frame.GetVRegDouble(dec_insn.vB) +
- shadow_frame.GetVRegDouble(dec_insn.vC));
+ shadow_frame.SetVRegDouble(inst->VRegA_23x(),
+ shadow_frame.GetVRegDouble(inst->VRegB_23x()) +
+ shadow_frame.GetVRegDouble(inst->VRegC_23x()));
break;
case Instruction::SUB_DOUBLE:
- shadow_frame.SetVRegDouble(dec_insn.vA,
- shadow_frame.GetVRegDouble(dec_insn.vB) -
- shadow_frame.GetVRegDouble(dec_insn.vC));
+ shadow_frame.SetVRegDouble(inst->VRegA_23x(),
+ shadow_frame.GetVRegDouble(inst->VRegB_23x()) -
+ shadow_frame.GetVRegDouble(inst->VRegC_23x()));
break;
case Instruction::MUL_DOUBLE:
- shadow_frame.SetVRegDouble(dec_insn.vA,
- shadow_frame.GetVRegDouble(dec_insn.vB) *
- shadow_frame.GetVRegDouble(dec_insn.vC));
+ shadow_frame.SetVRegDouble(inst->VRegA_23x(),
+ shadow_frame.GetVRegDouble(inst->VRegB_23x()) *
+ shadow_frame.GetVRegDouble(inst->VRegC_23x()));
break;
case Instruction::DIV_DOUBLE:
- shadow_frame.SetVRegDouble(dec_insn.vA,
- shadow_frame.GetVRegDouble(dec_insn.vB) /
- shadow_frame.GetVRegDouble(dec_insn.vC));
+ shadow_frame.SetVRegDouble(inst->VRegA_23x(),
+ shadow_frame.GetVRegDouble(inst->VRegB_23x()) /
+ shadow_frame.GetVRegDouble(inst->VRegC_23x()));
break;
case Instruction::REM_DOUBLE:
- shadow_frame.SetVRegDouble(dec_insn.vA,
- fmod(shadow_frame.GetVRegDouble(dec_insn.vB),
- shadow_frame.GetVRegDouble(dec_insn.vC)));
+ shadow_frame.SetVRegDouble(inst->VRegA_23x(),
+ fmod(shadow_frame.GetVRegDouble(inst->VRegB_23x()),
+ shadow_frame.GetVRegDouble(inst->VRegC_23x())));
break;
- case Instruction::ADD_INT_2ADDR:
- shadow_frame.SetVReg(dec_insn.vA,
- shadow_frame.GetVReg(dec_insn.vA) + shadow_frame.GetVReg(dec_insn.vB));
+ case Instruction::ADD_INT_2ADDR: {
+ uint32_t vregA = inst->VRegA_12x();
+ shadow_frame.SetVReg(vregA,
+ shadow_frame.GetVReg(vregA) +
+ shadow_frame.GetVReg(inst->VRegB_12x()));
break;
- case Instruction::SUB_INT_2ADDR:
- shadow_frame.SetVReg(dec_insn.vA,
- shadow_frame.GetVReg(dec_insn.vA) - shadow_frame.GetVReg(dec_insn.vB));
+ }
+ case Instruction::SUB_INT_2ADDR: {
+ uint32_t vregA = inst->VRegA_12x();
+ shadow_frame.SetVReg(vregA,
+ shadow_frame.GetVReg(vregA) -
+ shadow_frame.GetVReg(inst->VRegB_12x()));
break;
- case Instruction::MUL_INT_2ADDR:
- shadow_frame.SetVReg(dec_insn.vA,
- shadow_frame.GetVReg(dec_insn.vA) * shadow_frame.GetVReg(dec_insn.vB));
+ }
+ case Instruction::MUL_INT_2ADDR: {
+ uint32_t vregA = inst->VRegA_12x();
+ shadow_frame.SetVReg(vregA,
+ shadow_frame.GetVReg(vregA) *
+ shadow_frame.GetVReg(inst->VRegB_12x()));
break;
- case Instruction::REM_INT_2ADDR:
- DoIntRemainder(self, shadow_frame, dec_insn.vA, shadow_frame.GetVReg(dec_insn.vA),
- shadow_frame.GetVReg(dec_insn.vB));
+ }
+ case Instruction::REM_INT_2ADDR: {
+ uint32_t vregA = inst->VRegA_12x();
+ DoIntRemainder(self, shadow_frame, vregA, shadow_frame.GetVReg(vregA),
+ shadow_frame.GetVReg(inst->VRegB_12x()));
break;
- case Instruction::SHL_INT_2ADDR:
- shadow_frame.SetVReg(dec_insn.vA, shadow_frame.GetVReg(dec_insn.vA) <<
- (shadow_frame.GetVReg(dec_insn.vB) & 0x1f));
+ }
+ case Instruction::SHL_INT_2ADDR:{
+ uint32_t vregA = inst->VRegA_12x();
+ shadow_frame.SetVReg(vregA,
+ shadow_frame.GetVReg(vregA) <<
+ (shadow_frame.GetVReg(inst->VRegB_12x()) & 0x1f));
break;
- case Instruction::SHR_INT_2ADDR:
- shadow_frame.SetVReg(dec_insn.vA, shadow_frame.GetVReg(dec_insn.vA) >>
- (shadow_frame.GetVReg(dec_insn.vB) & 0x1f));
+ }
+ case Instruction::SHR_INT_2ADDR: {
+ uint32_t vregA = inst->VRegA_12x();
+ shadow_frame.SetVReg(vregA,
+ shadow_frame.GetVReg(vregA) >>
+ (shadow_frame.GetVReg(inst->VRegB_12x()) & 0x1f));
break;
- case Instruction::USHR_INT_2ADDR:
- shadow_frame.SetVReg(dec_insn.vA,
- static_cast<uint32_t>(shadow_frame.GetVReg(dec_insn.vA)) >>
- (shadow_frame.GetVReg(dec_insn.vB) & 0x1f));
+ }
+ case Instruction::USHR_INT_2ADDR: {
+ uint32_t vregA = inst->VRegA_12x();
+ shadow_frame.SetVReg(vregA,
+ static_cast<uint32_t>(shadow_frame.GetVReg(vregA)) >>
+ (shadow_frame.GetVReg(inst->VRegB_12x()) & 0x1f));
break;
- case Instruction::AND_INT_2ADDR:
- shadow_frame.SetVReg(dec_insn.vA,
- shadow_frame.GetVReg(dec_insn.vA) & shadow_frame.GetVReg(dec_insn.vB));
+ }
+ case Instruction::AND_INT_2ADDR: {
+ uint32_t vregA = inst->VRegA_12x();
+ shadow_frame.SetVReg(vregA,
+ shadow_frame.GetVReg(vregA) &
+ shadow_frame.GetVReg(inst->VRegB_12x()));
break;
- case Instruction::OR_INT_2ADDR:
- shadow_frame.SetVReg(dec_insn.vA,
- shadow_frame.GetVReg(dec_insn.vA) | shadow_frame.GetVReg(dec_insn.vB));
+ }
+ case Instruction::OR_INT_2ADDR: {
+ uint32_t vregA = inst->VRegA_12x();
+ shadow_frame.SetVReg(vregA,
+ shadow_frame.GetVReg(vregA) |
+ shadow_frame.GetVReg(inst->VRegB_12x()));
break;
- case Instruction::XOR_INT_2ADDR:
- shadow_frame.SetVReg(dec_insn.vA,
- shadow_frame.GetVReg(dec_insn.vA) ^ shadow_frame.GetVReg(dec_insn.vB));
+ }
+ case Instruction::XOR_INT_2ADDR: {
+ uint32_t vregA = inst->VRegA_12x();
+ shadow_frame.SetVReg(vregA,
+ shadow_frame.GetVReg(vregA) ^
+ shadow_frame.GetVReg(inst->VRegB_12x()));
break;
- case Instruction::DIV_INT_2ADDR:
- DoIntDivide(self, shadow_frame, dec_insn.vA, shadow_frame.GetVReg(dec_insn.vA),
- shadow_frame.GetVReg(dec_insn.vB));
+ }
+ case Instruction::DIV_INT_2ADDR: {
+ uint32_t vregA = inst->VRegA_12x();
+ DoIntDivide(self, shadow_frame, vregA, shadow_frame.GetVReg(vregA),
+ shadow_frame.GetVReg(inst->VRegB_12x()));
break;
- case Instruction::ADD_LONG_2ADDR:
- shadow_frame.SetVRegLong(dec_insn.vA,
- shadow_frame.GetVRegLong(dec_insn.vA) +
- shadow_frame.GetVRegLong(dec_insn.vB));
+ }
+ case Instruction::ADD_LONG_2ADDR: {
+ uint32_t vregA = inst->VRegA_12x();
+ shadow_frame.SetVRegLong(vregA,
+ shadow_frame.GetVRegLong(vregA) +
+ shadow_frame.GetVRegLong(inst->VRegB_12x()));
break;
- case Instruction::SUB_LONG_2ADDR:
- shadow_frame.SetVRegLong(dec_insn.vA,
- shadow_frame.GetVRegLong(dec_insn.vA) -
- shadow_frame.GetVRegLong(dec_insn.vB));
+ }
+ case Instruction::SUB_LONG_2ADDR: {
+ uint32_t vregA = inst->VRegA_12x();
+ shadow_frame.SetVRegLong(vregA,
+ shadow_frame.GetVRegLong(vregA) -
+ shadow_frame.GetVRegLong(inst->VRegB_12x()));
break;
- case Instruction::MUL_LONG_2ADDR:
- shadow_frame.SetVRegLong(dec_insn.vA,
- shadow_frame.GetVRegLong(dec_insn.vA) *
- shadow_frame.GetVRegLong(dec_insn.vB));
+ }
+ case Instruction::MUL_LONG_2ADDR: {
+ uint32_t vregA = inst->VRegA_12x();
+ shadow_frame.SetVRegLong(vregA,
+ shadow_frame.GetVRegLong(vregA) *
+ shadow_frame.GetVRegLong(inst->VRegB_12x()));
break;
- case Instruction::DIV_LONG_2ADDR:
- DoLongDivide(self, shadow_frame, dec_insn.vA, shadow_frame.GetVRegLong(dec_insn.vA),
- shadow_frame.GetVRegLong(dec_insn.vB));
+ }
+ case Instruction::DIV_LONG_2ADDR: {
+ uint32_t vregA = inst->VRegA_12x();
+ DoLongDivide(self, shadow_frame, vregA, shadow_frame.GetVRegLong(vregA),
+ shadow_frame.GetVRegLong(inst->VRegB_12x()));
break;
- case Instruction::REM_LONG_2ADDR:
- DoLongRemainder(self, shadow_frame, dec_insn.vA, shadow_frame.GetVRegLong(dec_insn.vA),
- shadow_frame.GetVRegLong(dec_insn.vB));
+ }
+ case Instruction::REM_LONG_2ADDR: {
+ uint32_t vregA = inst->VRegA_12x();
+ DoLongRemainder(self, shadow_frame, vregA, shadow_frame.GetVRegLong(vregA),
+ shadow_frame.GetVRegLong(inst->VRegB_12x()));
break;
- case Instruction::AND_LONG_2ADDR:
- shadow_frame.SetVRegLong(dec_insn.vA,
- shadow_frame.GetVRegLong(dec_insn.vA) &
- shadow_frame.GetVRegLong(dec_insn.vB));
+ }
+ case Instruction::AND_LONG_2ADDR: {
+ uint32_t vregA = inst->VRegA_12x();
+ shadow_frame.SetVRegLong(vregA,
+ shadow_frame.GetVRegLong(vregA) &
+ shadow_frame.GetVRegLong(inst->VRegB_12x()));
break;
- case Instruction::OR_LONG_2ADDR:
- shadow_frame.SetVRegLong(dec_insn.vA,
- shadow_frame.GetVRegLong(dec_insn.vA) |
- shadow_frame.GetVRegLong(dec_insn.vB));
+ }
+ case Instruction::OR_LONG_2ADDR: {
+ uint32_t vregA = inst->VRegA_12x();
+ shadow_frame.SetVRegLong(vregA,
+ shadow_frame.GetVRegLong(vregA) |
+ shadow_frame.GetVRegLong(inst->VRegB_12x()));
break;
- case Instruction::XOR_LONG_2ADDR:
- shadow_frame.SetVRegLong(dec_insn.vA,
- shadow_frame.GetVRegLong(dec_insn.vA) ^
- shadow_frame.GetVRegLong(dec_insn.vB));
+ }
+ case Instruction::XOR_LONG_2ADDR: {
+ uint32_t vregA = inst->VRegA_12x();
+ shadow_frame.SetVRegLong(vregA,
+ shadow_frame.GetVRegLong(vregA) ^
+ shadow_frame.GetVRegLong(inst->VRegB_12x()));
break;
- case Instruction::SHL_LONG_2ADDR:
- shadow_frame.SetVRegLong(dec_insn.vA,
- shadow_frame.GetVRegLong(dec_insn.vA) <<
- (shadow_frame.GetVReg(dec_insn.vB) & 0x3f));
+ }
+ case Instruction::SHL_LONG_2ADDR: {
+ uint32_t vregA = inst->VRegA_12x();
+ shadow_frame.SetVRegLong(vregA,
+ shadow_frame.GetVRegLong(vregA) <<
+ (shadow_frame.GetVReg(inst->VRegB_12x()) & 0x3f));
break;
- case Instruction::SHR_LONG_2ADDR:
- shadow_frame.SetVRegLong(dec_insn.vA,
- shadow_frame.GetVRegLong(dec_insn.vA) >>
- (shadow_frame.GetVReg(dec_insn.vB) & 0x3f));
+ }
+ case Instruction::SHR_LONG_2ADDR: {
+ uint32_t vregA = inst->VRegA_12x();
+ shadow_frame.SetVRegLong(vregA,
+ shadow_frame.GetVRegLong(vregA) >>
+ (shadow_frame.GetVReg(inst->VRegB_12x()) & 0x3f));
break;
- case Instruction::USHR_LONG_2ADDR:
- shadow_frame.SetVRegLong(dec_insn.vA,
- static_cast<uint64_t>(shadow_frame.GetVRegLong(dec_insn.vA)) >>
- (shadow_frame.GetVReg(dec_insn.vB) & 0x3f));
+ }
+ case Instruction::USHR_LONG_2ADDR: {
+ uint32_t vregA = inst->VRegA_12x();
+ shadow_frame.SetVRegLong(vregA,
+ static_cast<uint64_t>(shadow_frame.GetVRegLong(vregA)) >>
+ (shadow_frame.GetVReg(inst->VRegB_12x()) & 0x3f));
break;
- case Instruction::ADD_FLOAT_2ADDR:
- shadow_frame.SetVRegFloat(dec_insn.vA,
- shadow_frame.GetVRegFloat(dec_insn.vA) +
- shadow_frame.GetVRegFloat(dec_insn.vB));
+ }
+ case Instruction::ADD_FLOAT_2ADDR: {
+ uint32_t vregA = inst->VRegA_12x();
+ shadow_frame.SetVRegFloat(vregA,
+ shadow_frame.GetVRegFloat(vregA) +
+ shadow_frame.GetVRegFloat(inst->VRegB_12x()));
break;
- case Instruction::SUB_FLOAT_2ADDR:
- shadow_frame.SetVRegFloat(dec_insn.vA,
- shadow_frame.GetVRegFloat(dec_insn.vA) -
- shadow_frame.GetVRegFloat(dec_insn.vB));
+ }
+ case Instruction::SUB_FLOAT_2ADDR: {
+ uint32_t vregA = inst->VRegA_12x();
+ shadow_frame.SetVRegFloat(vregA,
+ shadow_frame.GetVRegFloat(vregA) -
+ shadow_frame.GetVRegFloat(inst->VRegB_12x()));
break;
- case Instruction::MUL_FLOAT_2ADDR:
- shadow_frame.SetVRegFloat(dec_insn.vA,
- shadow_frame.GetVRegFloat(dec_insn.vA) *
- shadow_frame.GetVRegFloat(dec_insn.vB));
+ }
+ case Instruction::MUL_FLOAT_2ADDR: {
+ uint32_t vregA = inst->VRegA_12x();
+ shadow_frame.SetVRegFloat(vregA,
+ shadow_frame.GetVRegFloat(vregA) *
+ shadow_frame.GetVRegFloat(inst->VRegB_12x()));
break;
- case Instruction::DIV_FLOAT_2ADDR:
- shadow_frame.SetVRegFloat(dec_insn.vA,
- shadow_frame.GetVRegFloat(dec_insn.vA) /
- shadow_frame.GetVRegFloat(dec_insn.vB));
+ }
+ case Instruction::DIV_FLOAT_2ADDR: {
+ uint32_t vregA = inst->VRegA_12x();
+ shadow_frame.SetVRegFloat(vregA,
+ shadow_frame.GetVRegFloat(vregA) /
+ shadow_frame.GetVRegFloat(inst->VRegB_12x()));
break;
- case Instruction::REM_FLOAT_2ADDR:
- shadow_frame.SetVRegFloat(dec_insn.vA,
- fmodf(shadow_frame.GetVRegFloat(dec_insn.vA),
- shadow_frame.GetVRegFloat(dec_insn.vB)));
+ }
+ case Instruction::REM_FLOAT_2ADDR: {
+ uint32_t vregA = inst->VRegA_12x();
+ shadow_frame.SetVRegFloat(vregA,
+ fmodf(shadow_frame.GetVRegFloat(vregA),
+ shadow_frame.GetVRegFloat(inst->VRegB_12x())));
break;
- case Instruction::ADD_DOUBLE_2ADDR:
- shadow_frame.SetVRegDouble(dec_insn.vA,
- shadow_frame.GetVRegDouble(dec_insn.vA) +
- shadow_frame.GetVRegDouble(dec_insn.vB));
+ }
+ case Instruction::ADD_DOUBLE_2ADDR: {
+ uint32_t vregA = inst->VRegA_12x();
+ shadow_frame.SetVRegDouble(vregA,
+ shadow_frame.GetVRegDouble(vregA) +
+ shadow_frame.GetVRegDouble(inst->VRegB_12x()));
break;
- case Instruction::SUB_DOUBLE_2ADDR:
- shadow_frame.SetVRegDouble(dec_insn.vA,
- shadow_frame.GetVRegDouble(dec_insn.vA) -
- shadow_frame.GetVRegDouble(dec_insn.vB));
+ }
+ case Instruction::SUB_DOUBLE_2ADDR: {
+ uint32_t vregA = inst->VRegA_12x();
+ shadow_frame.SetVRegDouble(vregA,
+ shadow_frame.GetVRegDouble(vregA) -
+ shadow_frame.GetVRegDouble(inst->VRegB_12x()));
break;
- case Instruction::MUL_DOUBLE_2ADDR:
- shadow_frame.SetVRegDouble(dec_insn.vA,
- shadow_frame.GetVRegDouble(dec_insn.vA) *
- shadow_frame.GetVRegDouble(dec_insn.vB));
+ }
+ case Instruction::MUL_DOUBLE_2ADDR: {
+ uint32_t vregA = inst->VRegA_12x();
+ shadow_frame.SetVRegDouble(vregA,
+ shadow_frame.GetVRegDouble(vregA) *
+ shadow_frame.GetVRegDouble(inst->VRegB_12x()));
break;
- case Instruction::DIV_DOUBLE_2ADDR:
- shadow_frame.SetVRegDouble(dec_insn.vA,
- shadow_frame.GetVRegDouble(dec_insn.vA) /
- shadow_frame.GetVRegDouble(dec_insn.vB));
+ }
+ case Instruction::DIV_DOUBLE_2ADDR: {
+ uint32_t vregA = inst->VRegA_12x();
+ shadow_frame.SetVRegDouble(vregA,
+ shadow_frame.GetVRegDouble(vregA) /
+ shadow_frame.GetVRegDouble(inst->VRegB_12x()));
break;
- case Instruction::REM_DOUBLE_2ADDR:
- shadow_frame.SetVRegDouble(dec_insn.vA,
- fmod(shadow_frame.GetVRegDouble(dec_insn.vA),
- shadow_frame.GetVRegDouble(dec_insn.vB)));
+ }
+ case Instruction::REM_DOUBLE_2ADDR: {
+ uint32_t vregA = inst->VRegA_12x();
+ shadow_frame.SetVRegDouble(vregA,
+ fmod(shadow_frame.GetVRegDouble(vregA),
+ shadow_frame.GetVRegDouble(inst->VRegB_12x())));
break;
+ }
case Instruction::ADD_INT_LIT16:
- case Instruction::ADD_INT_LIT8:
- shadow_frame.SetVReg(dec_insn.vA, shadow_frame.GetVReg(dec_insn.vB) + dec_insn.vC);
+ shadow_frame.SetVReg(inst->VRegA_22s(),
+ shadow_frame.GetVReg(inst->VRegB_22s()) +
+ inst->VRegC_22s());
break;
case Instruction::RSUB_INT:
- case Instruction::RSUB_INT_LIT8:
- shadow_frame.SetVReg(dec_insn.vA, dec_insn.vC - shadow_frame.GetVReg(dec_insn.vB));
+ shadow_frame.SetVReg(inst->VRegA_22s(),
+ inst->VRegC_22s() -
+ shadow_frame.GetVReg(inst->VRegB_22s()));
break;
case Instruction::MUL_INT_LIT16:
- case Instruction::MUL_INT_LIT8:
- shadow_frame.SetVReg(dec_insn.vA, shadow_frame.GetVReg(dec_insn.vB) * dec_insn.vC);
+ shadow_frame.SetVReg(inst->VRegA_22s(),
+ shadow_frame.GetVReg(inst->VRegB_22s()) *
+ inst->VRegC_22s());
break;
case Instruction::DIV_INT_LIT16:
- case Instruction::DIV_INT_LIT8:
- DoIntDivide(self, shadow_frame, dec_insn.vA, shadow_frame.GetVReg(dec_insn.vB),
- dec_insn.vC);
+ DoIntDivide(self, shadow_frame, inst->VRegA_22s(),
+ shadow_frame.GetVReg(inst->VRegB_22s()), inst->VRegC_22s());
break;
case Instruction::REM_INT_LIT16:
- case Instruction::REM_INT_LIT8:
- DoIntRemainder(self, shadow_frame, dec_insn.vA, shadow_frame.GetVReg(dec_insn.vB),
- dec_insn.vC);
+ DoIntRemainder(self, shadow_frame, inst->VRegA_22s(),
+ shadow_frame.GetVReg(inst->VRegB_22s()), inst->VRegC_22s());
break;
case Instruction::AND_INT_LIT16:
- case Instruction::AND_INT_LIT8:
- shadow_frame.SetVReg(dec_insn.vA, shadow_frame.GetVReg(dec_insn.vB) & dec_insn.vC);
+ shadow_frame.SetVReg(inst->VRegA_22s(),
+ shadow_frame.GetVReg(inst->VRegB_22s()) &
+ inst->VRegC_22s());
break;
case Instruction::OR_INT_LIT16:
- case Instruction::OR_INT_LIT8:
- shadow_frame.SetVReg(dec_insn.vA, shadow_frame.GetVReg(dec_insn.vB) | dec_insn.vC);
+ shadow_frame.SetVReg(inst->VRegA_22s(),
+ shadow_frame.GetVReg(inst->VRegB_22s()) |
+ inst->VRegC_22s());
break;
case Instruction::XOR_INT_LIT16:
+ shadow_frame.SetVReg(inst->VRegA_22s(),
+ shadow_frame.GetVReg(inst->VRegB_22s()) ^
+ inst->VRegC_22s());
+ break;
+ case Instruction::ADD_INT_LIT8:
+ shadow_frame.SetVReg(inst->VRegA_22b(),
+ shadow_frame.GetVReg(inst->VRegB_22b()) +
+ inst->VRegC_22b());
+ break;
+ case Instruction::RSUB_INT_LIT8:
+ shadow_frame.SetVReg(inst->VRegA_22b(),
+ inst->VRegC_22b() -
+ shadow_frame.GetVReg(inst->VRegB_22b()));
+ break;
+ case Instruction::MUL_INT_LIT8:
+ shadow_frame.SetVReg(inst->VRegA_22b(),
+ shadow_frame.GetVReg(inst->VRegB_22b()) *
+ inst->VRegC_22b());
+ break;
+ case Instruction::DIV_INT_LIT8:
+ DoIntDivide(self, shadow_frame, inst->VRegA_22b(),
+ shadow_frame.GetVReg(inst->VRegB_22b()), inst->VRegC_22b());
+ break;
+ case Instruction::REM_INT_LIT8:
+ DoIntRemainder(self, shadow_frame, inst->VRegA_22b(),
+ shadow_frame.GetVReg(inst->VRegB_22b()), inst->VRegC_22b());
+ break;
+ case Instruction::AND_INT_LIT8:
+ shadow_frame.SetVReg(inst->VRegA_22b(),
+ shadow_frame.GetVReg(inst->VRegB_22b()) &
+ inst->VRegC_22b());
+ break;
+ case Instruction::OR_INT_LIT8:
+ shadow_frame.SetVReg(inst->VRegA_22b(),
+ shadow_frame.GetVReg(inst->VRegB_22b()) |
+ inst->VRegC_22b());
+ break;
case Instruction::XOR_INT_LIT8:
- shadow_frame.SetVReg(dec_insn.vA, shadow_frame.GetVReg(dec_insn.vB) ^ dec_insn.vC);
+ shadow_frame.SetVReg(inst->VRegA_22b(),
+ shadow_frame.GetVReg(inst->VRegB_22b()) ^
+ inst->VRegC_22b());
break;
case Instruction::SHL_INT_LIT8:
- shadow_frame.SetVReg(dec_insn.vA, shadow_frame.GetVReg(dec_insn.vB) <<
- (dec_insn.vC & 0x1f));
+ shadow_frame.SetVReg(inst->VRegA_22b(),
+ shadow_frame.GetVReg(inst->VRegB_22b()) <<
+ (inst->VRegC_22b() & 0x1f));
break;
case Instruction::SHR_INT_LIT8:
- shadow_frame.SetVReg(dec_insn.vA, shadow_frame.GetVReg(dec_insn.vB) >>
- (dec_insn.vC & 0x1f));
+ shadow_frame.SetVReg(inst->VRegA_22b(),
+ shadow_frame.GetVReg(inst->VRegB_22b()) >>
+ (inst->VRegC_22b() & 0x1f));
break;
case Instruction::USHR_INT_LIT8:
- shadow_frame.SetVReg(dec_insn.vA,
- static_cast<uint32_t>(shadow_frame.GetVReg(dec_insn.vB)) >>
- (dec_insn.vC & 0x1f));
+ shadow_frame.SetVReg(inst->VRegA_22b(),
+ static_cast<uint32_t>(shadow_frame.GetVReg(inst->VRegB_22b())) >>
+ (inst->VRegC_22b() & 0x1f));
break;
default:
LOG(FATAL) << "Unexpected instruction: " << inst->DumpString(&mh.GetDexFile());
@@ -1837,18 +2087,17 @@
self->VerifyStack();
ThrowLocation throw_location;
mirror::Throwable* exception = self->GetException(&throw_location);
- uint32_t found_dex_pc =
- shadow_frame.GetMethod()->FindCatchBlock(exception->GetClass(), inst->GetDexPc(insns));
+ uint32_t found_dex_pc = shadow_frame.GetMethod()->FindCatchBlock(exception->GetClass(), dex_pc);
if (found_dex_pc == DexFile::kDexNoIndex) {
JValue result;
result.SetJ(0);
- instrumentation->MethodUnwindEvent(self, shadow_frame.GetThisObject(),
- shadow_frame.GetMethod(), shadow_frame.GetDexPC());
+ instrumentation->MethodUnwindEvent(self, this_object_ref.get(),
+ shadow_frame.GetMethod(), dex_pc);
return result; // Handler in caller.
} else {
- Runtime::Current()->GetInstrumentation()->ExceptionCaughtEvent(self, throw_location,
- shadow_frame.GetMethod(),
- found_dex_pc, exception);
+ instrumentation->ExceptionCaughtEvent(self, throw_location,
+ shadow_frame.GetMethod(),
+ found_dex_pc, exception);
next_inst = Instruction::At(insns + found_dex_pc);
}
}
@@ -1895,10 +2144,12 @@
CHECK(receiver != NULL);
shadow_frame->SetVRegReference(cur_reg, receiver);
++cur_reg;
- } else if (!method->GetDeclaringClass()->IsInitializing()) {
- if (!Runtime::Current()->GetClassLinker()->EnsureInitialized(method->GetDeclaringClass(),
- true, true)) {
- DCHECK(Thread::Current()->IsExceptionPending());
+ } else if (UNLIKELY(!method->GetDeclaringClass()->IsInitializing())) {
+ ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
+ if (UNLIKELY(!class_linker->EnsureInitialized(method->GetDeclaringClass(),
+ true, true))) {
+ CHECK(self->IsExceptionPending());
+ self->PopShadowFrame();
return;
}
CHECK(method->GetDeclaringClass()->IsInitializing());
diff --git a/src/runtime_support.cc b/src/runtime_support.cc
index d9b369b..b096431 100644
--- a/src/runtime_support.cc
+++ b/src/runtime_support.cc
@@ -163,7 +163,7 @@
DCHECK(self->IsExceptionPending()); // Throw exception and unwind.
return NULL; // Failure.
} else {
- if (resolved_field->IsStatic() != is_static) {
+ if (UNLIKELY(resolved_field->IsStatic() != is_static)) {
ThrowIncompatibleClassChangeErrorField(resolved_field, is_static, referrer);
return NULL;
}
diff --git a/src/stack.h b/src/stack.h
index 8e597b2..d6ff9c6 100644
--- a/src/stack.h
+++ b/src/stack.h
@@ -126,11 +126,13 @@
}
int64_t GetVRegLong(size_t i) const {
+ DCHECK_LT(i, NumberOfVRegs());
const uint32_t* vreg = &vregs_[i];
return *reinterpret_cast<const int64_t*>(vreg);
}
double GetVRegDouble(size_t i) const {
+ DCHECK_LT(i, NumberOfVRegs());
const uint32_t* vreg = &vregs_[i];
return *reinterpret_cast<const double*>(vreg);
}
@@ -163,11 +165,13 @@
}
void SetVRegLong(size_t i, int64_t val) {
+ DCHECK_LT(i, NumberOfVRegs());
uint32_t* vreg = &vregs_[i];
*reinterpret_cast<int64_t*>(vreg) = val;
}
void SetVRegDouble(size_t i, double val) {
+ DCHECK_LT(i, NumberOfVRegs());
uint32_t* vreg = &vregs_[i];
*reinterpret_cast<double*>(vreg) = val;
}