[PATCH] D56968: Refactor `AsanChunk` methods into code that supports both in-process and out-of-process examination of `AsanChunk`s.

Dan Liew via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Sun Jan 20 05:14:29 PST 2019


delcypher updated this revision to Diff 182697.
delcypher added a comment.

Comment tweak.


Repository:
  rCRT Compiler Runtime

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D56968/new/

https://reviews.llvm.org/D56968

Files:
  lib/asan/asan_allocator.cc


Index: lib/asan/asan_allocator.cc
===================================================================
--- lib/asan/asan_allocator.cc
+++ lib/asan/asan_allocator.cc
@@ -111,24 +111,79 @@
 };
 
 struct AsanChunk: ChunkBase {
-  uptr Beg() { return reinterpret_cast<uptr>(this) + kChunkHeaderSize; }
+  uptr Beg() { return BegInternal(reinterpret_cast<uptr>(this)); }
   uptr UsedSize(bool locked_version = false) {
-    if (user_requested_size != SizeClassMap::kMaxSize)
-      return user_requested_size;
-    return *reinterpret_cast<uptr *>(
-               get_allocator().GetMetaData(AllocBeg(locked_version)));
+    return UsedSizeInternal<LocalAddressSpaceView>(
+        reinterpret_cast<uptr>(this), locked_version,
+        reinterpret_cast<uptr>(&get_allocator()), nullptr);
   }
   void *AllocBeg(bool locked_version = false) {
+    return AllocBegInternal<LocalAddressSpaceView>(
+        reinterpret_cast<uptr>(this), locked_version,
+        reinterpret_cast<uptr>(&get_allocator()));
+  }
+  bool AddrIsInside(uptr addr, bool locked_version = false) {
+    return (addr >= Beg()) && (addr < Beg() + UsedSize(locked_version));
+  }
+
+ private:
+  // Common code for in-process and out-of-process chunk examination.
+  //
+  // * For the in-process case `chunk_storage_addr` is the same as the `this`
+  //   pointer. For the out-of-process case it is a pointer to the
+  //   `AsanChunk` in the target process.
+  // * `allocator` is a pointer to the allocator in the local
+  //   address space, instantiated with the appropriate `AddressSpaceView`
+  //   template parameter. For the `out-of-process` case this means the client
+  //   is responsible for copying the allocator from the target process into
+  //   the local process.
+
+  uptr BegInternal(uptr chunk_storage_addr) {
+    return chunk_storage_addr + kChunkHeaderSize;
+  }
+
+  template <typename AddressSpaceView>
+  void *AllocBegInternal(uptr chunk_storage_addr, bool locked_version,
+                         uptr allocator) {
     if (from_memalign) {
+      auto allocator_ptr =
+          reinterpret_cast<AsanAllocatorASVT<AddressSpaceView> *>(allocator);
       if (locked_version)
-        return get_allocator().GetBlockBeginFastLocked(
-            reinterpret_cast<void *>(this));
-      return get_allocator().GetBlockBegin(reinterpret_cast<void *>(this));
+        return allocator_ptr->GetBlockBeginFastLocked(
+            reinterpret_cast<void *>(chunk_storage_addr));
+      return allocator_ptr->GetBlockBegin(
+          reinterpret_cast<void *>(chunk_storage_addr));
     }
-    return reinterpret_cast<void*>(Beg() - RZLog2Size(rz_log));
+    return reinterpret_cast<void *>(BegInternal(chunk_storage_addr) -
+                                    RZLog2Size(rz_log));
   }
-  bool AddrIsInside(uptr addr, bool locked_version = false) {
-    return (addr >= Beg()) && (addr < Beg() + UsedSize(locked_version));
+
+  // `known_alloc_beg` - Address of the beginning of the underlying
+  // allocator block in the target process.
+  // If not set to zero then the following must be true `known_alloc_beg ==
+  // AllocBegInternal(chunk_storage_addr, lockec_version, allocator)`. If set to
+  // `0` then `AllocBegInternal()` will be called to determine the
+  // the address of the allocator block.
+  //
+  // This is an optimization to avoid calling `AllocBegInternal()` when
+  // the result of `AllocBegInternal(...)` is already know by the
+  // caller.
+  template <typename AddressSpaceView>
+  uptr UsedSizeInternal(uptr chunk_storage_addr, bool locked_version,
+                        uptr allocator, void *known_alloc_beg) {
+    if (user_requested_size != SizeClassMap::kMaxSize)
+      return user_requested_size;
+    if (!known_alloc_beg) {
+      known_alloc_beg = AllocBegInternal<AddressSpaceView>(
+          chunk_storage_addr, locked_version, allocator);
+    } else {
+      DCHECK_EQ(known_alloc_beg,
+                AllocBegInternal<AddressSpaceView>(chunk_storage_addr,
+                                                   locked_version, allocator));
+    }
+    return *AddressSpaceView::Load(reinterpret_cast<uptr *>(
+        reinterpret_cast<AsanAllocatorASVT<AddressSpaceView> *>(allocator)
+            ->GetMetaData(known_alloc_beg)));
   }
 };
 


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D56968.182697.patch
Type: text/x-patch
Size: 4279 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20190120/cf0962d7/attachment.bin>


More information about the llvm-commits mailing list