Author: Armin Rigo <[email protected]>
Branch: use-madv-free
Changeset: r85685:78c7dacab7ab
Date: 2016-07-14 10:08 +0200
http://bitbucket.org/pypy/pypy/changeset/78c7dacab7ab/

Log:    Call madvise() from minimarkpage and llarena

diff --git a/rpython/memory/gc/minimarkpage.py 
b/rpython/memory/gc/minimarkpage.py
--- a/rpython/memory/gc/minimarkpage.py
+++ b/rpython/memory/gc/minimarkpage.py
@@ -395,6 +395,7 @@
                 if arena.nfreepages == arena.totalpages:
                     #
                     # The whole arena is empty.  Free it.
+                    llarena.arena_reset(arena.base, self.arena_size, 4)
                     llarena.arena_free(arena.base)
                     lltype.free(arena, flavor='raw', track_allocation=False)
                     #
diff --git a/rpython/rlib/rmmap.py b/rpython/rlib/rmmap.py
--- a/rpython/rlib/rmmap.py
+++ b/rpython/rlib/rmmap.py
@@ -949,10 +949,3 @@
 
     def free(ptr, map_size):
         VirtualFree_safe(ptr, 0, MEM_RELEASE)
-
-    def madvice_free(addr, map_size):
-        """XXX find a Windows equivalent?
-        'addr' is in the middle of memory obtained with the C malloc()...
-        """
-
-# register_external here?
diff --git a/rpython/rtyper/lltypesystem/llarena.py 
b/rpython/rtyper/lltypesystem/llarena.py
--- a/rpython/rtyper/lltypesystem/llarena.py
+++ b/rpython/rtyper/lltypesystem/llarena.py
@@ -52,7 +52,7 @@
                 del self.objectptrs[offset]
                 del self.objectsizes[offset]
                 obj._free()
-        if zero and zero != 3:
+        if zero in (1, 2):
             initialbyte = "0"
         else:
             initialbyte = "#"
@@ -335,6 +335,8 @@
       * 1: clear, optimized for a very large area of memory
       * 2: clear, optimized for a small or medium area of memory
       * 3: fill with garbage
+      * 4: large area of memory that can benefit from MADV_FREE
+             (i.e. contains garbage, may be zero-filled or not)
     """
     arena_addr = getfakearenaaddress(arena_addr)
     arena_addr.arena.reset(zero, arena_addr.offset, size)
@@ -410,16 +412,19 @@
             self.pagesize = 0
         def _cleanup_(self):
             self.pagesize = 0
+        def get(self):
+            pagesize = self.pagesize
+            if pagesize == 0:
+                pagesize = rffi.cast(lltype.Signed, legacy_getpagesize())
+                self.pagesize = pagesize
+            return pagesize
+
     posixpagesize = PosixPageSize()
 
     def clear_large_memory_chunk(baseaddr, size):
         from rpython.rlib import rmmap
 
-        pagesize = posixpagesize.pagesize
-        if pagesize == 0:
-            pagesize = rffi.cast(lltype.Signed, legacy_getpagesize())
-            posixpagesize.pagesize = pagesize
-
+        pagesize = posixpagesize.get()
         if size > 2 * pagesize:
             lowbits = rffi.cast(lltype.Signed, baseaddr) & (pagesize - 1)
             if lowbits:     # clear the initial misaligned part, if any
@@ -435,6 +440,17 @@
         if size > 0:    # clear the final misaligned part, if any
             llmemory.raw_memclear(baseaddr, size)
 
+    def madvise_arena_free(baseaddr, size):
+        from rpython.rlib import rmmap
+
+        pagesize = posixpagesize.get()
+        baseaddr = rffi.cast(lltype.Signed, baseaddr)
+        aligned_addr = (baseaddr + pagesize - 1) & (pagesize - 1)
+        size -= (aligned_addr - baseaddr)
+        if size >= pagesize:
+            rmmap.madvise_free(rffi.cast(rmmap.PTR, aligned_addr),
+                               size & (pagesize - 1))
+
 else:
     # XXX any better implementation on Windows?
     # Should use VirtualAlloc() to reserve the range of pages,
@@ -443,6 +459,12 @@
     # them immediately.
     clear_large_memory_chunk = llmemory.raw_memclear
 
+    def madvise_arena_free(baseaddr, size):
+        """XXX find a Windows equivalent?
+        'baseaddr' is in the middle of memory obtained with the C malloc()...
+        """
+
+
 if os.name == "posix":
     from rpython.translator.tool.cbuild import ExternalCompilationInfo
     _eci = ExternalCompilationInfo(includes=['sys/mman.h'])
@@ -509,6 +531,8 @@
             clear_large_memory_chunk(arena_addr, size)
         elif zero == 3:
             llop.raw_memset(lltype.Void, arena_addr, ord('#'), size)
+        elif zero == 4:
+            madvise_arena_free(arena_addr, size)
         else:
             llmemory.raw_memclear(arena_addr, size)
 llimpl_arena_reset._always_inline_ = True
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to