[pypy-svn] r68929 - in pypy/branch/jit-removetypeptr/pypy: config jit/backend/llsupport jit/backend/llsupport/test jit/backend/x86 jit/backend/x86/test rpython rpython/lltypesystem rpython/memory rpython/memory/gc/test rpython/memory/gctransform rpython/memory/test translator/c translator/c/test

arigo at codespeak.net arigo at codespeak.net
Tue Nov 3 11:42:37 CET 2009


Author: arigo
Date: Tue Nov  3 11:42:36 2009
New Revision: 68929

Modified:
   pypy/branch/jit-removetypeptr/pypy/config/translationoption.py
   pypy/branch/jit-removetypeptr/pypy/jit/backend/llsupport/gc.py
   pypy/branch/jit-removetypeptr/pypy/jit/backend/llsupport/llmodel.py
   pypy/branch/jit-removetypeptr/pypy/jit/backend/llsupport/test/test_gc.py
   pypy/branch/jit-removetypeptr/pypy/jit/backend/x86/assembler.py
   pypy/branch/jit-removetypeptr/pypy/jit/backend/x86/ri386setup.py
   pypy/branch/jit-removetypeptr/pypy/jit/backend/x86/test/test_ri386_auto_encoding.py
   pypy/branch/jit-removetypeptr/pypy/jit/backend/x86/test/test_zrpy_gc.py
   pypy/branch/jit-removetypeptr/pypy/rpython/llinterp.py
   pypy/branch/jit-removetypeptr/pypy/rpython/lltypesystem/lloperation.py
   pypy/branch/jit-removetypeptr/pypy/rpython/memory/gc/test/test_direct.py
   pypy/branch/jit-removetypeptr/pypy/rpython/memory/gctransform/framework.py
   pypy/branch/jit-removetypeptr/pypy/rpython/memory/gctransform/transform.py
   pypy/branch/jit-removetypeptr/pypy/rpython/memory/gctypelayout.py
   pypy/branch/jit-removetypeptr/pypy/rpython/memory/test/test_gctypelayout.py
   pypy/branch/jit-removetypeptr/pypy/rpython/memory/test/test_transformed_gc.py
   pypy/branch/jit-removetypeptr/pypy/translator/c/database.py
   pypy/branch/jit-removetypeptr/pypy/translator/c/node.py
   pypy/branch/jit-removetypeptr/pypy/translator/c/test/test_newgc.py
Log:
Implement jit support for gcremovetypeptr.


Modified: pypy/branch/jit-removetypeptr/pypy/config/translationoption.py
==============================================================================
--- pypy/branch/jit-removetypeptr/pypy/config/translationoption.py	(original)
+++ pypy/branch/jit-removetypeptr/pypy/config/translationoption.py	Tue Nov  3 11:42:36 2009
@@ -95,8 +95,7 @@
     # JIT generation: use -Ojit to enable it
     BoolOption("jit", "generate a JIT",
                default=False,
-               requires=[("translation.thread", False),
-                         ("translation.gcremovetypeptr", False)],
+               requires=[("translation.thread", False)],
                suggests=[("translation.gc", "hybrid"),     # or "boehm"
                          ("translation.gcrootfinder", "asmgcc"),
                          ("translation.list_comprehension_operations", True)]),

Modified: pypy/branch/jit-removetypeptr/pypy/jit/backend/llsupport/gc.py
==============================================================================
--- pypy/branch/jit-removetypeptr/pypy/jit/backend/llsupport/gc.py	(original)
+++ pypy/branch/jit-removetypeptr/pypy/jit/backend/llsupport/gc.py	Tue Nov  3 11:42:36 2009
@@ -325,8 +325,7 @@
 
         # make a TransformerLayoutBuilder and save it on the translator
         # where it can be fished and reused by the FrameworkGCTransformer
-        self.layoutbuilder = framework.JITTransformerLayoutBuilder(
-            gcdescr.config)
+        self.layoutbuilder = framework.TransformerLayoutBuilder(translator)
         self.layoutbuilder.delay_encoding()
         self.translator._jit2gc = {
             'layoutbuilder': self.layoutbuilder,

Modified: pypy/branch/jit-removetypeptr/pypy/jit/backend/llsupport/llmodel.py
==============================================================================
--- pypy/branch/jit-removetypeptr/pypy/jit/backend/llsupport/llmodel.py	(original)
+++ pypy/branch/jit-removetypeptr/pypy/jit/backend/llsupport/llmodel.py	Tue Nov  3 11:42:36 2009
@@ -28,8 +28,11 @@
         else:
             translator = None
         self.gc_ll_descr = get_ll_description(gcdescr, translator)
-        self.vtable_offset, _ = symbolic.get_field_token(rclass.OBJECT,
-                                                         'typeptr',
+        if translator and translator.config.translation.gcremovetypeptr:
+            self.vtable_offset = None
+        else:
+            self.vtable_offset, _ = symbolic.get_field_token(rclass.OBJECT,
+                                                             'typeptr',
                                                         translate_support_code)
         self._setup_prebuilt_error('ovf', OverflowError)
         self._setup_prebuilt_error('zer', ZeroDivisionError)
@@ -424,8 +427,9 @@
         classint = classbox.getint()
         descrsize = self.class_sizes[classint]
         res = self.gc_ll_descr.gc_malloc(descrsize)
-        as_array = rffi.cast(rffi.CArrayPtr(lltype.Signed), res)
-        as_array[self.vtable_offset/WORD] = classint
+        if self.vtable_offset is not None:
+            as_array = rffi.cast(rffi.CArrayPtr(lltype.Signed), res)
+            as_array[self.vtable_offset/WORD] = classint
         return BoxPtr(res)
 
     def do_new_array(self, countbox, arraydescr):

Modified: pypy/branch/jit-removetypeptr/pypy/jit/backend/llsupport/test/test_gc.py
==============================================================================
--- pypy/branch/jit-removetypeptr/pypy/jit/backend/llsupport/test/test_gc.py	(original)
+++ pypy/branch/jit-removetypeptr/pypy/jit/backend/llsupport/test/test_gc.py	Tue Nov  3 11:42:36 2009
@@ -147,19 +147,20 @@
 class TestFramework:
 
     def setup_method(self, meth):
-        class FakeTranslator:
-            pass
-        class config:
+        class config_:
             class translation:
                 gc = 'hybrid'
                 gcrootfinder = 'asmgcc'
                 gctransformer = 'framework'
+                gcremovetypeptr = False
+        class FakeTranslator:
+            config = config_
         class FakeCPU:
             def cast_adr_to_int(self, adr):
                 ptr = llmemory.cast_adr_to_ptr(adr, gc_ll_descr.WB_FUNCPTR)
                 assert ptr._obj._callable == llop1._write_barrier_failing_case
                 return 42
-        gcdescr = get_description(config)
+        gcdescr = get_description(config_)
         translator = FakeTranslator()
         llop1 = FakeLLOp()
         gc_ll_descr = GcLLDescr_framework(gcdescr, FakeTranslator(), llop1)

Modified: pypy/branch/jit-removetypeptr/pypy/jit/backend/x86/assembler.py
==============================================================================
--- pypy/branch/jit-removetypeptr/pypy/jit/backend/x86/assembler.py	(original)
+++ pypy/branch/jit-removetypeptr/pypy/jit/backend/x86/assembler.py	Tue Nov  3 11:42:36 2009
@@ -518,7 +518,8 @@
         self.set_vtable(eax, loc_vtable)
 
     def set_vtable(self, loc, loc_vtable):
-        self.mc.MOV(mem(loc, self.cpu.vtable_offset), loc_vtable)
+        if self.cpu.vtable_offset is not None:
+            self.mc.MOV(mem(loc, self.cpu.vtable_offset), loc_vtable)
 
     # XXX genop_new is abused for all varsized mallocs with Boehm, for now
     # (instead of genop_new_array, genop_newstr, genop_newunicode)
@@ -713,7 +714,24 @@
 
     def genop_guard_guard_class(self, ign_1, guard_op, addr, locs, ign_2):
         offset = self.cpu.vtable_offset
-        self.mc.CMP(mem(locs[0], offset), locs[1])
+        if offset is not None:
+            self.mc.CMP(mem(locs[0], offset), locs[1])
+        else:
+            # XXX hard-coded assumption: to go from an object to its class
+            # we use the following algorithm:
+            #   - read the typeid from mem(locs[0]), i.e. at offset 0
+            #   - keep the lower 16 bits read there
+            #   - multiply by 4 and use it as an offset in type_info_group.
+            loc = locs[1]
+            assert isinstance(loc, IMM32)
+            classptr = loc.value
+            # here, we have to go back from 'classptr' to the value expected
+            # from reading the 16 bits in the object header
+            type_info_group = llop.gc_get_type_info_group(llmemory.Address)
+            type_info_group = rffi.cast(lltype.Signed, type_info_group)
+            expected_typeid = (classptr - type_info_group) >> 2
+            self.mc.CMP16(mem(locs[0], 0), imm32(expected_typeid))
+            #
         return self.implement_guard(addr, self.mc.JNE)
 
     def _no_const_locs(self, args):

Modified: pypy/branch/jit-removetypeptr/pypy/jit/backend/x86/ri386setup.py
==============================================================================
--- pypy/branch/jit-removetypeptr/pypy/jit/backend/x86/ri386setup.py	(original)
+++ pypy/branch/jit-removetypeptr/pypy/jit/backend/x86/ri386setup.py	Tue Nov  3 11:42:36 2009
@@ -310,6 +310,11 @@
 CMP = Instruction()
 CMP.common_modes(7)
 
+# special mode for comparing a 16-bit operand with an immediate
+CMP16 = Instruction()
+CMP16.mode2(MODRM, IMM32, ['\x66', '\x81', orbyte(7<<3), modrm(1),
+                           immediate(2,'h')])
+
 NOP = Instruction()
 NOP.mode0(['\x90'])
 

Modified: pypy/branch/jit-removetypeptr/pypy/jit/backend/x86/test/test_ri386_auto_encoding.py
==============================================================================
--- pypy/branch/jit-removetypeptr/pypy/jit/backend/x86/test/test_ri386_auto_encoding.py	(original)
+++ pypy/branch/jit-removetypeptr/pypy/jit/backend/x86/test/test_ri386_auto_encoding.py	Tue Nov  3 11:42:36 2009
@@ -218,6 +218,8 @@
                 return []   # MOV [constant-address], accum
         if instrname == "MOV16":
             return []   # skipped
+        if instrname == "CMP16":
+            return []   # skipped
         if instrname == "LEA":
             if (args[1][1].__class__ != i386.MODRM or
                 args[1][1].is_register()):

Modified: pypy/branch/jit-removetypeptr/pypy/jit/backend/x86/test/test_zrpy_gc.py
==============================================================================
--- pypy/branch/jit-removetypeptr/pypy/jit/backend/x86/test/test_zrpy_gc.py	(original)
+++ pypy/branch/jit-removetypeptr/pypy/jit/backend/x86/test/test_zrpy_gc.py	Tue Nov  3 11:42:36 2009
@@ -78,6 +78,7 @@
     #
     t = TranslationContext()
     t.config.translation.gc = gc
+    t.config.translation.gcremovetypeptr = True
     for name, value in kwds.items():
         setattr(t.config.translation, name, value)
     ann = t.buildannotator(policy=annpolicy.StrictAnnotatorPolicy())

Modified: pypy/branch/jit-removetypeptr/pypy/rpython/llinterp.py
==============================================================================
--- pypy/branch/jit-removetypeptr/pypy/rpython/llinterp.py	(original)
+++ pypy/branch/jit-removetypeptr/pypy/rpython/llinterp.py	Tue Nov  3 11:42:36 2009
@@ -890,6 +890,9 @@
     def op_gc_stack_bottom(self):
         pass       # marker for trackgcroot.py
 
+    def op_gc_get_type_info_group(self):
+        raise NotImplementedError("gc_get_type_info_group")
+
     def op_do_malloc_fixedsize_clear(self):
         raise NotImplementedError("do_malloc_fixedsize_clear")
 

Modified: pypy/branch/jit-removetypeptr/pypy/rpython/lltypesystem/lloperation.py
==============================================================================
--- pypy/branch/jit-removetypeptr/pypy/rpython/lltypesystem/lloperation.py	(original)
+++ pypy/branch/jit-removetypeptr/pypy/rpython/lltypesystem/lloperation.py	Tue Nov  3 11:42:36 2009
@@ -432,6 +432,7 @@
     'do_malloc_fixedsize_clear': LLOp(canunwindgc=True),
     'do_malloc_varsize_clear': LLOp(canunwindgc=True),
     'get_write_barrier_failing_case': LLOp(sideeffects=False),
+    'gc_get_type_info_group': LLOp(sideeffects=False),
 
     # __________ GC operations __________
 

Modified: pypy/branch/jit-removetypeptr/pypy/rpython/memory/gc/test/test_direct.py
==============================================================================
--- pypy/branch/jit-removetypeptr/pypy/rpython/memory/gc/test/test_direct.py	(original)
+++ pypy/branch/jit-removetypeptr/pypy/rpython/memory/gc/test/test_direct.py	Tue Nov  3 11:42:36 2009
@@ -68,7 +68,7 @@
         self.gc.DEBUG = True
         self.rootwalker = DirectRootWalker(self)
         self.gc.set_root_walker(self.rootwalker)
-        self.layoutbuilder = TypeLayoutBuilder(self.GCClass, {})
+        self.layoutbuilder = TypeLayoutBuilder(self.GCClass)
         self.get_type_id = self.layoutbuilder.get_type_id
         self.layoutbuilder.initialize_gc_query_function(self.gc)
         self.gc.setup()

Modified: pypy/branch/jit-removetypeptr/pypy/rpython/memory/gctransform/framework.py
==============================================================================
--- pypy/branch/jit-removetypeptr/pypy/rpython/memory/gctransform/framework.py	(original)
+++ pypy/branch/jit-removetypeptr/pypy/rpython/memory/gctransform/framework.py	Tue Nov  3 11:42:36 2009
@@ -130,12 +130,7 @@
         if hasattr(translator, '_jit2gc'):
             self.layoutbuilder = translator._jit2gc['layoutbuilder']
         else:
-            if translator.config.translation.gcremovetypeptr:
-                lltype2vtable = translator.rtyper.lltype2vtable
-            else:
-                lltype2vtable = {}
-            self.layoutbuilder = TransformerLayoutBuilder(GCClass,
-                                                          lltype2vtable)
+            self.layoutbuilder = TransformerLayoutBuilder(translator, GCClass)
         self.layoutbuilder.transformer = self
         self.get_type_id = self.layoutbuilder.get_type_id
 
@@ -508,11 +503,16 @@
         self.write_typeid_list()
         return newgcdependencies
 
-    def get_final_dependencies(self):
-        # returns an iterator enumerating the type_info_group's members,
-        # to make sure that they are all followed (only a part of them
-        # might have been followed by a previous enum_dependencies()).
-        return iter(self.layoutbuilder.type_info_group.members)
+    def get_finish_tables(self):
+        # We must first make sure that the type_info_group's members
+        # are all followed.  Do it repeatedly while new members show up.
+        # Once it is really done, do finish_tables().
+        seen = 0
+        while seen < len(self.layoutbuilder.type_info_group.members):
+            curtotal = len(self.layoutbuilder.type_info_group.members)
+            yield self.layoutbuilder.type_info_group.members[seen:curtotal]
+            seen = curtotal
+        yield self.finish_tables()
 
     def write_typeid_list(self):
         """write out the list of type ids together with some info"""
@@ -821,6 +821,9 @@
         if hasattr(self.root_walker, 'thread_die_ptr'):
             hop.genop("direct_call", [self.root_walker.thread_die_ptr])
 
+    def gct_gc_get_type_info_group(self, hop):
+        return hop.cast_result(self.c_type_info_group)
+
     def gct_malloc_nonmovable_varsize(self, hop):
         TYPE = hop.spaceop.result.concretetype
         if self.gcdata.gc.can_malloc_nonmovable():
@@ -964,6 +967,16 @@
 
 class TransformerLayoutBuilder(gctypelayout.TypeLayoutBuilder):
 
+    def __init__(self, translator, GCClass=None):
+        if GCClass is None:
+            from pypy.rpython.memory.gc.base import choose_gc_from_config
+            GCClass, _ = choose_gc_from_config(translator.config)
+        if translator.config.translation.gcremovetypeptr:
+            lltype2vtable = translator.rtyper.lltype2vtable
+        else:
+            lltype2vtable = None
+        super(TransformerLayoutBuilder, self).__init__(GCClass, lltype2vtable)
+
     def has_finalizer(self, TYPE):
         rtti = get_rtti(TYPE)
         return rtti is not None and hasattr(rtti._obj, 'destructor_funcptr')
@@ -990,18 +1003,6 @@
         return fptr
 
 
-class JITTransformerLayoutBuilder(TransformerLayoutBuilder):
-    # for the JIT: currently does not support removetypeptr
-    def __init__(self, config):
-        from pypy.rpython.memory.gc.base import choose_gc_from_config
-        try:
-            assert not config.translation.gcremovetypeptr
-        except AttributeError:    # for some tests
-            pass
-        GCClass, _ = choose_gc_from_config(config)
-        TransformerLayoutBuilder.__init__(self, GCClass, {})
-
-
 def gen_zero_gc_pointers(TYPE, v, llops, previous_steps=None):
     if previous_steps is None:
         previous_steps = []

Modified: pypy/branch/jit-removetypeptr/pypy/rpython/memory/gctransform/transform.py
==============================================================================
--- pypy/branch/jit-removetypeptr/pypy/rpython/memory/gctransform/transform.py	(original)
+++ pypy/branch/jit-removetypeptr/pypy/rpython/memory/gctransform/transform.py	Tue Nov  3 11:42:36 2009
@@ -312,12 +312,12 @@
         newgcdependencies = self.ll_finalizers_ptrs
         return newgcdependencies
 
-    def get_final_dependencies(self):
-        pass
-
     def finish_tables(self):
         pass
 
+    def get_finish_tables(self):
+        return self.finish_tables
+
     def finish(self, backendopt=True):
         self.finish_helpers(backendopt=backendopt)
         self.finish_tables()

Modified: pypy/branch/jit-removetypeptr/pypy/rpython/memory/gctypelayout.py
==============================================================================
--- pypy/branch/jit-removetypeptr/pypy/rpython/memory/gctypelayout.py	(original)
+++ pypy/branch/jit-removetypeptr/pypy/rpython/memory/gctypelayout.py	Tue Nov  3 11:42:36 2009
@@ -1,4 +1,5 @@
 from pypy.rpython.lltypesystem import lltype, llmemory, llarena, llgroup
+from pypy.rpython.lltypesystem import rclass
 from pypy.rpython.lltypesystem.lloperation import llop
 from pypy.rlib.objectmodel import we_are_translated
 from pypy.rlib.debug import ll_assert
@@ -169,7 +170,7 @@
 
     size_of_fixed_type_info = llmemory.sizeof(GCData.TYPE_INFO)
 
-    def __init__(self, GCClass, lltype2vtable):
+    def __init__(self, GCClass, lltype2vtable=None):
         self.GCClass = GCClass
         self.lltype2vtable = lltype2vtable
         self.make_type_info_group()
@@ -218,16 +219,28 @@
             # store it
             type_id = self.type_info_group.add_member(fullinfo)
             self.id_of_type[TYPE] = type_id
-            # store the vtable of the type (if any) immediately thereafter
-            # (note that if gcremovetypeptr is False, lltype2vtable is empty)
-            vtable = self.lltype2vtable.get(TYPE, None)
-            if vtable is not None:
-                # check that if we have a vtable, we are not varsize
-                assert lltype.typeOf(fullinfo) == GCData.TYPE_INFO_PTR
-                vtable = lltype.normalizeptr(vtable)
-                self.type_info_group.add_member(vtable)
+            self.add_vtable_after_typeinfo(TYPE)
             return type_id
 
+    def add_vtable_after_typeinfo(self, TYPE):
+        # if gcremovetypeptr is False, then lltype2vtable is None and it
+        # means that we don't have to store the vtables in type_info_group.
+        if self.lltype2vtable is None:
+            return
+        # does the type have a vtable?
+        vtable = self.lltype2vtable.get(TYPE, None)
+        if vtable is not None:
+            # yes.  check that in this case, we are not varsize
+            assert not TYPE._is_varsize()
+            vtable = lltype.normalizeptr(vtable)
+            self.type_info_group.add_member(vtable)
+        else:
+            # no vtable from lltype2vtable -- double-check to be sure
+            # that it's not a subclass of OBJECT.
+            while isinstance(TYPE, lltype.GcStruct):
+                assert TYPE is not rclass.OBJECT
+                _, TYPE = TYPE._first_struct()
+
     def get_info(self, type_id):
         return llop.get_group_member(GCData.TYPE_INFO_PTR,
                                      self.type_info_group._as_ptr(),

Modified: pypy/branch/jit-removetypeptr/pypy/rpython/memory/test/test_gctypelayout.py
==============================================================================
--- pypy/branch/jit-removetypeptr/pypy/rpython/memory/test/test_gctypelayout.py	(original)
+++ pypy/branch/jit-removetypeptr/pypy/rpython/memory/test/test_gctypelayout.py	Tue Nov  3 11:42:36 2009
@@ -37,7 +37,7 @@
     for T, c in [(GC_S, 0), (GC_S2, 2), (GC_A, 0), (GC_A2, 0), (GC_S3, 2)]:
         assert len(offsets_to_gc_pointers(T)) == c
 
-def test_layout_builder(lltype2vtable={}):
+def test_layout_builder(lltype2vtable=None):
     # XXX a very minimal test
     layoutbuilder = TypeLayoutBuilder(FakeGC, lltype2vtable)
     for T1, T2 in [(GC_A, GC_S), (GC_A2, GC_S2), (GC_S3, GC_S2)]:
@@ -67,7 +67,7 @@
                        layoutbuilder.size_of_fixed_type_info)
 
 def test_constfold():
-    layoutbuilder = TypeLayoutBuilder(FakeGC, {})
+    layoutbuilder = TypeLayoutBuilder(FakeGC)
     tid1 = layoutbuilder.get_type_id(GC_A)
     tid2 = layoutbuilder.get_type_id(GC_S3)
     class MockGC:

Modified: pypy/branch/jit-removetypeptr/pypy/rpython/memory/test/test_transformed_gc.py
==============================================================================
--- pypy/branch/jit-removetypeptr/pypy/rpython/memory/test/test_transformed_gc.py	(original)
+++ pypy/branch/jit-removetypeptr/pypy/rpython/memory/test/test_transformed_gc.py	Tue Nov  3 11:42:36 2009
@@ -709,9 +709,7 @@
         if jit2gc:
             return jit2gc['layoutbuilder']
         GCClass = cls.gcpolicy.transformerclass.GCClass
-        lltype2vtable = translator.rtyper.lltype2vtable
-        layoutbuilder = framework.TransformerLayoutBuilder(GCClass,
-                                                               lltype2vtable)
+        layoutbuilder = framework.TransformerLayoutBuilder(translator, GCClass)
         layoutbuilder.delay_encoding()
         translator._jit2gc = {
             'layoutbuilder': layoutbuilder,

Modified: pypy/branch/jit-removetypeptr/pypy/translator/c/database.py
==============================================================================
--- pypy/branch/jit-removetypeptr/pypy/translator/c/database.py	(original)
+++ pypy/branch/jit-removetypeptr/pypy/translator/c/database.py	Tue Nov  3 11:42:36 2009
@@ -288,10 +288,8 @@
             finish_callbacks.append(('Stackless transformer: finished',
                                      self.stacklesstransformer.finish))
         if self.gctransformer:
-            finish_callbacks.append(('GC transformer: tracking vtables',
-                                    self.gctransformer.get_final_dependencies))
             finish_callbacks.append(('GC transformer: finished tables',
-                                     self.gctransformer.finish_tables))
+                                     self.gctransformer.get_finish_tables()))
 
         def add_dependencies(newdependencies):
             for value in newdependencies:
@@ -336,8 +334,18 @@
 
             if finish_callbacks:
                 logmsg, finish = finish_callbacks.pop(0)
-                newdependencies = finish()
-                log.database(logmsg)
+                if not hasattr(finish, 'next'):
+                    newdependencies = finish()
+                else:
+                    # if 'finish' is a generator, consume the next element
+                    # and put the generator again in the queue
+                    try:
+                        newdependencies = finish.next()
+                        finish_callbacks.insert(0, (None, finish))
+                    except StopIteration:
+                        newdependencies = None
+                if logmsg:
+                    log.database(logmsg)
                 if newdependencies:
                     add_dependencies(newdependencies)
                 continue       # progress - follow all dependencies again

Modified: pypy/branch/jit-removetypeptr/pypy/translator/c/node.py
==============================================================================
--- pypy/branch/jit-removetypeptr/pypy/translator/c/node.py	(original)
+++ pypy/branch/jit-removetypeptr/pypy/translator/c/node.py	Tue Nov  3 11:42:36 2009
@@ -960,8 +960,8 @@
 
     def enum_dependencies(self):
         # note: for the group used by the GC, it can grow during this phase,
-        # which means that we might not return all members yet.  This is
-        # fixed by finish_tables() in rpython/memory/gctransform/framework.py
+        # which means that we might not return all members yet.  This is fixed
+        # by get_final_dependencies() in rpython.memory.gctransform.framework
         for member in self.obj.members:
             yield member._as_ptr()
 

Modified: pypy/branch/jit-removetypeptr/pypy/translator/c/test/test_newgc.py
==============================================================================
--- pypy/branch/jit-removetypeptr/pypy/translator/c/test/test_newgc.py	(original)
+++ pypy/branch/jit-removetypeptr/pypy/translator/c/test/test_newgc.py	Tue Nov  3 11:42:36 2009
@@ -949,6 +949,19 @@
 class TestHybridGCRemoveTypePtr(TestHybridGC):
     removetypeptr = True
 
+    def definestr_str_instance(cls):
+        class AbcDef:
+            pass
+        def fn(_):
+            a = AbcDef()
+            return str(a)
+        return fn
+
+    def test_str_instance(self):
+        res = self.run('str_instance')
+        assert res.startswith('<') and res.endswith('>')
+        assert 'AbcDef' in res
+
 
 class TestMarkCompactGC(TestSemiSpaceGC):
     gcpolicy = "markcompact"



More information about the Pypy-commit mailing list