[sanitizer][fuchsia] Implement ReleaseMemoryPagesToOS
authorMarco Vanotti <mvanotti@google.com>
Mon, 25 Jan 2021 19:08:49 +0000 (11:08 -0800)
committerMarco Vanotti <mvanotti@google.com>
Wed, 27 Jan 2021 19:13:24 +0000 (11:13 -0800)
The `zx_vmar_op_range` allows us to decommit memory pages without
needing a handle to the underlying vmo, as long as we have a handle to
a vmar that contains this mapping. This allows us to implement the
`ReleaseMemoryPagesToOS` function by decommitting the memory using a
handle to the root vmar.

Reviewed By: mcgrathr

Differential Revision: https://reviews.llvm.org/D95384

compiler-rt/lib/sanitizer_common/sanitizer_fuchsia.cpp

index 5ad20d0..e721788 100644 (file)
@@ -381,9 +381,18 @@ void UnmapOrDie(void *addr, uptr size) {
   UnmapOrDieVmar(addr, size, _zx_vmar_root_self());
 }
 
-// This is used on the shadow mapping, which cannot be changed.
-// Zircon doesn't have anything like MADV_DONTNEED.
-void ReleaseMemoryPagesToOS(uptr beg, uptr end) {}
+void ReleaseMemoryPagesToOS(uptr beg, uptr end) {
+  uptr beg_aligned = RoundUpTo(beg, PAGE_SIZE);
+  uptr end_aligned = RoundDownTo(end, PAGE_SIZE);
+  if (beg_aligned < end_aligned) {
+    zx_handle_t root_vmar = _zx_vmar_root_self();
+    CHECK_NE(root_vmar, ZX_HANDLE_INVALID);
+    zx_status_t status =
+        _zx_vmar_op_range(root_vmar, ZX_VMAR_OP_DECOMMIT, beg_aligned,
+                          end_aligned - beg_aligned, nullptr, 0);
+    CHECK_EQ(status, ZX_OK);
+  }
+}
 
 void DumpProcessMap() {
   // TODO(mcgrathr): write it