summaryrefslogtreecommitdiff
path: root/runtime/interpreter/mterp/nterp.cc
diff options
context:
space:
mode:
Diffstat (limited to 'runtime/interpreter/mterp/nterp.cc')
-rw-r--r--runtime/interpreter/mterp/nterp.cc19
1 files changed, 12 insertions, 7 deletions
diff --git a/runtime/interpreter/mterp/nterp.cc b/runtime/interpreter/mterp/nterp.cc
index 3d924734e9..1da8be67bd 100644
--- a/runtime/interpreter/mterp/nterp.cc
+++ b/runtime/interpreter/mterp/nterp.cc
@@ -384,18 +384,23 @@ extern "C" size_t NterpGetMethod(Thread* self, ArtMethod* caller, uint16_t* dex_
}
if (invoke_type == kInterface) {
+ size_t result = 0u;
if (resolved_method->GetDeclaringClass()->IsObjectClass()) {
- // Don't update the cache and return a value with high bit set to notify the
- // interpreter it should do a vtable call instead.
+ // Set the low bit to notify the interpreter it should do a vtable call.
DCHECK_LT(resolved_method->GetMethodIndex(), 0x10000);
- return resolved_method->GetMethodIndex() | (1U << 31);
+ result = (resolved_method->GetMethodIndex() << 16) | 1U;
} else {
DCHECK(resolved_method->GetDeclaringClass()->IsInterface());
- UpdateCache(self, dex_pc_ptr, resolved_method->GetImtIndex());
- // TODO: We should pass the resolved method, and have nterp fetch the IMT
- // index. Unfortunately, this doesn't work for default methods.
- return resolved_method->GetImtIndex();
+ if (!resolved_method->IsAbstract()) {
+ // Set the second bit to notify the interpreter this is a default
+ // method.
+ result = reinterpret_cast<size_t>(resolved_method) | 2U;
+ } else {
+ result = reinterpret_cast<size_t>(resolved_method);
+ }
}
+ UpdateCache(self, dex_pc_ptr, result);
+ return result;
} else if (resolved_method->GetDeclaringClass()->IsStringClass()
&& !resolved_method->IsStatic()
&& resolved_method->IsConstructor()) {