Author: Armin Rigo <[email protected]>
Branch: cffi-handle-lifetime
Changeset: r80112:235bc9c680e7
Date: 2015-10-11 19:29 +0200
http://bitbucket.org/pypy/pypy/changeset/235bc9c680e7/
Log: Implement nonmovable=True
diff --git a/rpython/jit/codewriter/jtransform.py
b/rpython/jit/codewriter/jtransform.py
--- a/rpython/jit/codewriter/jtransform.py
+++ b/rpython/jit/codewriter/jtransform.py
@@ -915,10 +915,13 @@
return [op0, op1]
def rewrite_op_malloc(self, op):
- if op.args[1].value['flavor'] == 'raw':
+ d = op.args[1].value
+ if d.get('nonmovable', False):
+ raise UnsupportedMallocFlags(d)
+ if d.value['flavor'] == 'raw':
return self._rewrite_raw_malloc(op, 'raw_malloc_fixedsize', [])
#
- if op.args[1].value.get('zero', False):
+ if d.value.get('zero', False):
zero = True
else:
zero = False
diff --git a/rpython/memory/gc/generation.py b/rpython/memory/gc/generation.py
--- a/rpython/memory/gc/generation.py
+++ b/rpython/memory/gc/generation.py
@@ -170,7 +170,10 @@
def malloc_fixedsize_clear(self, typeid, size,
has_finalizer=False,
is_finalizer_light=False,
- contains_weakptr=False):
+ contains_weakptr=False,
+ nonmovable=False):
+ if nonmovable:
+ raise MemoryError
if (has_finalizer or
(raw_malloc_usage(size) > self.lb_young_fixedsize and
raw_malloc_usage(size) > self.largest_young_fixedsize)):
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
@@ -587,7 +587,8 @@
def malloc_fixedsize(self, typeid, size,
needs_finalizer=False,
is_finalizer_light=False,
- contains_weakptr=False):
+ contains_weakptr=False,
+ nonmovable=False):
size_gc_header = self.gcheaderbuilder.size_gc_header
totalsize = size_gc_header + size
rawtotalsize = raw_malloc_usage(totalsize)
@@ -603,7 +604,7 @@
# If totalsize is greater than nonlarge_max (which should never be
# the case in practice), ask for a rawmalloc. The following check
# should be constant-folded.
- elif rawtotalsize > self.nonlarge_max:
+ 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)
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
@@ -509,7 +509,8 @@
def malloc_fixedsize_clear(self, typeid, size,
needs_finalizer=False,
is_finalizer_light=False,
- contains_weakptr=False):
+ contains_weakptr=False,
+ nonmovable=False):
size_gc_header = self.gcheaderbuilder.size_gc_header
totalsize = size_gc_header + size
rawtotalsize = raw_malloc_usage(totalsize)
@@ -525,7 +526,7 @@
# If totalsize is greater than nonlarge_max (which should never be
# the case in practice), ask for a rawmalloc. The following check
# should be constant-folded.
- elif rawtotalsize > self.nonlarge_max:
+ 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)
diff --git a/rpython/memory/gc/semispace.py b/rpython/memory/gc/semispace.py
--- a/rpython/memory/gc/semispace.py
+++ b/rpython/memory/gc/semispace.py
@@ -98,7 +98,10 @@
def malloc_fixedsize_clear(self, typeid16, size,
has_finalizer=False,
is_finalizer_light=False,
- contains_weakptr=False):
+ contains_weakptr=False,
+ nonmovable=False):
+ if nonmovable:
+ raise MemoryError
size_gc_header = self.gcheaderbuilder.size_gc_header
totalsize = size_gc_header + size
result = self.free
diff --git a/rpython/memory/gctransform/framework.py
b/rpython/memory/gctransform/framework.py
--- a/rpython/memory/gctransform/framework.py
+++ b/rpython/memory/gctransform/framework.py
@@ -305,6 +305,7 @@
annmodel.SomeInteger(nonneg=True),
annmodel.SomeBool(),
annmodel.SomeBool(),
+ annmodel.SomeBool(),
annmodel.SomeBool()], s_gcref,
inline = False)
self.malloc_varsize_ptr = getfn(
@@ -320,6 +321,7 @@
annmodel.SomeInteger(nonneg=True),
annmodel.SomeBool(),
annmodel.SomeBool(),
+ annmodel.SomeBool(),
annmodel.SomeBool()], s_gcref,
inline = False)
self.malloc_varsize_ptr = getfn(
@@ -363,7 +365,7 @@
raise NotImplementedError("GC needs write barrier, but does not
provide writebarrier_before_copy functionality")
# in some GCs we can inline the common case of
- # malloc_fixedsize(typeid, size, False, False, False)
+ # malloc_fixedsize(typeid, size, False, False, False, False)
if getattr(GCClass, 'inline_simple_malloc', False):
# make a copy of this function so that it gets annotated
# independently and the constants are folded inside
@@ -382,7 +384,7 @@
malloc_fast,
[s_gc, s_typeid16,
annmodel.SomeInteger(nonneg=True),
- s_False, s_False, s_False], s_gcref,
+ s_False, s_False, s_False, s_False], s_gcref,
inline = True)
else:
self.malloc_fast_ptr = None
@@ -759,15 +761,19 @@
if not op.opname.endswith('_varsize') and not flags.get('varsize'):
zero = flags.get('zero', False)
+ c_nonmovable = rmodel.inputconst(lltype.Bool,
+ flags.get('nonmovable', False))
if (self.malloc_fast_ptr is not None and
not c_has_finalizer.value and
+ not c_nonmovable.value and
(self.malloc_fast_is_clearing or not zero)):
malloc_ptr = self.malloc_fast_ptr
else:
malloc_ptr = self.malloc_fixedsize_ptr
args = [self.c_const_gc, c_type_id, c_size,
c_has_finalizer, c_has_light_finalizer,
- rmodel.inputconst(lltype.Bool, False)]
+ rmodel.inputconst(lltype.Bool, False),
+ c_nonmovable]
else:
assert not c_has_finalizer.value
info_varsize = self.layoutbuilder.get_info_varsize(type_id)
@@ -908,11 +914,12 @@
[v_typeid, v_size,
v_has_finalizer, v_has_light_finalizer, v_contains_weakptr] = op.args
livevars = self.push_roots(hop)
+ c_nonmovable = rmodel.inputconst(lltype.Bool, False)
hop.genop("direct_call",
[self.malloc_fixedsize_ptr, self.c_const_gc,
v_typeid, v_size,
v_has_finalizer, v_has_light_finalizer,
- v_contains_weakptr],
+ v_contains_weakptr, c_nonmovable],
resultvar=op.result)
self.pop_roots(hop, livevars)
@@ -1018,8 +1025,9 @@
malloc_ptr = self.malloc_fixedsize_ptr
c_false = rmodel.inputconst(lltype.Bool, False)
c_has_weakptr = rmodel.inputconst(lltype.Bool, True)
+ c_nonmovable = rmodel.inputconst(lltype.Bool, False)
args = [self.c_const_gc, c_type_id, c_size,
- c_false, c_false, c_has_weakptr]
+ c_false, c_false, c_has_weakptr, c_nonmovable]
# push and pop the current live variables *including* the argument
# to the weakref_create operation, which must be kept alive and
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
@@ -1247,6 +1247,21 @@
res = self.runner('nursery_hash_base')
assert res([]) >= 195
+ def define_instantiate_nonmovable(cls):
+ from rpython.rlib import objectmodel
+ from rpython.rtyper import annlowlevel
+ class A:
+ pass
+ def fn():
+ a = objectmodel.instantiate(A, nonmovable=True)
+ return rgc.can_move(annlowlevel.cast_instance_to_base_ptr(a))
+ return fn
+
+ def test_instantiate_nonmovable(self):
+ res = self.runner('instantiate_nonmovable')
+ assert res([]) == 0
+
+
class TestIncrementalMiniMarkGC(TestMiniMarkGC):
gcname = "incminimark"
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit