[Git][ghc/ghc][wip/gc/nonmoving-pinned] nonmoving: Teach allocatePinned() to allocate into nonmoving heap

Ben Gamari gitlab at gitlab.haskell.org
Sun Jul 26 19:56:18 UTC 2020



Ben Gamari pushed to branch wip/gc/nonmoving-pinned at Glasgow Haskell Compiler / GHC


Commits:
615373c2 by Ben Gamari at 2020-07-26T15:55:32-04:00
nonmoving: Teach allocatePinned() to allocate into nonmoving heap

The allocatePinned() function is used to allocate pinned memory (e.g.
for newPinnedByteArray#)

- - - - -


2 changed files:

- rts/sm/NonMoving.h
- rts/sm/Storage.c


Changes:

=====================================
rts/sm/NonMoving.h
=====================================
@@ -73,11 +73,17 @@ struct NonmovingAllocator {
 
 // allocators cover block sizes of 2^NONMOVING_ALLOCA0 to
 // 2^(NONMOVING_ALLOCA0 + NONMOVING_ALLOCA_CNT) (in bytes)
+// The largest allocator class must be at least LARGE_OBJECT_THRESHOLD in size
+// as Storage.c:allocatePinned will allocate small pinned allocations into the
+// non-moving heap.
 #define NONMOVING_ALLOCA_CNT 12
 
 // maximum number of free segments to hold on to
 #define NONMOVING_MAX_FREE 16
 
+// block size of largest allocator in bytes.
+#define NONMOVING_MAX_BLOCK_SZ (1 << (NONMOVING_ALLOCA0 + NONMOVING_ALLOCA_CNT))
+
 struct NonmovingHeap {
     struct NonmovingAllocator *allocators[NONMOVING_ALLOCA_CNT];
     // free segment list. This is a cache where we keep up to


=====================================
rts/sm/Storage.c
=====================================
@@ -1165,6 +1165,21 @@ allocatePinned (Capability *cap, W_ n /*words*/, W_ alignment /*bytes*/, W_ alig
 
     const StgWord alignment_w = alignment / sizeof(W_);
 
+    // If the non-moving collector is enabled then we can allocate small,
+    // pinned allocations directly into the non-moving heap. This is a bit more
+    // expensive up-front but reduces fragmentation and is worthwhile since
+    // pinned allocations are often long-lived..
+    if (RTS_UNLIKELY(RtsFlags.GcFlags.useNonmoving)
+        && n * WORD_SIZE + alignment_w <= NONMOVING_MAX_BLOCK_SZ)
+    {
+        p = nonmovingAllocate(cap, n + alignment_w);
+        W_ off_w = ALIGN_WITH_OFF_W(p, alignment, align_off);
+        MEMSET_IF_PROFILING_W(p, 0, off_w);
+        p += off_w;
+        MEMSET_IF_PROFILING_W(p + n, 0, alignment_w - off_w - 1);
+        return p;
+    }
+
     // If the request is for a large object, then allocate()
     // will give us a pinned object anyway.
     if (n >= LARGE_OBJECT_THRESHOLD/sizeof(W_)) {



View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/615373c20a9588a0a793e97e4eac0222d01532f8

-- 
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/615373c20a9588a0a793e97e4eac0222d01532f8
You're receiving this email because of your account on gitlab.haskell.org.


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.haskell.org/pipermail/ghc-commits/attachments/20200726/1acd4603/attachment-0001.html>


More information about the ghc-commits mailing list