Revert "Revert "Store resolved Strings for AOT code in .bss.""
Fixed oat_test to keep dex files alive. Fixed mips build.
Rewritten the .bss GC root visiting and added write barrier
to the artResolveStringFromCode().
Test: build aosp_mips-eng
Test: m ART_DEFAULT_GC_TYPE=SS test-art-target-host-gtest-oat_test
Test: Run ART test suite on host and Nexus 9.
Bug: 20323084
Bug: 30627598
This reverts commit 5f926055cb88089d8ca27243f35a9dfd89d981f0.
Change-Id: I07fa2278d82b8eb64964c9a4b66cb93726ccda6b
diff --git a/runtime/oat_file.cc b/runtime/oat_file.cc
index ea692cd..5f37b82 100644
--- a/runtime/oat_file.cc
+++ b/runtime/oat_file.cc
@@ -40,6 +40,7 @@
#include "base/unix_file/fd_file.h"
#include "elf_file.h"
#include "elf_utils.h"
+#include "gc_root.h"
#include "oat.h"
#include "mem_map.h"
#include "mirror/class.h"
@@ -239,6 +240,8 @@
}
// Readjust to be non-inclusive upper bound.
bss_end_ += sizeof(uint32_t);
+ // Find bss roots if present.
+ bss_roots_ = const_cast<uint8_t*>(FindDynamicSymbolAddress("oatbssroots", &symbol_error_msg));
}
return true;
@@ -291,8 +294,31 @@
return false;
}
+ if (!IsAligned<alignof(GcRoot<mirror::Object>)>(bss_begin_) ||
+ !IsAligned<alignof(GcRoot<mirror::Object>)>(bss_roots_) ||
+ !IsAligned<alignof(GcRoot<mirror::Object>)>(bss_end_)) {
+ *error_msg = StringPrintf("In oat file '%s' found unaligned bss symbol(s): "
+ "begin = %p, roots = %p, end = %p",
+ GetLocation().c_str(),
+ bss_begin_,
+ bss_roots_,
+ bss_end_);
+ return false;
+ }
+
+ if (bss_roots_ != nullptr && (bss_roots_ < bss_begin_ || bss_roots_ > bss_end_)) {
+ *error_msg = StringPrintf("In oat file '%s' found bss roots outside .bss: "
+ "%p is outside range [%p, %p]",
+ GetLocation().c_str(),
+ bss_roots_,
+ bss_begin_,
+ bss_end_);
+ return false;
+ }
+
PointerSize pointer_size = GetInstructionSetPointerSize(GetOatHeader().GetInstructionSet());
uint8_t* dex_cache_arrays = bss_begin_;
+ uint8_t* dex_cache_arrays_end = (bss_roots_ != nullptr) ? bss_roots_ : bss_end_;
uint32_t dex_file_count = GetOatHeader().GetDexFileCount();
oat_dex_files_storage_.reserve(dex_file_count);
for (size_t i = 0; i < dex_file_count; i++) {
@@ -469,13 +495,13 @@
if (dex_cache_arrays != nullptr) {
DexCacheArraysLayout layout(pointer_size, *header);
if (layout.Size() != 0u) {
- if (static_cast<size_t>(bss_end_ - dex_cache_arrays) < layout.Size()) {
+ if (static_cast<size_t>(dex_cache_arrays_end - dex_cache_arrays) < layout.Size()) {
*error_msg = StringPrintf("In oat file '%s' found OatDexFile #%zu for '%s' with "
"truncated dex cache arrays, %zu < %zu.",
GetLocation().c_str(),
i,
dex_file_location.c_str(),
- static_cast<size_t>(bss_end_ - dex_cache_arrays),
+ static_cast<size_t>(dex_cache_arrays_end - dex_cache_arrays),
layout.Size());
return false;
}
@@ -506,9 +532,9 @@
}
}
- if (dex_cache_arrays != bss_end_) {
+ if (dex_cache_arrays != dex_cache_arrays_end) {
// We expect the bss section to be either empty (dex_cache_arrays and bss_end_
- // both null) or contain just the dex cache arrays and nothing else.
+ // both null) or contain just the dex cache arrays and optionally some GC roots.
*error_msg = StringPrintf("In oat file '%s' found unexpected bss size bigger by %zu bytes.",
GetLocation().c_str(),
static_cast<size_t>(bss_end_ - dex_cache_arrays));
@@ -1082,6 +1108,7 @@
end_(nullptr),
bss_begin_(nullptr),
bss_end_(nullptr),
+ bss_roots_(nullptr),
is_executable_(is_executable),
secondary_lookup_lock_("OatFile secondary lookup lock", kOatFileSecondaryLookupLock) {
CHECK(!location_.empty());
@@ -1121,6 +1148,16 @@
return kIsVdexEnabled ? vdex_->End() : End();
}
+ArrayRef<GcRoot<mirror::Object>> OatFile::GetBssGcRoots() const {
+ if (bss_roots_ != nullptr) {
+ auto* roots = reinterpret_cast<GcRoot<mirror::Object>*>(bss_roots_);
+ auto* roots_end = reinterpret_cast<GcRoot<mirror::Object>*>(bss_end_);
+ return ArrayRef<GcRoot<mirror::Object>>(roots, roots_end - roots);
+ } else {
+ return ArrayRef<GcRoot<mirror::Object>>();
+ }
+}
+
const OatFile::OatDexFile* OatFile::GetOatDexFile(const char* dex_location,
const uint32_t* dex_location_checksum,
std::string* error_msg) const {