Author: Armin Rigo <[email protected]>
Branch: cffi-handle-lifetime
Changeset: r80114:cd5334105e34
Date: 2015-10-11 21:58 +0200
http://bitbucket.org/pypy/pypy/changeset/cd5334105e34/
Log: Test and fix
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
@@ -598,7 +598,7 @@
if needs_finalizer and not is_finalizer_light:
ll_assert(not contains_weakptr,
"'needs_finalizer' and 'contains_weakptr' both specified")
- obj = self.external_malloc(typeid, 0, can_make_young=False)
+ obj = self.external_malloc(typeid, 0, alloc_young=False)
self.objects_with_finalizers.append(obj)
#
# If totalsize is greater than nonlarge_max (which should never be
@@ -607,7 +607,7 @@
elif rawtotalsize > self.nonlarge_max or nonmovable:
ll_assert(not contains_weakptr,
"'contains_weakptr' specified for a large object")
- obj = self.external_malloc(typeid, 0)
+ obj = self.external_malloc(typeid, 0, alloc_young=True)
#
else:
# If totalsize is smaller than minimal_size_in_nursery, round it
@@ -660,7 +660,7 @@
# If the total size of the object would be larger than
# 'nonlarge_max', then allocate it externally. We also
# go there if 'length' is actually negative.
- obj = self.external_malloc(typeid, length)
+ obj = self.external_malloc(typeid, length, alloc_young=True)
#
else:
# With the above checks we know now that totalsize cannot be more
@@ -809,7 +809,7 @@
collect_and_reserve._dont_inline_ = True
- def external_malloc(self, typeid, length, can_make_young=True):
+ def external_malloc(self, typeid, length, alloc_young):
"""Allocate a large object using the ArenaCollection or
raw_malloc(), possibly as an object with card marking enabled,
if it has gc pointers in its var-sized part. 'length' should be
@@ -863,7 +863,9 @@
# we should get a MemoryError from major_collection_step().
#
# Check if the object would fit in the ArenaCollection.
- if raw_malloc_usage(totalsize) <= self.small_request_threshold:
+ # Also, an object allocated from ArenaCollection must be old.
+ if (raw_malloc_usage(totalsize) <= self.small_request_threshold
+ and not alloc_young):
#
# Yes. Round up 'totalsize' (it cannot overflow and it
# must remain <= self.small_request_threshold.)
@@ -875,10 +877,6 @@
# Allocate from the ArenaCollection. Don't clear it.
result = self.ac.malloc(totalsize)
#
- # An object allocated from ArenaCollection is always old, even
- # if 'can_make_young'. The interesting case of 'can_make_young'
- # is for large objects, bigger than the 'large_objects' threshold,
- # which are raw-malloced but still young.
extra_flags = GCFLAG_TRACK_YOUNG_PTRS
#
else:
@@ -898,11 +896,11 @@
extra_words = self.card_marking_words_for_length(length)
cardheadersize = WORD * extra_words
extra_flags = GCFLAG_HAS_CARDS | GCFLAG_TRACK_YOUNG_PTRS
- # if 'can_make_young', then we also immediately set
+ # if 'alloc_young', then we also immediately set
# GCFLAG_CARDS_SET, but without adding the object to
# 'old_objects_with_cards_set'. In this way it should
# never be added to that list as long as it is young.
- if can_make_young:
+ if alloc_young:
extra_flags |= GCFLAG_CARDS_SET
#
# Detect very rare cases of overflows
@@ -940,7 +938,7 @@
# Record the newly allocated object and its full malloced size.
# The object is young or old depending on the argument.
self.rawmalloced_total_size += r_uint(allocsize)
- if can_make_young:
+ if alloc_young:
if not self.young_rawmalloced_objects:
self.young_rawmalloced_objects = self.AddressDict()
self.young_rawmalloced_objects.add(result + size_gc_header)
diff --git a/rpython/memory/gc/minimark.py b/rpython/memory/gc/minimark.py
--- a/rpython/memory/gc/minimark.py
+++ b/rpython/memory/gc/minimark.py
@@ -520,7 +520,7 @@
if needs_finalizer and not is_finalizer_light:
ll_assert(not contains_weakptr,
"'needs_finalizer' and 'contains_weakptr' both specified")
- obj = self.external_malloc(typeid, 0, can_make_young=False)
+ obj = self.external_malloc(typeid, 0, alloc_young=False)
self.objects_with_finalizers.append(obj)
#
# If totalsize is greater than nonlarge_max (which should never be
@@ -529,7 +529,7 @@
elif rawtotalsize > self.nonlarge_max or nonmovable:
ll_assert(not contains_weakptr,
"'contains_weakptr' specified for a large object")
- obj = self.external_malloc(typeid, 0)
+ obj = self.external_malloc(typeid, 0, alloc_young=True)
#
else:
# If totalsize is smaller than minimal_size_in_nursery, round it
@@ -582,7 +582,7 @@
# If the total size of the object would be larger than
# 'nonlarge_max', then allocate it externally. We also
# go there if 'length' is actually negative.
- obj = self.external_malloc(typeid, length)
+ obj = self.external_malloc(typeid, length, alloc_young=True)
#
else:
# With the above checks we know now that totalsize cannot be more
@@ -672,7 +672,7 @@
collect_and_reserve._dont_inline_ = True
- def external_malloc(self, typeid, length, can_make_young=True):
+ def external_malloc(self, typeid, length, alloc_young):
"""Allocate a large object using the ArenaCollection or
raw_malloc(), possibly as an object with card marking enabled,
if it has gc pointers in its var-sized part. 'length' should be
@@ -712,7 +712,9 @@
self.major_collection(raw_malloc_usage(totalsize))
#
# Check if the object would fit in the ArenaCollection.
- if raw_malloc_usage(totalsize) <= self.small_request_threshold:
+ # Also, an object allocated from ArenaCollection must be old.
+ if (raw_malloc_usage(totalsize) <= self.small_request_threshold
+ and not alloc_young):
#
# Yes. Round up 'totalsize' (it cannot overflow and it
# must remain <= self.small_request_threshold.)
@@ -725,10 +727,6 @@
result = self.ac.malloc(totalsize)
llmemory.raw_memclear(result, totalsize)
#
- # An object allocated from ArenaCollection is always old, even
- # if 'can_make_young'. The interesting case of 'can_make_young'
- # is for large objects, bigger than the 'large_objects' threshold,
- # which are raw-malloced but still young.
extra_flags = GCFLAG_TRACK_YOUNG_PTRS
#
else:
@@ -748,11 +746,11 @@
extra_words = self.card_marking_words_for_length(length)
cardheadersize = WORD * extra_words
extra_flags = GCFLAG_HAS_CARDS | GCFLAG_TRACK_YOUNG_PTRS
- # if 'can_make_young', then we also immediately set
+ # if 'alloc_young', then we also immediately set
# GCFLAG_CARDS_SET, but without adding the object to
# 'old_objects_with_cards_set'. In this way it should
# never be added to that list as long as it is young.
- if can_make_young:
+ if alloc_young:
extra_flags |= GCFLAG_CARDS_SET
#
# Detect very rare cases of overflows
@@ -788,7 +786,7 @@
# Record the newly allocated object and its full malloced size.
# The object is young or old depending on the argument.
self.rawmalloced_total_size += r_uint(allocsize)
- if can_make_young:
+ if alloc_young:
if not self.young_rawmalloced_objects:
self.young_rawmalloced_objects = self.AddressDict()
self.young_rawmalloced_objects.add(result + size_gc_header)
diff --git a/rpython/memory/test/test_transformed_gc.py
b/rpython/memory/test/test_transformed_gc.py
--- a/rpython/memory/test/test_transformed_gc.py
+++ b/rpython/memory/test/test_transformed_gc.py
@@ -1253,8 +1253,13 @@
class A:
pass
def fn():
+ a1 = A()
a = objectmodel.instantiate(A, nonmovable=True)
- return rgc.can_move(annlowlevel.cast_instance_to_base_ptr(a))
+ a.next = a1 # 'a' is known young here, so no write barrier emitted
+ res = rgc.can_move(annlowlevel.cast_instance_to_base_ptr(a))
+ rgc.collect()
+ objectmodel.keepalive_until_here(a)
+ return res
return fn
def test_instantiate_nonmovable(self):
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit