summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Alex Light <allight@google.com> 2016-03-15 11:35:18 -0700
committer Alex Light <allight@google.com> 2016-03-16 13:58:40 -0700
commit4b34bf5b242dce5ee20db08b7781bbbaf0d25969 (patch)
tree861902b14b1cd23c2cbc80b69d67204257b58dc1
parent77d993107773b7b9bd7f07ce08d0aaac1631bf84 (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.h1
-rw-r--r--runtime/class_linker.cc10
-rw-r--r--runtime/interpreter/interpreter_common.cc6
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;