[pypy-commit] pypy gc-counters: merge default

fijal noreply at buildbot.pypy.org
Tue Dec 23 14:50:12 CET 2014


Author: Maciej Fijalkowski <fijall at gmail.com>
Branch: gc-counters
Changeset: r75078:690400327627
Date: 2014-12-23 15:48 +0200
http://bitbucket.org/pypy/pypy/changeset/690400327627/

Log:	merge default

diff --git a/pypy/module/_cffi_backend/test/_backend_test_c.py b/pypy/module/_cffi_backend/test/_backend_test_c.py
--- a/pypy/module/_cffi_backend/test/_backend_test_c.py
+++ b/pypy/module/_cffi_backend/test/_backend_test_c.py
@@ -397,7 +397,7 @@
 def test_invalid_indexing():
     p = new_primitive_type("int")
     x = cast(p, 42)
-    py.test.raises(TypeError, "p[0]")
+    py.test.raises(TypeError, "x[0]")
 
 def test_default_str():
     BChar = new_primitive_type("char")
diff --git a/pypy/module/gc/__init__.py b/pypy/module/gc/__init__.py
--- a/pypy/module/gc/__init__.py
+++ b/pypy/module/gc/__init__.py
@@ -31,6 +31,7 @@
                 'get_referrers': 'referents.get_referrers',
                 '_dump_rpy_heap': 'referents._dump_rpy_heap',
                 'get_typeids_z': 'referents.get_typeids_z',
+                'get_typeids_list': 'referents.get_typeids_list',
                 'GcRef': 'referents.W_GcRef',
                 })
         MixedModule.__init__(self, space, w_name)
diff --git a/pypy/module/gc/app_referents.py b/pypy/module/gc/app_referents.py
--- a/pypy/module/gc/app_referents.py
+++ b/pypy/module/gc/app_referents.py
@@ -16,7 +16,8 @@
     [0][0][0][-1] inserted after all GC roots, before all non-roots.
 
     If the argument is a filename and the 'zlib' module is available,
-    we also write a 'typeids.txt' in the same directory, if none exists.
+    we also write 'typeids.txt' and 'typeids.lst' in the same directory,
+    if they don't already exist.
     """
     if isinstance(file, str):
         f = open(file, 'wb')
@@ -30,7 +31,13 @@
             filename2 = os.path.join(os.path.dirname(file), 'typeids.txt')
             if not os.path.exists(filename2):
                 data = zlib.decompress(gc.get_typeids_z())
-                f = open(filename2, 'wb')
+                f = open(filename2, 'w')
+                f.write(data)
+                f.close()
+            filename2 = os.path.join(os.path.dirname(file), 'typeids.lst')
+            if not os.path.exists(filename2):
+                data = ''.join(['%d\n' % n for n in gc.get_typeids_list()])
+                f = open(filename2, 'w')
                 f.write(data)
                 f.close()
     else:
diff --git a/pypy/module/gc/referents.py b/pypy/module/gc/referents.py
--- a/pypy/module/gc/referents.py
+++ b/pypy/module/gc/referents.py
@@ -228,3 +228,8 @@
     a = rgc.get_typeids_z()
     s = ''.join([a[i] for i in range(len(a))])
     return space.wrap(s)
+
+def get_typeids_list(space):
+    l = rgc.get_typeids_list()
+    list_w = [space.wrap(l[i]) for i in range(len(l))]
+    return space.newlist(list_w)
diff --git a/pypy/module/thread/gil.py b/pypy/module/thread/gil.py
--- a/pypy/module/thread/gil.py
+++ b/pypy/module/thread/gil.py
@@ -7,7 +7,7 @@
 # all but one will be blocked.  The other threads get a chance to run
 # from time to time, using the periodic action GILReleaseAction.
 
-from rpython.rlib import rthread, rgil
+from rpython.rlib import rthread, rgil, rwin32
 from pypy.module.thread.error import wrap_thread_error
 from pypy.interpreter.executioncontext import PeriodicAsyncAction
 from pypy.module.thread.threadlocals import OSThreadLocals
@@ -76,9 +76,14 @@
 
 def after_external_call():
     e = get_errno()
+    e2 = 0
+    if rwin32.WIN32:
+        e2 = rwin32.GetLastError()
     rgil.gil_acquire()
     rthread.gc_thread_run()
     after_thread_switch()
+    if rwin32.WIN32:
+        rwin32.SetLastError(e2)
     set_errno(e)
 after_external_call._gctransformer_hint_cannot_collect_ = True
 after_external_call._dont_reach_me_in_del_ = True
diff --git a/pypy/objspace/std/test/test_dictproxy.py b/pypy/objspace/std/test/test_dictproxy.py
--- a/pypy/objspace/std/test/test_dictproxy.py
+++ b/pypy/objspace/std/test/test_dictproxy.py
@@ -15,14 +15,15 @@
         assert NotEmpty.__dict__.get("b") is None
         raises(TypeError, 'NotEmpty.__dict__[15] = "y"')
         raises(KeyError, 'del NotEmpty.__dict__[15]')
+
+        key, value = NotEmpty.__dict__.popitem()
+        assert (key == 'a' and value == 1) or (key == 'b' and value == 4)
+
         assert NotEmpty.__dict__.setdefault("string", 1) == 1
         assert NotEmpty.__dict__.setdefault("string", 2) == 1
         assert NotEmpty.string == 1
         raises(TypeError, 'NotEmpty.__dict__.setdefault(15, 1)')
 
-        key, value = NotEmpty.__dict__.popitem()
-        assert (key == 'a' and value == 1) or (key == 'b' and value == 4)
-
     def test_dictproxy_getitem(self):
         class NotEmpty(object):
             a = 1
diff --git a/rpython/memory/gc/inspector.py b/rpython/memory/gc/inspector.py
--- a/rpython/memory/gc/inspector.py
+++ b/rpython/memory/gc/inspector.py
@@ -1,7 +1,7 @@
 """
 Utility RPython functions to inspect objects in the GC.
 """
-from rpython.rtyper.lltypesystem import lltype, llmemory, rffi
+from rpython.rtyper.lltypesystem import lltype, llmemory, rffi, llgroup
 from rpython.rlib.objectmodel import free_non_gc_object
 from rpython.rtyper.module.ll_os import UNDERSCORE_ON_WIN32
 from rpython.rlib import rposix, rgc
@@ -238,3 +238,8 @@
 def get_typeids_z(gc):
     srcaddress = gc.root_walker.gcdata.typeids_z
     return llmemory.cast_adr_to_ptr(srcaddress, lltype.Ptr(rgc.ARRAY_OF_CHAR))
+
+def get_typeids_list(gc):
+    srcaddress = gc.root_walker.gcdata.typeids_list
+    return llmemory.cast_adr_to_ptr(srcaddress, lltype.Ptr(ARRAY_OF_HALFWORDS))
+ARRAY_OF_HALFWORDS = lltype.Array(llgroup.HALFWORD)
diff --git a/rpython/memory/gctransform/framework.py b/rpython/memory/gctransform/framework.py
--- a/rpython/memory/gctransform/framework.py
+++ b/rpython/memory/gctransform/framework.py
@@ -170,6 +170,7 @@
         gcdata.static_root_end = a_random_address        # patched in finish()
         gcdata.max_type_id = 13                          # patched in finish()
         gcdata.typeids_z = a_random_address              # patched in finish()
+        gcdata.typeids_list = a_random_address           # patched in finish()
         self.gcdata = gcdata
         self.malloc_fnptr_cache = {}
 
@@ -205,6 +206,7 @@
         data_classdef.generalize_attr('static_root_end', SomeAddress())
         data_classdef.generalize_attr('max_type_id', annmodel.SomeInteger())
         data_classdef.generalize_attr('typeids_z', SomeAddress())
+        data_classdef.generalize_attr('typeids_list', SomeAddress())
 
         annhelper = annlowlevel.MixLevelHelperAnnotator(self.translator.rtyper)
 
@@ -455,6 +457,11 @@
                                        [s_gc],
                                        SomePtr(lltype.Ptr(rgc.ARRAY_OF_CHAR)),
                                        minimal_transform=False)
+        self.get_typeids_list_ptr = getfn(inspector.get_typeids_list,
+                                       [s_gc],
+                                       SomePtr(lltype.Ptr(
+                                           lltype.Array(llgroup.HALFWORD))),
+                                       minimal_transform=False)
 
         self.set_max_heap_size_ptr = getfn(GCClass.set_max_heap_size.im_func,
                                            [s_gc,
@@ -604,7 +611,8 @@
         newgcdependencies = []
         newgcdependencies.append(ll_static_roots_inside)
         ll_instance.inst_max_type_id = len(group.members)
-        typeids_z = self.write_typeid_list()
+        #
+        typeids_z, typeids_list = self.write_typeid_list()
         ll_typeids_z = lltype.malloc(rgc.ARRAY_OF_CHAR,
                                      len(typeids_z),
                                      immortal=True)
@@ -612,6 +620,15 @@
             ll_typeids_z[i] = typeids_z[i]
         ll_instance.inst_typeids_z = llmemory.cast_ptr_to_adr(ll_typeids_z)
         newgcdependencies.append(ll_typeids_z)
+        #
+        ll_typeids_list = lltype.malloc(lltype.Array(llgroup.HALFWORD),
+                                        len(typeids_list),
+                                        immortal=True)
+        for i in range(len(typeids_list)):
+            ll_typeids_list[i] = typeids_list[i]
+        ll_instance.inst_typeids_list= llmemory.cast_ptr_to_adr(ll_typeids_list)
+        newgcdependencies.append(ll_typeids_list)
+        #
         return newgcdependencies
 
     def get_finish_tables(self):
@@ -632,6 +649,13 @@
         # XXX argh argh, this only gives the member index but not the
         #     real typeid, which is a complete mess to obtain now...
         all_ids = self.layoutbuilder.id_of_type.items()
+        list_data = []
+        ZERO = rffi.cast(llgroup.HALFWORD, 0)
+        for _, typeinfo in all_ids:
+            while len(list_data) <= typeinfo.index:
+                list_data.append(ZERO)
+            list_data[typeinfo.index] = typeinfo
+        #
         all_ids = [(typeinfo.index, TYPE) for (TYPE, typeinfo) in all_ids]
         all_ids = dict(all_ids)
         f = udir.join("typeids.txt").open("w")
@@ -640,9 +664,10 @@
         f.close()
         try:
             import zlib
-            return zlib.compress(udir.join("typeids.txt").read(), 9)
+            z_data = zlib.compress(udir.join("typeids.txt").read(), 9)
         except ImportError:
-            return ''
+            z_data = ''
+        return z_data, list_data
 
     def transform_graph(self, graph):
         func = getattr(graph, 'func', None)
@@ -1183,6 +1208,13 @@
                   resultvar=hop.spaceop.result)
         self.pop_roots(hop, livevars)
 
+    def gct_gc_typeids_list(self, hop):
+        livevars = self.push_roots(hop)
+        hop.genop("direct_call",
+                  [self.get_typeids_list_ptr, self.c_const_gc],
+                  resultvar=hop.spaceop.result)
+        self.pop_roots(hop, livevars)
+
     def _set_into_gc_array_part(self, op):
         if op.opname == 'setarrayitem':
             return op.args[1]
diff --git a/rpython/rlib/rgc.py b/rpython/rlib/rgc.py
--- a/rpython/rlib/rgc.py
+++ b/rpython/rlib/rgc.py
@@ -445,6 +445,10 @@
     "NOT_RPYTHON"
     raise NotImplementedError
 
+def get_typeids_list():
+    "NOT_RPYTHON"
+    raise NotImplementedError
+
 def has_gcflag_extra():
     "NOT_RPYTHON"
     return True
@@ -644,6 +648,18 @@
         return hop.genop('gc_typeids_z', [], resulttype = hop.r_result)
 
 class Entry(ExtRegistryEntry):
+    _about_ = get_typeids_list
+
+    def compute_result_annotation(self):
+        from rpython.rtyper.llannotation import SomePtr
+        from rpython.rtyper.lltypesystem import llgroup
+        return SomePtr(lltype.Ptr(lltype.Array(llgroup.HALFWORD)))
+
+    def specialize_call(self, hop):
+        hop.exception_is_here()
+        return hop.genop('gc_typeids_list', [], resulttype = hop.r_result)
+
+class Entry(ExtRegistryEntry):
     _about_ = (has_gcflag_extra, get_gcflag_extra, toggle_gcflag_extra)
     def compute_result_annotation(self, s_arg=None):
         from rpython.annotator.model import s_Bool
diff --git a/rpython/rlib/rwin32.py b/rpython/rlib/rwin32.py
--- a/rpython/rlib/rwin32.py
+++ b/rpython/rlib/rwin32.py
@@ -118,8 +118,10 @@
     INVALID_HANDLE_VALUE = rffi.cast(HANDLE, -1)
     PFILETIME = rffi.CArrayPtr(FILETIME)
 
-    _GetLastError = winexternal('GetLastError', [], DWORD, releasegil=False)
-    _SetLastError = winexternal('SetLastError', [DWORD], lltype.Void)
+    _GetLastError = winexternal('GetLastError', [], DWORD,
+                                _nowrapper=True, sandboxsafe=True)
+    _SetLastError = winexternal('SetLastError', [DWORD], lltype.Void,
+                                _nowrapper=True, sandboxsafe=True)
 
     def GetLastError():
         return rffi.cast(lltype.Signed, _GetLastError())
diff --git a/rpython/rtyper/llinterp.py b/rpython/rtyper/llinterp.py
--- a/rpython/rtyper/llinterp.py
+++ b/rpython/rtyper/llinterp.py
@@ -911,6 +911,9 @@
     def op_gc_typeids_z(self):
         raise NotImplementedError("gc_typeids_z")
 
+    def op_gc_typeids_list(self):
+        raise NotImplementedError("gc_typeids_list")
+
     def op_gc_gcflag_extra(self, subopnum, *args):
         return self.heap.gcflag_extra(subopnum, *args)
 
diff --git a/rpython/rtyper/lltypesystem/lloperation.py b/rpython/rtyper/lltypesystem/lloperation.py
--- a/rpython/rtyper/lltypesystem/lloperation.py
+++ b/rpython/rtyper/lltypesystem/lloperation.py
@@ -493,6 +493,7 @@
     'gc_is_rpy_instance'  : LLOp(),
     'gc_dump_rpy_heap'    : LLOp(),
     'gc_typeids_z'        : LLOp(),
+    'gc_typeids_list'     : LLOp(),
     'gc_gcflag_extra'     : LLOp(),
     'gc_add_memory_pressure': LLOp(),
     'gc_reset_tid_counters': LLOp(),
diff --git a/rpython/translator/c/test/test_newgc.py b/rpython/translator/c/test/test_newgc.py
--- a/rpython/translator/c/test/test_newgc.py
+++ b/rpython/translator/c/test/test_newgc.py
@@ -1147,6 +1147,10 @@
             fd = os.open(filename, open_flags, 0666)
             os.write(fd, s)
             os.close(fd)
+            #
+            a = rgc.get_typeids_list()
+            assert len(a) > 1
+            assert 0 < rffi.cast(lltype.Signed, a[1]) < 10000
             return 0
 
         return fn


More information about the pypy-commit mailing list