diff options
Diffstat (limited to 'runtime/class_linker.cc')
| -rw-r--r-- | runtime/class_linker.cc | 22 |
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. |