diff options
| author | 2016-03-15 11:35:18 -0700 | |
|---|---|---|
| committer | 2016-03-16 13:58:40 -0700 | |
| commit | 4b34bf5b242dce5ee20db08b7781bbbaf0d25969 (patch) | |
| tree | 861902b14b1cd23c2cbc80b69d67204257b58dc1 | |
| parent | 77d993107773b7b9bd7f07ce08d0aaac1631bf84 (diff) | |
Fix issue with proxy invocation on default methods
Bug: 27621360
(cherry picked from commit ec3b7ab8f008f36f1072d4ba03da204229b95976)
Change-Id: I617eee243f475872235fd75b6a401e056111ea23
| -rw-r--r-- | runtime/art_method-inl.h | 1 | ||||
| -rw-r--r-- | runtime/class_linker.cc | 10 | ||||
| -rw-r--r-- | runtime/interpreter/interpreter_common.cc | 6 |
3 files changed, 12 insertions, 5 deletions
diff --git a/runtime/art_method-inl.h b/runtime/art_method-inl.h index 8541210791..f692ef62dd 100644 --- a/runtime/art_method-inl.h +++ b/runtime/art_method-inl.h @@ -332,6 +332,7 @@ inline const char* ArtMethod::GetName() { } inline const DexFile::CodeItem* ArtMethod::GetCodeItem() { + DCHECK(!IsProxyMethod()); return GetDeclaringClass()->GetDexFile().GetCodeItem(GetCodeItemOffset()); } diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc index 6a2b702056..f57048aca2 100644 --- a/runtime/class_linker.cc +++ b/runtime/class_linker.cc @@ -4282,10 +4282,14 @@ void ClassLinker::CreateProxyMethod(Handle<mirror::Class> klass, ArtMethod* prot DCHECK(out != nullptr); out->CopyFrom(prototype, image_pointer_size_); - // Set class to be the concrete proxy class and clear the abstract flag, modify exceptions to - // the intersection of throw exceptions as defined in Proxy + // Set class to be the concrete proxy class. out->SetDeclaringClass(klass.Get()); - out->SetAccessFlags((out->GetAccessFlags() & ~kAccAbstract) | kAccFinal); + // Clear the abstract, default and conflict flags to ensure that defaults aren't picked in + // preference to the invocation handler. + const uint32_t kRemoveFlags = kAccAbstract | kAccDefault | kAccDefaultConflict; + // Make the method final. + const uint32_t kAddFlags = kAccFinal; + out->SetAccessFlags((out->GetAccessFlags() & ~kRemoveFlags) | kAddFlags); // At runtime the method looks like a reference and argument saving method, clone the code // related parameters from this method. diff --git a/runtime/interpreter/interpreter_common.cc b/runtime/interpreter/interpreter_common.cc index 3453abcd64..310e211aaf 100644 --- a/runtime/interpreter/interpreter_common.cc +++ b/runtime/interpreter/interpreter_common.cc @@ -555,8 +555,10 @@ static inline bool DoCallCommon(ArtMethod* called_method, string_init = true; } - // Compute method information. - const DexFile::CodeItem* code_item = called_method->GetCodeItem(); + // Compute method information. Need to specifically check for proxy methods since default-method + // proxies might have a CodeItem from the default version. + const DexFile::CodeItem* code_item = + called_method->IsProxyMethod() ? nullptr : called_method->GetCodeItem(); // Number of registers for the callee's call frame. uint16_t num_regs; |