Make MemMap::MapAnonymous() fail if the requested address is not available.
Change MapAnonymous() so that a requested address vs. actual map
address mismatch will cause a failure. The existing MapAnonymous()
call sites do not check this. This should prevent potential rare case
bugs where mmap does not happen to map a region at an specified
address.
There's a potential bug that if MapAnonymous() does not guarantee the
requested address (and there's a gap between the image/oat files and
the zygote/malloc space), then GC could in theory allocate a large
object space in the gap. This would break the GC notion of the immune
space. This change will prevent this by causing all non-moving spaces
to be (really) adjacent, with no gaps in between, which CL 87711
missed.
Change-Id: Id4adb0e30adbad497334d7e00def4c0c66b15719
diff --git a/runtime/mem_map_test.cc b/runtime/mem_map_test.cc
index 6cb59b4..eea3307 100644
--- a/runtime/mem_map_test.cc
+++ b/runtime/mem_map_test.cc
@@ -120,6 +120,39 @@
}
#endif
+TEST_F(MemMapTest, MapAnonymousExactAddr) {
+ std::string error_msg;
+ // Map at an address that should work, which should succeed.
+ UniquePtr<MemMap> map0(MemMap::MapAnonymous("MapAnonymous0",
+ reinterpret_cast<byte*>(ART_BASE_ADDRESS),
+ kPageSize,
+ PROT_READ | PROT_WRITE,
+ false,
+ &error_msg));
+ ASSERT_TRUE(map0.get() != nullptr) << error_msg;
+ ASSERT_TRUE(error_msg.empty());
+ ASSERT_TRUE(map0->BaseBegin() == reinterpret_cast<void*>(ART_BASE_ADDRESS));
+ // Map at an unspecified address, which should succeed.
+ UniquePtr<MemMap> map1(MemMap::MapAnonymous("MapAnonymous1",
+ nullptr,
+ kPageSize,
+ PROT_READ | PROT_WRITE,
+ false,
+ &error_msg));
+ ASSERT_TRUE(map1.get() != nullptr) << error_msg;
+ ASSERT_TRUE(error_msg.empty());
+ ASSERT_TRUE(map1->BaseBegin() != nullptr);
+ // Attempt to map at the same address, which should fail.
+ UniquePtr<MemMap> map2(MemMap::MapAnonymous("MapAnonymous2",
+ reinterpret_cast<byte*>(map1->BaseBegin()),
+ kPageSize,
+ PROT_READ | PROT_WRITE,
+ false,
+ &error_msg));
+ ASSERT_TRUE(map2.get() == nullptr) << error_msg;
+ ASSERT_TRUE(!error_msg.empty());
+}
+
TEST_F(MemMapTest, RemapAtEnd) {
RemapAtEndTest(false);
}