summaryrefslogtreecommitdiff
path: root/runtime/class_linker.cc
diff options
context:
space:
mode:
Diffstat (limited to 'runtime/class_linker.cc')
-rw-r--r--runtime/class_linker.cc22
1 files changed, 18 insertions, 4 deletions
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc
index 52beb15277..268b9822ac 100644
--- a/runtime/class_linker.cc
+++ b/runtime/class_linker.cc
@@ -2528,8 +2528,18 @@ uint32_t ClassLinker::SizeOfClassWithoutEmbeddedTables(const DexFile& dex_file,
size_t num_32 = 0;
size_t num_64 = 0;
if (class_data != nullptr) {
+ // We allow duplicate definitions of the same field in a class_data_item
+ // but ignore the repeated indexes here, b/21868015.
+ uint32_t last_field_idx = DexFile::kDexNoIndex;
for (ClassDataItemIterator it(dex_file, class_data); it.HasNextStaticField(); it.Next()) {
- const DexFile::FieldId& field_id = dex_file.GetFieldId(it.GetMemberIndex());
+ uint32_t field_idx = it.GetMemberIndex();
+ // Ordering enforced by DexFileVerifier.
+ DCHECK(last_field_idx == DexFile::kDexNoIndex || last_field_idx <= field_idx);
+ if (UNLIKELY(field_idx == last_field_idx)) {
+ continue;
+ }
+ last_field_idx = field_idx;
+ const DexFile::FieldId& field_id = dex_file.GetFieldId(field_idx);
const char* descriptor = dex_file.GetFieldTypeDescriptor(field_id);
char c = descriptor[0];
switch (c) {
@@ -4255,10 +4265,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.