[pypy-svn] r76818 - in pypy/branch/jit-bounds: . lib-python/modified-2.5.2/test pypy/config pypy/interpreter pypy/interpreter/test pypy/jit/backend/test pypy/jit/backend/x86 pypy/jit/backend/x86/test pypy/jit/tool pypy/jit/tool/test pypy/module/_socket pypy/module/_socket/test pypy/module/array/benchmark pypy/module/array/test pypy/rlib pypy/rpython/memory/gc pypy/tool pypy/translator/c/test pypy/translator/goal pypy/translator/goal/test2 pypy/translator/platform pypy/translator/platform/test

hakanardo at codespeak.net hakanardo at codespeak.net
Wed Sep 1 18:02:02 CEST 2010


Author: hakanardo
Date: Wed Sep  1 18:02:00 2010
New Revision: 76818

Removed:
   pypy/branch/jit-bounds/lib-python/modified-2.5.2/test/test_re.py
Modified:
   pypy/branch/jit-bounds/   (props changed)
   pypy/branch/jit-bounds/pypy/config/translationoption.py
   pypy/branch/jit-bounds/pypy/interpreter/generator.py
   pypy/branch/jit-bounds/pypy/interpreter/pyframe.py
   pypy/branch/jit-bounds/pypy/interpreter/test/test_generator.py
   pypy/branch/jit-bounds/pypy/jit/backend/test/runner_test.py
   pypy/branch/jit-bounds/pypy/jit/backend/x86/assembler.py
   pypy/branch/jit-bounds/pypy/jit/backend/x86/test/test_runner.py
   pypy/branch/jit-bounds/pypy/jit/tool/test/test_traceviewer.py
   pypy/branch/jit-bounds/pypy/jit/tool/traceviewer.py
   pypy/branch/jit-bounds/pypy/module/_socket/interp_socket.py
   pypy/branch/jit-bounds/pypy/module/_socket/test/test_sock_app.py
   pypy/branch/jit-bounds/pypy/module/array/benchmark/Makefile   (props changed)
   pypy/branch/jit-bounds/pypy/module/array/benchmark/intimg.c   (props changed)
   pypy/branch/jit-bounds/pypy/module/array/benchmark/intimgtst.c   (props changed)
   pypy/branch/jit-bounds/pypy/module/array/benchmark/intimgtst.py   (props changed)
   pypy/branch/jit-bounds/pypy/module/array/benchmark/loop.c   (props changed)
   pypy/branch/jit-bounds/pypy/module/array/benchmark/sum.c   (props changed)
   pypy/branch/jit-bounds/pypy/module/array/benchmark/sumtst.c   (props changed)
   pypy/branch/jit-bounds/pypy/module/array/benchmark/sumtst.py   (props changed)
   pypy/branch/jit-bounds/pypy/module/array/test/test_array_old.py   (props changed)
   pypy/branch/jit-bounds/pypy/rlib/rlocale.py
   pypy/branch/jit-bounds/pypy/rpython/memory/gc/markcompact.py
   pypy/branch/jit-bounds/pypy/tool/runsubprocess.py
   pypy/branch/jit-bounds/pypy/translator/c/test/test_standalone.py
   pypy/branch/jit-bounds/pypy/translator/goal/app_main.py
   pypy/branch/jit-bounds/pypy/translator/goal/test2/test_app_main.py
   pypy/branch/jit-bounds/pypy/translator/goal/translate.py
   pypy/branch/jit-bounds/pypy/translator/platform/__init__.py
   pypy/branch/jit-bounds/pypy/translator/platform/test/test_platform.py
Log:
svn merge -r76716:76816 svn+ssh://hakanardo@codespeak.net/svn/pypy/trunk

Modified: pypy/branch/jit-bounds/pypy/config/translationoption.py
==============================================================================
--- pypy/branch/jit-bounds/pypy/config/translationoption.py	(original)
+++ pypy/branch/jit-bounds/pypy/config/translationoption.py	Wed Sep  1 18:02:00 2010
@@ -342,9 +342,12 @@
     'jit':  'hybrid      extraopts     jit',
     }
 
-# For now, 64-bit JIT requires boehm
-if IS_64_BITS:
-    OPT_TABLE['jit'] = OPT_TABLE['jit'].replace('hybrid', 'boehm')
+def final_check_config(config):
+    # For now, 64-bit JIT requires boehm.  You have to say it explicitly
+    # with --gc=boehm, so that you don't get boehm by mistake.
+    if IS_64_BITS:
+        if config.translation.jit and config.translation.gc != 'boehm':
+            raise ConfigError("for now, 64-bit JIT requires --gc=boehm")
 
 def set_opt_level(config, level):
     """Apply optimization suggestions on the 'config'.

Modified: pypy/branch/jit-bounds/pypy/interpreter/generator.py
==============================================================================
--- pypy/branch/jit-bounds/pypy/interpreter/generator.py	(original)
+++ pypy/branch/jit-bounds/pypy/interpreter/generator.py	Wed Sep  1 18:02:00 2010
@@ -1,7 +1,6 @@
 from pypy.interpreter.error import OperationError
 from pypy.interpreter.baseobjspace import Wrappable
 from pypy.interpreter.gateway import NoneNotWrapped
-from pypy.rlib.rarithmetic import intmask
 from pypy.rlib import jit
 from pypy.interpreter.pyopcode import LoopBlock
 
@@ -37,13 +36,17 @@
 return next yielded value or raise StopIteration."""
         return self.send_ex(w_arg)
 
-    def send_ex(self, w_arg, exc=False):
+    def send_ex(self, w_arg, operr=None):
         space = self.space
         if self.running:
             raise OperationError(space.w_ValueError,
                                  space.wrap('generator already executing'))
         if self.frame.frame_finished_execution:
-            raise OperationError(space.w_StopIteration, space.w_None)
+            # xxx a bit ad-hoc, but we don't want to go inside
+            # execute_generator_frame() if the frame is actually finished
+            if operr is None:
+                operr = OperationError(space.w_StopIteration, space.w_None)
+            raise operr
         # XXX it's not clear that last_instr should be promoted at all
         # but as long as it is necessary for call_assembler, let's do it early
         last_instr = jit.hint(self.frame.last_instr, promote=True)
@@ -57,7 +60,7 @@
         self.running = True
         try:
             try:
-                w_result = self.frame.execute_generator_frame(w_arg, exc)
+                w_result = self.frame.execute_generator_frame(w_arg, operr)
             except OperationError:
                 # errors finish a frame
                 self.frame.frame_finished_execution = True
@@ -89,12 +92,7 @@
        
         operr = OperationError(w_type, w_val, tb)
         operr.normalize_exception(space)
-        
-        ec = space.getexecutioncontext()
-        next_instr = self.frame.handle_operation_error(ec, operr)
-        self.frame.last_instr = intmask(next_instr - 1)
-
-        return self.send_ex(space.w_None, True)
+        return self.send_ex(space.w_None, operr)
              
     def descr_next(self):
         """next() -> the next value, or raise StopIteration"""

Modified: pypy/branch/jit-bounds/pypy/interpreter/pyframe.py
==============================================================================
--- pypy/branch/jit-bounds/pypy/interpreter/pyframe.py	(original)
+++ pypy/branch/jit-bounds/pypy/interpreter/pyframe.py	Wed Sep  1 18:02:00 2010
@@ -10,6 +10,7 @@
 from pypy.rlib.objectmodel import we_are_translated, instantiate
 from pypy.rlib.jit import hint
 from pypy.rlib.debug import make_sure_not_resized
+from pypy.rlib.rarithmetic import intmask
 from pypy.rlib import jit, rstack
 from pypy.tool import stdlib_opcode
 
@@ -125,8 +126,12 @@
         else:
             return self.execute_frame()
 
-    def execute_generator_frame(self, w_inputvalue, ex=False):
-        if self.last_instr != -1 and not ex:
+    def execute_generator_frame(self, w_inputvalue, operr=None):
+        if operr is not None:
+            ec = self.space.getexecutioncontext()
+            next_instr = self.handle_operation_error(ec, operr)
+            self.last_instr = intmask(next_instr - 1)
+        elif self.last_instr != -1:
             self.pushvalue(w_inputvalue)
         return self.execute_frame()
 

Modified: pypy/branch/jit-bounds/pypy/interpreter/test/test_generator.py
==============================================================================
--- pypy/branch/jit-bounds/pypy/interpreter/test/test_generator.py	(original)
+++ pypy/branch/jit-bounds/pypy/interpreter/test/test_generator.py	Wed Sep  1 18:02:00 2010
@@ -126,6 +126,25 @@
         raises(ValueError, g.throw, ValueError)
         assert g.gi_frame is None
 
+    def test_throw_bug(self):
+        def f():
+            try:
+                x.throw(IndexError)     # => "generator already executing"
+            except ValueError:
+                yield 1
+        x = f()
+        res = list(x)
+        assert res == [1]
+
+    def test_throw_on_finished_generator(self):
+        def f():
+            yield 1
+        g = f()
+        res = g.next()
+        assert res == 1
+        raises(StopIteration, g.next)
+        raises(NameError, g.throw, NameError)
+
     def test_close(self):
         def f():
             yield 1

Modified: pypy/branch/jit-bounds/pypy/jit/backend/test/runner_test.py
==============================================================================
--- pypy/branch/jit-bounds/pypy/jit/backend/test/runner_test.py	(original)
+++ pypy/branch/jit-bounds/pypy/jit/backend/test/runner_test.py	Wed Sep  1 18:02:00 2010
@@ -785,6 +785,20 @@
                                        'float', descr=arraydescr)
             assert r.value == 4.5
 
+        # For platforms where sizeof(INT) != sizeof(Signed) (ie, x86-64)
+        a_box, A = self.alloc_array_of(rffi.INT, 342)
+        arraydescr = self.cpu.arraydescrof(A)
+        assert not arraydescr.is_array_of_pointers()
+        r = self.execute_operation(rop.ARRAYLEN_GC, [a_box],
+                                   'int', descr=arraydescr)
+        assert r.value == 342
+        r = self.execute_operation(rop.SETARRAYITEM_GC, [a_box, BoxInt(310),
+                                                         BoxInt(7441)],
+                                   'void', descr=arraydescr)
+        assert r is None
+        r = self.execute_operation(rop.GETARRAYITEM_GC, [a_box, BoxInt(310)],
+                                   'int', descr=arraydescr)
+        assert r.value == 7441
 
     def test_string_basic(self):
         s_box = self.alloc_string("hello\xfe")

Modified: pypy/branch/jit-bounds/pypy/jit/backend/x86/assembler.py
==============================================================================
--- pypy/branch/jit-bounds/pypy/jit/backend/x86/assembler.py	(original)
+++ pypy/branch/jit-bounds/pypy/jit/backend/x86/assembler.py	Wed Sep  1 18:02:00 2010
@@ -1046,7 +1046,10 @@
             self.mc.MOVZX8(resloc, source_addr)
         elif size == 2:
             self.mc.MOVZX16(resloc, source_addr)
-        elif size == WORD:
+        elif size == 4:
+            # MOV32 is zero-extending on 64-bit, so this is okay
+            self.mc.MOV32(resloc, source_addr)
+        elif IS_X86_64 and size == 8:
             self.mc.MOV(resloc, source_addr)
         else:
             raise NotImplementedError("getfield size = %d" % size)
@@ -1059,19 +1062,18 @@
         base_loc, ofs_loc, scale, ofs = arglocs
         assert isinstance(ofs, ImmedLoc)
         assert isinstance(scale, ImmedLoc)
+        src_addr = addr_add(base_loc, ofs_loc, ofs.value, scale.value)
         if op.result.type == FLOAT:
-            self.mc.MOVSD(resloc, addr_add(base_loc, ofs_loc, ofs.value,
-                                             scale.value))
+            self.mc.MOVSD(resloc, src_addr)
         else:
             if scale.value == 0:
-                self.mc.MOVZX8(resloc, addr_add(base_loc, ofs_loc, ofs.value,
-                                                scale.value))
+                self.mc.MOVZX8(resloc, src_addr)
             elif scale.value == 1:
-                self.mc.MOVZX16(resloc, addr_add(base_loc, ofs_loc, ofs.value,
-                                                scale.value))
-            elif (1 << scale.value) == WORD:
-                self.mc.MOV(resloc, addr_add(base_loc, ofs_loc, ofs.value,
-                                             scale.value))
+                self.mc.MOVZX16(resloc, src_addr)
+            elif scale.value == 2:
+                self.mc.MOV32(resloc, src_addr)
+            elif IS_X86_64 and scale.value == 3:
+                self.mc.MOV(resloc, src_addr)
             else:
                 print "[asmgen]getarrayitem unsupported size: %d" % scale.value
                 raise NotImplementedError()
@@ -1086,8 +1088,10 @@
         dest_addr = AddressLoc(base_loc, ofs_loc)
         if isinstance(value_loc, RegLoc) and value_loc.is_xmm:
             self.mc.MOVSD(dest_addr, value_loc)
-        elif size == WORD:
+        elif IS_X86_64 and size == 8:
             self.mc.MOV(dest_addr, value_loc)
+        elif size == 4:
+            self.mc.MOV32(dest_addr, value_loc)
         elif size == 2:
             self.mc.MOV16(dest_addr, value_loc)
         elif size == 1:
@@ -1104,8 +1108,10 @@
         if op.args[2].type == FLOAT:
             self.mc.MOVSD(dest_addr, value_loc)
         else:
-            if (1 << scale_loc.value) == WORD:
+            if IS_X86_64 and scale_loc.value == 3:
                 self.mc.MOV(dest_addr, value_loc)
+            elif scale_loc.value == 2:
+                self.mc.MOV32(dest_addr, value_loc)
             elif scale_loc.value == 1:
                 self.mc.MOV16(dest_addr, value_loc)
             elif scale_loc.value == 0:

Modified: pypy/branch/jit-bounds/pypy/jit/backend/x86/test/test_runner.py
==============================================================================
--- pypy/branch/jit-bounds/pypy/jit/backend/x86/test/test_runner.py	(original)
+++ pypy/branch/jit-bounds/pypy/jit/backend/x86/test/test_runner.py	Wed Sep  1 18:02:00 2010
@@ -193,6 +193,7 @@
 
     def test_getfield_setfield(self):
         TP = lltype.GcStruct('x', ('s', lltype.Signed),
+                             ('i', rffi.INT),
                              ('f', lltype.Float),
                              ('u', rffi.USHORT),
                              ('c1', lltype.Char),
@@ -201,6 +202,7 @@
         res = self.execute_operation(rop.NEW, [],
                                      'ref', self.cpu.sizeof(TP))
         ofs_s = self.cpu.fielddescrof(TP, 's')
+        ofs_i = self.cpu.fielddescrof(TP, 'i')
         #ofs_f = self.cpu.fielddescrof(TP, 'f')
         ofs_u = self.cpu.fielddescrof(TP, 'u')
         ofsc1 = self.cpu.fielddescrof(TP, 'c1')
@@ -218,6 +220,11 @@
                                ofs_s)
         s = self.execute_operation(rop.GETFIELD_GC, [res], 'int', ofs_s)
         assert s.value == 3
+
+        self.execute_operation(rop.SETFIELD_GC, [res, BoxInt(1234)], 'void', ofs_i)
+        i = self.execute_operation(rop.GETFIELD_GC, [res], 'int', ofs_i)
+        assert i.value == 1234
+        
         #u = self.execute_operation(rop.GETFIELD_GC, [res, ofs_u], 'int')
         #assert u.value == 5
         self.execute_operation(rop.SETFIELD_GC, [res, ConstInt(1)], 'void',

Modified: pypy/branch/jit-bounds/pypy/jit/tool/test/test_traceviewer.py
==============================================================================
--- pypy/branch/jit-bounds/pypy/jit/tool/test/test_traceviewer.py	(original)
+++ pypy/branch/jit-bounds/pypy/jit/tool/test/test_traceviewer.py	Wed Sep  1 18:02:00 2010
@@ -52,10 +52,10 @@
 
     def test_postparse(self):
         real_loops = [FinalBlock("debug_merge_point('<code object _runCallbacks, file '/tmp/x/twisted-trunk/twisted/internet/defer.py', line 357> #40 POP_TOP')", None)]
-        postprocess(real_loops, real_loops[:])
+        postprocess(real_loops, real_loops[:], {})
         assert real_loops[0].header.startswith("_runCallbacks, file '/tmp/x/twisted-trunk/twisted/internet/defer.py', line 357")
 
     def test_load_actual(self):
         fname = py.path.local(__file__).join('..', 'data.log.bz2')
-        main(str(fname), view=False)
+        main(str(fname), False, view=False)
         # assert did not explode

Modified: pypy/branch/jit-bounds/pypy/jit/tool/traceviewer.py
==============================================================================
--- pypy/branch/jit-bounds/pypy/jit/tool/traceviewer.py	(original)
+++ pypy/branch/jit-bounds/pypy/jit/tool/traceviewer.py	Wed Sep  1 18:02:00 2010
@@ -1,11 +1,12 @@
 #!/usr/bin/env python
-""" Usage: traceviewer.py loopfile
+""" Usage: traceviewer.py [--use-threshold] loopfile
 """
 
 import optparse
 import sys
 import re
 import math
+import py
 
 import autopath
 from pypy.translator.tool.graphpage import GraphPage
@@ -40,13 +41,13 @@
         self.source = dotgen.generate(target=None)
 
 class Page(GraphPage):
-    def compute(self, graphs):
+    def compute(self, graphs, counts):
         dotgen = DotGen('trace')
         self.loops = graphs
         self.links = {}
         self.cache = {}
         for loop in self.loops:
-            loop.generate(dotgen)
+            loop.generate(dotgen, counts)
             loop.getlinks(self.links)
             self.cache["loop" + str(loop.no)] = loop
         self.source = dotgen.generate(target=None)
@@ -71,9 +72,14 @@
     def getlinks(self, links):
         links[self.linksource] = self.name()
 
-    def generate(self, dotgen):
+    def generate(self, dotgen, counts):
+        val = counts.get(self.key, 0)
+        if val > counts.threshold:
+            fillcolor = get_gradient_color(self.ratio)
+        else:
+            fillcolor = "white"
         dotgen.emit_node(self.name(), label=self.header,
-                         shape='box', fillcolor=get_gradient_color(self.ratio))
+                         shape='box', fillcolor=fillcolor)
 
     def get_content(self):
         return self._content
@@ -113,11 +119,11 @@
         self.target = target
         BasicBlock.__init__(self, content)
 
-    def postprocess(self, loops, memo):
-        postprocess_loop(self.target, loops, memo)
+    def postprocess(self, loops, memo, counts):
+        postprocess_loop(self.target, loops, memo, counts)
 
-    def generate(self, dotgen):
-        BasicBlock.generate(self, dotgen)
+    def generate(self, dotgen, counts):
+        BasicBlock.generate(self, dotgen, counts)
         if self.target is not None:
             dotgen.emit_edge(self.name(), self.target.name())
 
@@ -127,12 +133,12 @@
         self.right = right
         BasicBlock.__init__(self, content)
 
-    def postprocess(self, loops, memo):
-        postprocess_loop(self.left, loops, memo)
-        postprocess_loop(self.right, loops, memo)
+    def postprocess(self, loops, memo, counts):
+        postprocess_loop(self.left, loops, memo, counts)
+        postprocess_loop(self.right, loops, memo, counts)
 
-    def generate(self, dotgen):
-        BasicBlock.generate(self, dotgen)
+    def generate(self, dotgen, counts):
+        BasicBlock.generate(self, dotgen, counts)
         dotgen.emit_edge(self.name(), self.left.name())
         dotgen.emit_edge(self.name(), self.right.name())
 
@@ -176,13 +182,11 @@
     real_loops = []
     counter = 1
     bar = progressbar.ProgressBar(color='blue')
-    single_percent = len(loops) / 100
     allloops = []
-    for i, loop in enumerate(loops):
+    for i, loop in enumerate(loops): 
         if i > MAX_LOOPS:
             return real_loops, allloops
-        if single_percent and i % single_percent == 0:
-            bar.render(i / single_percent)
+        bar.render((i * 100) / len(loops))
         firstline = loop[:loop.find("\n")]
         m = re.match('# Loop (\d+)', firstline)
         if m:
@@ -202,17 +206,19 @@
         counter += loop.count("\n") + 2
     return real_loops, allloops
 
-def postprocess_loop(loop, loops, memo):
+def postprocess_loop(loop, loops, memo, counts):
     if loop in memo:
         return
     memo.add(loop)
     if loop is None:
         return
-    m = re.search("debug_merge_point\('<code object (.*?)> (.*?)'", loop.content)
+    m = re.search("debug_merge_point\('(<code object (.*?)> (.*?))'", loop.content)
     if m is None:
         name = '?'
+        loop.key = '?'
     else:
-        name = m.group(1) + " " + m.group(2)
+        name = m.group(2) + " " + m.group(3)
+        loop.key = m.group(1)
     opsno = loop.content.count("\n")
     lastline = loop.content[loop.content.rfind("\n", 0, len(loop.content) - 2):]
     m = re.search('descr=<Loop(\d+)', lastline)
@@ -221,8 +227,8 @@
         loop.target = loops[int(m.group(1))]
     bcodes = loop.content.count('debug_merge_point')
     loop.linksource = "loop" + str(loop.no)
-    loop.header = "%s loop%d\n%d operations\n%d opcodes" % (name, loop.no, opsno,
-                                                          bcodes)
+    loop.header = ("%s loop%d\nrun %s times\n%d operations\n%d opcodes" %
+                   (name, loop.no, counts.get(loop.key, '?'), opsno, bcodes))
     loop.header += "\n" * (opsno / 100)
     if bcodes == 0:
         loop.ratio = opsno
@@ -230,29 +236,47 @@
         loop.ratio = float(opsno) / bcodes
     content = loop.content
     loop.content = "Logfile at %d\n" % loop.startlineno + content
-    loop.postprocess(loops, memo)
-
-def postprocess(loops, allloops):
+    loop.postprocess(loops, memo, counts)
+    
+def postprocess(loops, allloops, counts):
     for loop in allloops:
         if isinstance(loop, Block):
             loop.left = allloops[loop.left]
             loop.right = allloops[loop.right]
     memo = set()
     for loop in loops:
-        postprocess_loop(loop, loops, memo)
+        postprocess_loop(loop, loops, memo, counts)
+
+class Counts(dict):
+    pass
 
-def main(loopfile, view=True):
+def main(loopfile, options, view=True):
+    countname = py.path.local(loopfile + '.count')
+    if countname.check():
+        counts = [line.rsplit(':', 1) for line in countname.readlines()]
+        counts = Counts([(k, int(v.strip('\n'))) for k, v in counts])
+        l = list(sorted(counts.values()))
+        if len(l) > 20 and options.use_threshold:
+            counts.threshold = l[-20]
+        else:
+            counts.threshold = 0
+        for_print = [(v, k) for k, v in counts.iteritems()]
+        for_print.sort()
+    else:
+        counts = {}
     log = logparser.parse_log_file(loopfile)
     loops = logparser.extract_category(log, "jit-log-opt-")
     real_loops, allloops = splitloops(loops)
-    postprocess(real_loops, allloops)
+    postprocess(real_loops, allloops, counts)
     if view:
-        Page(allloops).display()
+        Page(allloops, counts).display()
 
 if __name__ == '__main__':
     parser = optparse.OptionParser(usage=__doc__)
+    parser.add_option('--use-threshold', dest='use_threshold',
+                      action="store_true")
     options, args = parser.parse_args(sys.argv)
     if len(args) != 2:
         print __doc__
         sys.exit(1)
-    main(args[1])
+    main(args[1], options.use_threshold)

Modified: pypy/branch/jit-bounds/pypy/module/_socket/interp_socket.py
==============================================================================
--- pypy/branch/jit-bounds/pypy/module/_socket/interp_socket.py	(original)
+++ pypy/branch/jit-bounds/pypy/module/_socket/interp_socket.py	Wed Sep  1 18:02:00 2010
@@ -74,7 +74,11 @@
         This is like connect(address), but returns an error code (the errno value)
         instead of raising an exception when an error occurs.
         """
-        error = self.connect_ex(self.addr_from_object(space, w_addr))
+        try:
+            addr = self.addr_from_object(space, w_addr)
+        except SocketError, e:
+            raise converted_error(space, e)
+        error = self.connect_ex(addr)
         return space.wrap(error)
     connect_ex_w.unwrap_spec = ['self', ObjSpace, W_Root]
 

Modified: pypy/branch/jit-bounds/pypy/module/_socket/test/test_sock_app.py
==============================================================================
--- pypy/branch/jit-bounds/pypy/module/_socket/test/test_sock_app.py	(original)
+++ pypy/branch/jit-bounds/pypy/module/_socket/test/test_sock_app.py	Wed Sep  1 18:02:00 2010
@@ -339,6 +339,13 @@
         name = s.getpeername() # Will raise socket.error if not connected
         assert name[1] == 80
         s.close()
+    
+    def test_socket_connect_ex(self):
+        import _socket
+        s = _socket.socket(_socket.AF_INET, _socket.SOCK_STREAM, 0)
+        # Make sure we get an app-level error, not an interp one.
+        raises(_socket.gaierror, s.connect_ex, ("wrong.invalid", 80))
+        s.close()
 
     def test_socket_connect_typeerrors(self):
         tests = [

Modified: pypy/branch/jit-bounds/pypy/rlib/rlocale.py
==============================================================================
--- pypy/branch/jit-bounds/pypy/rlib/rlocale.py	(original)
+++ pypy/branch/jit-bounds/pypy/rlib/rlocale.py	Wed Sep  1 18:02:00 2010
@@ -15,6 +15,12 @@
 HAVE_LANGINFO = sys.platform != 'win32'
 HAVE_LIBINTL  = sys.platform != 'win32'
 
+if HAVE_LIBINTL:
+    try:
+        platform.verify_eci(ExternalCompilationInfo(includes=['libintl.h']))
+    except platform.CompilationError:
+        HAVE_LIBINTL = False
+
 class CConfig:
     includes = ['locale.h', 'limits.h']
 

Modified: pypy/branch/jit-bounds/pypy/rpython/memory/gc/markcompact.py
==============================================================================
--- pypy/branch/jit-bounds/pypy/rpython/memory/gc/markcompact.py	(original)
+++ pypy/branch/jit-bounds/pypy/rpython/memory/gc/markcompact.py	Wed Sep  1 18:02:00 2010
@@ -3,7 +3,8 @@
 
 from pypy.rpython.lltypesystem import lltype, llmemory, llarena, llgroup
 from pypy.rpython.memory.gc.base import MovingGCBase
-from pypy.rlib.debug import ll_assert
+from pypy.rlib.debug import ll_assert, have_debug_prints
+from pypy.rlib.debug import debug_print, debug_start, debug_stop
 from pypy.rpython.memory.support import DEFAULT_CHUNK_SIZE
 from pypy.rpython.memory.support import get_address_stack, get_address_deque
 from pypy.rpython.memory.support import AddressDict
@@ -98,8 +99,7 @@
         self.space_size = self.param_space_size
         self.next_collect_after = self.param_space_size/2 # whatever...
 
-        if self.config.gcconfig.debugprint:
-            self.program_start_time = time.time()
+        self.program_start_time = time.time()
         self.space = llarena.arena_malloc(self.space_size, True)
         ll_assert(bool(self.space), "couldn't allocate arena")
         self.free = self.space
@@ -289,15 +289,16 @@
         return weakref_offsets
 
     def debug_collect_start(self):
-        if self.config.gcconfig.debugprint:
-            llop.debug_print(lltype.Void)
-            llop.debug_print(lltype.Void,
-                             ".----------- Full collection ------------------")
+        if have_debug_prints():
+            debug_start("gc-collect")
+            debug_print()
+            debug_print(".----------- Full collection ------------------")
             start_time = time.time()
-            return start_time 
+            return start_time
+        return -1
 
     def debug_collect_finish(self, start_time):
-        if self.config.gcconfig.debugprint:
+        if start_time != -1:
             end_time = time.time()
             elapsed_time = end_time - start_time
             self.total_collection_time += elapsed_time
@@ -305,20 +306,16 @@
             total_program_time = end_time - self.program_start_time
             ct = self.total_collection_time
             cc = self.total_collection_count
-            llop.debug_print(lltype.Void,
-                             "| number of collections so far       ", 
-                             cc)
-            llop.debug_print(lltype.Void,
-                             "| total collections per second:      ",
-                             cc / total_program_time)
-            llop.debug_print(lltype.Void,
-                             "| total time in markcompact-collect: ",
-                             ct, "seconds")
-            llop.debug_print(lltype.Void,
-                             "| percentage collection<->total time:",
-                             ct * 100.0 / total_program_time, "%")
-            llop.debug_print(lltype.Void,
-                             "`----------------------------------------------")
+            debug_print("| number of collections so far       ", 
+                        cc)
+            debug_print("| total collections per second:      ",
+                        cc / total_program_time)
+            debug_print("| total time in markcompact-collect: ",
+                        ct, "seconds")
+            debug_print("| percentage collection<->total time:",
+                        ct * 100.0 / total_program_time, "%")
+            debug_print("`----------------------------------------------")
+            debug_stop("gc-collect")
 
 
     def update_run_finalizers(self):

Modified: pypy/branch/jit-bounds/pypy/tool/runsubprocess.py
==============================================================================
--- pypy/branch/jit-bounds/pypy/tool/runsubprocess.py	(original)
+++ pypy/branch/jit-bounds/pypy/tool/runsubprocess.py	Wed Sep  1 18:02:00 2010
@@ -70,5 +70,5 @@
         assert results.startswith('(')
         results = eval(results)
         if results[0] is None:
-            raise OSError(results[1])
+            raise OSError('%s: %s' % (args[0], results[1]))
         return results

Modified: pypy/branch/jit-bounds/pypy/translator/c/test/test_standalone.py
==============================================================================
--- pypy/branch/jit-bounds/pypy/translator/c/test/test_standalone.py	(original)
+++ pypy/branch/jit-bounds/pypy/translator/c/test/test_standalone.py	Wed Sep  1 18:02:00 2010
@@ -604,6 +604,33 @@
         out, err = cbuilder.cmdexec("a b")
         assert out == "3"
 
+    def test_gcc_options(self):
+        # check that the env var CC is correctly interpreted, even if
+        # it contains the compiler name followed by some options.
+        if sys.platform == 'win32':
+            py.test.skip("only for gcc")
+
+        from pypy.rpython.lltypesystem import lltype, rffi
+        dir = udir.ensure('test_gcc_options', dir=1)
+        dir.join('someextraheader.h').write('#define someextrafunc() 42\n')
+        eci = ExternalCompilationInfo(includes=['someextraheader.h'])
+        someextrafunc = rffi.llexternal('someextrafunc', [], lltype.Signed,
+                                        compilation_info=eci)
+
+        def entry_point(argv):
+            return someextrafunc()
+
+        old_cc = os.environ.get('CC')
+        try:
+            os.environ['CC'] = 'gcc -I%s' % dir
+            t, cbuilder = self.compile(entry_point)
+        finally:
+            if old_cc is None:
+                del os.environ['CC']
+            else:
+                os.environ['CC'] = old_cc
+
+
 class TestMaemo(TestStandalone):
     def setup_class(cls):
         py.test.skip("TestMaemo: tests skipped for now")

Modified: pypy/branch/jit-bounds/pypy/translator/goal/app_main.py
==============================================================================
--- pypy/branch/jit-bounds/pypy/translator/goal/app_main.py	(original)
+++ pypy/branch/jit-bounds/pypy/translator/goal/app_main.py	Wed Sep  1 18:02:00 2010
@@ -292,8 +292,8 @@
         else:
             raise CommandLineError('unrecognized option %r' % (arg,))
         i += 1
-    sys.argv = argv[i:]
-    if not sys.argv:
+    sys.argv[:] = argv[i:]    # don't change the list that sys.argv is bound to
+    if not sys.argv:          # (relevant in case of "reload(sys)")
         sys.argv.append('')
         run_stdin = True
     return locals()
@@ -478,6 +478,10 @@
         reset.append(('PYTHONINSPECT', os.environ.get('PYTHONINSPECT', '')))
         os.environ['PYTHONINSPECT'] = os.environ['PYTHONINSPECT_']
 
+    # no one should change to which lists sys.argv and sys.path are bound
+    old_argv = sys.argv
+    old_path = sys.path
+
     from pypy.module.sys.version import PYPY_VERSION
     sys.pypy_version_info = PYPY_VERSION
     sys.pypy_initial_path = pypy_initial_path
@@ -490,3 +494,5 @@
         sys.ps1 = '>>> '     # restore the normal ones, in case
         sys.ps2 = '... '     # we are dropping to CPython's prompt
         import os; os.environ.update(reset)
+        assert old_argv is sys.argv
+        assert old_path is sys.path

Modified: pypy/branch/jit-bounds/pypy/translator/goal/test2/test_app_main.py
==============================================================================
--- pypy/branch/jit-bounds/pypy/translator/goal/test2/test_app_main.py	(original)
+++ pypy/branch/jit-bounds/pypy/translator/goal/test2/test_app_main.py	Wed Sep  1 18:02:00 2010
@@ -1,6 +1,7 @@
 """
 Tests for the entry point of pypy-c, app_main.py.
 """
+from __future__ import with_statement
 import py
 import sys, os, re
 import autopath

Modified: pypy/branch/jit-bounds/pypy/translator/goal/translate.py
==============================================================================
--- pypy/branch/jit-bounds/pypy/translator/goal/translate.py	(original)
+++ pypy/branch/jit-bounds/pypy/translator/goal/translate.py	Wed Sep  1 18:02:00 2010
@@ -18,7 +18,7 @@
                                ArbitraryOption, StrOption, IntOption, Config, \
                                ChoiceOption, OptHelpFormatter
 from pypy.config.translationoption import get_combined_translation_config
-from pypy.config.translationoption import set_opt_level
+from pypy.config.translationoption import set_opt_level, final_check_config
 from pypy.config.translationoption import OPT_LEVELS, DEFAULT_OPT_LEVEL
 from pypy.config.translationoption import PLATFORMS, set_platform
 
@@ -175,6 +175,9 @@
     if 'handle_config' in targetspec_dic:
         targetspec_dic['handle_config'](config, translateconfig)
 
+    # perform checks (if any) on the final config
+    final_check_config(config)
+
     if translateconfig.help:
         opt_parser.print_help()
         if 'print_help' in targetspec_dic:

Modified: pypy/branch/jit-bounds/pypy/translator/platform/__init__.py
==============================================================================
--- pypy/branch/jit-bounds/pypy/translator/platform/__init__.py	(original)
+++ pypy/branch/jit-bounds/pypy/translator/platform/__init__.py	Wed Sep  1 18:02:00 2010
@@ -99,15 +99,20 @@
                 self.__dict__ == other.__dict__)
 
     def key(self):
-        bits = [self.__class__.__name__, 'cc=%s' % self.cc]
+        bits = [self.__class__.__name__, 'cc=%r' % self.cc]
         for varname in self.relevant_environ:
-            bits.append('%s=%s' % (varname, os.environ.get(varname)))
+            bits.append('%s=%r' % (varname, os.environ.get(varname)))
         return ' '.join(bits)
 
     # some helpers which seem to be cross-platform enough
 
     def _execute_c_compiler(self, cc, args, outname, cwd=None):
         log.execute(cc + ' ' + ' '.join(args))
+        # 'cc' can also contain some options for the C compiler;
+        # e.g. it can be "gcc -m32".  We handle it by splitting on ' '.
+        cclist = cc.split()
+        cc = cclist[0]
+        args = cclist[1:] + args
         returncode, stdout, stderr = _run_subprocess(cc, args, self.c_environ,
                                                      cwd)
         self._handle_error(returncode, stderr, stdout, outname)

Modified: pypy/branch/jit-bounds/pypy/translator/platform/test/test_platform.py
==============================================================================
--- pypy/branch/jit-bounds/pypy/translator/platform/test/test_platform.py	(original)
+++ pypy/branch/jit-bounds/pypy/translator/platform/test/test_platform.py	Wed Sep  1 18:02:00 2010
@@ -131,7 +131,7 @@
                 self.cc = 'xcc'
         x = XPlatform()
         res = x.key()
-        assert res.startswith('XPlatform cc=xcc CPATH=')
+        assert res.startswith("XPlatform cc='xcc' CPATH=")
 
 def test_equality():
     class X(Platform):



More information about the Pypy-commit mailing list