[pypy-svn] r30244 - in pypy/dist/pypy/translator/llvm: . test

rxe at codespeak.net rxe at codespeak.net
Wed Jul 19 21:58:19 CEST 2006


Author: rxe
Date: Wed Jul 19 21:58:15 2006
New Revision: 30244

Modified:
   pypy/dist/pypy/translator/llvm/codewriter.py
   pypy/dist/pypy/translator/llvm/gc.py
   pypy/dist/pypy/translator/llvm/genllvm.py
   pypy/dist/pypy/translator/llvm/opwriter.py
   pypy/dist/pypy/translator/llvm/test/test_gc.py
Log:
Small updates for Boehm and None policies.



Modified: pypy/dist/pypy/translator/llvm/codewriter.py
==============================================================================
--- pypy/dist/pypy/translator/llvm/codewriter.py	(original)
+++ pypy/dist/pypy/translator/llvm/codewriter.py	Wed Jul 19 21:58:15 2006
@@ -202,8 +202,15 @@
     def alloca(self, targetvar, vartype):
         self._indent("%s = alloca %s" % (targetvar, vartype))
 
-    def malloc(self, targetvar, vartype):
-        self._indent("%s = malloc %s" % (targetvar, vartype))
+    def malloc(self, targetvar, vartype, numelements=1):
+        if numelements == 1:
+            self._indent("%s = malloc %s" % (targetvar, vartype))
+        else:
+            assert numelements > 1
+            self._indent("%s = malloc %s, uint %s" % (targetvar,
+                                                      vartype,
+                                                      numelements))
+            
 
     def free(self, vartype, varref):
         self._indent("free %s %s" % (vartype, varref))

Modified: pypy/dist/pypy/translator/llvm/gc.py
==============================================================================
--- pypy/dist/pypy/translator/llvm/gc.py	(original)
+++ pypy/dist/pypy/translator/llvm/gc.py	Wed Jul 19 21:58:15 2006
@@ -4,7 +4,14 @@
 from pypy.translator.llvm.log import log
 log = log.gc
 
+def have_boehm():
+    import distutils.sysconfig
+    from os.path import exists
+    libdir = distutils.sysconfig.EXEC_PREFIX + "/lib"  
+    return exists(libdir + '/libgc.so') or exists(libdir + '/libgc.a')
+
 class GcPolicy:
+    n_malloced = 0
     def __init__(self, db):
         raise Exception, 'GcPolicy should not be used directly'
     
@@ -17,26 +24,80 @@
     def pyrex_code(self):
         return ''    
 
-    def malloc(self, codewriter, targetvar, type_, size=1, atomic=False):
-        raise NotImplementedError, 'GcPolicy should not be used directly'
+    def get_count(self, inc=False):
+        if inc:
+            self.n_malloced = self.n_malloced + 1
+        return '_%d' % self.n_malloced
 
-    def var_malloc(self, codewriter, targetvar, type_, node, len, atomic=False):
+    def _zeromalloc(self, codewriter, targetvar, size=1, atomic=False,
+                    exc_flag=False):
         raise NotImplementedError, 'GcPolicy should not be used directly'
 
-    def new(db, gcpolicy=None):
-        """ factory """
-        gcpolicy = gcpolicy or 'boehm'
+    def zeromalloc(self, codewriter, targetvar, type_, size=1, atomic=False,
+                   exc_flag=False):
+        uword = self.db.get_machine_uword()
+        malloc_ptr = '%malloc_ptr' + self.get_count(True)
+        malloc_size = '%malloc_size' + self.get_count()
+        malloc_sizeu = '%malloc_sizeu' + self.get_count()
+        
+        codewriter.getelementptr(malloc_size, type_, 'null',
+                                 [(uword, size)], getptr=False)
+        codewriter.cast(malloc_sizeu, type_, malloc_size, uword)
+        self._zeromalloc(codewriter, malloc_ptr, malloc_sizeu, atomic, exc_flag)
+        codewriter.cast(targetvar, 'sbyte*', malloc_ptr, type_)            
+
+    def var_zeromalloc(self, codewriter, targetvar,
+                       type_, node, len, atomic=False):
+
+        word = lentype = self.db.get_machine_word()
+        uword = self.db.get_machine_uword()
+        malloc_ptr = '%malloc_ptr' + self.get_count(True)
+        malloc_size = '%malloc_size' + self.get_count()
+        malloc_sizeu = '%malloc_sizeu' + self.get_count()
+        actuallen = '%actuallen' + self.get_count()
+        arraylength = '%arraylength' + self.get_count()
+        
+        ARRAY, indices_to_array = node.var_malloc_info()
+        
+        #varsized arrays and structs look like this: 
+        #Array: {int length , elemtype*}
+        #Struct: {...., Array}
         
-        # XXX would be nice to localise this sort of thing?
-        import distutils.sysconfig
-        from os.path import exists
-        libdir = distutils.sysconfig.EXEC_PREFIX + "/lib"  
-        boehm_on_path = exists(libdir + '/libgc.so') or exists(libdir + '/libgc.a')
-        if gcpolicy == 'boehm' and not boehm_on_path:
-            log.gc.WARNING('warning: Boehm GC libary not found in /usr/lib, falling back on no gc')
-            gcpolicy = 'raw'
+        # the following indices access the last element in the array
+        elemtype = self.db.repr_type(ARRAY.OF)
+        word = lentype = self.db.get_machine_word()
+        uword = self.db.get_machine_uword()
+        
+        # need room for NUL terminator
+        if ARRAY is STR.chars:
+            codewriter.binaryop('add', actuallen, lentype, len, 1)
+        else:
+            codewriter.cast(actuallen, lentype, len, lentype)
+            
+        elemindices = list(indices_to_array)
+        elemindices += [('uint', 1), (lentype, actuallen)]
+        codewriter.getelementptr(malloc_size, type_, 'null', elemindices) 
+        codewriter.cast(malloc_sizeu, elemtype + '*', malloc_size, uword)
+        
+        self._zeromalloc(codewriter, malloc_ptr, malloc_sizeu, atomic=atomic)
 
+        indices_to_arraylength = tuple(indices_to_array) + (('uint', 0),)
+
+        codewriter.cast(targetvar, 'sbyte*', malloc_ptr, type_)
+
+        #XXX ctypes Arrays have no length field
+        #XXXif not VARPART._hints.get('nolength', False):
+
+        # the following accesses the length field of the array 
+        codewriter.getelementptr(arraylength, type_, 
+                                 targetvar,  indices_to_arraylength)
+        codewriter.store(lentype, len, arraylength)
+
+    def new(db, gcpolicy=None):
+        """ factory """
         if gcpolicy == 'boehm':
+            # XXX would be nice to localise this sort of thing?
+            assert have_boehm(), 'warning: Boehm GC libary not found in /usr/lib'
             gcpolicy = BoehmGcPolicy(db)
         elif gcpolicy == 'ref':
             gcpolicy = RefcountingGcPolicy(db)
@@ -50,13 +111,7 @@
 
 class RawGcPolicy(GcPolicy):
     def __init__(self, db):
-        self.boehm = BoehmGcPolicy(db)
-
-    def malloc(self, codewriter, targetvar, type_, size=1, atomic=False, exc_flag=False):
-        return self.boehm.malloc(codewriter, targetvar, type_, size, atomic, exc_flag)
-
-    def var_malloc(self, codewriter, targetvar, type_, node, len, atomic=False):
-        return self.boehm.var_malloc(codewriter, targetvar, type_, node, len, atomic)
+        self.db = db
 
     def genextern_code(self):
         r  = ''
@@ -66,12 +121,27 @@
         r += 'char* pypy_malloc_atomic(int size) { return calloc(1, size); }\n'
         return r
 
+    def gc_libraries(self):
+        return ['pthread']
+
+    def _zeromalloc(self, codewriter, targetvar, size=1, atomic=False,
+                    exc_flag=False):
+        """ assumes malloc of word size """
+        uword = self.db.get_machine_uword()
+        boundary_size = 0
+
+        # malloc_size is unsigned right now
+        codewriter.malloc(targetvar, "sbyte", size)
+        codewriter.call(None, 'void', '%llvm.memset',
+                        ['sbyte*', 'ubyte', uword, uword],
+                        [targetvar, 0, size, boundary_size],
+                        cconv='ccc')               
 
 class BoehmGcPolicy(GcPolicy):
 
     def __init__(self, db, exc_useringbuf=True):
         self.db = db
-        self.n_malloced = 0
+        # XXX a config option...
         self.exc_useringbuf = exc_useringbuf
         
     def genextern_code(self):
@@ -81,7 +151,7 @@
         return r
     
     def gc_libraries(self):
-        return ['gc', 'pthread'] # XXX on windows?
+        return ['gc', 'pthread']
 
     def pyrex_code(self):
         return '''
@@ -91,19 +161,9 @@
     return GC_get_heap_size()
 '''
 
-    def get_count(self, inc=False):
-        if inc:
-            self.n_malloced += 1
-        return '_%d' % self.n_malloced
-
-    def _malloc(self, codewriter, targetvar, size=1, atomic=False,
-                exc_flag=False):
+    def _zeromalloc(self, codewriter, targetvar, size=1, atomic=False,
+                    exc_flag=False):
         """ assumes malloc of word size """
-        # XXX Boehm aligns on 8 byte boundaries
-    	#if sys.platform == 'linux2' and sys.maxint == 2**63-1:
-        #    boundary_size = 8
-	#else:
-        #    boundary_size = 0
         boundary_size = 0
 
         word = self.db.get_machine_word()
@@ -112,7 +172,8 @@
         fnname = '%pypy_malloc' + (atomic and '_atomic' or '')
         if self.exc_useringbuf and exc_flag:
             fnname += '_ringbuffer'
-            atomic  = False #XXX performance hack to never clear the ringbuffer data
+            # dont clear the ringbuffer data
+            atomic = False 
 
         # malloc_size is unsigned right now
         sizei = '%malloc_sizei' + self.get_count()        
@@ -125,63 +186,6 @@
                             [targetvar, 0, size, boundary_size],
                             cconv='ccc')        
 
-    def malloc(self, codewriter, targetvar, type_, size=1, atomic=False,
-               exc_flag=False):
-        uword = self.db.get_machine_uword()
-        malloc_ptr = '%malloc_ptr' + self.get_count(True)
-        malloc_size = '%malloc_size' + self.get_count()
-        malloc_sizeu = '%malloc_sizeu' + self.get_count()
-        
-        codewriter.getelementptr(malloc_size, type_, 'null',
-                                 [(uword, size)], getptr=False)
-        codewriter.cast(malloc_sizeu, type_, malloc_size, uword)
-        self._malloc(codewriter, malloc_ptr, malloc_sizeu, atomic, exc_flag)
-        codewriter.cast(targetvar, 'sbyte*', malloc_ptr, type_)            
-
-    def var_malloc(self, codewriter, targetvar,
-                   type_, node, len, atomic=False):
-
-        word = lentype = self.db.get_machine_word()
-        uword = self.db.get_machine_uword()
-        malloc_ptr = '%malloc_ptr' + self.get_count(True)
-        malloc_size = '%malloc_size' + self.get_count()
-        malloc_sizeu = '%malloc_sizeu' + self.get_count()
-        actuallen = '%actuallen' + self.get_count()
-        arraylength = '%arraylength' + self.get_count()
-        
-        ARRAY, indices_to_array = node.var_malloc_info()
-        
-        #varsized arrays and structs look like this: 
-        #Array: {int length , elemtype*}
-        #Struct: {...., Array}
-        
-        # the following indices access the last element in the array
-        elemtype = self.db.repr_type(ARRAY.OF)
-        word = lentype = self.db.get_machine_word()
-        uword = self.db.get_machine_uword()
-        
-        # need room for NUL terminator
-        if ARRAY is STR.chars:
-            codewriter.binaryop('add', actuallen, lentype, len, 1)
-        else:
-            codewriter.cast(actuallen, lentype, len, lentype)
-            
-        elemindices = list(indices_to_array)
-        elemindices += [('uint', 1), (lentype, actuallen)]
-        codewriter.getelementptr(malloc_size, type_, 'null', elemindices) 
-        codewriter.cast(malloc_sizeu, elemtype + '*', malloc_size, uword)
-        
-        self._malloc(codewriter, malloc_ptr, malloc_sizeu, atomic=atomic)
-
-        indices_to_arraylength = tuple(indices_to_array) + (('uint', 0),)
-
-        codewriter.cast(targetvar, 'sbyte*', malloc_ptr, type_)
-
-        # the following accesses the length field of the array 
-        codewriter.getelementptr(arraylength, type_, 
-                                 targetvar,  indices_to_arraylength)
-        codewriter.store(lentype, len, arraylength)
-
 
 class RefcountingGcPolicy(GcPolicy):
     def __init__(self, db):

Modified: pypy/dist/pypy/translator/llvm/genllvm.py
==============================================================================
--- pypy/dist/pypy/translator/llvm/genllvm.py	(original)
+++ pypy/dist/pypy/translator/llvm/genllvm.py	Wed Jul 19 21:58:15 2006
@@ -30,6 +30,9 @@
         # reset counters
         LLVMNode.nodename_count = {}    
 
+        if gcpolicy is None:
+            gcpolicy = "none"
+            
         self.gcpolicy = gcpolicy
 
         self.stackless = stackless
@@ -73,7 +76,7 @@
         # please dont ask!
         from pypy.translator.c.genc import CStandaloneBuilder
         from pypy.translator.c import gc
-        cbuild = CStandaloneBuilder(self.translator, func, gc.NoneGcPolicy)
+        cbuild = CStandaloneBuilder(self.translator, func, self.gcpolicy)
         cbuild.stackless = self.stackless
         c_db = cbuild.generate_graphs_for_llinterp()
 

Modified: pypy/dist/pypy/translator/llvm/opwriter.py
==============================================================================
--- pypy/dist/pypy/translator/llvm/opwriter.py	(original)
+++ pypy/dist/pypy/translator/llvm/opwriter.py	Wed Jul 19 21:58:15 2006
@@ -287,8 +287,8 @@
         if 'Exception' in name or 'Error' in name:
             exc = True
 
-        self.db.gcpolicy.malloc(self.codewriter, opr.retref, opr.rettype,
-                                atomic=arg_type._is_atomic(), exc_flag=exc)
+        self.db.gcpolicy.zeromalloc(self.codewriter, opr.retref, opr.rettype,
+                                    atomic=arg_type._is_atomic(), exc_flag=exc)
 
     def malloc_varsize(self, opr):
 
@@ -301,10 +301,10 @@
             return
 
         node = self.db.obj2node[arg_type]
-        self.db.gcpolicy.var_malloc(self.codewriter, opr.retref, opr.rettype,
-                                    node, opr.argrefs[1],
-                                    atomic=arg_type._is_atomic())
-
+        self.db.gcpolicy.var_zeromalloc(self.codewriter, opr.retref,
+                                        opr.rettype, node, opr.argrefs[1],
+                                        atomic=arg_type._is_atomic())
+        
     def flavored_malloc(self, opr):
         flavor = opr.op.args[0].value
         type_  = opr.rettype[:-1] #XXX stripping of *

Modified: pypy/dist/pypy/translator/llvm/test/test_gc.py
==============================================================================
--- pypy/dist/pypy/translator/llvm/test/test_gc.py	(original)
+++ pypy/dist/pypy/translator/llvm/test/test_gc.py	Wed Jul 19 21:58:15 2006
@@ -17,7 +17,7 @@
             x += l[2]
             i += 1
         return x
-    mod, f = compile_test(tuple_getitem, [int])
+    mod, f = compile_test(tuple_getitem, [int], gcpolicy="boehm")
     n = 5000
     result = tuple_getitem(n)
     assert f(n) == result
@@ -27,3 +27,15 @@
         assert f(n) == result
         heap_size_inc = get_heap_size() - heap_size_start
         assert heap_size_inc < 1000000
+
+def test_nogc(): 
+    def tuple_getitem(n): 
+        x = 666
+        i = 0
+        while i < n:
+            l = (1,2,i,4,5,6,7,8,9,10,11)
+            x += l[2]
+            i += 1
+        return x
+    mod, f = compile_test(tuple_getitem, [int], gcpolicy="none")
+    assert f(5000) == tuple_getitem(5000)



More information about the Pypy-commit mailing list