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