summaryrefslogtreecommitdiff
path: root/src/interpreter/interpreter.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/interpreter/interpreter.cc')
-rw-r--r--src/interpreter/interpreter.cc255
1 files changed, 132 insertions, 123 deletions
diff --git a/src/interpreter/interpreter.cc b/src/interpreter/interpreter.cc
index e2cc3d63aa..c7b9c58c74 100644
--- a/src/interpreter/interpreter.cc
+++ b/src/interpreter/interpreter.cc
@@ -50,12 +50,13 @@ static const int32_t kMinInt = std::numeric_limits<int32_t>::min();
static const int64_t kMaxLong = std::numeric_limits<int64_t>::max();
static const int64_t kMinLong = std::numeric_limits<int64_t>::min();
-static void UnstartedRuntimeInvoke(Thread* self, AbstractMethod* target_method,
- ShadowFrame* shadow_frame, JValue* result, size_t arg_offset)
+static void UnstartedRuntimeInvoke(Thread* self, MethodHelper& mh,
+ const DexFile::CodeItem* code_item, ShadowFrame* shadow_frame,
+ JValue* result, size_t arg_offset)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
// In a runtime that's not started we intercept certain methods to avoid complicated dependency
// problems in core libraries.
- std::string name(PrettyMethod(target_method));
+ std::string name(PrettyMethod(shadow_frame->GetMethod()));
if (name == "java.lang.Class java.lang.Class.forName(java.lang.String)") {
std::string descriptor(DotToDescriptor(shadow_frame->GetVRegReference(arg_offset)->AsString()->ToModifiedUtf8().c_str()));
ClassLoader* class_loader = NULL; // shadow_frame.GetMethod()->GetDeclaringClass()->GetClassLoader();
@@ -132,7 +133,7 @@ static void UnstartedRuntimeInvoke(Thread* self, AbstractMethod* target_method,
}
} else {
// Not special, continue with regular interpreter execution.
- EnterInterpreterFromInterpreter(self, shadow_frame, result);
+ artInterpreterToInterpreterEntry(self, mh, code_item, shadow_frame, result);
}
}
@@ -383,51 +384,49 @@ static void DoMonitorExit(Thread* self, Object* ref) NO_THREAD_SAFETY_ANALYSIS {
ref->MonitorExit(self);
}
-static void DoInvoke(Thread* self, MethodHelper& mh, ShadowFrame& shadow_frame,
- 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(vregC);
- }
+// TODO: should be SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) which is failing due to template
+// specialization.
+template<InvokeType type, bool is_range>
+static void DoInvoke(Thread* self, ShadowFrame& shadow_frame,
+ const Instruction* inst, JValue* result) NO_THREAD_SAFETY_ANALYSIS;
+
+template<InvokeType type, bool is_range>
+static void DoInvoke(Thread* self, ShadowFrame& shadow_frame,
+ const Instruction* inst, JValue* result) {
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);
- if (UNLIKELY(target_method == NULL)) {
+ uint32_t vregC = (is_range) ? inst->VRegC_3rc() : inst->VRegC_35c();
+ Object* receiver = (type == kStatic) ? NULL : shadow_frame.GetVRegReference(vregC);
+ AbstractMethod* method = FindMethodFromCode(method_idx, receiver, shadow_frame.GetMethod(), self,
+ true, type);
+ if (UNLIKELY(method == NULL)) {
CHECK(self->IsExceptionPending());
result->SetJ(0);
return;
}
- MethodHelper target_mh(target_method);
- const DexFile::CodeItem* code_item = target_mh.GetCodeItem();
+ MethodHelper mh(method);
+ const DexFile::CodeItem* code_item = mh.GetCodeItem();
uint16_t num_regs;
uint16_t num_ins;
- if (code_item != NULL) {
+ if (LIKELY(code_item != NULL)) {
num_regs = code_item->registers_size_;
num_ins = code_item->ins_size_;
- } else if (target_method->IsAbstract()) {
+ } else if (method->IsAbstract()) {
ThrowLocation throw_location = self->GetCurrentLocationForThrow();
self->ThrowNewExceptionF(throw_location, "Ljava/lang/AbstractMethodError;",
- "abstract method \"%s\"", PrettyMethod(target_method).c_str());
+ "abstract method \"%s\"", PrettyMethod(method).c_str());
return;
} else {
- DCHECK(target_method->IsNative() || target_method->IsProxyMethod());
- num_regs = num_ins = AbstractMethod::NumArgRegisters(target_mh.GetShorty());
- if (!target_method->IsStatic()) {
+ DCHECK(method->IsNative() || method->IsProxyMethod());
+ num_regs = num_ins = AbstractMethod::NumArgRegisters(mh.GetShorty());
+ if (!method->IsStatic()) {
num_regs++;
num_ins++;
}
}
void* memory = alloca(ShadowFrame::ComputeSize(num_regs));
- ShadowFrame* new_shadow_frame(ShadowFrame::Create(num_regs, &shadow_frame,
- target_method, 0, memory));
+ ShadowFrame* new_shadow_frame(ShadowFrame::Create(num_regs, &shadow_frame, method, 0, memory));
size_t cur_reg = num_regs - num_ins;
if (receiver != NULL) {
new_shadow_frame->SetVRegReference(cur_reg, receiver);
@@ -435,13 +434,13 @@ static void DoInvoke(Thread* self, MethodHelper& mh, ShadowFrame& shadow_frame,
}
size_t arg_offset = (receiver == NULL) ? 0 : 1;
- const char* shorty = target_mh.GetShorty();
+ 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, target_mh.GetShortyLength());
+ DCHECK_LT(shorty_pos + 1, mh.GetShortyLength());
size_t arg_pos = is_range ? vregC + arg_offset : arg[arg_offset];
switch (shorty[shorty_pos + 1]) {
case 'L': {
@@ -464,20 +463,28 @@ static void DoInvoke(Thread* self, MethodHelper& mh, ShadowFrame& shadow_frame,
}
if (LIKELY(Runtime::Current()->IsStarted())) {
- (target_method->GetEntryPointFromInterpreter())(self, new_shadow_frame, result);
+ (method->GetEntryPointFromInterpreter())(self, mh, code_item, new_shadow_frame, result);
} else {
- UnstartedRuntimeInvoke(self, target_method, new_shadow_frame, result, num_regs - num_ins);
+ UnstartedRuntimeInvoke(self, mh, code_item, new_shadow_frame, result, num_regs - num_ins);
}
}
+// We use template functions to optimize compiler inlining process. Otherwise,
+// some parts of the code (like a switch statement) which depend on a constant
+// parameter would not be inlined while it should be. These constant parameters
+// are now part of the template arguments.
+// Note these template functions are static and inlined so they should not be
+// part of the final object file.
+// TODO: should be SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) which is failing due to template
+// specialization.
+template<FindFieldType find_type, Primitive::Type field_type>
static void DoFieldGet(Thread* self, ShadowFrame& shadow_frame,
- const Instruction* inst, FindFieldType find_type,
- Primitive::Type field_type)
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) ALWAYS_INLINE;
+ const Instruction* inst)
+ NO_THREAD_SAFETY_ANALYSIS ALWAYS_INLINE;
+template<FindFieldType find_type, Primitive::Type field_type>
static inline void DoFieldGet(Thread* self, ShadowFrame& shadow_frame,
- const Instruction* inst, FindFieldType find_type,
- Primitive::Type field_type) {
+ const Instruction* inst) {
bool is_static = (find_type == StaticObjectRead) || (find_type == StaticPrimitiveRead);
uint32_t field_idx = is_static ? inst->VRegB_21c() : inst->VRegC_22c();
Field* f = FindFieldFromCode(field_idx, shadow_frame.GetMethod(), self,
@@ -524,14 +531,16 @@ static inline void DoFieldGet(Thread* self, ShadowFrame& shadow_frame,
}
}
-static void DoFieldPut(Thread* self, ShadowFrame& shadow_frame,
- const Instruction* inst, FindFieldType find_type,
- Primitive::Type field_type)
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) ALWAYS_INLINE;
+// TODO: should be SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) which is failing due to template
+// specialization.
+template<FindFieldType find_type, Primitive::Type field_type>
+static void DoFieldPut(Thread* self, const ShadowFrame& shadow_frame,
+ const Instruction* inst)
+ NO_THREAD_SAFETY_ANALYSIS ALWAYS_INLINE;
-static inline void DoFieldPut(Thread* self, ShadowFrame& shadow_frame,
- const Instruction* inst, FindFieldType find_type,
- Primitive::Type field_type) {
+template<FindFieldType find_type, Primitive::Type field_type>
+static inline void DoFieldPut(Thread* self, const ShadowFrame& shadow_frame,
+ const Instruction* inst) {
bool is_static = (find_type == StaticObjectWrite) || (find_type == StaticPrimitiveWrite);
uint32_t field_idx = is_static ? inst->VRegB_21c() : inst->VRegC_22c();
Field* f = FindFieldFromCode(field_idx, shadow_frame.GetMethod(), self,
@@ -716,7 +725,7 @@ static JValue Execute(Thread* self, MethodHelper& mh, const DexFile::CodeItem* c
// 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());
+ SirtRef<Object> this_object_ref(self, shadow_frame.GetThisObject(code_item->ins_size_));
const Instruction* inst = Instruction::At(insns + shadow_frame.GetDexPC());
if (inst->GetDexPc(insns) == 0) { // We are entering the method as opposed to deoptimizing..
@@ -1193,34 +1202,34 @@ static JValue Execute(Thread* self, MethodHelper& mh, const DexFile::CodeItem* c
}
case Instruction::GOTO: {
PREAMBLE();
- inst = Instruction::At(insns + inst->GetDexPc(insns) + inst->VRegA_10t());
+ inst = inst->RelativeAt(inst->VRegA_10t());
break;
}
case Instruction::GOTO_16: {
PREAMBLE();
- inst = Instruction::At(insns + inst->GetDexPc(insns) + inst->VRegA_20t());
+ inst = inst->RelativeAt(inst->VRegA_20t());
break;
}
case Instruction::GOTO_32: {
PREAMBLE();
- inst = Instruction::At(insns + inst->GetDexPc(insns) + inst->VRegA_30t());
+ inst = inst->RelativeAt(inst->VRegA_30t());
break;
}
case Instruction::PACKED_SWITCH: {
PREAMBLE();
- const uint16_t* switch_data = insns + inst->GetDexPc(insns) + inst->VRegB_31t();
+ const uint16_t* switch_data = reinterpret_cast<const uint16_t*>(inst) + inst->VRegB_31t();
int32_t test_val = shadow_frame.GetVReg(inst->VRegA_31t());
DCHECK_EQ(switch_data[0], static_cast<uint16_t>(Instruction::kPackedSwitchSignature));
uint16_t size = switch_data[1];
DCHECK_GT(size, 0);
const int32_t* keys = reinterpret_cast<const int32_t*>(&switch_data[2]);
- CHECK(IsAligned<4>(keys));
+ DCHECK(IsAligned<4>(keys));
int32_t first_key = keys[0];
const int32_t* targets = reinterpret_cast<const int32_t*>(&switch_data[4]);
DCHECK(IsAligned<4>(targets));
int32_t index = test_val - first_key;
if (index >= 0 && index < size) {
- inst = Instruction::At(insns + inst->GetDexPc(insns) + targets[index]);
+ inst = inst->RelativeAt(targets[index]);
} else {
inst = inst->Next_3xx();
}
@@ -1228,18 +1237,18 @@ static JValue Execute(Thread* self, MethodHelper& mh, const DexFile::CodeItem* c
}
case Instruction::SPARSE_SWITCH: {
PREAMBLE();
- uint32_t dex_pc = inst->GetDexPc(insns);
- const uint16_t* switch_data = insns + dex_pc + inst->VRegB_31t();
+ const uint16_t* switch_data = reinterpret_cast<const uint16_t*>(inst) + inst->VRegB_31t();
int32_t test_val = shadow_frame.GetVReg(inst->VRegA_31t());
- CHECK_EQ(switch_data[0], static_cast<uint16_t>(Instruction::kSparseSwitchSignature));
+ DCHECK_EQ(switch_data[0], static_cast<uint16_t>(Instruction::kSparseSwitchSignature));
uint16_t size = switch_data[1];
- CHECK_GT(size, 0);
+ DCHECK_GT(size, 0);
const int32_t* keys = reinterpret_cast<const int32_t*>(&switch_data[2]);
- CHECK(IsAligned<4>(keys));
+ DCHECK(IsAligned<4>(keys));
const int32_t* entries = keys + size;
- CHECK(IsAligned<4>(entries));
+ DCHECK(IsAligned<4>(entries));
int lo = 0;
int hi = size - 1;
+ const Instruction* current_inst = inst;
inst = inst->Next_3xx();
while (lo <= hi) {
int mid = (lo + hi) / 2;
@@ -1249,7 +1258,7 @@ static JValue Execute(Thread* self, MethodHelper& mh, const DexFile::CodeItem* c
} else if (test_val > foundVal) {
lo = mid + 1;
} else {
- inst = Instruction::At(insns + dex_pc + entries[mid]);
+ inst = current_inst->RelativeAt(entries[mid]);
break;
}
}
@@ -1339,7 +1348,7 @@ static JValue Execute(Thread* self, MethodHelper& mh, const DexFile::CodeItem* c
case Instruction::IF_EQ: {
PREAMBLE();
if (shadow_frame.GetVReg(inst->VRegA_22t()) == shadow_frame.GetVReg(inst->VRegB_22t())) {
- inst = Instruction::At(insns + inst->GetDexPc(insns) + inst->VRegC_22t());
+ inst = inst->RelativeAt(inst->VRegC_22t());
} else {
inst = inst->Next_2xx();
}
@@ -1348,7 +1357,7 @@ static JValue Execute(Thread* self, MethodHelper& mh, const DexFile::CodeItem* c
case Instruction::IF_NE: {
PREAMBLE();
if (shadow_frame.GetVReg(inst->VRegA_22t()) != shadow_frame.GetVReg(inst->VRegB_22t())) {
- inst = Instruction::At(insns + inst->GetDexPc(insns) + inst->VRegC_22t());
+ inst = inst->RelativeAt(inst->VRegC_22t());
} else {
inst = inst->Next_2xx();
}
@@ -1357,7 +1366,7 @@ static JValue Execute(Thread* self, MethodHelper& mh, const DexFile::CodeItem* c
case Instruction::IF_LT: {
PREAMBLE();
if (shadow_frame.GetVReg(inst->VRegA_22t()) < shadow_frame.GetVReg(inst->VRegB_22t())) {
- inst = Instruction::At(insns + inst->GetDexPc(insns) + inst->VRegC_22t());
+ inst = inst->RelativeAt(inst->VRegC_22t());
} else {
inst = inst->Next_2xx();
}
@@ -1366,7 +1375,7 @@ static JValue Execute(Thread* self, MethodHelper& mh, const DexFile::CodeItem* c
case Instruction::IF_GE: {
PREAMBLE();
if (shadow_frame.GetVReg(inst->VRegA_22t()) >= shadow_frame.GetVReg(inst->VRegB_22t())) {
- inst = Instruction::At(insns + inst->GetDexPc(insns) + inst->VRegC_22t());
+ inst = inst->RelativeAt(inst->VRegC_22t());
} else {
inst = inst->Next_2xx();
}
@@ -1375,7 +1384,7 @@ static JValue Execute(Thread* self, MethodHelper& mh, const DexFile::CodeItem* c
case Instruction::IF_GT: {
PREAMBLE();
if (shadow_frame.GetVReg(inst->VRegA_22t()) > shadow_frame.GetVReg(inst->VRegB_22t())) {
- inst = Instruction::At(insns + inst->GetDexPc(insns) + inst->VRegC_22t());
+ inst = inst->RelativeAt(inst->VRegC_22t());
} else {
inst = inst->Next_2xx();
}
@@ -1384,7 +1393,7 @@ static JValue Execute(Thread* self, MethodHelper& mh, const DexFile::CodeItem* c
case Instruction::IF_LE: {
PREAMBLE();
if (shadow_frame.GetVReg(inst->VRegA_22t()) <= shadow_frame.GetVReg(inst->VRegB_22t())) {
- inst = Instruction::At(insns + inst->GetDexPc(insns) + inst->VRegC_22t());
+ inst = inst->RelativeAt(inst->VRegC_22t());
} else {
inst = inst->Next_2xx();
}
@@ -1393,7 +1402,7 @@ static JValue Execute(Thread* self, MethodHelper& mh, const DexFile::CodeItem* c
case Instruction::IF_EQZ: {
PREAMBLE();
if (shadow_frame.GetVReg(inst->VRegA_21t()) == 0) {
- inst = Instruction::At(insns + inst->GetDexPc(insns) + inst->VRegB_21t());
+ inst = inst->RelativeAt(inst->VRegB_21t());
} else {
inst = inst->Next_2xx();
}
@@ -1402,7 +1411,7 @@ static JValue Execute(Thread* self, MethodHelper& mh, const DexFile::CodeItem* c
case Instruction::IF_NEZ: {
PREAMBLE();
if (shadow_frame.GetVReg(inst->VRegA_21t()) != 0) {
- inst = Instruction::At(insns + inst->GetDexPc(insns) + inst->VRegB_21t());
+ inst = inst->RelativeAt(inst->VRegB_21t());
} else {
inst = inst->Next_2xx();
}
@@ -1411,7 +1420,7 @@ static JValue Execute(Thread* self, MethodHelper& mh, const DexFile::CodeItem* c
case Instruction::IF_LTZ: {
PREAMBLE();
if (shadow_frame.GetVReg(inst->VRegA_21t()) < 0) {
- inst = Instruction::At(insns + inst->GetDexPc(insns) + inst->VRegB_21t());
+ inst = inst->RelativeAt(inst->VRegB_21t());
} else {
inst = inst->Next_2xx();
}
@@ -1420,7 +1429,7 @@ static JValue Execute(Thread* self, MethodHelper& mh, const DexFile::CodeItem* c
case Instruction::IF_GEZ: {
PREAMBLE();
if (shadow_frame.GetVReg(inst->VRegA_21t()) >= 0) {
- inst = Instruction::At(insns + inst->GetDexPc(insns) + inst->VRegB_21t());
+ inst = inst->RelativeAt(inst->VRegB_21t());
} else {
inst = inst->Next_2xx();
}
@@ -1429,7 +1438,7 @@ static JValue Execute(Thread* self, MethodHelper& mh, const DexFile::CodeItem* c
case Instruction::IF_GTZ: {
PREAMBLE();
if (shadow_frame.GetVReg(inst->VRegA_21t()) > 0) {
- inst = Instruction::At(insns + inst->GetDexPc(insns) + inst->VRegB_21t());
+ inst = inst->RelativeAt(inst->VRegB_21t());
} else {
inst = inst->Next_2xx();
}
@@ -1438,7 +1447,7 @@ static JValue Execute(Thread* self, MethodHelper& mh, const DexFile::CodeItem* c
case Instruction::IF_LEZ: {
PREAMBLE();
if (shadow_frame.GetVReg(inst->VRegA_21t()) <= 0) {
- inst = Instruction::At(insns + inst->GetDexPc(insns) + inst->VRegB_21t());
+ inst = inst->RelativeAt(inst->VRegB_21t());
} else {
inst = inst->Next_2xx();
}
@@ -1705,192 +1714,192 @@ static JValue Execute(Thread* self, MethodHelper& mh, const DexFile::CodeItem* c
}
case Instruction::IGET_BOOLEAN:
PREAMBLE();
- DoFieldGet(self, shadow_frame, inst, InstancePrimitiveRead, Primitive::kPrimBoolean);
+ DoFieldGet<InstancePrimitiveRead, Primitive::kPrimBoolean>(self, shadow_frame, inst);
POSSIBLY_HANDLE_PENDING_EXCEPTION(Next_2xx);
break;
case Instruction::IGET_BYTE:
PREAMBLE();
- DoFieldGet(self, shadow_frame, inst, InstancePrimitiveRead, Primitive::kPrimByte);
+ DoFieldGet<InstancePrimitiveRead, Primitive::kPrimByte>(self, shadow_frame, inst);
POSSIBLY_HANDLE_PENDING_EXCEPTION(Next_2xx);
break;
case Instruction::IGET_CHAR:
PREAMBLE();
- DoFieldGet(self, shadow_frame, inst, InstancePrimitiveRead, Primitive::kPrimChar);
+ DoFieldGet<InstancePrimitiveRead, Primitive::kPrimChar>(self, shadow_frame, inst);
POSSIBLY_HANDLE_PENDING_EXCEPTION(Next_2xx);
break;
case Instruction::IGET_SHORT:
PREAMBLE();
- DoFieldGet(self, shadow_frame, inst, InstancePrimitiveRead, Primitive::kPrimShort);
+ DoFieldGet<InstancePrimitiveRead, Primitive::kPrimShort>(self, shadow_frame, inst);
POSSIBLY_HANDLE_PENDING_EXCEPTION(Next_2xx);
break;
case Instruction::IGET:
PREAMBLE();
- DoFieldGet(self, shadow_frame, inst, InstancePrimitiveRead, Primitive::kPrimInt);
+ DoFieldGet<InstancePrimitiveRead, Primitive::kPrimInt>(self, shadow_frame, inst);
POSSIBLY_HANDLE_PENDING_EXCEPTION(Next_2xx);
break;
case Instruction::IGET_WIDE:
PREAMBLE();
- DoFieldGet(self, shadow_frame, inst, InstancePrimitiveRead, Primitive::kPrimLong);
+ DoFieldGet<InstancePrimitiveRead, Primitive::kPrimLong>(self, shadow_frame, inst);
POSSIBLY_HANDLE_PENDING_EXCEPTION(Next_2xx);
break;
case Instruction::IGET_OBJECT:
PREAMBLE();
- DoFieldGet(self, shadow_frame, inst, InstanceObjectRead, Primitive::kPrimNot);
+ DoFieldGet<InstanceObjectRead, Primitive::kPrimNot>(self, shadow_frame, inst);
POSSIBLY_HANDLE_PENDING_EXCEPTION(Next_2xx);
break;
case Instruction::SGET_BOOLEAN:
PREAMBLE();
- DoFieldGet(self, shadow_frame, inst, StaticPrimitiveRead, Primitive::kPrimBoolean);
+ DoFieldGet<StaticPrimitiveRead, Primitive::kPrimBoolean>(self, shadow_frame, inst);
POSSIBLY_HANDLE_PENDING_EXCEPTION(Next_2xx);
break;
case Instruction::SGET_BYTE:
PREAMBLE();
- DoFieldGet(self, shadow_frame, inst, StaticPrimitiveRead, Primitive::kPrimByte);
+ DoFieldGet<StaticPrimitiveRead, Primitive::kPrimByte>(self, shadow_frame, inst);
POSSIBLY_HANDLE_PENDING_EXCEPTION(Next_2xx);
break;
case Instruction::SGET_CHAR:
PREAMBLE();
- DoFieldGet(self, shadow_frame, inst, StaticPrimitiveRead, Primitive::kPrimChar);
+ DoFieldGet<StaticPrimitiveRead, Primitive::kPrimChar>(self, shadow_frame, inst);
POSSIBLY_HANDLE_PENDING_EXCEPTION(Next_2xx);
break;
case Instruction::SGET_SHORT:
PREAMBLE();
- DoFieldGet(self, shadow_frame, inst, StaticPrimitiveRead, Primitive::kPrimShort);
+ DoFieldGet<StaticPrimitiveRead, Primitive::kPrimShort>(self, shadow_frame, inst);
POSSIBLY_HANDLE_PENDING_EXCEPTION(Next_2xx);
break;
case Instruction::SGET:
PREAMBLE();
- DoFieldGet(self, shadow_frame, inst, StaticPrimitiveRead, Primitive::kPrimInt);
+ DoFieldGet<StaticPrimitiveRead, Primitive::kPrimInt>(self, shadow_frame, inst);
POSSIBLY_HANDLE_PENDING_EXCEPTION(Next_2xx);
break;
case Instruction::SGET_WIDE:
PREAMBLE();
- DoFieldGet(self, shadow_frame, inst, StaticPrimitiveRead, Primitive::kPrimLong);
+ DoFieldGet<StaticPrimitiveRead, Primitive::kPrimLong>(self, shadow_frame, inst);
POSSIBLY_HANDLE_PENDING_EXCEPTION(Next_2xx);
break;
case Instruction::SGET_OBJECT:
PREAMBLE();
- DoFieldGet(self, shadow_frame, inst, StaticObjectRead, Primitive::kPrimNot);
+ DoFieldGet<StaticObjectRead, Primitive::kPrimNot>(self, shadow_frame, inst);
POSSIBLY_HANDLE_PENDING_EXCEPTION(Next_2xx);
break;
case Instruction::IPUT_BOOLEAN:
PREAMBLE();
- DoFieldPut(self, shadow_frame, inst, InstancePrimitiveWrite, Primitive::kPrimBoolean);
+ DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimBoolean>(self, shadow_frame, inst);
POSSIBLY_HANDLE_PENDING_EXCEPTION(Next_2xx);
break;
case Instruction::IPUT_BYTE:
PREAMBLE();
- DoFieldPut(self, shadow_frame, inst, InstancePrimitiveWrite, Primitive::kPrimByte);
+ DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimByte>(self, shadow_frame, inst);
POSSIBLY_HANDLE_PENDING_EXCEPTION(Next_2xx);
break;
case Instruction::IPUT_CHAR:
PREAMBLE();
- DoFieldPut(self, shadow_frame, inst, InstancePrimitiveWrite, Primitive::kPrimChar);
+ DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimChar>(self, shadow_frame, inst);
POSSIBLY_HANDLE_PENDING_EXCEPTION(Next_2xx);
break;
case Instruction::IPUT_SHORT:
PREAMBLE();
- DoFieldPut(self, shadow_frame, inst, InstancePrimitiveWrite, Primitive::kPrimShort);
+ DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimShort>(self, shadow_frame, inst);
POSSIBLY_HANDLE_PENDING_EXCEPTION(Next_2xx);
break;
case Instruction::IPUT:
PREAMBLE();
- DoFieldPut(self, shadow_frame, inst, InstancePrimitiveWrite, Primitive::kPrimInt);
+ DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimInt>(self, shadow_frame, inst);
POSSIBLY_HANDLE_PENDING_EXCEPTION(Next_2xx);
break;
case Instruction::IPUT_WIDE:
PREAMBLE();
- DoFieldPut(self, shadow_frame, inst, InstancePrimitiveWrite, Primitive::kPrimLong);
+ DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimLong>(self, shadow_frame, inst);
POSSIBLY_HANDLE_PENDING_EXCEPTION(Next_2xx);
break;
case Instruction::IPUT_OBJECT:
PREAMBLE();
- DoFieldPut(self, shadow_frame, inst, InstanceObjectWrite, Primitive::kPrimNot);
+ DoFieldPut<InstanceObjectWrite, Primitive::kPrimNot>(self, shadow_frame, inst);
POSSIBLY_HANDLE_PENDING_EXCEPTION(Next_2xx);
break;
case Instruction::SPUT_BOOLEAN:
PREAMBLE();
- DoFieldPut(self, shadow_frame, inst, StaticPrimitiveWrite, Primitive::kPrimBoolean);
+ DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimBoolean>(self, shadow_frame, inst);
POSSIBLY_HANDLE_PENDING_EXCEPTION(Next_2xx);
break;
case Instruction::SPUT_BYTE:
PREAMBLE();
- DoFieldPut(self, shadow_frame, inst, StaticPrimitiveWrite, Primitive::kPrimByte);
+ DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimByte>(self, shadow_frame, inst);
POSSIBLY_HANDLE_PENDING_EXCEPTION(Next_2xx);
break;
case Instruction::SPUT_CHAR:
PREAMBLE();
- DoFieldPut(self, shadow_frame, inst, StaticPrimitiveWrite, Primitive::kPrimChar);
+ DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimChar>(self, shadow_frame, inst);
POSSIBLY_HANDLE_PENDING_EXCEPTION(Next_2xx);
break;
case Instruction::SPUT_SHORT:
PREAMBLE();
- DoFieldPut(self, shadow_frame, inst, StaticPrimitiveWrite, Primitive::kPrimShort);
+ DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimShort>(self, shadow_frame, inst);
POSSIBLY_HANDLE_PENDING_EXCEPTION(Next_2xx);
break;
case Instruction::SPUT:
PREAMBLE();
- DoFieldPut(self, shadow_frame, inst, StaticPrimitiveWrite, Primitive::kPrimInt);
+ DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimInt>(self, shadow_frame, inst);
POSSIBLY_HANDLE_PENDING_EXCEPTION(Next_2xx);
break;
case Instruction::SPUT_WIDE:
PREAMBLE();
- DoFieldPut(self, shadow_frame, inst, StaticPrimitiveWrite, Primitive::kPrimLong);
+ DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimLong>(self, shadow_frame, inst);
POSSIBLY_HANDLE_PENDING_EXCEPTION(Next_2xx);
break;
case Instruction::SPUT_OBJECT:
PREAMBLE();
- DoFieldPut(self, shadow_frame, inst, StaticObjectWrite, Primitive::kPrimNot);
+ DoFieldPut<StaticObjectWrite, Primitive::kPrimNot>(self, shadow_frame, inst);
POSSIBLY_HANDLE_PENDING_EXCEPTION(Next_2xx);
break;
case Instruction::INVOKE_VIRTUAL:
PREAMBLE();
- DoInvoke(self, mh, shadow_frame, inst, kVirtual, false, &result_register);
+ DoInvoke<kVirtual, false>(self, shadow_frame, inst, &result_register);
POSSIBLY_HANDLE_PENDING_EXCEPTION(Next_3xx);
break;
case Instruction::INVOKE_VIRTUAL_RANGE:
PREAMBLE();
- DoInvoke(self, mh, shadow_frame, inst, kVirtual, true, &result_register);
+ DoInvoke<kVirtual, true>(self, shadow_frame, inst, &result_register);
POSSIBLY_HANDLE_PENDING_EXCEPTION(Next_3xx);
break;
case Instruction::INVOKE_SUPER:
PREAMBLE();
- DoInvoke(self, mh, shadow_frame, inst, kSuper, false, &result_register);
+ DoInvoke<kSuper, false>(self, shadow_frame, inst, &result_register);
POSSIBLY_HANDLE_PENDING_EXCEPTION(Next_3xx);
break;
case Instruction::INVOKE_SUPER_RANGE:
PREAMBLE();
- DoInvoke(self, mh, shadow_frame, inst, kSuper, true, &result_register);
+ DoInvoke<kSuper, true>(self, shadow_frame, inst, &result_register);
POSSIBLY_HANDLE_PENDING_EXCEPTION(Next_3xx);
break;
case Instruction::INVOKE_DIRECT:
PREAMBLE();
- DoInvoke(self, mh, shadow_frame, inst, kDirect, false, &result_register);
+ DoInvoke<kDirect, false>(self, shadow_frame, inst, &result_register);
POSSIBLY_HANDLE_PENDING_EXCEPTION(Next_3xx);
break;
case Instruction::INVOKE_DIRECT_RANGE:
PREAMBLE();
- DoInvoke(self, mh, shadow_frame, inst, kDirect, true, &result_register);
+ DoInvoke<kDirect, true>(self, shadow_frame, inst, &result_register);
POSSIBLY_HANDLE_PENDING_EXCEPTION(Next_3xx);
break;
case Instruction::INVOKE_INTERFACE:
PREAMBLE();
- DoInvoke(self, mh, shadow_frame, inst, kInterface, false, &result_register);
+ DoInvoke<kInterface, false>(self, shadow_frame, inst, &result_register);
POSSIBLY_HANDLE_PENDING_EXCEPTION(Next_3xx);
break;
case Instruction::INVOKE_INTERFACE_RANGE:
PREAMBLE();
- DoInvoke(self, mh, shadow_frame, inst, kInterface, true, &result_register);
+ DoInvoke<kInterface, true>(self, shadow_frame, inst, &result_register);
POSSIBLY_HANDLE_PENDING_EXCEPTION(Next_3xx);
break;
case Instruction::INVOKE_STATIC:
PREAMBLE();
- DoInvoke(self, mh, shadow_frame, inst, kStatic, false, &result_register);
+ DoInvoke<kStatic, false>(self, shadow_frame, inst, &result_register);
POSSIBLY_HANDLE_PENDING_EXCEPTION(Next_3xx);
break;
case Instruction::INVOKE_STATIC_RANGE:
PREAMBLE();
- DoInvoke(self, mh, shadow_frame, inst, kStatic, true, &result_register);
+ DoInvoke<kStatic, true>(self, shadow_frame, inst, &result_register);
POSSIBLY_HANDLE_PENDING_EXCEPTION(Next_3xx);
break;
case Instruction::NEG_INT:
@@ -2296,6 +2305,14 @@ static JValue Execute(Thread* self, MethodHelper& mh, const DexFile::CodeItem* c
inst = inst->Next_1xx();
break;
}
+ case Instruction::DIV_INT_2ADDR: {
+ PREAMBLE();
+ uint32_t vregA = inst->VRegA_12x();
+ DoIntDivide(self, shadow_frame, vregA, shadow_frame.GetVReg(vregA),
+ shadow_frame.GetVReg(inst->VRegB_12x()));
+ inst = inst->Next_1xx();
+ break;
+ }
case Instruction::REM_INT_2ADDR: {
PREAMBLE();
uint32_t vregA = inst->VRegA_12x();
@@ -2358,14 +2375,6 @@ static JValue Execute(Thread* self, MethodHelper& mh, const DexFile::CodeItem* c
inst = inst->Next_1xx();
break;
}
- case Instruction::DIV_INT_2ADDR: {
- PREAMBLE();
- uint32_t vregA = inst->VRegA_12x();
- DoIntDivide(self, shadow_frame, vregA, shadow_frame.GetVReg(vregA),
- shadow_frame.GetVReg(inst->VRegB_12x()));
- inst = inst->Next_1xx();
- break;
- }
case Instruction::ADD_LONG_2ADDR: {
PREAMBLE();
uint32_t vregA = inst->VRegA_12x();
@@ -2695,7 +2704,7 @@ static JValue Execute(Thread* self, MethodHelper& mh, const DexFile::CodeItem* c
void EnterInterpreterFromInvoke(Thread* self, AbstractMethod* method, Object* receiver,
uint32_t* args, JValue* result) {
DCHECK_EQ(self, Thread::Current());
- if (__builtin_frame_address(0) < self->GetStackEnd()) {
+ if (UNLIKELY(__builtin_frame_address(0) < self->GetStackEnd())) {
ThrowStackOverflowError(self);
return;
}
@@ -2799,7 +2808,7 @@ JValue EnterInterpreterFromStub(Thread* self, MethodHelper& mh, const DexFile::C
ShadowFrame& shadow_frame)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
DCHECK_EQ(self, Thread::Current());
- if (__builtin_frame_address(0) < self->GetStackEnd()) {
+ if (UNLIKELY(__builtin_frame_address(0) < self->GetStackEnd())) {
ThrowStackOverflowError(self);
return JValue();
}
@@ -2807,9 +2816,11 @@ JValue EnterInterpreterFromStub(Thread* self, MethodHelper& mh, const DexFile::C
return Execute(self, mh, code_item, shadow_frame, JValue());
}
-void EnterInterpreterFromInterpreter(Thread* self, ShadowFrame* shadow_frame, JValue* result)
+void artInterpreterToInterpreterEntry(Thread* self, MethodHelper& mh,
+ const DexFile::CodeItem* code_item,
+ ShadowFrame* shadow_frame, JValue* result)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- if (__builtin_frame_address(0) < self->GetStackEnd()) {
+ if (UNLIKELY(__builtin_frame_address(0) < self->GetStackEnd())) {
ThrowStackOverflowError(self);
return;
}
@@ -2826,8 +2837,6 @@ void EnterInterpreterFromInterpreter(Thread* self, ShadowFrame* shadow_frame, JV
self->PushShadowFrame(shadow_frame);
- MethodHelper mh(method);
- const DexFile::CodeItem* code_item = mh.GetCodeItem();
if (LIKELY(!method->IsNative())) {
result->SetJ(Execute(self, mh, code_item, *shadow_frame, JValue()).GetJ());
} else {