[pypy-commit] pypy array-overallocation-in-nursery: (fijal around, arigo)
arigo
noreply at buildbot.pypy.org
Tue Oct 22 12:05:13 CEST 2013
Author: Armin Rigo <arigo at tunes.org>
Branch: array-overallocation-in-nursery
Changeset: r67498:75ab419638af
Date: 2013-10-22 12:04 +0200
http://bitbucket.org/pypy/pypy/changeset/75ab419638af/
Log: (fijal around, arigo)
Support rtyping the operations specific to overallocated arrays.
diff --git a/rpython/rtyper/llinterp.py b/rpython/rtyper/llinterp.py
--- a/rpython/rtyper/llinterp.py
+++ b/rpython/rtyper/llinterp.py
@@ -624,6 +624,19 @@
if ITEMTYPE is not lltype.Void:
array[index] = item
+ def op_getarrayallocatedlength(self, obj):
+ checkptr(obj)
+ return obj.allocated_length
+
+ def op_getarrayusedlength(self, obj):
+ checkptr(obj)
+ return obj.used_length
+
+ def op_setarrayusedlength(self, obj, nlen):
+ checkptr(obj)
+ assert isinstance(nlen, int)
+ obj.used_length = nlen
+
def perform_call(self, f, ARGS, args):
fobj = self.llinterpreter.typer.type_system.deref(f)
has_callable = getattr(fobj, '_callable', None) is not None
diff --git a/rpython/rtyper/lltypesystem/lloperation.py b/rpython/rtyper/lltypesystem/lloperation.py
--- a/rpython/rtyper/lltypesystem/lloperation.py
+++ b/rpython/rtyper/lltypesystem/lloperation.py
@@ -386,6 +386,9 @@
'bare_setfield': LLOp(),
'setarrayitem': LLOp(),
'bare_setarrayitem': LLOp(),
+ 'getarrayallocatedlength': LLOp(sideeffects=False), # over-allocated arrays
+ 'getarrayusedlength': LLOp(sideeffects=False), # over-allocated arrays
+ 'setarrayusedlength': LLOp(), # over-allocated arrays
'cast_pointer': LLOp(canfold=True),
'ptr_eq': LLOp(canfold=True),
'ptr_ne': LLOp(canfold=True),
diff --git a/rpython/rtyper/rptr.py b/rpython/rtyper/rptr.py
--- a/rpython/rtyper/rptr.py
+++ b/rpython/rtyper/rptr.py
@@ -47,6 +47,16 @@
else:
assert hop.s_result.is_constant()
return hop.inputconst(hop.r_result, hop.s_result.const)
+ if self.lowleveltype.TO._is_overallocated_array():
+ v_self = hop.inputarg(self, arg=0)
+ if attr == 'allocated_length':
+ return hop.genop('getarrayallocatedlength', [v_self],
+ resulttype = lltype.Signed)
+ elif attr == 'used_length':
+ return hop.genop('getarrayusedlength', [v_self],
+ resulttype = lltype.Signed)
+ else:
+ raise TyperError("getattr(overallocated_array, %r)" % (attr,))
assert attr in self.lowleveltype.TO._flds # check that the field exists
FIELD_TYPE = getattr(self.lowleveltype.TO, attr)
if isinstance(FIELD_TYPE, lltype.ContainerType):
@@ -65,6 +75,14 @@
def rtype_setattr(self, hop):
attr = hop.args_s[1].const
+ if self.lowleveltype.TO._is_overallocated_array():
+ if attr == 'used_length':
+ v_self = hop.inputarg(self, arg=0)
+ v_length = hop.inputarg(lltype.Signed, arg=2)
+ hop.genop('setarrayusedlength', [v_self, v_length])
+ return
+ else:
+ raise TyperError("setattr(overallocated_array, %r)" % (attr,))
FIELD_TYPE = getattr(self.lowleveltype.TO, attr)
assert not isinstance(FIELD_TYPE, lltype.ContainerType)
vlist = hop.inputargs(self, lltype.Void, hop.args_r[2])
diff --git a/rpython/rtyper/test/test_llann.py b/rpython/rtyper/test/test_llann.py
--- a/rpython/rtyper/test/test_llann.py
+++ b/rpython/rtyper/test/test_llann.py
@@ -509,3 +509,18 @@
assert res is True
res = interpret(f, [25, 10])
assert res is True
+
+
+def test_overallocated_array():
+ A = GcArray(Signed, hints={'overallocated': True})
+
+ def f():
+ a = malloc(A, 10)
+ a.used_length = 5
+ a[3] = 42
+ assert a[3] == 42
+ return a.used_length + (a.allocated_length * 100)
+
+ assert f() == 1005
+ res = interpret(f, [])
+ assert res == 1005
More information about the pypy-commit
mailing list