[pypy-commit] pypy gc-incminimark-pinning-countlimit: simple implementation and tests for limiting the amount of pinned objects
groggi
noreply at buildbot.pypy.org
Mon Jun 2 17:24:47 CEST 2014
Author: Gregor Wegberg <code at gregorwegberg.com>
Branch: gc-incminimark-pinning-countlimit
Changeset: r71858:345cfc1ac23a
Date: 2014-05-29 20:02 +0200
http://bitbucket.org/pypy/pypy/changeset/345cfc1ac23a/
Log: simple implementation and tests for limiting the amount of pinned
objects
diff --git a/rpython/memory/gc/incminimark.py b/rpython/memory/gc/incminimark.py
--- a/rpython/memory/gc/incminimark.py
+++ b/rpython/memory/gc/incminimark.py
@@ -256,6 +256,10 @@
# so we trade it by cleaning it bit-by-bit, as we progress through
# nursery. Has to fit at least one large object
"nursery_cleanup": 32768 * WORD,
+
+ # Number of objects that are allowed to be pinned in the nursery
+ # at the same time.
+ "max_number_of_pinned_objects": 100,
}
def __init__(self, config,
@@ -268,6 +272,7 @@
major_collection_threshold=2.5,
growth_rate_max=2.5, # for tests
card_page_indices=0,
+ max_number_of_pinned_objects=100,
large_object=8*WORD,
ArenaCollectionClass=None,
**kwds):
@@ -284,6 +289,7 @@
self.max_heap_size = 0.0
self.max_heap_size_already_raised = False
self.max_delta = float(r_uint(-1))
+ self.max_number_of_pinned_objects = max_number_of_pinned_objects
#
self.card_page_indices = card_page_indices
if self.card_page_indices > 0:
@@ -965,7 +971,7 @@
# Reason: It would be possible that the first caller unpins
# while the second caller thinks it's still pinned.
return False
- if not self.should_pin(obj):
+ if self.pinned_objects_in_nursery >= self.max_number_of_pinned_objects:
return False
self.header(obj).tid |= GCFLAG_PINNED
@@ -981,9 +987,6 @@
self.header(obj).tid &= ~GCFLAG_PINNED
self.pinned_objects_in_nursery -= 1
- def should_pin(self, obj):
- return True
-
def shrink_array(self, obj, smallerlength):
#
# Only objects in the nursery can be "resized". Resizing them
diff --git a/rpython/memory/gc/test/test_object_pinning.py b/rpython/memory/gc/test/test_object_pinning.py
--- a/rpython/memory/gc/test/test_object_pinning.py
+++ b/rpython/memory/gc/test/test_object_pinning.py
@@ -3,6 +3,8 @@
from rpython.memory.gc.incminimark import IncrementalMiniMarkGC
from test_direct import BaseDirectGCTest
+# YYY
+
S = lltype.GcForwardReference()
S.become(lltype.GcStruct('pinning_test_struct',
('someInt', lltype.Signed),
@@ -172,6 +174,39 @@
assert not self.gc.is_in_nursery(adr)
assert self.gc.nursery_free == self.gc.nursery
assert self.gc.nursery_top > self.gc.nursery
+
+ # XXX test/define what happens if we try to pin an object that is too
+ # big for the nursery and will be raw-malloc'ed.
+
+ # XXX fill nursery with pinned objects -> + define behavior for such a
+ # case
+
+
+class TestIncminimarkFewPinnedObjects(BaseDirectGCTest):
+ from rpython.memory.gc.incminimark import IncrementalMiniMarkGC as GCClass
+
+ GC_PARAMS = {'max_number_of_pinned_objects': 5
+ }
+
+ def test_pinning_limit(self):
+ for instance_nr in xrange(self.GC_PARAMS['max_number_of_pinned_objects']):
+ ptr = self.malloc(S)
+ adr = llmemory.cast_ptr_to_adr(ptr)
+ ptr.someInt = 100 + instance_nr
+ self.stackroots.append(ptr)
+ self.gc.pin(adr)
+ #
+ # now we reached the maximum amount of pinned objects
+ ptr = self.malloc(S)
+ adr = llmemory.cast_ptr_to_adr(ptr)
+ self.stackroots.append(ptr)
+ assert not self.gc.pin(adr)
+
+class TestIncminimarkManyPinnedObjects(BaseDirectGCTest):
+ from rpython.memory.gc.incminimark import IncrementalMiniMarkGC as GCClass
+
+ GC_PARAMS_PLENTY_PINNED_OBJECTS = {'max_number_of_pinned_objects': 50
+ }
def get_max_nursery_objects(self, TYPE):
typeid = self.get_type_id(TYPE)
@@ -181,18 +216,22 @@
def test_full_pinned_nursery_pin_fail(self):
object_mallocs = self.get_max_nursery_objects(S)
+ # just to be sure we do not run into the limit as we test not the limiter
+ # but rather the case of a nursery full with pinned objects.
+ assert object_mallocs < self.gc.max_number_of_pinned_objects
for instance_nr in xrange(object_mallocs):
ptr = self.malloc(S)
adr = llmemory.cast_ptr_to_adr(ptr)
ptr.someInt = 100 + instance_nr
self.stackroots.append(ptr)
self.gc.pin(adr)
+ #
# nursery should be full now, at least no space for another `S`. Next malloc should fail.
py.test.raises(Exception, self.malloc, S)
- # XXX test/define what happens if we try to pin an object that is too
- # big for the nursery and will be raw-malloc'ed.
+ # XXX check if we have to take chunk size of AddressStack in /rpython/memory/support.py into account.
+ # As far as gc-minimark-pinning tells us: yes (groggi)
- # XXX fill nursery with pinned objects -> + define behavior for such a
- # case
+
+
More information about the pypy-commit
mailing list