[pypy-commit] pypy py3k: merge default

pjenvey noreply at buildbot.pypy.org
Wed Aug 14 02:22:37 CEST 2013


Author: Philip Jenvey <pjenvey at underboss.org>
Branch: py3k
Changeset: r66136:2822f8aa1a49
Date: 2013-08-13 17:20 -0700
http://bitbucket.org/pypy/pypy/changeset/2822f8aa1a49/

Log:	merge default

diff --git a/dotviewer/graphparse.py b/dotviewer/graphparse.py
--- a/dotviewer/graphparse.py
+++ b/dotviewer/graphparse.py
@@ -152,7 +152,8 @@
         try:
             plaincontent = dot2plain_graphviz(content, contenttype)
         except PlainParseError, e:
-            print e
-            # failed, retry via codespeak
-            plaincontent = dot2plain_codespeak(content, contenttype)
+            raise
+            ##print e
+            ### failed, retry via codespeak
+            ##plaincontent = dot2plain_codespeak(content, contenttype)
     return list(parse_plain(graph_id, plaincontent, links, fixedfont))
diff --git a/pypy/module/__pypy__/test/test_signal.py b/pypy/module/__pypy__/test/test_signal.py
--- a/pypy/module/__pypy__/test/test_signal.py
+++ b/pypy/module/__pypy__/test/test_signal.py
@@ -28,6 +28,7 @@
         import __pypy__, _thread, signal, time, sys
 
         def subthread():
+            print('subthread started')
             try:
                 with __pypy__.thread.signals_enabled:
                     _thread.interrupt_main()
diff --git a/pypy/module/micronumpy/__init__.py b/pypy/module/micronumpy/__init__.py
--- a/pypy/module/micronumpy/__init__.py
+++ b/pypy/module/micronumpy/__init__.py
@@ -140,6 +140,7 @@
         ("deg2rad", "radians"),
         ("rad2deg", "degrees"),
         ("reciprocal", "reciprocal"),
+        ("rint", "rint"),
         ("sign", "sign"),
         ("signbit", "signbit"),
         ("sin", "sin"),
@@ -175,6 +176,8 @@
         ('logaddexp2', 'logaddexp2'),
         ('real', 'real'),
         ('imag', 'imag'),
+        ('ones_like', 'ones_like'),
+        ('zeros_like', 'zeros_like'),
     ]:
         interpleveldefs[exposed] = "interp_ufuncs.get(space).%s" % impl
 
diff --git a/pypy/module/micronumpy/interp_ufuncs.py b/pypy/module/micronumpy/interp_ufuncs.py
--- a/pypy/module/micronumpy/interp_ufuncs.py
+++ b/pypy/module/micronumpy/interp_ufuncs.py
@@ -615,6 +615,7 @@
             ("positive", "pos", 1),
             ("negative", "neg", 1),
             ("absolute", "abs", 1, {"complex_to_float": True}),
+            ("rint", "rint", 1),
             ("sign", "sign", 1, {"promote_bools": True}),
             ("signbit", "signbit", 1, {"bool_result": True,
                                        "allow_complex": False}),
@@ -670,6 +671,8 @@
                                        "allow_complex": False}),
             ("logaddexp2", "logaddexp2", 2, {"promote_to_float": True,
                                        "allow_complex": False}),
+            ("ones_like", "ones_like", 1),
+            ("zeros_like", "zeros_like", 1),
         ]:
             self.add_ufunc(space, *ufunc_def)
 
diff --git a/pypy/module/micronumpy/test/test_ufuncs.py b/pypy/module/micronumpy/test/test_ufuncs.py
--- a/pypy/module/micronumpy/test/test_ufuncs.py
+++ b/pypy/module/micronumpy/test/test_ufuncs.py
@@ -255,6 +255,22 @@
         for i in range(3):
             assert c[i] == a[i] * b[i]
 
+    def test_rint(self):
+        from numpypy import array, complex, rint, isnan
+
+        nnan, nan, inf, ninf = float('-nan'), float('nan'), float('inf'), float('-inf')
+
+        reference = array([ninf, -2., -1., -0., 0., 0., 0., 1., 2., inf])
+        a = array([ninf, -1.5, -1., -0.5, -0., 0., 0.5, 1., 1.5, inf])
+        b = rint(a)
+        for i in range(len(a)):
+            assert b[i] == reference[i]
+        assert isnan(rint(nan))
+        assert isnan(rint(nnan))
+
+        assert rint(complex(inf, 1.5)) == complex(inf, 2.)
+        assert rint(complex(0.5, inf)) == complex(0., inf)
+
     def test_sign(self):
         from numpypy import array, sign, dtype
 
@@ -939,4 +955,18 @@
         assert logaddexp2(float('inf'), float('-inf')) == float('inf')
         assert logaddexp2(float('inf'), float('inf')) == float('inf')
 
+    def test_ones_like(self):
+        from numpypy import array, ones_like
 
+        assert ones_like(False) == array(True)
+        assert ones_like(2) == array(1)
+        assert ones_like(2.) == array(1.)
+        assert ones_like(complex(2)) == array(complex(1))
+
+    def test_zeros_like(self):
+        from numpypy import array, zeros_like
+
+        assert zeros_like(True) == array(False)
+        assert zeros_like(2) == array(0)
+        assert zeros_like(2.) == array(0.)
+        assert zeros_like(complex(2)) == array(complex(0))
diff --git a/pypy/module/micronumpy/types.py b/pypy/module/micronumpy/types.py
--- a/pypy/module/micronumpy/types.py
+++ b/pypy/module/micronumpy/types.py
@@ -307,6 +307,22 @@
     def min(self, v1, v2):
         return min(v1, v2)
 
+    @simple_unary_op
+    def rint(self, v):
+        if isfinite(v):
+            return rfloat.round_double(v, 0, half_even=True)
+        else:
+            return v
+
+    @simple_unary_op
+    def ones_like(self, v):
+        return 1
+
+    @simple_unary_op
+    def zeros_like(self, v):
+        return 0
+
+
 class NonNativePrimitive(Primitive):
     _mixin_ = True
 
@@ -1392,11 +1408,14 @@
     def round(self, v, decimals=0):
         ans = list(self.for_computation(self.unbox(v)))
         if isfinite(ans[0]):
-            ans[0] = rfloat.round_double(ans[0], decimals,  half_even=True)
+            ans[0] = rfloat.round_double(ans[0], decimals, half_even=True)
         if isfinite(ans[1]):
-            ans[1] = rfloat.round_double(ans[1], decimals,  half_even=True)
+            ans[1] = rfloat.round_double(ans[1], decimals, half_even=True)
         return self.box_complex(ans[0], ans[1])
 
+    def rint(self, v):
+        return self.round(v)
+
     # No floor, ceil, trunc in numpy for complex
     #@simple_unary_op
     #def floor(self, v):
@@ -1599,6 +1618,15 @@
         except ValueError:
             return rfloat.NAN, rfloat.NAN
 
+    @complex_unary_op
+    def ones_like(self, v):
+        return 1, 0
+
+    @complex_unary_op
+    def zeros_like(self, v):
+        return 0, 0
+
+
 class Complex64(ComplexFloating, BaseType):
     _attrs_ = ()
 
diff --git a/pypy/module/posix/interp_posix.py b/pypy/module/posix/interp_posix.py
--- a/pypy/module/posix/interp_posix.py
+++ b/pypy/module/posix/interp_posix.py
@@ -725,11 +725,16 @@
     for hook in get_fork_hooks(where):
         hook(space)
 
-def fork(space):
+def _run_forking_function(space, kind):
     run_fork_hooks('before', space)
-
     try:
-        pid = os.fork()
+        if kind == "F":
+            pid = os.fork()
+            master_fd = -1
+        elif kind == "P":
+            pid, master_fd = os.forkpty()
+        else:
+            raise AssertionError
     except OSError, e:
         try:
             run_fork_hooks('parent', space)
@@ -737,12 +742,14 @@
             # Don't clobber the OSError if the fork failed
             pass
         raise wrap_oserror(space, e)
-
     if pid == 0:
         run_fork_hooks('child', space)
     else:
         run_fork_hooks('parent', space)
+    return pid, master_fd
 
+def fork(space):
+    pid, irrelevant = _run_forking_function(space, "F")
     return space.wrap(pid)
 
 def openpty(space):
@@ -754,10 +761,7 @@
     return space.newtuple([space.wrap(master_fd), space.wrap(slave_fd)])
 
 def forkpty(space):
-    try:
-        pid, master_fd = os.forkpty()
-    except OSError, e:
-        raise wrap_oserror(space, e)
+    pid, master_fd = _run_forking_function(space, "P")
     return space.newtuple([space.wrap(pid),
                            space.wrap(master_fd)])
 
diff --git a/pypy/tool/jitlogparser/parser.py b/pypy/tool/jitlogparser/parser.py
--- a/pypy/tool/jitlogparser/parser.py
+++ b/pypy/tool/jitlogparser/parser.py
@@ -85,7 +85,7 @@
                     continue
                 e = elem.split("\t")
                 adr = e[0]
-                v = " ".join(e[2:])
+                v = elem   # --- more compactly:  " ".join(e[2:])
                 if not start:
                     start = int(adr.strip(":"), 16)
                 ofs = int(adr.strip(":"), 16) - start
@@ -379,15 +379,16 @@
             name = entry[:entry.find('(') - 1].lower()
             addr = int(m.group(1), 16)
         addrs.setdefault(addr, []).append(name)
+    from rpython.jit.backend.tool.viewcode import World
+    world = World()
+    for entry in extract_category(log, 'jit-backend-dump'):
+        world.parse(entry.splitlines(True), truncate_addr=False)
     dumps = {}
-    for entry in extract_category(log, 'jit-backend-dump'):
-        backend, _, dump, _ = entry.split("\n")
-        _, addr, _, data = re.split(" +", dump)
-        backend_name = backend.split(" ")[1]
-        addr = int(addr[1:], 16)
-        if addr in addrs and addrs[addr]:
-            name = addrs[addr].pop(0) # they should come in order
-            dumps[name] = (backend_name, addr, data)
+    for r in world.ranges:
+        if r.addr in addrs and addrs[r.addr]:
+            name = addrs[r.addr].pop(0) # they should come in order
+            data = r.data.encode('hex')       # backward compatibility
+            dumps[name] = (world.backend_name, r.addr, data)
     loops = []
     for entry in extract_category(log, 'jit-log-opt'):
         parser = ParserCls(entry, None, {}, 'lltype', None,
diff --git a/rpython/jit/backend/arm/assembler.py b/rpython/jit/backend/arm/assembler.py
--- a/rpython/jit/backend/arm/assembler.py
+++ b/rpython/jit/backend/arm/assembler.py
@@ -62,20 +62,21 @@
         self.current_clt = looptoken.compiled_loop_token
         self.mc = InstrBuilder(self.cpu.cpuinfo.arch_version)
         self.pending_guards = []
-        assert self.datablockwrapper is None
+        #assert self.datablockwrapper is None --- but obscure case
+        # possible, e.g. getting MemoryError and continuing
         allblocks = self.get_asmmemmgr_blocks(looptoken)
         self.datablockwrapper = MachineDataBlockWrapper(self.cpu.asmmemmgr,
                                                         allblocks)
         self.mc.datablockwrapper = self.datablockwrapper
         self.target_tokens_currently_compiling = {}
         self.frame_depth_to_patch = []
+        self._finish_gcmap = lltype.nullptr(jitframe.GCMAP)
 
     def teardown(self):
         self.current_clt = None
         self._regalloc = None
         self.mc = None
         self.pending_guards = None
-        assert self.datablockwrapper is None
 
     def setup_failure_recovery(self):
         self.failure_recovery_code = [0, 0, 0, 0]
@@ -889,7 +890,7 @@
             relative_offset = tok.pos_recovery_stub - tok.offset
             guard_pos = block_start + tok.offset
             if not tok.is_guard_not_invalidated:
-                # patch the guard jumpt to the stub
+                # patch the guard jump to the stub
                 # overwrite the generate NOP with a B_offs to the pos of the
                 # stub
                 mc = InstrBuilder(self.cpu.cpuinfo.arch_version)
diff --git a/rpython/jit/backend/arm/opassembler.py b/rpython/jit/backend/arm/opassembler.py
--- a/rpython/jit/backend/arm/opassembler.py
+++ b/rpython/jit/backend/arm/opassembler.py
@@ -33,6 +33,7 @@
 from rpython.rtyper.lltypesystem import rstr, rffi, lltype
 from rpython.rtyper.annlowlevel import cast_instance_to_gcref
 from rpython.jit.backend.arm import callbuilder
+from rpython.rlib.rarithmetic import r_uint
 
 
 class ArmGuardToken(GuardToken):
@@ -190,7 +191,7 @@
         self.mc.RSB_ri(resloc.value, l0.value, imm=0)
         return fcond
 
-    def _emit_guard(self, op, arglocs, fcond, save_exc,
+    def build_guard_token(self, op, frame_depth, arglocs, offset, fcond, save_exc,
                                     is_guard_not_invalidated=False,
                                     is_guard_not_forced=False):
         assert isinstance(save_exc, bool)
@@ -198,7 +199,27 @@
         descr = op.getdescr()
         assert isinstance(descr, AbstractFailDescr)
 
+        gcmap = allocate_gcmap(self, frame_depth, JITFRAME_FIXED_SIZE)
+        token = ArmGuardToken(self.cpu, gcmap,
+                                    descr,
+                                    failargs=op.getfailargs(),
+                                    fail_locs=arglocs,
+                                    offset=offset,
+                                    exc=save_exc,
+                                    frame_depth=frame_depth,
+                                    is_guard_not_invalidated=is_guard_not_invalidated,
+                                    is_guard_not_forced=is_guard_not_forced,
+                                    fcond=fcond)
+        return token
+
+    def _emit_guard(self, op, arglocs, fcond, save_exc,
+                                    is_guard_not_invalidated=False,
+                                    is_guard_not_forced=False):
         pos = self.mc.currpos()
+        token = self.build_guard_token(op, arglocs[0].value, arglocs[1:], pos, fcond, save_exc,
+                                        is_guard_not_invalidated,
+                                        is_guard_not_forced)
+        self.pending_guards.append(token)
         # For all guards that are not GUARD_NOT_INVALIDATED we emit a
         # breakpoint to ensure the location is patched correctly. In the case
         # of GUARD_NOT_INVALIDATED we use just a NOP, because it is only
@@ -207,17 +228,6 @@
             self.mc.NOP()
         else:
             self.mc.BKPT()
-        gcmap = allocate_gcmap(self, arglocs[0].value, JITFRAME_FIXED_SIZE)
-        self.pending_guards.append(ArmGuardToken(self.cpu, gcmap,
-                                    descr,
-                                    failargs=op.getfailargs(),
-                                    fail_locs=arglocs[1:],
-                                    offset=pos,
-                                    exc=save_exc,
-                                    frame_depth=arglocs[0].value,
-                                    is_guard_not_invalidated=is_guard_not_invalidated,
-                                    is_guard_not_forced=is_guard_not_forced,
-                                    fcond=fcond))
         return c.AL
 
     def _emit_guard_overflow(self, guard, failargs, fcond):
@@ -351,7 +361,11 @@
         # XXX self.mov(fail_descr_loc, RawStackLoc(ofs))
         self.store_reg(self.mc, r.ip, r.fp, ofs, helper=r.lr)
         if op.numargs() > 0 and op.getarg(0).type == REF:
-            gcmap = self.gcmap_for_finish
+            if self._finish_gcmap:
+                self._finish_gcmap[0] |= r_uint(0) # r0
+                gcmap = self._finish_gcmap
+            else:
+                gcmap = self.gcmap_for_finish
             self.push_gcmap(self.mc, gcmap, store=True)
         else:
             # note that the 0 here is redundant, but I would rather
@@ -912,6 +926,14 @@
 
         return fcond
 
+    def store_force_descr(self, op, fail_locs, frame_depth):
+        pos = self.mc.currpos()
+        guard_token = self.build_guard_token(op, frame_depth, fail_locs, pos, c.AL, True, False, True)
+        #self.pending_guards.append(guard_token)
+        self._finish_gcmap = guard_token.gcmap
+        self._store_force_index(op)
+        self.store_info_on_descr(pos, guard_token)
+
     def emit_op_force_token(self, op, arglocs, regalloc, fcond):
         # XXX kill me
         res_loc = arglocs[0]
diff --git a/rpython/jit/backend/arm/regalloc.py b/rpython/jit/backend/arm/regalloc.py
--- a/rpython/jit/backend/arm/regalloc.py
+++ b/rpython/jit/backend/arm/regalloc.py
@@ -1194,6 +1194,12 @@
         #    self._compute_hint_frame_locations_from_descr(descr)
         return []
 
+    def prepare_op_guard_not_forced_2(self, op, fcond):
+        self.rm.before_call(op.getfailargs(), save_all_regs=True)
+        fail_locs = self._prepare_guard(op)
+        self.assembler.store_force_descr(op, fail_locs[1:], fail_locs[0].value)
+        self.possibly_free_vars(op.getfailargs())
+
     def prepare_guard_call_may_force(self, op, guard_op, fcond):
         args = self._prepare_call(op, save_all_regs=True)
         return self._prepare_guard(guard_op, args)
diff --git a/rpython/jit/backend/tool/viewcode.py b/rpython/jit/backend/tool/viewcode.py
--- a/rpython/jit/backend/tool/viewcode.py
+++ b/rpython/jit/backend/tool/viewcode.py
@@ -51,18 +51,18 @@
     raise ObjdumpNotFound('(g)objdump was not found in PATH')
 
 def machine_code_dump(data, originaddr, backend_name, label_list=None):
-    objdump_backend_option = {
+    objdump_machine_option = {
         'x86': 'i386',
         'x86-without-sse2': 'i386',
         'x86_32': 'i386',
-        'x86_64': 'x86-64',
-        'x86-64': 'x86-64',
+        'x86_64': 'i386:x86-64',
+        'x86-64': 'i386:x86-64',
         'i386': 'i386',
         'arm': 'arm',
         'arm_32': 'arm',
     }
     cmd = find_objdump()
-    objdump = ('%(command)s -M %(backend)s -b binary -m %(machine)s '
+    objdump = ('%(command)s -b binary -m %(machine)s '
                '--disassembler-options=intel-mnemonics '
                '--adjust-vma=%(origin)d -D %(file)s')
     #
@@ -73,8 +73,7 @@
         'command': cmd,
         'file': tmpfile,
         'origin': originaddr,
-        'backend': objdump_backend_option[backend_name],
-        'machine': 'i386' if not backend_name.startswith('arm') else 'arm',
+        'machine': objdump_machine_option[backend_name],
     }, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
     stdout, stderr = p.communicate()
     assert not p.returncode, ('Encountered an error running objdump: %s' %
@@ -250,7 +249,9 @@
                 assert pieces[2].startswith('+')
                 if len(pieces) == 3:
                     continue     # empty line
-                baseaddr = long(pieces[1][1:], 16) & 0xFFFFFFFFL
+                baseaddr = long(pieces[1][1:], 16)
+                if baseaddr < 0:
+                    baseaddr += (2 * sys.maxint + 2)
                 offset = int(pieces[2][1:])
                 addr = baseaddr + offset
                 data = pieces[3].replace(':', '').decode('hex')
@@ -268,14 +269,19 @@
                 pieces = line.split(None, 3)
                 assert pieces[1].startswith('@')
                 assert pieces[2].startswith('+')
-                baseaddr = long(pieces[1][1:], 16) & 0xFFFFFFFFL
+                baseaddr = long(pieces[1][1:], 16)
+                if baseaddr < 0:
+                    baseaddr += (2 * sys.maxint + 2)
                 offset = int(pieces[2][1:])
                 addr = baseaddr + offset
                 self.logentries[addr] = pieces[3]
             elif line.startswith('SYS_EXECUTABLE '):
                 filename = line[len('SYS_EXECUTABLE '):].strip()
                 if filename != self.executable_name and filename != '??':
-                    self.symbols.update(load_symbols(filename))
+                    try:
+                        self.symbols.update(load_symbols(filename))
+                    except Exception as e:
+                        print e
                     self.executable_name = filename
 
     def find_cross_references(self):
diff --git a/rpython/jit/metainterp/typesystem.py b/rpython/jit/metainterp/typesystem.py
--- a/rpython/jit/metainterp/typesystem.py
+++ b/rpython/jit/metainterp/typesystem.py
@@ -52,7 +52,10 @@
         return FUNCTYPE, FUNCPTRTYPE
 
     def get_superclass(self, TYPE):
-        return lltype.Ptr(TYPE.TO._first_struct()[1])
+        SUPER = TYPE.TO._first_struct()[1]
+        if SUPER is None:
+            return None
+        return lltype.Ptr(SUPER)
 
     def cast_to_instance_maybe(self, TYPE, instance):
         return lltype.cast_pointer(TYPE, instance)
diff --git a/rpython/jit/metainterp/virtualizable.py b/rpython/jit/metainterp/virtualizable.py
--- a/rpython/jit/metainterp/virtualizable.py
+++ b/rpython/jit/metainterp/virtualizable.py
@@ -17,8 +17,14 @@
         self.cpu = cpu
         self.BoxArray = cpu.ts.BoxRef
         #
+        VTYPEPTR1 = VTYPEPTR
         while 'virtualizable_accessor' not in deref(VTYPEPTR)._hints:
             VTYPEPTR = cpu.ts.get_superclass(VTYPEPTR)
+            assert VTYPEPTR is not None, (
+                "%r is listed in the jit driver's 'virtualizables', "
+                "but that class doesn't have a '_virtualizable_' attribute "
+                "(if it has _virtualizable2_, rename it to _virtualizable_)"
+                % (VTYPEPTR1,))
         self.VTYPEPTR = VTYPEPTR
         self.VTYPE = VTYPE = deref(VTYPEPTR)
         self.vable_token_descr = cpu.fielddescrof(VTYPE, 'vable_token')
diff --git a/rpython/memory/gc/env.py b/rpython/memory/gc/env.py
--- a/rpython/memory/gc/env.py
+++ b/rpython/memory/gc/env.py
@@ -131,13 +131,8 @@
 
 # ---------- Linux2 ----------
 
-try:
-    ARCH = os.uname()[4]  # machine
-except (OSError, AttributeError):
-    ARCH = ''
-
 def get_L2cache_linux2():
-    arch = ARCH      # precomputed; the call to os.uname() is not translated
+    arch = os.uname()[4]  # machine
     if arch.endswith('86') or arch == 'x86_64':
         return get_L2cache_linux2_cpuinfo()
     if arch in ('alpha', 'ppc', 'ppc64'):
diff --git a/rpython/memory/gc/minimark.py b/rpython/memory/gc/minimark.py
--- a/rpython/memory/gc/minimark.py
+++ b/rpython/memory/gc/minimark.py
@@ -2046,6 +2046,8 @@
     # The code relies on the fact that no weakref can be an old object
     # weakly pointing to a young object.  Indeed, weakrefs are immutable
     # so they cannot point to an object that was created after it.
+    # Thanks to this, during a minor collection, we don't have to fix
+    # or clear the address stored in old weakrefs.
     def invalidate_young_weakrefs(self):
         """Called during a nursery collection."""
         # walk over the list of objects that contain weakrefs and are in the
diff --git a/rpython/rlib/streamio.py b/rpython/rlib/streamio.py
--- a/rpython/rlib/streamio.py
+++ b/rpython/rlib/streamio.py
@@ -558,19 +558,22 @@
             if -self.pos <= difpos <= currentsize:
                 self.pos += difpos
                 return
-            self.buf = ""
-            self.pos = 0
             if whence == 1:
                 offset -= currentsize
             try:
                 self.do_seek(offset, whence)
             except MyNotImplementedError:
+                self.buf = ""
+                self.pos = 0
                 if difpos < 0:
                     raise
                 if whence == 0:
                     offset = difpos - currentsize
                 intoffset = offset2int(offset)
                 self.read(intoffset)
+            else:
+                self.buf = ""
+                self.pos = 0
             return
         if whence == 2:
             try:
diff --git a/rpython/rtyper/module/ll_os.py b/rpython/rtyper/module/ll_os.py
--- a/rpython/rtyper/module/ll_os.py
+++ b/rpython/rtyper/module/ll_os.py
@@ -1574,6 +1574,7 @@
                                   _nowrapper = True)
 
         def fork_llimpl():
+            # NB. keep forkpty() up-to-date, too
             opaqueaddr = rthread.gc_thread_before_fork()
             childpid = rffi.cast(lltype.Signed, os_fork())
             rthread.gc_thread_after_fork(childpid, opaqueaddr)
@@ -1609,6 +1610,7 @@
 
     @registering_if(os, 'forkpty')
     def register_os_forkpty(self):
+        from rpython.rlib import rthread
         os_forkpty = self.llexternal(
             'forkpty',
             [rffi.INTP, rffi.VOIDP, rffi.VOIDP, rffi.VOIDP],
@@ -1616,7 +1618,11 @@
             compilation_info=ExternalCompilationInfo(libraries=['util']))
         def forkpty_llimpl():
             master_p = lltype.malloc(rffi.INTP.TO, 1, flavor='raw')
-            childpid = os_forkpty(master_p, None, None, None)
+            master_p[0] = rffi.cast(rffi.INT, -1)
+            opaqueaddr = rthread.gc_thread_before_fork()
+            childpid = rffi.cast(lltype.Signed,
+                                 os_forkpty(master_p, None, None, None))
+            rthread.gc_thread_after_fork(childpid, opaqueaddr)
             master_fd = master_p[0]
             lltype.free(master_p, flavor='raw')
             if childpid == -1:
diff --git a/rpython/tool/logparser.py b/rpython/tool/logparser.py
--- a/rpython/tool/logparser.py
+++ b/rpython/tool/logparser.py
@@ -133,6 +133,8 @@
     def rectime(category1, timestart1, timestop1, subcats):
         substartstop = []
         for entry in getsubcategories(subcats):
+            if len(entry) != 4:
+                continue
             rectime(*entry)
             substartstop.append(entry[1:3])   # (start, stop)
         # compute the total time for category1 as the part of the
@@ -238,7 +240,11 @@
     #
     def recdraw(sublist, subheight):
         firstx1 = None
-        for category1, timestart1, timestop1, subcats in sublist:
+        for entry in sublist:
+            try:
+                category1, timestart1, timestop1, subcats = entry
+            except ValueError:
+                continue
             x1 = int((timestart1 - timestart0) * timefactor)
             x2 = int((timestop1 - timestart0) * timefactor)
             y1 = (height - subheight) / 2


More information about the pypy-commit mailing list