diff options
-rw-r--r-- | runtime/dex_instruction-inl.h | 13 | ||||
-rw-r--r-- | runtime/dex_instruction.h | 5 | ||||
-rw-r--r-- | runtime/entrypoints/interpreter/interpreter_entrypoints.cc | 12 | ||||
-rw-r--r-- | runtime/interpreter/interpreter.cc | 18 | ||||
-rw-r--r-- | runtime/interpreter/interpreter_common.cc | 195 | ||||
-rw-r--r-- | runtime/interpreter/interpreter_common.h | 79 | ||||
-rw-r--r-- | runtime/interpreter/interpreter_goto_table_impl.cc | 25 | ||||
-rw-r--r-- | runtime/interpreter/interpreter_switch_impl.cc | 24 | ||||
-rw-r--r-- | runtime/stack.h | 3 |
9 files changed, 165 insertions, 209 deletions
diff --git a/runtime/dex_instruction-inl.h b/runtime/dex_instruction-inl.h index 4d39024..207b0b6 100644 --- a/runtime/dex_instruction-inl.h +++ b/runtime/dex_instruction-inl.h @@ -281,7 +281,7 @@ inline uint16_t Instruction::VRegC_3rc() const { return Fetch16(2); } -inline void Instruction::GetArgs(uint32_t arg[5]) const { +inline void Instruction::GetArgs(uint32_t arg[5], uint16_t inst_data) const { DCHECK_EQ(FormatOf(Opcode()), k35c); /* @@ -295,7 +295,8 @@ inline void Instruction::GetArgs(uint32_t arg[5]) const { * method constant (or equivalent) is always in vB. */ uint16_t regList = Fetch16(2); - uint4_t count = InstB(); // This is labeled A in the spec. + uint4_t count = InstB(inst_data); // This is labeled A in the spec. + DCHECK_LE(count, 5U) << "Invalid arg count in 35c (" << count << ")"; /* * Copy the argument registers into the arg[] array, and @@ -305,15 +306,13 @@ inline void Instruction::GetArgs(uint32_t arg[5]) const { * copies of those.) Note that cases 5..2 fall through. */ switch (count) { - case 5: arg[4] = InstA(); + case 5: arg[4] = InstA(inst_data); 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; + default: // case 0 + break; // Valid, but no need to do anything. } } diff --git a/runtime/dex_instruction.h b/runtime/dex_instruction.h index e8db3bc..c434cdd 100644 --- a/runtime/dex_instruction.h +++ b/runtime/dex_instruction.h @@ -365,7 +365,10 @@ class Instruction { uint16_t VRegC_3rc() const; // Fills the given array with the 'arg' array of the instruction. - void GetArgs(uint32_t args[5]) const; + void GetArgs(uint32_t args[5], uint16_t inst_data) const; + void GetArgs(uint32_t args[5]) const { + return GetArgs(args, Fetch16(0)); + } // Returns the opcode field of the instruction. The given "inst_data" parameter must be the first // 16 bits of instruction. diff --git a/runtime/entrypoints/interpreter/interpreter_entrypoints.cc b/runtime/entrypoints/interpreter/interpreter_entrypoints.cc index ecf98bc..05c02f2 100644 --- a/runtime/entrypoints/interpreter/interpreter_entrypoints.cc +++ b/runtime/entrypoints/interpreter/interpreter_entrypoints.cc @@ -31,7 +31,15 @@ extern "C" void artInterpreterToCompiledCodeBridge(Thread* self, MethodHelper& m mirror::ArtMethod* method = shadow_frame->GetMethod(); // Ensure static methods are initialized. if (method->IsStatic()) { - Runtime::Current()->GetClassLinker()->EnsureInitialized(method->GetDeclaringClass(), true, true); + mirror::Class* declaringClass = method->GetDeclaringClass(); + if (UNLIKELY(!declaringClass->IsInitializing())) { + if (UNLIKELY(!Runtime::Current()->GetClassLinker()->EnsureInitialized(declaringClass, + true, true))) { + DCHECK(Thread::Current()->IsExceptionPending()); + return; + } + CHECK(declaringClass->IsInitializing()); + } } uint16_t arg_offset = (code_item == NULL) ? 0 : code_item->registers_size_ - code_item->ins_size_; #if defined(ART_USE_PORTABLE_COMPILER) @@ -40,7 +48,7 @@ extern "C" void artInterpreterToCompiledCodeBridge(Thread* self, MethodHelper& m method->Invoke(self, arg_array.GetArray(), arg_array.GetNumBytes(), result, mh.GetShorty()[0]); #else method->Invoke(self, shadow_frame->GetVRegArgs(arg_offset), - (shadow_frame->NumberOfVRegs() - arg_offset) * 4, + (shadow_frame->NumberOfVRegs() - arg_offset) * sizeof(uint32_t), result, mh.GetShorty()[0]); #endif } diff --git a/runtime/interpreter/interpreter.cc b/runtime/interpreter/interpreter.cc index fd92e06..8aa6fa2 100644 --- a/runtime/interpreter/interpreter.cc +++ b/runtime/interpreter/interpreter.cc @@ -422,15 +422,18 @@ extern "C" void artInterpreterToInterpreterBridge(Thread* self, MethodHelper& mh } ArtMethod* method = shadow_frame->GetMethod(); - if (method->IsStatic() && !method->GetDeclaringClass()->IsInitializing()) { - if (!Runtime::Current()->GetClassLinker()->EnsureInitialized(method->GetDeclaringClass(), - true, true)) { - DCHECK(Thread::Current()->IsExceptionPending()); - return; + // Ensure static methods are initialized. + if (method->IsStatic()) { + Class* declaringClass = method->GetDeclaringClass(); + if (UNLIKELY(!declaringClass->IsInitializing())) { + if (UNLIKELY(!Runtime::Current()->GetClassLinker()->EnsureInitialized(declaringClass, + true, true))) { + DCHECK(Thread::Current()->IsExceptionPending()); + return; + } + CHECK(declaringClass->IsInitializing()); } - CHECK(method->GetDeclaringClass()->IsInitializing()); } - self->PushShadowFrame(shadow_frame); if (LIKELY(!method->IsNative())) { @@ -445,7 +448,6 @@ extern "C" void artInterpreterToInterpreterBridge(Thread* self, MethodHelper& mh } self->PopShadowFrame(); - return; } } // namespace interpreter diff --git a/runtime/interpreter/interpreter_common.cc b/runtime/interpreter/interpreter_common.cc index 36b250c..4992031 100644 --- a/runtime/interpreter/interpreter_common.cc +++ b/runtime/interpreter/interpreter_common.cc @@ -19,62 +19,59 @@ namespace art { namespace interpreter { -template<InvokeType type, bool is_range, bool do_access_check> -bool DoInvoke(Thread* self, ShadowFrame& shadow_frame, - const Instruction* inst, JValue* result) { - bool do_assignability_check = do_access_check; - uint32_t method_idx = (is_range) ? inst->VRegB_3rc() : inst->VRegB_35c(); - uint32_t vregC = (is_range) ? inst->VRegC_3rc() : inst->VRegC_35c(); - Object* receiver = (type == kStatic) ? NULL : shadow_frame.GetVRegReference(vregC); - ArtMethod* method = FindMethodFromCode(method_idx, receiver, shadow_frame.GetMethod(), self, - do_access_check, type); - if (UNLIKELY(method == NULL)) { - CHECK(self->IsExceptionPending()); - result->SetJ(0); - return false; - } else if (UNLIKELY(method->IsAbstract())) { - ThrowAbstractMethodError(method); - result->SetJ(0); - return false; - } +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_); +template<bool is_range, bool do_assignability_check> +bool DoCall(ArtMethod* method, Object* receiver, Thread* self, ShadowFrame& shadow_frame, + const Instruction* inst, uint16_t inst_data, JValue* result) { + // Compute method information. MethodHelper mh(method); const DexFile::CodeItem* code_item = mh.GetCodeItem(); + const uint16_t num_ins = (is_range) ? inst->VRegA_3rc(inst_data) : inst->VRegA_35c(inst_data); uint16_t num_regs; - uint16_t num_ins; if (LIKELY(code_item != NULL)) { num_regs = code_item->registers_size_; - num_ins = code_item->ins_size_; + DCHECK_EQ(num_ins, code_item->ins_size_); } else { DCHECK(method->IsNative() || method->IsProxyMethod()); - num_regs = num_ins = ArtMethod::NumArgRegisters(mh.GetShorty()); - if (!method->IsStatic()) { - num_regs++; - num_ins++; - } + num_regs = num_ins; } + // Allocate shadow frame on the stack. void* memory = alloca(ShadowFrame::ComputeSize(num_regs)); ShadowFrame* new_shadow_frame(ShadowFrame::Create(num_regs, &shadow_frame, method, 0, memory)); + + // Initialize new shadow frame. size_t cur_reg = num_regs - num_ins; + size_t arg_offset = 0; if (receiver != NULL) { + DCHECK(!method->IsStatic()); new_shadow_frame->SetVRegReference(cur_reg, receiver); ++cur_reg; + ++arg_offset; + } else { + DCHECK(method->IsStatic()); } const DexFile::TypeList* params; if (do_assignability_check) { params = mh.GetParameterTypeList(); } - size_t arg_offset = (receiver == NULL) ? 0 : 1; const char* shorty = mh.GetShorty(); - uint32_t arg[5]; - if (!is_range) { - inst->GetArgs(arg); + // TODO: find a cleaner way to separate non-range and range information. + uint32_t arg[5]; // only used in invoke-XXX. + uint32_t vregC; // only used in invoke-XXX-range. + if (is_range) { + vregC = inst->VRegC_3rc(); + } else { + inst->GetArgs(arg, inst_data); } - for (size_t shorty_pos = 0; cur_reg < num_regs; ++shorty_pos, cur_reg++, arg_offset++) { + 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 ? vregC + arg_offset : 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); @@ -102,94 +99,8 @@ bool DoInvoke(Thread* self, ShadowFrame& shadow_frame, uint64_t wide_value = (static_cast<uint64_t>(shadow_frame.GetVReg(arg_pos + 1)) << 32) | static_cast<uint32_t>(shadow_frame.GetVReg(arg_pos)); new_shadow_frame->SetVRegLong(cur_reg, wide_value); - cur_reg++; - arg_offset++; - break; - } - default: - new_shadow_frame->SetVReg(cur_reg, shadow_frame.GetVReg(arg_pos)); - break; - } - } - - if (LIKELY(Runtime::Current()->IsStarted())) { - (method->GetEntryPointFromInterpreter())(self, mh, code_item, new_shadow_frame, result); - } else { - UnstartedRuntimeInvoke(self, mh, code_item, new_shadow_frame, result, num_regs - num_ins); - } - return !self->IsExceptionPending(); -} - -template<bool is_range> -bool DoInvokeVirtualQuick(Thread* self, ShadowFrame& shadow_frame, - const Instruction* inst, JValue* result) { - uint32_t vregC = (is_range) ? inst->VRegC_3rc() : inst->VRegC_35c(); - Object* receiver = shadow_frame.GetVRegReference(vregC); - if (UNLIKELY(receiver == NULL)) { - // We lost the reference to the method index so we cannot get a more - // precised exception message. - ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow()); - return false; - } - uint32_t vtable_idx = (is_range) ? inst->VRegB_3rc() : inst->VRegB_35c(); - // TODO: use ObjectArray<T>::GetWithoutChecks ? - ArtMethod* method = receiver->GetClass()->GetVTable()->Get(vtable_idx); - if (UNLIKELY(method == NULL)) { - CHECK(self->IsExceptionPending()); - result->SetJ(0); - return false; - } else if (UNLIKELY(method->IsAbstract())) { - ThrowAbstractMethodError(method); - result->SetJ(0); - return false; - } - - MethodHelper mh(method); - const DexFile::CodeItem* code_item = mh.GetCodeItem(); - uint16_t num_regs; - uint16_t num_ins; - if (code_item != NULL) { - num_regs = code_item->registers_size_; - num_ins = code_item->ins_size_; - } else { - DCHECK(method->IsNative() || method->IsProxyMethod()); - num_regs = num_ins = ArtMethod::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, - method, 0, memory)); - size_t cur_reg = num_regs - num_ins; - if (receiver != NULL) { - new_shadow_frame->SetVRegReference(cur_reg, receiver); - ++cur_reg; - } - - 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 ? vregC + arg_offset : arg[arg_offset]; - switch (shorty[shorty_pos + 1]) { - case 'L': { - Object* o = shadow_frame.GetVRegReference(arg_pos); - new_shadow_frame->SetVRegReference(cur_reg, o); - break; - } - case 'J': case 'D': { - uint64_t wide_value = (static_cast<uint64_t>(shadow_frame.GetVReg(arg_pos + 1)) << 32) | - static_cast<uint32_t>(shadow_frame.GetVReg(arg_pos)); - new_shadow_frame->SetVRegLong(cur_reg, wide_value); - cur_reg++; - arg_offset++; + ++cur_reg; + ++arg_offset; break; } default: @@ -198,6 +109,7 @@ bool DoInvokeVirtualQuick(Thread* self, ShadowFrame& shadow_frame, } } + // Do the call now. if (LIKELY(Runtime::Current()->IsStarted())) { (method->GetEntryPointFromInterpreter())(self, mh, code_item, new_shadow_frame, result); } else { @@ -273,9 +185,9 @@ bool DoFilledNewArray(const Instruction* inst, const ShadowFrame& shadow_frame, return true; } -void UnstartedRuntimeInvoke(Thread* self, MethodHelper& mh, - const DexFile::CodeItem* code_item, 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) { // In a runtime that's not started we intercept certain methods to avoid complicated dependency // problems in core libraries. std::string name(PrettyMethod(shadow_frame->GetMethod())); @@ -367,34 +279,17 @@ void UnstartedRuntimeInvoke(Thread* self, MethodHelper& mh, } } -// Explicit DoInvoke template function declarations. -#define EXPLICIT_DO_INVOKE_TEMPLATE_DECL(_type, _is_range_, _check) \ - template bool DoInvoke<_type, _is_range_, _check>(Thread* self, ShadowFrame& shadow_frame, \ - const Instruction* inst, JValue* result) - -#define EXPLICIT_DO_INVOKE_TEMPLATE_DECL_VARIANTS(_type) \ - EXPLICIT_DO_INVOKE_TEMPLATE_DECL(_type, false, false); \ - EXPLICIT_DO_INVOKE_TEMPLATE_DECL(_type, false, true); \ - EXPLICIT_DO_INVOKE_TEMPLATE_DECL(_type, true, false); \ - EXPLICIT_DO_INVOKE_TEMPLATE_DECL(_type, true, true) - -EXPLICIT_DO_INVOKE_TEMPLATE_DECL_VARIANTS(kStatic); -EXPLICIT_DO_INVOKE_TEMPLATE_DECL_VARIANTS(kDirect); -EXPLICIT_DO_INVOKE_TEMPLATE_DECL_VARIANTS(kVirtual); -EXPLICIT_DO_INVOKE_TEMPLATE_DECL_VARIANTS(kSuper); -EXPLICIT_DO_INVOKE_TEMPLATE_DECL_VARIANTS(kInterface); - -#undef EXPLICIT_DO_INVOKE_TEMPLATE_DECL_VARIANTS -#undef EXPLICIT_DO_INVOKE_TEMPLATE_DECL - -// Explicit DoInvokeVirtualQuick template function declarations. -#define EXPLICIT_DO_INVOKE_VIRTUAL_QUICK_TEMPLATE_DECL(_is_range) \ -template bool DoInvokeVirtualQuick<_is_range>(Thread* self, ShadowFrame& shadow_frame, \ - const Instruction* inst, JValue* result) - -EXPLICIT_DO_INVOKE_VIRTUAL_QUICK_TEMPLATE_DECL(false); -EXPLICIT_DO_INVOKE_VIRTUAL_QUICK_TEMPLATE_DECL(true); -#undef EXPLICIT_DO_INVOKE_VIRTUAL_QUICK_TEMPLATE_DECL +// Explicit DoCall template function declarations. +#define EXPLICIT_DO_CALL_TEMPLATE_DECL(_is_range, _do_assignability_check) \ +template bool DoCall<_is_range, _do_assignability_check>(ArtMethod* method, Object* receiver, \ + Thread* self, ShadowFrame& shadow_frame, \ + const Instruction* inst, \ + uint16_t inst_data, JValue* result) +EXPLICIT_DO_CALL_TEMPLATE_DECL(false, false); +EXPLICIT_DO_CALL_TEMPLATE_DECL(false, true); +EXPLICIT_DO_CALL_TEMPLATE_DECL(true, false); +EXPLICIT_DO_CALL_TEMPLATE_DECL(true, true); +#undef EXPLICIT_DO_CALL_TEMPLATE_DECL // Explicit DoFilledNewArray template function declarations. #define EXPLICIT_DO_FILLED_NEW_ARRAY_TEMPLATE_DECL(_is_range_, _check) \ diff --git a/runtime/interpreter/interpreter_common.h b/runtime/interpreter/interpreter_common.h index 3ad1935..80502b4 100644 --- a/runtime/interpreter/interpreter_common.h +++ b/runtime/interpreter/interpreter_common.h @@ -71,7 +71,7 @@ template<bool do_access_check> extern JValue ExecuteSwitchImpl(Thread* self, MethodHelper& mh, const DexFile::CodeItem* code_item, ShadowFrame& shadow_frame, JValue result_register) - NO_THREAD_SAFETY_ANALYSIS __attribute__((hot)); + NO_THREAD_SAFETY_ANALYSIS HOT_ATTR; // TODO: should be SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) which is failing due to template // specialization. @@ -79,12 +79,7 @@ template<bool do_access_check> extern JValue ExecuteGotoImpl(Thread* self, MethodHelper& mh, const DexFile::CodeItem* code_item, ShadowFrame& shadow_frame, JValue result_register) - NO_THREAD_SAFETY_ANALYSIS __attribute__((hot)); - -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_); + NO_THREAD_SAFETY_ANALYSIS HOT_ATTR; static inline void DoMonitorEnter(Thread* self, Object* ref) NO_THREAD_SAFETY_ANALYSIS { ref->MonitorEnter(self); @@ -96,16 +91,72 @@ static inline void DoMonitorExit(Thread* self, Object* ref) NO_THREAD_SAFETY_ANA // TODO: should be SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) which is failing due to template // specialization. +template<bool is_range, bool do_assignability_check> +bool DoCall(ArtMethod* method, Object* receiver, Thread* self, ShadowFrame& shadow_frame, + const Instruction* inst, uint16_t inst_data, JValue* result) NO_THREAD_SAFETY_ANALYSIS; + +// TODO: should be SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) which is failing due to template +// specialization. template<InvokeType type, bool is_range, bool do_access_check> -bool DoInvoke(Thread* self, ShadowFrame& shadow_frame, - const Instruction* inst, JValue* result) NO_THREAD_SAFETY_ANALYSIS; +static bool DoInvoke(Thread* self, ShadowFrame& shadow_frame, const Instruction* inst, + uint16_t inst_data, JValue* result) NO_THREAD_SAFETY_ANALYSIS ALWAYS_INLINE; + +template<InvokeType type, bool is_range, bool do_access_check> +static inline bool DoInvoke(Thread* self, ShadowFrame& shadow_frame, const Instruction* inst, + uint16_t inst_data, JValue* result) { + const uint32_t method_idx = (is_range) ? inst->VRegB_3rc() : inst->VRegB_35c(); + const uint32_t vregC = (is_range) ? inst->VRegC_3rc() : inst->VRegC_35c(); + Object* const receiver = (type == kStatic) ? NULL : shadow_frame.GetVRegReference(vregC); + ArtMethod* const method = FindMethodFromCode(method_idx, receiver, shadow_frame.GetMethod(), self, + do_access_check, type); + if (UNLIKELY(method == NULL)) { + CHECK(self->IsExceptionPending()); + result->SetJ(0); + return false; + } else if (UNLIKELY(method->IsAbstract())) { + ThrowAbstractMethodError(method); + result->SetJ(0); + return false; + } else { + return DoCall<is_range, do_access_check>(method, receiver, self, shadow_frame, inst, + inst_data, result); + } +} // TODO: should be SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) which is failing due to template // specialization. template<bool is_range> -bool DoInvokeVirtualQuick(Thread* self, ShadowFrame& shadow_frame, - const Instruction* inst, JValue* result) - NO_THREAD_SAFETY_ANALYSIS; +static bool DoInvokeVirtualQuick(Thread* self, ShadowFrame& shadow_frame, const Instruction* inst, + uint16_t inst_data, JValue* result) + NO_THREAD_SAFETY_ANALYSIS ALWAYS_INLINE; + +template<bool is_range> +static inline bool DoInvokeVirtualQuick(Thread* self, ShadowFrame& shadow_frame, + const Instruction* inst, uint16_t inst_data, + JValue* result) { + const uint32_t vregC = (is_range) ? inst->VRegC_3rc() : inst->VRegC_35c(); + Object* const receiver = shadow_frame.GetVRegReference(vregC); + if (UNLIKELY(receiver == NULL)) { + // We lost the reference to the method index so we cannot get a more + // precised exception message. + ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow()); + return false; + } + const uint32_t vtable_idx = (is_range) ? inst->VRegB_3rc() : inst->VRegB_35c(); + ArtMethod* const method = receiver->GetClass()->GetVTable()->GetWithoutChecks(vtable_idx); + if (UNLIKELY(method == NULL)) { + CHECK(self->IsExceptionPending()); + result->SetJ(0); + return false; + } else if (UNLIKELY(method->IsAbstract())) { + ThrowAbstractMethodError(method); + result->SetJ(0); + return false; + } else { + // No need to check since we've been quickened. + return DoCall<is_range, false>(method, receiver, self, shadow_frame, inst, inst_data, result); + } +} // We use template functions to optimize compiler inlining process. Otherwise, // some parts of the code (like a switch statement) which depend on a constant @@ -283,11 +334,11 @@ static inline bool DoFieldPut(Thread* self, const ShadowFrame& shadow_frame, // TODO: should be SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) which is failing due to template // specialization. template<Primitive::Type field_type> -static bool DoIPutQuick(ShadowFrame& shadow_frame, const Instruction* inst, uint16_t inst_data) +static bool DoIPutQuick(const ShadowFrame& shadow_frame, const Instruction* inst, uint16_t inst_data) NO_THREAD_SAFETY_ANALYSIS ALWAYS_INLINE; template<Primitive::Type field_type> -static inline bool DoIPutQuick(ShadowFrame& shadow_frame, const Instruction* inst, uint16_t inst_data) { +static inline bool DoIPutQuick(const ShadowFrame& shadow_frame, const Instruction* inst, uint16_t inst_data) { Object* obj = shadow_frame.GetVRegReference(inst->VRegB_22c(inst_data)); if (UNLIKELY(obj == NULL)) { // We lost the reference to the field index so we cannot get a more diff --git a/runtime/interpreter/interpreter_goto_table_impl.cc b/runtime/interpreter/interpreter_goto_table_impl.cc index 018add3..5a00831 100644 --- a/runtime/interpreter/interpreter_goto_table_impl.cc +++ b/runtime/interpreter/interpreter_goto_table_impl.cc @@ -29,7 +29,6 @@ namespace interpreter { // - "currentHandlersTable": the current table of pointer to each instruction handler. // Advance to the next instruction and updates interpreter state. -// TODO: move check suspend to backward branch, return and exception handling. #define ADVANCE(_offset) \ do { \ int32_t disp = static_cast<int32_t>(_offset); \ @@ -1339,84 +1338,84 @@ JValue ExecuteGotoImpl(Thread* self, MethodHelper& mh, const DexFile::CodeItem* HANDLE_INSTRUCTION_END(); HANDLE_INSTRUCTION_START(INVOKE_VIRTUAL) { - bool success = DoInvoke<kVirtual, false, do_access_check>(self, shadow_frame, inst, &result_register); + bool success = DoInvoke<kVirtual, false, do_access_check>(self, shadow_frame, inst, inst_data, &result_register); UPDATE_HANDLER_TABLE(); POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3); } HANDLE_INSTRUCTION_END(); HANDLE_INSTRUCTION_START(INVOKE_VIRTUAL_RANGE) { - bool success = DoInvoke<kVirtual, true, do_access_check>(self, shadow_frame, inst, &result_register); + bool success = DoInvoke<kVirtual, true, do_access_check>(self, shadow_frame, inst, inst_data, &result_register); UPDATE_HANDLER_TABLE(); POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3); } HANDLE_INSTRUCTION_END(); HANDLE_INSTRUCTION_START(INVOKE_SUPER) { - bool success = DoInvoke<kSuper, false, do_access_check>(self, shadow_frame, inst, &result_register); + bool success = DoInvoke<kSuper, false, do_access_check>(self, shadow_frame, inst, inst_data, &result_register); UPDATE_HANDLER_TABLE(); POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3); } HANDLE_INSTRUCTION_END(); HANDLE_INSTRUCTION_START(INVOKE_SUPER_RANGE) { - bool success = DoInvoke<kSuper, true, do_access_check>(self, shadow_frame, inst, &result_register); + bool success = DoInvoke<kSuper, true, do_access_check>(self, shadow_frame, inst, inst_data, &result_register); UPDATE_HANDLER_TABLE(); POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3); } HANDLE_INSTRUCTION_END(); HANDLE_INSTRUCTION_START(INVOKE_DIRECT) { - bool success = DoInvoke<kDirect, false, do_access_check>(self, shadow_frame, inst, &result_register); + bool success = DoInvoke<kDirect, false, do_access_check>(self, shadow_frame, inst, inst_data, &result_register); UPDATE_HANDLER_TABLE(); POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3); } HANDLE_INSTRUCTION_END(); HANDLE_INSTRUCTION_START(INVOKE_DIRECT_RANGE) { - bool success = DoInvoke<kDirect, true, do_access_check>(self, shadow_frame, inst, &result_register); + bool success = DoInvoke<kDirect, true, do_access_check>(self, shadow_frame, inst, inst_data, &result_register); UPDATE_HANDLER_TABLE(); POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3); } HANDLE_INSTRUCTION_END(); HANDLE_INSTRUCTION_START(INVOKE_INTERFACE) { - bool success = DoInvoke<kInterface, false, do_access_check>(self, shadow_frame, inst, &result_register); + bool success = DoInvoke<kInterface, false, do_access_check>(self, shadow_frame, inst, inst_data, &result_register); UPDATE_HANDLER_TABLE(); POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3); } HANDLE_INSTRUCTION_END(); HANDLE_INSTRUCTION_START(INVOKE_INTERFACE_RANGE) { - bool success = DoInvoke<kInterface, true, do_access_check>(self, shadow_frame, inst, &result_register); + bool success = DoInvoke<kInterface, true, do_access_check>(self, shadow_frame, inst, inst_data, &result_register); UPDATE_HANDLER_TABLE(); POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3); } HANDLE_INSTRUCTION_END(); HANDLE_INSTRUCTION_START(INVOKE_STATIC) { - bool success = DoInvoke<kStatic, false, do_access_check>(self, shadow_frame, inst, &result_register); + bool success = DoInvoke<kStatic, false, do_access_check>(self, shadow_frame, inst, inst_data, &result_register); UPDATE_HANDLER_TABLE(); POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3); } HANDLE_INSTRUCTION_END(); HANDLE_INSTRUCTION_START(INVOKE_STATIC_RANGE) { - bool success = DoInvoke<kStatic, true, do_access_check>(self, shadow_frame, inst, &result_register); + bool success = DoInvoke<kStatic, true, do_access_check>(self, shadow_frame, inst, inst_data, &result_register); UPDATE_HANDLER_TABLE(); POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3); } HANDLE_INSTRUCTION_END(); HANDLE_INSTRUCTION_START(INVOKE_VIRTUAL_QUICK) { - bool success = DoInvokeVirtualQuick<false>(self, shadow_frame, inst, &result_register); + bool success = DoInvokeVirtualQuick<false>(self, shadow_frame, inst, inst_data, &result_register); UPDATE_HANDLER_TABLE(); POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3); } HANDLE_INSTRUCTION_END(); HANDLE_INSTRUCTION_START(INVOKE_VIRTUAL_RANGE_QUICK) { - bool success = DoInvokeVirtualQuick<true>(self, shadow_frame, inst, &result_register); + bool success = DoInvokeVirtualQuick<true>(self, shadow_frame, inst, inst_data, &result_register); UPDATE_HANDLER_TABLE(); POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3); } diff --git a/runtime/interpreter/interpreter_switch_impl.cc b/runtime/interpreter/interpreter_switch_impl.cc index 2d658b3..82f216a 100644 --- a/runtime/interpreter/interpreter_switch_impl.cc +++ b/runtime/interpreter/interpreter_switch_impl.cc @@ -1283,73 +1283,73 @@ static JValue ExecuteSwitchImpl(Thread* self, MethodHelper& mh, const DexFile::C } case Instruction::INVOKE_VIRTUAL: { PREAMBLE(); - bool success = DoInvoke<kVirtual, false, do_access_check>(self, shadow_frame, inst, &result_register); + bool success = DoInvoke<kVirtual, false, do_access_check>(self, shadow_frame, inst, inst_data, &result_register); POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx); break; } case Instruction::INVOKE_VIRTUAL_RANGE: { PREAMBLE(); - bool success = DoInvoke<kVirtual, true, do_access_check>(self, shadow_frame, inst, &result_register); + bool success = DoInvoke<kVirtual, true, do_access_check>(self, shadow_frame, inst, inst_data, &result_register); POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx); break; } case Instruction::INVOKE_SUPER: { PREAMBLE(); - bool success = DoInvoke<kSuper, false, do_access_check>(self, shadow_frame, inst, &result_register); + bool success = DoInvoke<kSuper, false, do_access_check>(self, shadow_frame, inst, inst_data, &result_register); POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx); break; } case Instruction::INVOKE_SUPER_RANGE: { PREAMBLE(); - bool success = DoInvoke<kSuper, true, do_access_check>(self, shadow_frame, inst, &result_register); + bool success = DoInvoke<kSuper, true, do_access_check>(self, shadow_frame, inst, inst_data, &result_register); POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx); break; } case Instruction::INVOKE_DIRECT: { PREAMBLE(); - bool success = DoInvoke<kDirect, false, do_access_check>(self, shadow_frame, inst, &result_register); + bool success = DoInvoke<kDirect, false, do_access_check>(self, shadow_frame, inst, inst_data, &result_register); POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx); break; } case Instruction::INVOKE_DIRECT_RANGE: { PREAMBLE(); - bool success = DoInvoke<kDirect, true, do_access_check>(self, shadow_frame, inst, &result_register); + bool success = DoInvoke<kDirect, true, do_access_check>(self, shadow_frame, inst, inst_data, &result_register); POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx); break; } case Instruction::INVOKE_INTERFACE: { PREAMBLE(); - bool success = DoInvoke<kInterface, false, do_access_check>(self, shadow_frame, inst, &result_register); + bool success = DoInvoke<kInterface, false, do_access_check>(self, shadow_frame, inst, inst_data, &result_register); POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx); break; } case Instruction::INVOKE_INTERFACE_RANGE: { PREAMBLE(); - bool success = DoInvoke<kInterface, true, do_access_check>(self, shadow_frame, inst, &result_register); + bool success = DoInvoke<kInterface, true, do_access_check>(self, shadow_frame, inst, inst_data, &result_register); POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx); break; } case Instruction::INVOKE_STATIC: { PREAMBLE(); - bool success = DoInvoke<kStatic, false, do_access_check>(self, shadow_frame, inst, &result_register); + bool success = DoInvoke<kStatic, false, do_access_check>(self, shadow_frame, inst, inst_data, &result_register); POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx); break; } case Instruction::INVOKE_STATIC_RANGE: { PREAMBLE(); - bool success = DoInvoke<kStatic, true, do_access_check>(self, shadow_frame, inst, &result_register); + bool success = DoInvoke<kStatic, true, do_access_check>(self, shadow_frame, inst, inst_data, &result_register); POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx); break; } case Instruction::INVOKE_VIRTUAL_QUICK: { PREAMBLE(); - bool success = DoInvokeVirtualQuick<false>(self, shadow_frame, inst, &result_register); + bool success = DoInvokeVirtualQuick<false>(self, shadow_frame, inst, inst_data, &result_register); POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx); break; } case Instruction::INVOKE_VIRTUAL_RANGE_QUICK: { PREAMBLE(); - bool success = DoInvokeVirtualQuick<true>(self, shadow_frame, inst, &result_register); + bool success = DoInvokeVirtualQuick<true>(self, shadow_frame, inst, inst_data, &result_register); POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx); break; } diff --git a/runtime/stack.h b/runtime/stack.h index 2bf3340..700b7f1 100644 --- a/runtime/stack.h +++ b/runtime/stack.h @@ -68,8 +68,7 @@ class ShadowFrame { static ShadowFrame* Create(uint32_t num_vregs, ShadowFrame* link, mirror::ArtMethod* method, uint32_t dex_pc) { uint8_t* memory = new uint8_t[ComputeSize(num_vregs)]; - ShadowFrame* sf = new (memory) ShadowFrame(num_vregs, link, method, dex_pc, true); - return sf; + return Create(num_vregs, link, method, dex_pc, memory); } // Create ShadowFrame for interpreter using provided memory. |