[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