Commits

Carl Friedrich Bolz  committed 09e2a38

(pedronis, cfbolz):

garbage collection:

- added a bit of planning documentation for GC
- added a dummy implementation of the Address class
- this class does nothing at the moment but is annotated correctly

  • Participants
  • Parent commits 769d7f4

Comments (0)

Files changed (7)

File pypy/annotation/bookkeeper.py

 from pypy.rpython.rarithmetic import r_uint
 from pypy.tool.unionfind import UnionFind
 from pypy.rpython import lltype
+from pypy.rpython.memory import lladdress
 
 from pypy.annotation.specialize import decide_callable
 
             result = SomeBuiltin(BUILTIN_ANALYZERS[x], methodname="%s.%s" % (x.__module__, x.__name__))
         elif isinstance(x, lltype._ptr):
             result = SomePtr(lltype.typeOf(x))
+        elif isinstance(x, lladdress.Address):
+            assert x is lladdress.NULL
+            result= SomeAddress(is_null=True)
         elif callable(x) or isinstance(x, staticmethod): # XXX
             # maybe 'x' is a method bound to a not-yet-frozen cache?
             # fun fun fun.

File pypy/annotation/builtin.py

 from pypy.tool.ansi_print import ansi_print
 from pypy.annotation.model import SomeInteger, SomeObject, SomeChar, SomeBool
 from pypy.annotation.model import SomeList, SomeString, SomeTuple, SomeSlice
-from pypy.annotation.model import SomeUnicodeCodePoint
+from pypy.annotation.model import SomeUnicodeCodePoint, SomeAddress
 from pypy.annotation.model import SomeFloat, unionof
 from pypy.annotation.model import SomePBC, SomeInstance
 from pypy.annotation.model import annotation_to_lltype
 BUILTIN_ANALYZERS[lltype.getRuntimeTypeInfo] = getRuntimeTypeInfo
 BUILTIN_ANALYZERS[lltype.runtime_type_info] = runtime_type_info
 
+#_________________________________
+# memory address
+
+from pypy.rpython.memory import lladdress
+
+def raw_malloc(s_size):
+    assert isinstance(s_size, SomeInteger) #XXX add noneg...?
+    return SomeAddress()
+
+def raw_free(s_addr):
+    assert isinstance(s_addr, SomeAddress)
+    assert not s_addr.is_null
+
+def raw_memcopy(s_addr1, s_addr2, s_int):
+    assert isinstance(s_addr1, SomeAddress)
+    assert isinstance(s_addr2, SomeAddress)
+    assert isinstance(s_int, SomeInteger) #XXX add noneg...?
+
+BUILTIN_ANALYZERS[lladdress.raw_malloc] = raw_malloc
+BUILTIN_ANALYZERS[lladdress.raw_free] = raw_free
+BUILTIN_ANALYZERS[lladdress.raw_memcopy] = raw_memcopy
+
+#_________________________________
+# external functions
+
+
 from pypy.rpython import extfunctable
 
 # import annotation information for external functions 
 # from the extfunctable.table  into our own annotation specific table 
 for func, extfuncinfo in extfunctable.table.iteritems():
     BUILTIN_ANALYZERS[func] = extfuncinfo.annotation 
+

File pypy/annotation/model.py

     return lltype_to_annotation(lltype.typeOf(v))
 
 # ____________________________________________________________
+# memory addresses
+
+class SomeAddress(SomeObject):
+    def __init__(self, is_null=False):
+        self.is_null = is_null
+
+    def can_be_none(self):
+        return False
+
+# ____________________________________________________________
 
 class UnionError(Exception):
     """Signals an suspicious attempt at taking the union of

File pypy/documentation/gc_planning.txt

+plan:
+=====
+   - write a simulator using arrays
+   - blocks are malloced with their size
+   - addresses are pointers memory locations:
+       * they are basically integers
+       * offsets are just regular integers
+       * their annotation is SomeAddress
+
+Address operations:
+===================
+
+construction / destruction:
+----------------------------
+   - NULL: global object
+   - raw_malloc(size) --> address
+   - raw_free(addr)
+   - memcopy(addr1, addr2, size)
+
+memory access:
+--------------
+
+   - reading: addr.signed[offset]
+   - writing: addr.signed[offset] = value
+   - datatypes:
+       * signed, unsigned, char, address
+
+
+open question / whish:
+======================
+
+it would be cool to do something like::
+
+    class A(object):
+        _raw_allocate_ = True
+        def method(self):
+            ...
+
+    a = A()
+    free_non_gc_object(a)
+    a.method() #-> crash
+
+it seems possible, will be messy
+
+
+Memory Layout:
+==============
+
+for now we go for the simple solution::
+
+                        +-<-<-<  object model sees only this
+                        V
+    +---------+---------+----------------------------+
+    | gc info | type id | object data                |
+    | int     | int     | whatever                   |
+    +---------+---------+----------------------------+
+

File pypy/rpython/memory/__init__.py

+#

File pypy/rpython/memory/lladdress.py

+
+class Address(object):
+    pass
+
+NULL = Address()
+
+def raw_malloc(size):
+    pass
+
+def raw_free(addr):
+    pass
+
+def raw_memcopy(addr1, addr2, size):
+    pass
+
+

File pypy/rpython/memory/test/test_address.py

+import py
+
+from pypy.annotation import model as annmodel
+from pypy.translator.annrpython import RPythonAnnotator
+from pypy.objspace.flow import FlowObjSpace
+from pypy.rpython.memory.lladdress import raw_malloc, raw_free, NULL, raw_memcopy
+
+class TestAddressAnnotation(object):
+    def test_raw_malloc(self):
+        def f():
+            return raw_malloc(100)
+        a = RPythonAnnotator()
+        s = a.build_types(f, [])
+        assert isinstance(s, annmodel.SomeAddress)
+        assert not s.is_null
+
+    def test_null(self):
+        def f():
+            return NULL
+        a = RPythonAnnotator()
+        s = a.build_types(f, [])
+        assert isinstance(s, annmodel.SomeAddress)
+        assert s.is_null
+
+    def test_raw_free(self):
+        def f(addr):
+            raw_free(addr)
+        a = RPythonAnnotator()
+        s = a.build_types(f, [annmodel.SomeAddress()]) #does not raise
+        py.test.raises(AssertionError,
+                       a.build_types, f, [annmodel.SomeAddress(is_null=True)])
+
+    def test_memcopy(self):
+        def f(addr1, addr2):
+            raw_memcopy(addr1, addr2, 100)
+        a = RPythonAnnotator()
+        #does not raise:
+        s = a.build_types(f, [annmodel.SomeAddress(), annmodel.SomeAddress()])
+        py.test.raises(AssertionError, a.build_types, f,
+                       [annmodel.SomeAddress(is_null=True),
+                        annmodel.SomeAddress()])
+
+