diff options
Diffstat (limited to 'runtime/interpreter/mterp/nterp.cc')
-rw-r--r-- | runtime/interpreter/mterp/nterp.cc | 19 |
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()) { |