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

Reply via email to