Author: Armin Rigo <[email protected]>
Branch: array-overallocation-in-nursery
Changeset: r67504:1a8508ac5763
Date: 2013-10-22 12:54 +0200
http://bitbucket.org/pypy/pypy/changeset/1a8508ac5763/
Log: (fijal, arigo)
The first translated test passes. The 2nd not
diff --git a/rpython/memory/gctransform/transform.py
b/rpython/memory/gctransform/transform.py
--- a/rpython/memory/gctransform/transform.py
+++ b/rpython/memory/gctransform/transform.py
@@ -543,6 +543,9 @@
if isinstance(TYPE, lltype.Struct):
offset_to_length = llmemory.FieldOffset(TYPE, TYPE._arrayfld)
+ \
llmemory.ArrayLengthOffset(ARRAY)
+ elif TYPE._is_overallocated_array():
+ offset_to_length = llmemory.ArrayLengthOffset(ARRAY,
+ attrkind="allocated_length")
else:
offset_to_length = llmemory.ArrayLengthOffset(ARRAY)
c_offset_to_length = intconst(offset_to_length)
diff --git a/rpython/translator/c/funcgen.py b/rpython/translator/c/funcgen.py
--- a/rpython/translator/c/funcgen.py
+++ b/rpython/translator/c/funcgen.py
@@ -508,9 +508,28 @@
return '%s = %d;' % (self.expr(op.result),
ARRAY.length)
else:
+ assert not ARRAY._is_overallocated_array()
return '%s = %s->length;' % (self.expr(op.result),
self.expr(op.args[0]))
+ def OP_GETARRAYALLOCATEDLENGTH(self, op):
+ ARRAY = self.lltypemap(op.args[0]).TO
+ assert ARRAY._is_overallocated_array()
+ return '%s = %s->allocated_length;' % (self.expr(op.result),
+ self.expr(op.args[0]))
+
+ def OP_GETARRAYUSEDLENGTH(self, op):
+ ARRAY = self.lltypemap(op.args[0]).TO
+ assert ARRAY._is_overallocated_array()
+ return '%s = %s->used_length;' % (self.expr(op.result),
+ self.expr(op.args[0]))
+
+ def OP_SETARRAYUSEDLENGTH(self, op):
+ ARRAY = self.lltypemap(op.args[0]).TO
+ assert ARRAY._is_overallocated_array()
+ return 'RPySetUsedLength(%s, %s);' % (self.expr(op.args[0]),
+ self.expr(op.args[1]))
+
def OP_GETARRAYITEM(self, op):
ARRAY = self.lltypemap(op.args[0]).TO
ptr = self.expr(op.args[0])
diff --git a/rpython/translator/c/node.py b/rpython/translator/c/node.py
--- a/rpython/translator/c/node.py
+++ b/rpython/translator/c/node.py
@@ -254,6 +254,8 @@
def itemindex_access_expr(self, baseexpr, indexexpr):
if self.ARRAY._hints.get('nolength', False):
return 'RPyNLenItem(%s, %s)' % (baseexpr, indexexpr)
+ elif self.ARRAY._hints.get('overallocated', False):
+ return 'RPyOAItem(%s, %s)' % (baseexpr, indexexpr)
else:
return 'RPyItem(%s, %s)' % (baseexpr, indexexpr)
@@ -261,7 +263,12 @@
yield 'struct %s {' % self.name
for fname, typename in self.gcfields:
yield '\t' + cdecl(typename, fname) + ';'
- if not self.ARRAY._hints.get('nolength', False):
+ if self.ARRAY._hints.get('nolength', False):
+ pass
+ elif self.ARRAY._hints.get('overallocated', False):
+ yield '\tlong used_length;'
+ yield '\tlong allocated_length;'
+ else:
yield '\tlong length;'
line = '%s;' % cdecl(self.itemtypename,
'items[%s]' % deflength(self.varlength))
@@ -684,6 +691,8 @@
yield line
if T._hints.get('nolength', False):
length = ''
+ elif T._hints.get('overallocated', False):
+ xxxxxxxxxxx
else:
length = '%d, ' % len(self.obj.items)
if T.OF is Void or len(self.obj.items) == 0:
diff --git a/rpython/translator/c/primitive.py
b/rpython/translator/c/primitive.py
--- a/rpython/translator/c/primitive.py
+++ b/rpython/translator/c/primitive.py
@@ -59,8 +59,9 @@
else:
return 'sizeof(%s)' % (cdecl(db.gettype(value.TYPE), ''),)
elif isinstance(value, ArrayLengthOffset):
- return 'offsetof(%s, length)' % (
- cdecl(db.gettype(value.TYPE), ''))
+ return 'offsetof(%s, %s)' % (
+ cdecl(db.gettype(value.TYPE), ''),
+ value.attrkind) # "length", "allocated_length", "used_length"
elif isinstance(value, CompositeOffset):
names = [name_signed(item, db) for item in value.offsets]
return '(%s)' % (' + '.join(names),)
diff --git a/rpython/translator/c/src/support.h
b/rpython/translator/c/src/support.h
--- a/rpython/translator/c/src/support.h
+++ b/rpython/translator/c/src/support.h
@@ -52,6 +52,9 @@
# define RPyItem(array, index) \
((RPyCHECK((index) >= 0 && (index) < (array)->length), \
(array))->items[index])
+# define RPyOAItem(array, index) \
+ ((RPyCHECK((index) >= 0 && (index) < (array)->used_length), \
+ (array))->items[index])
# define RPyFxItem(ptr, index, fixedsize) \
((RPyCHECK((ptr) && (index) >= 0 && (index) < (fixedsize)), \
(ptr))[index])
@@ -59,11 +62,17 @@
((RPyCHECK((array) && (index) >= 0), (array))->items[index])
# define RPyBareItem(array, index) \
((RPyCHECK((array) && (index) >= 0), (array))[index])
+# define RPySetUsedLength(array, nlength) \
+ ((RPyCHECK((array) && (nlength) >= 0 \
+ && (nlength) <= (array)->allocated_length), \
+ (array))->used_length = (nlength))
#else
# define RPyField(ptr, name) ((ptr)->name)
# define RPyItem(array, index) ((array)->items[index])
+# define RPyOAItem(array, index) ((array)->items[index])
# define RPyFxItem(ptr, index, fixedsize) ((ptr)[index])
# define RPyNLenItem(array, index) ((array)->items[index])
# define RPyBareItem(array, index) ((array)[index])
+# define RPySetUsedLength(array, nlength) ((array)->used_length = (nlength))
#endif
diff --git a/rpython/translator/c/test/test_lltyped.py
b/rpython/translator/c/test/test_lltyped.py
--- a/rpython/translator/c/test/test_lltyped.py
+++ b/rpython/translator/c/test/test_lltyped.py
@@ -960,3 +960,33 @@
fn = self.getcompiled(f, [int])
assert fn(0) == 9
+
+ def test_overallocated_array(self):
+ 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)
+
+ fn = self.getcompiled(f, [])
+ assert fn() == 1005
+
+ def test_overallocated_array_prebuilt(self):
+ A = GcArray(Signed, hints={'overallocated': True})
+ a = malloc(A, 10)
+ a.used_length = 2
+ a[0] = 42
+ a[1] = 421
+
+ def f():
+ assert a.used_length == 2
+ assert a.allocated_length == 2 # reduced to its min by translation
+ assert a[0] == 42
+ assert a[1] == 421
+ return 1
+
+ fn = self.getcompiled(f, [])
+ assert fn() == 1
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit