diff options
-rw-r--r-- | runtime/interpreter/interpreter_common.cc | 27 | ||||
-rw-r--r-- | runtime/interpreter/interpreter_common.h | 11 | ||||
-rw-r--r-- | runtime/stack.h | 2 |
3 files changed, 17 insertions, 23 deletions
diff --git a/runtime/interpreter/interpreter_common.cc b/runtime/interpreter/interpreter_common.cc index 5b9e55f..1d40293 100644 --- a/runtime/interpreter/interpreter_common.cc +++ b/runtime/interpreter/interpreter_common.cc @@ -38,7 +38,7 @@ static inline void AssignRegister(ShadowFrame& new_shadow_frame, const ShadowFra } template<bool is_range, bool do_assignability_check> -bool DoCall(ArtMethod* method, Object* receiver, Thread* self, ShadowFrame& shadow_frame, +bool DoCall(ArtMethod* method, Thread* self, ShadowFrame& shadow_frame, const Instruction* inst, uint16_t inst_data, JValue* result) { // Compute method information. MethodHelper mh(method); @@ -66,17 +66,6 @@ bool DoCall(ArtMethod* method, Object* receiver, Thread* self, ShadowFrame& shad const DexFile::TypeList* params = mh.GetParameterTypeList(); const char* shorty = mh.GetShorty(); - // Handle receiver apart since it's not part of the shorty. - size_t dest_reg = first_dest_reg; - size_t arg_offset = 0; - if (receiver != NULL) { - DCHECK(!method->IsStatic()); - new_shadow_frame->SetVRegReference(dest_reg, receiver); - ++dest_reg; - ++arg_offset; - } else { - DCHECK(method->IsStatic()); - } // TODO: find a cleaner way to separate non-range and range information without duplicating code. uint32_t arg[5]; // only used in invoke-XXX. uint32_t vregC; // only used in invoke-XXX-range. @@ -85,6 +74,16 @@ bool DoCall(ArtMethod* method, Object* receiver, Thread* self, ShadowFrame& shad } else { inst->GetArgs(arg, inst_data); } + + // Handle receiver apart since it's not part of the shorty. + size_t dest_reg = first_dest_reg; + size_t arg_offset = 0; + if (!method->IsStatic()) { + size_t receiver_reg = (is_range) ? vregC : arg[0]; + new_shadow_frame->SetVRegReference(dest_reg, shadow_frame.GetVRegReference(receiver_reg)); + ++dest_reg; + ++arg_offset; + } for (size_t shorty_pos = 0; dest_reg < num_regs; ++shorty_pos, ++dest_reg, ++arg_offset) { DCHECK_LT(shorty_pos + 1, mh.GetShortyLength()); const size_t src_reg = (is_range) ? vregC + arg_offset : arg[arg_offset]; @@ -333,8 +332,8 @@ static void UnstartedRuntimeInvoke(Thread* self, MethodHelper& mh, // Explicit DoCall template function declarations. #define EXPLICIT_DO_CALL_TEMPLATE_DECL(_is_range, _do_assignability_check) \ template SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) \ - bool DoCall<_is_range, _do_assignability_check>(ArtMethod* method, Object* receiver, \ - Thread* self, ShadowFrame& shadow_frame, \ + bool DoCall<_is_range, _do_assignability_check>(ArtMethod* method, Thread* self, \ + ShadowFrame& shadow_frame, \ const Instruction* inst, uint16_t inst_data, \ JValue* result) EXPLICIT_DO_CALL_TEMPLATE_DECL(false, false); diff --git a/runtime/interpreter/interpreter_common.h b/runtime/interpreter/interpreter_common.h index a9b8909..4481210 100644 --- a/runtime/interpreter/interpreter_common.h +++ b/runtime/interpreter/interpreter_common.h @@ -87,7 +87,7 @@ static inline void DoMonitorExit(Thread* self, Object* ref) NO_THREAD_SAFETY_ANA // DoInvokeVirtualQuick functions. // Returns true on success, otherwise throws an exception and returns false. template<bool is_range, bool do_assignability_check> -bool DoCall(ArtMethod* method, Object* receiver, Thread* self, ShadowFrame& shadow_frame, +bool DoCall(ArtMethod* method, Thread* self, ShadowFrame& shadow_frame, const Instruction* inst, uint16_t inst_data, JValue* result); // Handles invoke-XXX/range instructions. @@ -101,10 +101,6 @@ static inline bool DoInvoke(Thread* self, ShadowFrame& shadow_frame, const Instr ArtMethod* const method = FindMethodFromCode<type, do_access_check>(method_idx, receiver, shadow_frame.GetMethod(), self); - if (type != kStatic) { - // Reload the vreg since the GC may have moved the object. - receiver = shadow_frame.GetVRegReference(vregC); - } if (UNLIKELY(method == nullptr)) { CHECK(self->IsExceptionPending()); result->SetJ(0); @@ -114,8 +110,7 @@ static inline bool DoInvoke(Thread* self, ShadowFrame& shadow_frame, const Instr result->SetJ(0); return false; } else { - return DoCall<is_range, do_access_check>(method, receiver, self, shadow_frame, inst, - inst_data, result); + return DoCall<is_range, do_access_check>(method, self, shadow_frame, inst, inst_data, result); } } @@ -145,7 +140,7 @@ static inline bool DoInvokeVirtualQuick(Thread* self, ShadowFrame& shadow_frame, 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); + return DoCall<is_range, false>(method, self, shadow_frame, inst, inst_data, result); } } diff --git a/runtime/stack.h b/runtime/stack.h index 3d6b06a..590f406 100644 --- a/runtime/stack.h +++ b/runtime/stack.h @@ -160,7 +160,7 @@ class ShadowFrame { << ") is in protected space, reference array " << true; } // If the vreg reference is not equal to the vreg then the vreg reference is stale. - if (reinterpret_cast<uint32_t>(ref) != vregs_[i]) { + if (UNLIKELY(reinterpret_cast<uint32_t>(ref) != vregs_[i])) { return nullptr; } return ref; |