[pypy-commit] pypy miniscan: In-progress: import existing tests for using them with 'gcrootfinder=scan'.
arigo
noreply at buildbot.pypy.org
Tue Feb 28 14:52:46 CET 2012
Author: Armin Rigo <arigo at tunes.org>
Branch: miniscan
Changeset: r52978:8ab8c0ea5f42
Date: 2012-02-28 14:51 +0100
http://bitbucket.org/pypy/pypy/changeset/8ab8c0ea5f42/
Log: In-progress: import existing tests for using them with
'gcrootfinder=scan'.
diff --git a/pypy/rpython/memory/gc/minimark.py b/pypy/rpython/memory/gc/minimark.py
--- a/pypy/rpython/memory/gc/minimark.py
+++ b/pypy/rpython/memory/gc/minimark.py
@@ -251,9 +251,12 @@
self.nursery = NULL
self.nursery_next = NULL
self.nursery_frag_end = NULL
+ self.nursery_top = NULL
self.debug_tiny_nursery = -1
self.debug_rotating_nurseries = None
#
+ self.gcrootfinder_scan = (config.gcrootfinder == "scan")
+ #
# The ArenaCollection() handles the nonmovable objects allocation.
if ArenaCollectionClass is None:
ArenaCollectionClass = minimarkpage.ArenaCollection
@@ -396,7 +399,8 @@
# the current position in the nursery:
self.nursery_next = self.nursery
# the end of the nursery:
- self.nursery_frag_end = self.nursery + self.nursery_size
+ self.nursery_top = self.nursery + self.nursery_size
+ self.nursery_frag_end = self.nursery_top
# initialize the threshold
self.min_heap_size = max(self.min_heap_size, self.nursery_size *
self.major_collection_threshold)
@@ -559,10 +563,10 @@
#
# Get the memory from the nursery. If there is not enough space
# there, do a collect first.
- result = self.nursery_free
- self.nursery_free = result + totalsize
- if self.nursery_free > self.nursery_top:
- result = self.collect_and_reserve(totalsize)
+ result = self.nursery_next
+ self.nursery_next = result + totalsize
+ if self.nursery_next > self.nursery_frag_end:
+ result = self.pick_next_fragment(totalsize)
#
# Build the object.
llarena.arena_reserve(result, totalsize)
@@ -581,8 +585,17 @@
if gen > 0:
self.major_collection()
+ def pick_next_fragment(self, totalsize):
+ """To call when nursery_next overflows nursery_frag_end.
+ Pick the next fragment of the nursery, or if there are none
+ big enough for 'totalsize', do a collection.
+ """
+ # XXX
+ return self.collect_and_reserve(totalsize)
+ pick_next_fragment._dont_inline_ = True
+
def collect_and_reserve(self, totalsize):
- """To call when nursery_free overflows nursery_top.
+ """To call when we have run out of nursery fragments.
Do a minor collection, and possibly also a major collection,
and finally reserve 'totalsize' bytes at the start of the
now-empty nursery.
@@ -607,7 +620,6 @@
self.nursery_free = self.nursery_top - self.debug_tiny_nursery
#
return result
- collect_and_reserve._dont_inline_ = True
def external_malloc(self, typeid, length, can_make_young=True):
@@ -753,6 +765,7 @@
if self.next_major_collection_threshold < 0:
# cannot trigger a full collection now, but we can ensure
# that one will occur very soon
+ xxx
self.nursery_free = self.nursery_top
def can_malloc_nonmovable(self):
@@ -822,7 +835,9 @@
# have been chosen to allow 'flags' to be zero in the common
# case (hence the 'NO' in their name).
hdr = llmemory.cast_adr_to_ptr(addr, lltype.Ptr(self.HDR))
- hdr.tid = self.combine(typeid16, flags | GCFLAG_HIGH)
+ if self.gcrootfinder_scan: # don't bother setting these high
+ flags |= GCFLAG_HIGH # bits if not "scan"
+ hdr.tid = self.combine(typeid16, flags)
def init_gc_object_immortal(self, addr, typeid16, flags=0):
# For prebuilt GC objects, the flags must contain
@@ -876,8 +891,13 @@
if result:
ll_assert(tid == -42, "bogus header for young obj")
else:
- ll_assert(bool(tid), "bogus header (1)")
- ll_assert(tid & ~TID_MASK == 0, "bogus header (2)")
+ htid = llop.extract_ushort(llgroup.HALFWORD, tid)
+ ll_assert(bool(htid), "bogus header (1)")
+ if self.gcrootfinder_scan:
+ expected = GCFLAG_HIGH
+ else:
+ expected = 0
+ ll_assert(tid & GCFLAG_HIGH_MASK == expected, "bogus header (2)")
return result
def get_forwarding_address(self, obj):
@@ -1294,6 +1314,7 @@
# the whole nursery with zero and reset the current nursery pointer.
llarena.arena_reset(self.nursery, self.nursery_size, 2)
self.debug_rotate_nursery()
+ xxx
self.nursery_free = self.nursery
#
debug_print("minor collect, total memory used:",
diff --git a/pypy/rpython/memory/gcwrapper.py b/pypy/rpython/memory/gcwrapper.py
--- a/pypy/rpython/memory/gcwrapper.py
+++ b/pypy/rpython/memory/gcwrapper.py
@@ -177,6 +177,8 @@
if self.gcheap.gc.points_to_valid_gc_object(addrofaddr):
collect_static_in_prebuilt_nongc(gc, addrofaddr)
if collect_stack_root:
+ translator = gcheap.llinterp.typer.annotator.translator
+ assert translator.config.translation.gcrootfinder != 'scan'
for addrofaddr in gcheap.llinterp.find_roots():
if self.gcheap.gc.points_to_valid_gc_object(addrofaddr):
collect_stack_root(gc, addrofaddr)
diff --git a/pypy/rpython/memory/test/test_gc.py b/pypy/rpython/memory/test/test_gc.py
--- a/pypy/rpython/memory/test/test_gc.py
+++ b/pypy/rpython/memory/test/test_gc.py
@@ -24,6 +24,7 @@
class GCTest(object):
GC_PARAMS = {}
+ CONFIG_OPTS = {}
GC_CAN_MOVE = False
GC_CAN_MALLOC_NONMOVABLE = True
GC_CAN_SHRINK_ARRAY = False
@@ -40,6 +41,7 @@
py.log._setstate(cls._saved_logstate)
def interpret(self, func, values, **kwds):
+ kwds.update(self.CONFIG_OPTS)
interp, graph = get_interpreter(func, values, **kwds)
gcwrapper.prepare_graphs_and_create_gc(interp, self.GCClass,
self.GC_PARAMS)
@@ -921,3 +923,6 @@
class TestMiniMarkGCCardMarking(TestMiniMarkGC):
GC_PARAMS = {'card_page_indices': 4}
+
+class TestMiniMarkGCScan(TestMiniMarkGC):
+ CONFIG_OPTS = {'gcrootfinder': 'scan'}
diff --git a/pypy/translator/c/gc.py b/pypy/translator/c/gc.py
--- a/pypy/translator/c/gc.py
+++ b/pypy/translator/c/gc.py
@@ -6,7 +6,7 @@
typeOf, Ptr, ContainerType, RttiStruct, \
RuntimeTypeInfo, getRuntimeTypeInfo, top_container
from pypy.rpython.memory.gctransform import \
- refcounting, boehm, framework, asmgcroot
+ refcounting, boehm, framework, asmgcroot, scan
from pypy.rpython.lltypesystem import lltype, llmemory
from pypy.translator.tool.cbuild import ExternalCompilationInfo
@@ -403,6 +403,12 @@
def OP_GC_STACK_BOTTOM(self, funcgen, op):
return 'pypy_asm_stack_bottom();'
+class ScanFrameworkGcPolicy(FrameworkGcPolicy):
+ transformerclass = scan.ScanFrameworkGCTransformer
+
+ def GC_KEEPALIVE(self, funcgen, v):
+ return 'pypy_asm_keepalive(%s);' % funcgen.expr(v)
+
name_to_gcpolicy = {
'boehm': BoehmGcPolicy,
@@ -410,6 +416,5 @@
'none': NoneGcPolicy,
'framework': FrameworkGcPolicy,
'framework+asmgcroot': AsmGcRootFrameworkGcPolicy,
+ 'framework+scan': ScanFrameworkGcPolicy,
}
-
-
diff --git a/pypy/translator/c/genc.py b/pypy/translator/c/genc.py
--- a/pypy/translator/c/genc.py
+++ b/pypy/translator/c/genc.py
@@ -193,6 +193,8 @@
name = self.config.translation.gctransformer
if self.config.translation.gcrootfinder == "asmgcc":
name = "%s+asmgcroot" % (name,)
+ if self.config.translation.gcrootfinder == "scan":
+ name = "%s+scan" % (name,)
return gc.name_to_gcpolicy[name]
return self.gcpolicy
diff --git a/pypy/translator/c/test/test_newgc.py b/pypy/translator/c/test/test_newgc.py
--- a/pypy/translator/c/test/test_newgc.py
+++ b/pypy/translator/c/test/test_newgc.py
@@ -15,6 +15,7 @@
class TestUsingFramework(object):
gcpolicy = "marksweep"
+ gcrootfinder = "shadowstack"
should_be_moving = False
removetypeptr = False
taggedpointers = False
@@ -41,7 +42,8 @@
t = Translation(main, standalone=True, gc=cls.gcpolicy,
policy=annpolicy.StrictAnnotatorPolicy(),
taggedpointers=cls.taggedpointers,
- gcremovetypeptr=cls.removetypeptr)
+ gcremovetypeptr=cls.removetypeptr,
+ gcrootfinder=cls.gcrootfinder)
t.disable(['backendopt'])
t.set_backend_extra_options(c_debug_defines=True)
t.rtype()
@@ -1600,3 +1602,6 @@
class TestMiniMarkGCMostCompact(TaggedPointersTest, TestMiniMarkGC):
removetypeptr = True
+
+class TestMiniMarkGCScan(TestMiniMarkGC):
+ gcrootfinder = "scan"
More information about the pypy-commit
mailing list