ART: Move DexCache arrays to native.
This CL has a companion CL in libcore/
https://android-review.googlesource.com/162985
Change-Id: Icbc9e20ad1b565e603195b12714762bb446515fa
diff --git a/oatdump/oatdump.cc b/oatdump/oatdump.cc
index c553a18..2353dcf 100644
--- a/oatdump/oatdump.cc
+++ b/oatdump/oatdump.cc
@@ -44,6 +44,7 @@
#include "mapping_table.h"
#include "mirror/array-inl.h"
#include "mirror/class-inl.h"
+#include "mirror/dex_cache-inl.h"
#include "mirror/object-inl.h"
#include "mirror/object_array-inl.h"
#include "oat.h"
@@ -1615,15 +1616,14 @@
}
{
// Mark dex caches.
- dex_cache_arrays_.clear();
+ dex_caches_.clear();
{
ReaderMutexLock mu(self, *class_linker->DexLock());
for (jobject weak_root : class_linker->GetDexCaches()) {
mirror::DexCache* dex_cache =
down_cast<mirror::DexCache*>(self->DecodeJObject(weak_root));
if (dex_cache != nullptr) {
- dex_cache_arrays_.insert(dex_cache->GetResolvedFields());
- dex_cache_arrays_.insert(dex_cache->GetResolvedMethods());
+ dex_caches_.insert(dex_cache);
}
}
}
@@ -1659,22 +1659,25 @@
const auto& bitmap_section = image_header_.GetImageSection(ImageHeader::kSectionImageBitmap);
const auto& field_section = image_header_.GetImageSection(ImageHeader::kSectionArtFields);
const auto& method_section = image_header_.GetMethodsSection();
+ const auto& dex_cache_arrays_section = image_header_.GetImageSection(
+ ImageHeader::kSectionDexCacheArrays);
const auto& intern_section = image_header_.GetImageSection(
ImageHeader::kSectionInternedStrings);
stats_.header_bytes = header_bytes;
stats_.alignment_bytes += RoundUp(header_bytes, kObjectAlignment) - header_bytes;
// Add padding between the field and method section.
// (Field section is 4-byte aligned, method section is 8-byte aligned on 64-bit targets.)
- stats_.alignment_bytes +=
- method_section.Offset() - (field_section.Offset() + field_section.Size());
- // Add padding between the method section and the intern table.
- // (Method section is 4-byte aligned on 32-bit targets, intern table is 8-byte aligned.)
- stats_.alignment_bytes +=
- intern_section.Offset() - (method_section.Offset() + method_section.Size());
+ stats_.alignment_bytes += method_section.Offset() -
+ (field_section.Offset() + field_section.Size());
+ // Add padding between the dex cache arrays section and the intern table. (Dex cache
+ // arrays section is 4-byte aligned on 32-bit targets, intern table is 8-byte aligned.)
+ stats_.alignment_bytes += intern_section.Offset() -
+ (dex_cache_arrays_section.Offset() + dex_cache_arrays_section.Size());
stats_.alignment_bytes += bitmap_section.Offset() - image_header_.GetImageSize();
stats_.bitmap_bytes += bitmap_section.Size();
stats_.art_field_bytes += field_section.Size();
stats_.art_method_bytes += method_section.Size();
+ stats_.dex_cache_arrays_bytes += dex_cache_arrays_section.Size();
stats_.interned_strings_bytes += intern_section.Size();
stats_.Dump(os, indent_os);
os << "\n";
@@ -1881,33 +1884,73 @@
}
}
} else {
- auto it = state->dex_cache_arrays_.find(obj);
- if (it != state->dex_cache_arrays_.end()) {
+ auto it = state->dex_caches_.find(obj);
+ if (it != state->dex_caches_.end()) {
+ auto* dex_cache = down_cast<mirror::DexCache*>(obj);
const auto& field_section = state->image_header_.GetImageSection(
ImageHeader::kSectionArtFields);
const auto& method_section = state->image_header_.GetMethodsSection();
- auto* arr = down_cast<mirror::PointerArray*>(obj);
- for (int32_t i = 0, length = arr->GetLength(); i < length; i++) {
- void* elem = arr->GetElementPtrSize<void*>(i, image_pointer_size);
- size_t run = 0;
- for (int32_t j = i + 1; j < length &&
- elem == arr->GetElementPtrSize<void*>(j, image_pointer_size); j++, run++) { }
- if (run == 0) {
- os << StringPrintf("%d: ", i);
- } else {
- os << StringPrintf("%d to %zd: ", i, i + run);
- i = i + run;
+ size_t num_methods = dex_cache->NumResolvedMethods();
+ if (num_methods != 0u) {
+ os << "Methods (size=" << num_methods << "):";
+ ScopedIndentation indent2(&state->vios_);
+ auto* resolved_methods = dex_cache->GetResolvedMethods();
+ for (size_t i = 0, length = dex_cache->NumResolvedMethods(); i < length; ++i) {
+ auto* elem = mirror::DexCache::GetElementPtrSize(resolved_methods, i, image_pointer_size);
+ size_t run = 0;
+ for (size_t j = i + 1;
+ j != length && elem == mirror::DexCache::GetElementPtrSize(resolved_methods,
+ j,
+ image_pointer_size);
+ ++j, ++run) {}
+ if (run == 0) {
+ os << StringPrintf("%zd: ", i);
+ } else {
+ os << StringPrintf("%zd to %zd: ", i, i + run);
+ i = i + run;
+ }
+ std::string msg;
+ if (elem == nullptr) {
+ msg = "null";
+ } else if (method_section.Contains(
+ reinterpret_cast<uint8_t*>(elem) - state->image_space_.Begin())) {
+ msg = PrettyMethod(reinterpret_cast<ArtMethod*>(elem));
+ } else {
+ msg = "<not in method section>";
+ }
+ os << StringPrintf("%p %s\n", elem, msg.c_str());
}
- auto offset = reinterpret_cast<uint8_t*>(elem) - state->image_space_.Begin();
- std::string msg;
- if (field_section.Contains(offset)) {
- msg = PrettyField(reinterpret_cast<ArtField*>(elem));
- } else if (method_section.Contains(offset)) {
- msg = PrettyMethod(reinterpret_cast<ArtMethod*>(elem));
- } else {
- msg = "Unknown type";
+ }
+ size_t num_fields = dex_cache->NumResolvedFields();
+ if (num_fields != 0u) {
+ os << "Fields (size=" << num_fields << "):";
+ ScopedIndentation indent2(&state->vios_);
+ auto* resolved_fields = dex_cache->GetResolvedFields();
+ for (size_t i = 0, length = dex_cache->NumResolvedFields(); i < length; ++i) {
+ auto* elem = mirror::DexCache::GetElementPtrSize(resolved_fields, i, image_pointer_size);
+ size_t run = 0;
+ for (size_t j = i + 1;
+ j != length && elem == mirror::DexCache::GetElementPtrSize(resolved_fields,
+ j,
+ image_pointer_size);
+ ++j, ++run) {}
+ if (run == 0) {
+ os << StringPrintf("%zd: ", i);
+ } else {
+ os << StringPrintf("%zd to %zd: ", i, i + run);
+ i = i + run;
+ }
+ std::string msg;
+ if (elem == nullptr) {
+ msg = "null";
+ } else if (field_section.Contains(
+ reinterpret_cast<uint8_t*>(elem) - state->image_space_.Begin())) {
+ msg = PrettyField(reinterpret_cast<ArtField*>(elem));
+ } else {
+ msg = "<not in field section>";
+ }
+ os << StringPrintf("%p %s\n", elem, msg.c_str());
}
- os << StringPrintf("%p %s\n", elem, msg.c_str());
}
}
}
@@ -2022,6 +2065,7 @@
size_t object_bytes;
size_t art_field_bytes;
size_t art_method_bytes;
+ size_t dex_cache_arrays_bytes;
size_t interned_strings_bytes;
size_t bitmap_bytes;
size_t alignment_bytes;
@@ -2052,6 +2096,7 @@
object_bytes(0),
art_field_bytes(0),
art_method_bytes(0),
+ dex_cache_arrays_bytes(0),
interned_strings_bytes(0),
bitmap_bytes(0),
alignment_bytes(0),
@@ -2209,24 +2254,27 @@
{
os << "art_file_bytes = " << PrettySize(file_bytes) << "\n\n"
<< "art_file_bytes = header_bytes + object_bytes + alignment_bytes\n";
- indent_os << StringPrintf("header_bytes = %8zd (%2.0f%% of art file bytes)\n"
- "object_bytes = %8zd (%2.0f%% of art file bytes)\n"
- "art_field_bytes = %8zd (%2.0f%% of art file bytes)\n"
- "art_method_bytes = %8zd (%2.0f%% of art file bytes)\n"
- "interned_string_bytes = %8zd (%2.0f%% of art file bytes)\n"
- "bitmap_bytes = %8zd (%2.0f%% of art file bytes)\n"
- "alignment_bytes = %8zd (%2.0f%% of art file bytes)\n\n",
+ indent_os << StringPrintf("header_bytes = %8zd (%2.0f%% of art file bytes)\n"
+ "object_bytes = %8zd (%2.0f%% of art file bytes)\n"
+ "art_field_bytes = %8zd (%2.0f%% of art file bytes)\n"
+ "art_method_bytes = %8zd (%2.0f%% of art file bytes)\n"
+ "dex_cache_arrays_bytes = %8zd (%2.0f%% of art file bytes)\n"
+ "interned_string_bytes = %8zd (%2.0f%% of art file bytes)\n"
+ "bitmap_bytes = %8zd (%2.0f%% of art file bytes)\n"
+ "alignment_bytes = %8zd (%2.0f%% of art file bytes)\n\n",
header_bytes, PercentOfFileBytes(header_bytes),
object_bytes, PercentOfFileBytes(object_bytes),
art_field_bytes, PercentOfFileBytes(art_field_bytes),
art_method_bytes, PercentOfFileBytes(art_method_bytes),
+ dex_cache_arrays_bytes,
+ PercentOfFileBytes(dex_cache_arrays_bytes),
interned_strings_bytes,
PercentOfFileBytes(interned_strings_bytes),
bitmap_bytes, PercentOfFileBytes(bitmap_bytes),
alignment_bytes, PercentOfFileBytes(alignment_bytes))
<< std::flush;
CHECK_EQ(file_bytes, header_bytes + object_bytes + art_field_bytes + art_method_bytes +
- interned_strings_bytes + bitmap_bytes + alignment_bytes);
+ dex_cache_arrays_bytes + interned_strings_bytes + bitmap_bytes + alignment_bytes);
}
os << "object_bytes breakdown:\n";
@@ -2312,7 +2360,7 @@
const ImageHeader& image_header_;
std::unique_ptr<OatDumper> oat_dumper_;
OatDumperOptions* oat_dumper_options_;
- std::set<mirror::Object*> dex_cache_arrays_;
+ std::set<mirror::Object*> dex_caches_;
DISALLOW_COPY_AND_ASSIGN(ImageDumper);
};