summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--runtime/interpreter/interpreter_common.cc27
-rw-r--r--runtime/interpreter/interpreter_common.h11
-rw-r--r--runtime/stack.h2
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;