summaryrefslogtreecommitdiffstats
path: root/oatdump
diff options
context:
space:
mode:
authorMathieu Chartier <mathieuc@google.com>2013-09-13 13:46:47 -0700
committerMathieu Chartier <mathieuc@google.com>2013-11-11 15:34:27 -0800
commit590fee9e8972f872301c2d16a575d579ee564bee (patch)
treeb02db45c72f1911ec896b93379ada0276aea3199 /oatdump
parent5b70680b8df6d8fa95bb8e1070d0107f3d388940 (diff)
downloadart-590fee9e8972f872301c2d16a575d579ee564bee.zip
art-590fee9e8972f872301c2d16a575d579ee564bee.tar.gz
art-590fee9e8972f872301c2d16a575d579ee564bee.tar.bz2
Compacting collector.
The compacting collector is currently similar to semispace. It works by copying objects back and forth between two bump pointer spaces. There are types of objects which are "non-movable" due to current runtime limitations. These are Classes, Methods, and Fields. Bump pointer spaces are a new type of continuous alloc space which have no lock in the allocation code path. When you allocate from these it uses atomic operations to increase an index. Traversing the objects in the bump pointer space relies on Object::SizeOf matching the allocated size exactly. Runtime changes: JNI::GetArrayElements returns copies objects if you attempt to get the backing data of a movable array. For GetArrayElementsCritical, we return direct backing storage for any types of arrays, but temporarily disable the GC until the critical region is completed. Added a new runtime call called VisitObjects, this is used in place of the old pattern which was flushing the allocation stack and walking the bitmaps. Changed image writer to be compaction safe and use object monitor word for forwarding addresses. Added a bunch of added SIRTs to ClassLinker, MethodLinker, etc.. TODO: Enable switching allocators, compacting on background, etc.. Bug: 8981901 Change-Id: I3c886fd322a6eef2b99388d19a765042ec26ab99
Diffstat (limited to 'oatdump')
-rw-r--r--oatdump/oatdump.cc57
1 files changed, 27 insertions, 30 deletions
diff --git a/oatdump/oatdump.cc b/oatdump/oatdump.cc
index 90276c2..e219dd3 100644
--- a/oatdump/oatdump.cc
+++ b/oatdump/oatdump.cc
@@ -257,6 +257,9 @@ class OatDumper {
os << "OAT DEX FILE:\n";
os << StringPrintf("location: %s\n", oat_dex_file.GetDexFileLocation().c_str());
os << StringPrintf("checksum: 0x%08x\n", oat_dex_file.GetDexFileLocationChecksum());
+
+ // Create the verifier early.
+
std::string error_msg;
UniquePtr<const DexFile> dex_file(oat_dex_file.OpenDexFile(&error_msg));
if (dex_file.get() == NULL) {
@@ -377,8 +380,20 @@ class OatDumper {
oat_method.GetCode() != NULL ? "..." : "");
Indenter indent2_filter(indent1_os.rdbuf(), kIndentChar, kIndentBy1Count);
std::ostream indent2_os(&indent2_filter);
- DumpCode(indent2_os, oat_method, dex_method_idx, &dex_file, class_def, code_item,
- method_access_flags);
+
+ Runtime* runtime = Runtime::Current();
+ if (runtime != nullptr) {
+ ScopedObjectAccess soa(Thread::Current());
+ SirtRef<mirror::DexCache> dex_cache(
+ soa.Self(), runtime->GetClassLinker()->FindDexCache(dex_file));
+ SirtRef<mirror::ClassLoader> class_loader(soa.Self(), nullptr);
+ verifier::MethodVerifier verifier(&dex_file, &dex_cache, &class_loader, &class_def, code_item,
+ dex_method_idx, nullptr, method_access_flags, true, true);
+ verifier.Verify();
+ DumpCode(indent2_os, &verifier, oat_method, code_item);
+ } else {
+ DumpCode(indent2_os, nullptr, oat_method, code_item);
+ }
}
}
@@ -566,24 +581,10 @@ class OatDumper {
}
}
- void DumpVRegsAtDexPc(std::ostream& os, const OatFile::OatMethod& oat_method,
- uint32_t dex_method_idx, const DexFile* dex_file,
- const DexFile::ClassDef& class_def, const DexFile::CodeItem* code_item,
- uint32_t method_access_flags, uint32_t dex_pc) {
- static UniquePtr<verifier::MethodVerifier> verifier;
- static const DexFile* verified_dex_file = NULL;
- static uint32_t verified_dex_method_idx = DexFile::kDexNoIndex;
- if (dex_file != verified_dex_file || verified_dex_method_idx != dex_method_idx) {
- ScopedObjectAccess soa(Thread::Current());
- mirror::DexCache* dex_cache = Runtime::Current()->GetClassLinker()->FindDexCache(*dex_file);
- mirror::ClassLoader* class_loader = NULL;
- verifier.reset(new verifier::MethodVerifier(dex_file, dex_cache, class_loader, &class_def,
- code_item, dex_method_idx, NULL,
- method_access_flags, true, true));
- verifier->Verify();
- verified_dex_file = dex_file;
- verified_dex_method_idx = dex_method_idx;
- }
+ void DumpVRegsAtDexPc(std::ostream& os, verifier::MethodVerifier* verifier,
+ const OatFile::OatMethod& oat_method,
+ const DexFile::CodeItem* code_item, uint32_t dex_pc) {
+ DCHECK(verifier != nullptr);
std::vector<int32_t> kinds = verifier->DescribeVRegs(dex_pc);
bool first = true;
for (size_t reg = 0; reg < code_item->registers_size_; reg++) {
@@ -633,18 +634,16 @@ class OatDumper {
uint32_t method_access_flags) {
if ((method_access_flags & kAccNative) == 0) {
ScopedObjectAccess soa(Thread::Current());
- mirror::DexCache* dex_cache = Runtime::Current()->GetClassLinker()->FindDexCache(*dex_file);
- mirror::ClassLoader* class_loader = NULL;
+ SirtRef<mirror::DexCache> dex_cache(soa.Self(), Runtime::Current()->GetClassLinker()->FindDexCache(*dex_file));
+ SirtRef<mirror::ClassLoader> class_loader(soa.Self(), nullptr);
verifier::MethodVerifier::VerifyMethodAndDump(os, dex_method_idx, dex_file, dex_cache,
class_loader, &class_def, code_item, NULL,
method_access_flags);
}
}
- void DumpCode(std::ostream& os, const OatFile::OatMethod& oat_method,
- uint32_t dex_method_idx, const DexFile* dex_file,
- const DexFile::ClassDef& class_def, const DexFile::CodeItem* code_item,
- uint32_t method_access_flags) {
+ void DumpCode(std::ostream& os, verifier::MethodVerifier* verifier,
+ const OatFile::OatMethod& oat_method, const DexFile::CodeItem* code_item) {
const void* code = oat_method.GetCode();
size_t code_size = oat_method.GetCodeSize();
if (code == NULL || code_size == 0) {
@@ -653,16 +652,14 @@ class OatDumper {
}
const uint8_t* native_pc = reinterpret_cast<const uint8_t*>(code);
size_t offset = 0;
- const bool kDumpVRegs = (Runtime::Current() != NULL);
while (offset < code_size) {
DumpMappingAtOffset(os, oat_method, offset, false);
offset += disassembler_->Dump(os, native_pc + offset);
uint32_t dex_pc = DumpMappingAtOffset(os, oat_method, offset, true);
if (dex_pc != DexFile::kDexNoIndex) {
DumpGcMapAtNativePcOffset(os, oat_method, code_item, offset);
- if (kDumpVRegs) {
- DumpVRegsAtDexPc(os, oat_method, dex_method_idx, dex_file, class_def, code_item,
- method_access_flags, dex_pc);
+ if (verifier != nullptr) {
+ DumpVRegsAtDexPc(os, verifier, oat_method, code_item, dex_pc);
}
}
}