[pypy-svn] r50349 - in pypy/branch/applevel-ctypes/pypy/translator/c: . src test

fijal at codespeak.net fijal at codespeak.net
Sat Jan 5 11:51:44 CET 2008


Author: fijal
Date: Sat Jan  5 11:51:44 2008
New Revision: 50349

Modified:
   pypy/branch/applevel-ctypes/pypy/translator/c/database.py
   pypy/branch/applevel-ctypes/pypy/translator/c/funcgen.py
   pypy/branch/applevel-ctypes/pypy/translator/c/genc.py
   pypy/branch/applevel-ctypes/pypy/translator/c/node.py
   pypy/branch/applevel-ctypes/pypy/translator/c/primitive.py
   pypy/branch/applevel-ctypes/pypy/translator/c/src/stack.h
   pypy/branch/applevel-ctypes/pypy/translator/c/support.py
   pypy/branch/applevel-ctypes/pypy/translator/c/test/test_boehm.py
   pypy/branch/applevel-ctypes/pypy/translator/c/test/test_newgc.py
Log:
Merge translator/c from trunk as well.


Modified: pypy/branch/applevel-ctypes/pypy/translator/c/database.py
==============================================================================
--- pypy/branch/applevel-ctypes/pypy/translator/c/database.py	(original)
+++ pypy/branch/applevel-ctypes/pypy/translator/c/database.py	Sat Jan  5 11:51:44 2008
@@ -7,11 +7,10 @@
 from pypy.rpython.lltypesystem.rffi import CConstant
 from pypy.tool.sourcetools import valid_identifier
 from pypy.translator.c.primitive import PrimitiveName, PrimitiveType
-from pypy.translator.c.primitive import PrimitiveErrorValue
 from pypy.translator.c.node import StructDefNode, ArrayDefNode
 from pypy.translator.c.node import FixedSizeArrayDefNode, BareBoneArrayDefNode
 from pypy.translator.c.node import ContainerNodeFactory, ExtTypeOpaqueDefNode
-from pypy.translator.c.support import cdecl, CNameManager, ErrorValue
+from pypy.translator.c.support import cdecl, CNameManager
 from pypy.translator.c.support import log, barebonearray
 from pypy.translator.c.extfunc import do_the_getting
 from pypy import conftest
@@ -164,21 +163,14 @@
             self.containerstats[kind] = self.containerstats.get(kind, 0) + 1
             self.containerlist.append(node)
             if self.completed:
-                assert not node.globalcontainer
-                # non-global containers are found very late, e.g. _subarrays
-                # via addresses introduced by the GC transformer
+                pass # we would like to fail here, but a few containers
+                     # are found very late, e.g. _subarrays via addresses
+                     # introduced by the GC transformer, or the type_info_table
         return node
 
     def get(self, obj):
-        if isinstance(obj, ErrorValue):
-            T = obj.TYPE
-            if isinstance(T, Primitive):
-                return PrimitiveErrorValue[T]
-            elif isinstance(T, Ptr):
-                return 'NULL'
-            else:
-                raise Exception("don't know about %r" % (T,))
-        else:
+        # XXX extra indent is preserve svn blame - kind of important IMHO (rxe)
+        if 1:
             if isinstance(obj, CConstant):
                 return obj.c_name  # without further checks
             T = typeOf(obj)
@@ -195,11 +187,15 @@
                         n = len('delayed!')
                         if len(name) == n:
                             raise
-                        if id(obj) in self.delayedfunctionnames:
-                            return self.delayedfunctionnames[id(obj)][0]
-                        funcname = name[n:]
-                        funcname = self.namespace.uniquename('g_' + funcname)
-                        self.delayedfunctionnames[id(obj)] = funcname, obj
+                        if isinstance(lltype.typeOf(obj).TO, lltype.FuncType):
+                            if id(obj) in self.delayedfunctionnames:
+                                return self.delayedfunctionnames[id(obj)][0]
+                            funcname = name[n:]
+                            funcname = self.namespace.uniquename('g_'+funcname)
+                            self.delayedfunctionnames[id(obj)] = funcname, obj
+                        else:
+                            funcname = None      # can't use the name of a
+                                                 # delayed non-function ptr
                         self.delayedfunctionptrs.append(obj)
                         return funcname
                         # /hack hack hack
@@ -283,11 +279,14 @@
         # list:
         finish_callbacks = []
         if self.gctransformer:
-            finish_callbacks.append(self.gctransformer.finish_helpers)
+            finish_callbacks.append(('GC transformer: finished helpers',
+                                     self.gctransformer.finish_helpers))
         if self.stacklesstransformer:
-            finish_callbacks.append(self.stacklesstransformer.finish)
+            finish_callbacks.append(('Stackless transformer: finished',
+                                     self.stacklesstransformer.finish))
         if self.gctransformer:
-            finish_callbacks.append(self.gctransformer.finish_tables)
+            finish_callbacks.append(('GC transformer: finished tables',
+                                     self.gctransformer.finish_tables))
 
         def add_dependencies(newdependencies):
             for value in newdependencies:
@@ -331,8 +330,9 @@
                     continue   # progress - follow all dependencies again
 
             if finish_callbacks:
-                finish = finish_callbacks.pop(0)
+                logmsg, finish = finish_callbacks.pop(0)
                 newdependencies = finish()
+                log.database(logmsg)
                 if newdependencies:
                     add_dependencies(newdependencies)
                 continue       # progress - follow all dependencies again
@@ -343,6 +343,7 @@
         self.completed = True
         if show_progress:
             dump()
+        log.database("Completed")
 
     def globalcontainers(self):
         for node in self.containerlist:

Modified: pypy/branch/applevel-ctypes/pypy/translator/c/funcgen.py
==============================================================================
--- pypy/branch/applevel-ctypes/pypy/translator/c/funcgen.py	(original)
+++ pypy/branch/applevel-ctypes/pypy/translator/c/funcgen.py	Sat Jan  5 11:51:44 2008
@@ -1,6 +1,6 @@
 from __future__ import generators
 from pypy.translator.c.support import USESLOTS # set to False if necessary while refactoring
-from pypy.translator.c.support import cdecl, ErrorValue
+from pypy.translator.c.support import cdecl
 from pypy.translator.c.support import llvalue_from_constant, gen_assignments
 from pypy.translator.c.support import c_string_constant, barebonearray
 from pypy.objspace.flow.model import Variable, Constant, Block
@@ -37,6 +37,7 @@
                        oldgraph""".split()
 
     def __init__(self, graph, db, exception_policy=None, functionname=None):
+        graph._seen_by_the_backend = True
         self.graph = graph
         self.db = db
         self.gcpolicy = db.gcpolicy
@@ -177,21 +178,6 @@
         else:
             raise TypeError, "expr(%r)" % (v,)
 
-    def error_return_value(self):
-        returnlltype = self.lltypemap(self.graph.getreturnvar())
-        return self.db.get(ErrorValue(returnlltype))
-
-    def return_with_error(self):
-        if self.exception_policy == "CPython":
-            assert self.lltypemap(self.graph.getreturnvar()) == PyObjPtr
-            v, exc_cleanup_ops = self.graph.exc_cleanup
-            vanishing_exc_value = self.expr(v)
-            yield 'RPyConvertExceptionToCPython(%s);' % vanishing_exc_value
-            for cleanupop in exc_cleanup_ops:
-                for line in self.gen_op(cleanupop):
-                    yield line
-        yield 'return %s; ' % self.error_return_value()
-
     # ____________________________________________________________
 
     def cfunction_declarations(self):
@@ -285,7 +271,7 @@
                         yield 'case %s:' % self.db.get(link.llexitcase)
                         for op in self.gen_link(link):
                             yield '\t' + op
-                        yield 'break;'
+                        # 'break;' not needed, as gen_link ends in a 'goto'
                         
                     # Emit default case
                     yield 'default:'

Modified: pypy/branch/applevel-ctypes/pypy/translator/c/genc.py
==============================================================================
--- pypy/branch/applevel-ctypes/pypy/translator/c/genc.py	(original)
+++ pypy/branch/applevel-ctypes/pypy/translator/c/genc.py	Sat Jan  5 11:51:44 2008
@@ -14,7 +14,6 @@
 from pypy.rpython.lltypesystem import lltype
 from pypy.tool.udir import udir
 from pypy.tool import isolate
-from pypy.translator.locality.calltree import CallTree
 from pypy.translator.c.support import log, c_string_constant
 from pypy.rpython.typesystem import getfunctionptr
 from pypy.translator.c import gc
@@ -24,18 +23,16 @@
     _compiled = False
     modulename = None
     
-    def __init__(self, translator, entrypoint, config,
-                 eci=ExternalCompilationInfo(), gcpolicy=None):
+    def __init__(self, translator, entrypoint, config, gcpolicy=None):
         self.translator = translator
         self.entrypoint = entrypoint
         self.entrypoint_name = self.entrypoint.func_name
         self.originalentrypoint = entrypoint
-        self.gcpolicy = gcpolicy
+        self.config = config
+        self.gcpolicy = gcpolicy    # for tests only, e.g. rpython/memory/
         if gcpolicy is not None and gcpolicy.requires_stackless:
             config.translation.stackless = True
-        self.config = config
-        self.exports = {}
-        self.eci = eci
+        self.eci = ExternalCompilationInfo()
 
     def build_database(self):
         translator = self.translator
@@ -60,11 +57,7 @@
                               thread_enabled=self.config.translation.thread,
                               sandbox=self.config.translation.sandbox)
         self.db = db
-
-        # we need a concrete gcpolicy to do this
-        self.eci = self.eci.merge(ExternalCompilationInfo(
-            libraries=db.gcpolicy.gc_libraries()))
-
+        
         # give the gc a chance to register interest in the start-up functions it
         # need (we call this for its side-effects of db.get())
         list(db.gcpolicy.gc_startup_code())
@@ -72,16 +65,19 @@
         # build entrypoint and eventually other things to expose
         pf = self.getentrypointptr()
         pfname = db.get(pf)
-        self.exports[self.entrypoint_name] = pf
         self.c_entrypoint_name = pfname
         db.complete()
-        
-        self.collect_compilation_info()
+
+        self.collect_compilation_info(db)
         return db
 
     have___thread = None
 
-    def collect_compilation_info(self):
+    def collect_compilation_info(self, db):
+        # we need a concrete gcpolicy to do this
+        self.eci = self.eci.merge(ExternalCompilationInfo(
+            libraries=db.gcpolicy.gc_libraries()))
+
         all = []
         for node in self.db.globalcontainers():
             eci = getattr(node, 'compilation_info', None)
@@ -90,12 +86,12 @@
         self.eci = self.eci.merge(*all)
 
     def get_gcpolicyclass(self):
-        if self.gcpolicy is None:
-            name = self.config.translation.gctransformer
-            if self.config.translation.stacklessgc:
-                name = "%s+stacklessgc" % (name,)
-            return gc.name_to_gcpolicy[name]
-        return self.gcpolicy
+        if self.gcpolicy is not None:
+            return self.gcpolicy     # for tests only
+        name = self.config.translation.gctransformer
+        if self.config.translation.stacklessgc:
+            name = "%s+stacklessgc" % (name,)
+        return gc.name_to_gcpolicy[name]
 
     # use generate_source(defines=DEBUG_DEFINES) to force the #definition
     # of the macros that enable debugging assertions
@@ -126,8 +122,7 @@
         if not self.standalone:
             assert not self.config.translation.instrument
             cfile, extra = gen_source(db, modulename, targetdir, self.eci,
-                                      defines = defines,
-                                      exports = self.exports)
+                                      defines = defines)
         else:
             if self.config.translation.instrument:
                 defines['INSTRUMENT'] = 1
@@ -396,11 +391,6 @@
         self.funcnodes = funcnodes
         self.othernodes = othernodes
         self.path = path
-        # disabled this for a while, does worsen things
-#        graph = CallTree(self.funcnodes, self.database)
-#        graph.simulate()
-#        graph.optimize()
-#        self.funcnodes = graph.ordered_funcnodes()
 
     def uniquecname(self, name):
         assert name.endswith('.c')
@@ -693,7 +683,7 @@
     return filename, sg.getextrafiles() + list(eci.separate_module_files)
 
 
-def gen_source(database, modulename, targetdir, eci, defines={}, exports={}):
+def gen_source(database, modulename, targetdir, eci, defines={}):
     assert not database.standalone
     if isinstance(targetdir, str):
         targetdir = py.path.local(targetdir)
@@ -770,7 +760,7 @@
       ext_modules = [Extension(name = "%(modulename)s",
                             sources = ["%(modulename)s.c"],
                  extra_compile_args = extra_compile_args,
-                       include_dirs = [PYPY_INCLUDE_DIR] + %(include_dirs)r,
+                       include_dirs = (PYPY_INCLUDE_DIR,) + %(include_dirs)r,
                        library_dirs = %(library_dirs)r,
                           libraries = %(libraries)r)])
 '''

Modified: pypy/branch/applevel-ctypes/pypy/translator/c/node.py
==============================================================================
--- pypy/branch/applevel-ctypes/pypy/translator/c/node.py	(original)
+++ pypy/branch/applevel-ctypes/pypy/translator/c/node.py	Sat Jan  5 11:51:44 2008
@@ -908,6 +908,7 @@
     ptarget = obj._dereference()
     wrapper = db.gcpolicy.convert_weakref_to(ptarget)
     container = wrapper._obj
+    obj._converted_weakref = container     # hack for genllvm :-/
     return db.getcontainernode(container, _dont_write_c_code=False)
 
 

Modified: pypy/branch/applevel-ctypes/pypy/translator/c/primitive.py
==============================================================================
--- pypy/branch/applevel-ctypes/pypy/translator/c/primitive.py	(original)
+++ pypy/branch/applevel-ctypes/pypy/translator/c/primitive.py	Sat Jan  5 11:51:44 2008
@@ -158,20 +158,6 @@
     Address:  'void* @',
     }
 
-PrimitiveErrorValue = {
-    SignedLongLong:   '-1LL',
-    Signed:   '-1',
-    UnsignedLongLong: '((unsigned long long) -1)',
-    Unsigned: '((unsigned) -1)',
-    Float:    '-1.0',
-    SingleFloat: '-1.0f',
-    Char:     '((char) -1)',
-    UniChar:  '((unsigned) -1)',
-    Bool:     '0 /* error */',
-    Void:     '/* error */',
-    Address:  'NULL',
-    }
-
 def define_c_primitive(ll_type, c_name):
     if ll_type in PrimitiveName:
         return
@@ -181,7 +167,6 @@
         name_str = '((%s) %%dLL)' % c_name
     PrimitiveName[ll_type] = lambda value, db: name_str % value
     PrimitiveType[ll_type] = '%s @'% c_name
-    PrimitiveErrorValue[ll_type] = '((%s) -1)'% c_name
     
 for ll_type, c_name in [(rffi.SIGNEDCHAR, 'signed char'),
                         (rffi.UCHAR, 'unsigned char'),

Modified: pypy/branch/applevel-ctypes/pypy/translator/c/src/stack.h
==============================================================================
--- pypy/branch/applevel-ctypes/pypy/translator/c/src/stack.h	(original)
+++ pypy/branch/applevel-ctypes/pypy/translator/c/src/stack.h	Sat Jan  5 11:51:44 2008
@@ -9,7 +9,26 @@
 #endif
 
 void LL_stack_unwind(void);
-int LL_stack_too_big(void);
+int LL_stack_too_big_slowpath(void);
+
+extern volatile char *_LLstacktoobig_stack_base_pointer;
+extern long _LLstacktoobig_stack_min;
+extern long _LLstacktoobig_stack_max;
+
+static int LL_stack_too_big(void)
+{
+	/* The fast path of stack_too_big, called extremely often.
+	   Making it static makes an *inlinable* copy of this small
+	   function's implementation in each compilation unit. */
+	char local;
+	long diff = &local - _LLstacktoobig_stack_base_pointer;
+	/* common case: we are still in the same thread as last time
+	   we checked, and still in the allowed part of the stack */
+	return ((diff < _LLstacktoobig_stack_min ||
+		 diff > _LLstacktoobig_stack_max)
+		/* if not, call the slow path */
+		&& LL_stack_too_big_slowpath());
+}
 
 #ifndef PYPY_NOT_MAIN_FILE
 #include <stdio.h>
@@ -33,15 +52,16 @@
 		return &local - parent;
 }
 
-int LL_stack_too_big(void)
+volatile char *_LLstacktoobig_stack_base_pointer = NULL;
+long _LLstacktoobig_stack_min = 0;
+long _LLstacktoobig_stack_max = 0;
+RPyThreadStaticTLS _LLstacktoobig_stack_base_pointer_key;
+
+int LL_stack_too_big_slowpath(void)
 {
 	char local;
 	long diff;
 	char *baseptr;
-	static volatile char *stack_base_pointer = NULL;
-	static long stack_min = 0;
-	static long stack_max = 0;
-	static RPyThreadStaticTLS stack_base_pointer_key;
 	/* Check that the stack is less than MAX_STACK_SIZE bytes bigger
 	   than the value recorded in stack_base_pointer.  The base
 	   pointer is updated to the current value if it is still NULL
@@ -50,41 +70,37 @@
 	   try to minimize its overhead by keeping a local copy in
 	   stack_pointer_pointer. */
 
-	diff = &local - stack_base_pointer;
-	if (stack_min <= diff && diff <= stack_max) {
-		/* common case: we are still in the same thread as last time
-		   we checked, and still in the allowed part of the stack */
-		return 0;
-	}
-
-	if (stack_min == stack_max /* == 0 */) {
+	if (_LLstacktoobig_stack_min == _LLstacktoobig_stack_max /* == 0 */) {
 		/* not initialized */
 		/* XXX We assume that initialization is performed early,
 		   when there is still only one thread running.  This
 		   allows us to ignore race conditions here */
-		char *errmsg = RPyThreadStaticTLS_Create(&stack_base_pointer_key);
+		char *errmsg = RPyThreadStaticTLS_Create(
+			&_LLstacktoobig_stack_base_pointer_key);
 		if (errmsg) {
 			/* XXX should we exit the process? */
 			fprintf(stderr, "Internal PyPy error: %s\n", errmsg);
 			return 1;
 		}
 		if (_LL_stack_growing_direction(NULL) > 0)
-			stack_max = MAX_STACK_SIZE;
+			_LLstacktoobig_stack_max = MAX_STACK_SIZE;
 		else
-			stack_min = -MAX_STACK_SIZE;
+			_LLstacktoobig_stack_min = -MAX_STACK_SIZE;
 	}
 
-	baseptr = (char *) RPyThreadStaticTLS_Get(stack_base_pointer_key);
+	baseptr = (char *) RPyThreadStaticTLS_Get(
+			_LLstacktoobig_stack_base_pointer_key);
 	if (baseptr != NULL) {
 		diff = &local - baseptr;
-		if (stack_min <= diff && diff <= stack_max) {
+		if (_LLstacktoobig_stack_min <= diff &&
+		    diff <= _LLstacktoobig_stack_max) {
 			/* within bounds */
-			stack_base_pointer = baseptr;
+			_LLstacktoobig_stack_base_pointer = baseptr;
 			return 0;
 		}
 
-		if ((stack_min == 0 && diff < 0) ||
-		    (stack_max == 0 && diff > 0)) {
+		if ((_LLstacktoobig_stack_min == 0 && diff < 0) ||
+		    (_LLstacktoobig_stack_max == 0 && diff > 0)) {
 			/* we underflowed the stack, which means that
 			   the initial estimation of the stack base must
 			   be revised (see below) */
@@ -96,8 +112,8 @@
 
 	/* update the stack base pointer to the current value */
 	baseptr = &local;
-	RPyThreadStaticTLS_Set(stack_base_pointer_key, baseptr);
-	stack_base_pointer = baseptr;
+	RPyThreadStaticTLS_Set(_LLstacktoobig_stack_base_pointer_key, baseptr);
+	_LLstacktoobig_stack_base_pointer = baseptr;
 	return 0;
 }
 

Modified: pypy/branch/applevel-ctypes/pypy/translator/c/support.py
==============================================================================
--- pypy/branch/applevel-ctypes/pypy/translator/c/support.py	(original)
+++ pypy/branch/applevel-ctypes/pypy/translator/c/support.py	Sat Jan  5 11:51:44 2008
@@ -9,11 +9,6 @@
 
 PyObjPtr = lltype.Ptr(lltype.PyObject)
 
-
-class ErrorValue:
-    def __init__(self, TYPE):
-        self.TYPE = TYPE
-
 def barebonearray(ARRAY):
     """Check if ARRAY is a 'simple' array type,
     i.e. doesn't need a length nor GC headers."""

Modified: pypy/branch/applevel-ctypes/pypy/translator/c/test/test_boehm.py
==============================================================================
--- pypy/branch/applevel-ctypes/pypy/translator/c/test/test_boehm.py	(original)
+++ pypy/branch/applevel-ctypes/pypy/translator/c/test/test_boehm.py	Sat Jan  5 11:51:44 2008
@@ -150,7 +150,6 @@
 
     def test_del_raises(self):
         from pypy.rpython.lltypesystem.lloperation import llop
-        import os
         class A(object):
             def __del__(self):
                 s.dels += 1

Modified: pypy/branch/applevel-ctypes/pypy/translator/c/test/test_newgc.py
==============================================================================
--- pypy/branch/applevel-ctypes/pypy/translator/c/test/test_newgc.py	(original)
+++ pypy/branch/applevel-ctypes/pypy/translator/c/test/test_newgc.py	Sat Jan  5 11:51:44 2008
@@ -298,7 +298,7 @@
             a = A()
             a.b = g(1)
             return a
-        make.dont_inline = True
+        make._dont_inline_ = True
         def f():
             a = make()
             llop.gc__collect(lltype.Void)
@@ -316,7 +316,7 @@
             pass
         def g(x): # cause a collect
             llop.gc__collect(lltype.Void)
-        g.dont_inline = True
+        g._dont_inline_ = True
         global_a = A()
         global_a.b = B()
         global_a.b.a = A()
@@ -330,7 +330,7 @@
             g(1)
             b0 = a.b
             b0.c = b.c = 42
-        make.dont_inline = True
+        make._dont_inline_ = True
         def f():
             make()
             llop.gc__collect(lltype.Void)
@@ -356,7 +356,7 @@
             for i in range(1000):
                 prepare(B(), -1)    # probably overwrites collected memory
             return a.value
-        g.dont_inline = True
+        g._dont_inline_ = True
         def f():
             b = B()
             prepare(b, 123)
@@ -420,7 +420,7 @@
         a.x = None
         def make():
             a.x = A(42)
-        make.dont_inline = True
+        make._dont_inline_ = True
         def f():
             make()
             llop.gc__collect(lltype.Void)
@@ -481,12 +481,12 @@
             a = lltype.malloc(A)
             a.value = -n * 7
             return lltype.cast_opaque_ptr(lltype.Ptr(O), a)
-        gethidden.dont_inline = True
+        gethidden._dont_inline_ = True
         def reveal(o):
             return lltype.cast_opaque_ptr(lltype.Ptr(A), o)
         def overwrite(a, i):
             a.value = i
-        overwrite.dont_inline = True
+        overwrite._dont_inline_ = True
         def f():
             o = gethidden(10)
             llop.gc__collect(lltype.Void)


More information about the pypy-svn mailing list