Author: Armin Rigo <ar...@tunes.org> Branch: Changeset: r75075:ea9a1e9c799d Date: 2014-12-23 11:36 +0100 http://bitbucket.org/pypy/pypy/changeset/ea9a1e9c799d/
Log: Add gc.get_typeids_list() to the Python 'gc' module. Returns a list of integers that are typeids. The Nth item in the list correspond to the 'memberN' in the string returned by gc.get_typeids_z(). 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 @@ -30,6 +30,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/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/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, @@ -596,7 +603,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) @@ -604,6 +612,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): @@ -624,6 +641,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") @@ -632,9 +656,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) @@ -1175,6 +1200,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/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(), 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 _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit