diff options
Diffstat (limited to 'src/interpreter/interpreter.cc')
| -rw-r--r-- | src/interpreter/interpreter.cc | 255 |
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 { |