[pypy-svn] r16169 - in pypy/dist/pypy/rpython/memory: . test

cfbolz at codespeak.net cfbolz at codespeak.net
Fri Aug 19 18:52:18 CEST 2005


Author: cfbolz
Date: Fri Aug 19 18:52:17 2005
New Revision: 16169

Modified:
   pypy/dist/pypy/rpython/memory/convertlltype.py
   pypy/dist/pypy/rpython/memory/gc.py
   pypy/dist/pypy/rpython/memory/gcwrapper.py
   pypy/dist/pypy/rpython/memory/lltypelayout.py
   pypy/dist/pypy/rpython/memory/lltypesimulation.py
   pypy/dist/pypy/rpython/memory/test/test_gc.py
Log:
Moved the functionality that finds gc pointers in an object to
lltypesimulation. In addition all the information the gc needs from
ObjectModel are now precomputed. The idea is that the backend can
somehow generate those tables as well at compile time.



Modified: pypy/dist/pypy/rpython/memory/convertlltype.py
==============================================================================
--- pypy/dist/pypy/rpython/memory/convertlltype.py	(original)
+++ pypy/dist/pypy/rpython/memory/convertlltype.py	Fri Aug 19 18:52:17 2005
@@ -27,6 +27,7 @@
             index = len(self.types)
             self.type_to_typeid[TYPE] = index
             self.types.append(TYPE)
+            return index
         typeid = self.type_to_typeid[TYPE]
         return typeid
 
@@ -140,13 +141,15 @@
         self.total_size = 0
         self.gc = gc
 
-    def collect_constants(self):
+    def collect_constants_and_types(self):
         constants = {}
+        types = {}
         def collect_args(args):
             for arg in args:
                 if (isinstance(arg, Constant) and
                     arg.concretetype is not lltype.Void):
                     constants[arg] = None
+                    types[arg.concretetype] = True
         def visit(obj):
             if isinstance(obj, Link):
                 collect_args(obj.args)
@@ -157,9 +160,12 @@
             elif isinstance(obj, Block):
                 for op in obj.operations:
                     collect_args(op.args)
+                    if op.opname in ("malloc", "malloc_varsize"):
+                        types[op.args[0].value] = True
         for graph in self.flowgraphs.itervalues():
             traverse(visit, graph)
         self.constants = constants
+        self.types = types
 
     def calculate_size(self):
         total_size = 0
@@ -248,8 +254,18 @@
         for graph in self.flowgraphs.itervalues():
             traverse(visit, graph)
 
+    def create_type_ids(self):
+        for TYPE in self.types:
+            print TYPE
+            if isinstance(TYPE, (lltype.Array, lltype.Struct)):
+                #assign a typeid
+                self.cvter.get_typeid(TYPE)
+            elif isinstance(TYPE, lltype.Ptr):
+                self.cvter.get_typeid(TYPE.TO)
+
     def convert(self):
-        self.collect_constants()
+        self.collect_constants_and_types()
         self.calculate_size()
         self.convert_constants()
         self.patch_graphs()
+        self.create_type_ids()

Modified: pypy/dist/pypy/rpython/memory/gc.py
==============================================================================
--- pypy/dist/pypy/rpython/memory/gc.py	(original)
+++ pypy/dist/pypy/rpython/memory/gc.py	Fri Aug 19 18:52:17 2005
@@ -56,13 +56,24 @@
             gc_info = curr - self.size_gc_header()
             if gc_info.signed[0] == 1:
                 continue
-            pointers = self.objectmodel.get_contained_pointers(
-                curr, gc_info.signed[1])
-            while 1:
-                pointer = pointers.pop()
-                if pointer == NULL:
-                    break
+            typeid = gc_info.signed[1]
+            offsets = self.objectmodel.offsets_to_gc_pointers(typeid)
+            for i in range(len(offsets)):
+                pointer = curr + offsets[i]
                 objects.append(pointer.address[0])
+                i += 1
+            if self.objectmodel.is_varsize(typeid):
+                offset = self.objectmodel.varsize_offset_to_variable_part(
+                    typeid)
+                length = (curr + self.objectmodel.varsize_offset_to_length(typeid)).signed[0]
+                offsets = self.objectmodel.varsize_offsets_to_gcpointers_in_var_part(typeid)
+                itemlength = self.objectmodel.varsize_item_sizes(typeid)
+                curr += offset
+                i = 0
+                for i in range(length):
+                    item = curr + itemlength * i
+                    for j in range(len(offsets)):
+                        objects.append((item + offsets[j]).address[0])
             gc_info.signed[0] = 1
         newmo = AddressLinkedList()
         while 1:  #sweep
@@ -80,7 +91,6 @@
     def size_gc_header(self):
         return lltypesimulation.sizeof(lltype.Signed) * 2
 
-
     def init_gc_object(self, addr, typeid):
         addr.signed[0] = 0
         addr.signed[1] = typeid

Modified: pypy/dist/pypy/rpython/memory/gcwrapper.py
==============================================================================
--- pypy/dist/pypy/rpython/memory/gcwrapper.py	(original)
+++ pypy/dist/pypy/rpython/memory/gcwrapper.py	Fri Aug 19 18:52:17 2005
@@ -1,17 +1,49 @@
 from pypy.rpython import lltype
 from pypy.rpython.memory.support import AddressLinkedList, INT_SIZE
 from pypy.rpython.memory.lladdress import raw_malloc, raw_free, NULL
+from pypy.rpython.memory import lltypelayout
 from pypy.rpython.memory import lltypesimulation
 from pypy.rpython.memory.gc import MarkSweepGC
 
 class LLInterpObjectModel(object):
-    def __init__(self, llinterp, types, type_to_typeid, constantroots):
-        self.types = types
+    def __init__(self, llinterp, types,
+                 type_to_typeid, constantroots):
         self.type_to_typeid = type_to_typeid
         self.constantroots = constantroots
         self.roots = []
         self.pseudo_root_pointers = NULL
         self.llinterp = llinterp
+        self.types = types
+        self._is_varsize = []
+        self._offsets_to_gc_pointers = []
+        self._varsize_item_sizes = []
+        self._varsize_offset_to_variable_part = []
+        self._varsize_offset_to_length = []
+        self._varsize_offsets_to_gcpointers_in_var_part = []
+        tttid = zip(*zip(*type_to_typeid.items())[::-1])
+        tttid.sort()
+        tttid = zip(*zip(*tttid)[::-1])
+        for TYPE, typeid in tttid:
+            varsize = (isinstance(TYPE, lltype.Array) or
+                       (isinstance(TYPE, lltype.Struct) and
+                        TYPE._arrayfld is not None))
+            self._is_varsize.append(varsize)
+            self._offsets_to_gc_pointers.append(
+                lltypelayout.offsets_to_gc_pointers(TYPE))
+            if varsize:
+                self._varsize_item_sizes.append(
+                    lltypelayout.get_variable_size(TYPE))
+                self._varsize_offset_to_variable_part.append(
+                    lltypelayout.get_fixed_size(TYPE))
+                self._varsize_offset_to_length.append(
+                    lltypelayout.varsize_offset_to_length(TYPE))
+                self._varsize_offsets_to_gcpointers_in_var_part.append(
+                    lltypelayout.varsize_offsets_to_gcpointers_in_var_part(TYPE))
+            else:
+                self._varsize_item_sizes.append(0)
+                self._varsize_offset_to_variable_part.append(0)
+                self._varsize_offset_to_length.append(0)
+                self._varsize_offsets_to_gcpointers_in_var_part.append([])
 
     def update_changed_addresses(self):
         for i, root in enumerate(self.roots):
@@ -20,21 +52,26 @@
             root.__dict__['_address'] = self.pseudo_root_pointers.address[i]
 
     def get_typeid(self, TYPE):
-        if TYPE not in self.type_to_typeid:
-            index = len(self.types)
-            self.type_to_typeid[TYPE] = index
-            self.types.append(TYPE)
         typeid = self.type_to_typeid[TYPE]
         return typeid
 
-    def get_contained_pointers(self, addr, typeid):
-        TYPE = self.types[typeid]
-        ptr = lltypesimulation.simulatorptr(lltype.Ptr(TYPE), addr)
-        ll = AddressLinkedList()
-        offsets = ptr.get_offsets_of_contained_pointers()
-        for offset in offsets:
-            ll.append(addr + offset)
-        return ll
+    def is_varsize(self, typeid):
+        return self._is_varsize[typeid]
+
+    def offsets_to_gc_pointers(self, typeid):
+        return self._offsets_to_gc_pointers[typeid]
+
+    def varsize_item_sizes(self, typeid):
+        return self._varsize_item_sizes[typeid]
+
+    def varsize_offset_to_variable_part(self, typeid):
+        return self._varsize_offset_to_variable_part[typeid]
+
+    def varsize_offset_to_length(self, typeid):
+        return self._varsize_offset_to_length[typeid]
+
+    def varsize_offsets_to_gcpointers_in_var_part(self, typeid):
+        return self._varsize_offsets_to_gcpointers_in_var_part[typeid]
 
     def get_roots(self):
         print "getting roots"

Modified: pypy/dist/pypy/rpython/memory/lltypelayout.py
==============================================================================
--- pypy/dist/pypy/rpython/memory/lltypelayout.py	(original)
+++ pypy/dist/pypy/rpython/memory/lltypelayout.py	Fri Aug 19 18:52:17 2005
@@ -86,3 +86,41 @@
         return fixedsize
     else:
         return fixedsize + i * varsize
+
+
+# _____________________________________________________________________________
+# the following functions are used to find contained pointers
+
+
+def offsets_to_gc_pointers(TYPE):
+    if isinstance(TYPE, lltype.Struct):
+        offsets = []
+        layout = get_layout(TYPE)
+        for name in TYPE._names:
+            FIELD = getattr(TYPE, name)
+            if (isinstance(FIELD, lltype.Ptr) and FIELD._needsgc() and
+                FIELD.TO is not lltype.PyObject):
+                offsets.append(layout[name])
+            elif isinstance(FIELD, lltype.Struct):
+                suboffsets = offsets_to_gc_pointers(FIELD)
+                offsets += [s + layout[name] for s in suboffsets]
+        return offsets
+    return []
+
+def varsize_offset_to_length(TYPE):
+    if isinstance(TYPE, lltype.Array):
+        return 0
+    elif isinstance(TYPE, lltype.Struct):
+        layout = get_layout(TYPE)
+        return layout[TYPE._arrayfld]
+
+def varsize_offsets_to_gcpointers_in_var_part(TYPE):
+    if isinstance(TYPE, lltype.Array):
+        if isinstance(TYPE.OF, lltype.Ptr):
+            return [0]
+        elif isinstance(TYPE.OF, lltype.Struct):
+            return offsets_to_gc_pointers(TYPE.OF)
+        return []
+    elif isinstance(TYPE, lltype.Struct):
+        return offsets_to_gc_pointers(getattr(TYPE, TYPE._arrayfld)) 
+    

Modified: pypy/dist/pypy/rpython/memory/lltypesimulation.py
==============================================================================
--- pypy/dist/pypy/rpython/memory/lltypesimulation.py	(original)
+++ pypy/dist/pypy/rpython/memory/lltypesimulation.py	Fri Aug 19 18:52:17 2005
@@ -164,38 +164,6 @@
     def __repr__(self):
         return '<simulatorptr %s to %s>' % (self._TYPE.TO, self._address)
 
-    def get_offsets_of_contained_pointers(self):
-        if isinstance(self._TYPE.TO, lltype.Struct):
-            offsets = self._get_offsets_of_contained_pointers_struct()
-        elif isinstance(self._TYPE.TO, lltype.Array):
-            offsets = self._get_offsets_of_contained_pointers_array()
-        return offsets
-
-    def _get_offsets_of_contained_pointers_struct(self):
-        offsets = []
-        for name in self._TYPE.TO._names:
-            FIELD = getattr(self._TYPE.TO, name)
-            if isinstance(FIELD, lltype.Ptr) and FIELD._needsgc():
-                offsets.append(self._layout[name])
-            elif isinstance(FIELD, (lltype.Struct, lltype.Array)):
-                embedded_ptr = getattr(self, name)
-                suboffsets = embedded_ptr.get_offsets_of_contained_pointers()
-                offsets += [s + self._layout[name] for s in suboffsets]
-        return offsets
-
-    def _get_offsets_of_contained_pointers_array(self):
-        offsets = []
-        if (isinstance(self._TYPE.TO.OF, lltype.Ptr) and
-            self._TYPE.TO.OF._needsgc()):
-            for i in range(len(self)):
-                offsets.append(self._layout[0] + i * self._layout[1])
-        elif isinstance(self._TYPE.TO.OF, lltype.GcStruct):
-            for i in range(len(self)):
-                suboffsets += self[i].get_offsets_of_contained_pointers()
-                offsets += [s + self._layout[0] + i * self._layout[1]
-                               for s in suboffsets]
-        return offsets
-
 
 def cast_pointer(PTRTYPE, ptr):
     if not isinstance(ptr, simulatorptr) or not isinstance(PTRTYPE, lltype.Ptr):

Modified: pypy/dist/pypy/rpython/memory/test/test_gc.py
==============================================================================
--- pypy/dist/pypy/rpython/memory/test/test_gc.py	(original)
+++ pypy/dist/pypy/rpython/memory/test/test_gc.py	Fri Aug 19 18:52:17 2005
@@ -36,14 +36,12 @@
             ll.append(root)
         return ll
 
-    def get_contained_pointers(self, addr, typeid):
-        if addr is NULL:
-            return AddressLinkedList()
+    def is_varsize(self, typeid):
+        False
+
+    def offsets_to_gc_pointers(self, typeid):
         layout = self.layout_mapping[typeid]
-        result = AddressLinkedList()
-        for offset in layout:
-            result.append(addr + offset)
-        return result
+        return layout
 
 class TestMarkSweepGC(object):
     def test_simple(self):



More information about the Pypy-commit mailing list