summaryrefslogtreecommitdiff
path: root/runtime/class_linker.cc
diff options
context:
space:
mode:
author Alex Light <allight@google.com> 2016-03-17 18:02:06 +0000
committer Gerrit Code Review <noreply-gerritcodereview@google.com> 2016-03-17 18:02:06 +0000
commit7f3397bec51bdeb7dfe76a17ea9d3279ddf79345 (patch)
treef450acdd3d621287cbf0ad12e1c7442d8de7013c /runtime/class_linker.cc
parent1160f2e14d61f95f3fb6bea03acb5451ad926acc (diff)
parente9dd04f633fcffc485f8d74861f39f66fc8bc522 (diff)
Merge "Revert "Revert "Fix issue with proxy invocation on default methods"""
Diffstat (limited to 'runtime/class_linker.cc')
-rw-r--r--runtime/class_linker.cc14
1 files changed, 11 insertions, 3 deletions
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc
index 3c69323b20..d0a784dfc9 100644
--- a/runtime/class_linker.cc
+++ b/runtime/class_linker.cc
@@ -4265,10 +4265,18 @@ 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);
+
+ // Clear the dex_code_item_offset_. It needs to be 0 since proxy methods have no CodeItems but the
+ // method they copy might (if it's a default method).
+ out->SetCodeItemOffset(0);
// At runtime the method looks like a reference and argument saving method, clone the code
// related parameters from this method.