[pypy-svn] r79705 - in pypy/trunk/pypy/jit/backend: llsupport llsupport/test x86 x86/test

arigo at codespeak.net arigo at codespeak.net
Wed Dec 1 12:06:59 CET 2010


Author: arigo
Date: Wed Dec  1 12:06:57 2010
New Revision: 79705

Modified:
   pypy/trunk/pypy/jit/backend/llsupport/asmmemmgr.py
   pypy/trunk/pypy/jit/backend/llsupport/gc.py
   pypy/trunk/pypy/jit/backend/llsupport/test/test_asmmemmgr.py
   pypy/trunk/pypy/jit/backend/llsupport/test/test_gc.py
   pypy/trunk/pypy/jit/backend/x86/assembler.py
   pypy/trunk/pypy/jit/backend/x86/regalloc.py
   pypy/trunk/pypy/jit/backend/x86/regloc.py
   pypy/trunk/pypy/jit/backend/x86/test/test_gc_integration.py
Log:
Merge branch/jit-free-asm2, finishing the freeing of memory from the
x86 backend.  It moves some of the allocation logic out of the x86
backend, too.


Modified: pypy/trunk/pypy/jit/backend/llsupport/asmmemmgr.py
==============================================================================
--- pypy/trunk/pypy/jit/backend/llsupport/asmmemmgr.py	(original)
+++ pypy/trunk/pypy/jit/backend/llsupport/asmmemmgr.py	Wed Dec  1 12:06:57 2010
@@ -43,6 +43,22 @@
         self.total_mallocs -= (stop - start)
         self._add_free_block(start, stop)
 
+    def open_malloc(self, minsize):
+        """Allocate at least minsize bytes.  Returns (start, stop)."""
+        result = self._allocate_block(minsize)
+        (start, stop) = result
+        self.total_mallocs += stop - start
+        return result
+
+    def open_free(self, middle, stop):
+        """Used for freeing the end of an open-allocated block of memory."""
+        if stop - middle >= self.min_fragment:
+            self.total_mallocs -= (stop - middle)
+            self._add_free_block(middle, stop)
+            return True
+        else:
+            return False    # too small to record
+
     def _allocate_large_block(self, minsize):
         # Compute 'size' from 'minsize': it must be rounded up to
         # 'large_alloc_size'.  Additionally, we use the following line
@@ -140,6 +156,40 @@
         self._allocated = None
 
 
+class MachineDataBlockWrapper(object):
+    def __init__(self, asmmemmgr, allblocks):
+        self.asmmemmgr = asmmemmgr
+        self.allblocks = allblocks
+        self.rawstart    = 0
+        self.rawposition = 0
+        self.rawstop     = 0
+
+    def done(self):
+        if self.rawstart != 0:
+            if self.asmmemmgr.open_free(self.rawposition, self.rawstop):
+                self.rawstop = self.rawposition
+            self.allblocks.append((self.rawstart, self.rawstop))
+            self.rawstart    = 0
+            self.rawposition = 0
+            self.rawstop     = 0
+
+    def _allocate_next_block(self, minsize):
+        self.done()
+        self.rawstart, self.rawstop = self.asmmemmgr.open_malloc(minsize)
+        self.rawposition = self.rawstart
+
+    def malloc_aligned(self, size, alignment):
+        p = self.rawposition
+        p = (p + alignment - 1) & (-alignment)
+        if p + size > self.rawstop:
+            self._allocate_next_block(size + alignment - 1)
+            p = self.rawposition
+            p = (p + alignment - 1) & (-alignment)
+            assert p + size <= self.rawstop
+        self.rawposition = p + size
+        return p
+
+
 class BlockBuilderMixin(object):
     _mixin_ = True
     # A base class to generate assembler.  It is equivalent to just a list
@@ -156,7 +206,6 @@
     SUBBLOCK_PTR.TO.become(SUBBLOCK)
 
     gcroot_markers = None
-    gcroot_markers_total_size = 0
 
     def __init__(self, translated=None):
         if translated is None:
@@ -224,11 +273,8 @@
         self.copy_to_raw_memory(rawstart)
         if self.gcroot_markers is not None:
             assert gcrootmap is not None
-            gcrootmap.add_raw_gcroot_markers(asmmemmgr,
-                                             allblocks,
-                                             self.gcroot_markers,
-                                             self.gcroot_markers_total_size,
-                                             rawstart)
+            for pos, mark in self.gcroot_markers:
+                gcrootmap.put(rawstart + pos, mark)
         return rawstart
 
     def _become_a_plain_block_builder(self):
@@ -247,4 +293,3 @@
         if self.gcroot_markers is None:
             self.gcroot_markers = []
         self.gcroot_markers.append((self.get_relative_pos(), mark))
-        self.gcroot_markers_total_size += len(mark)

Modified: pypy/trunk/pypy/jit/backend/llsupport/gc.py
==============================================================================
--- pypy/trunk/pypy/jit/backend/llsupport/gc.py	(original)
+++ pypy/trunk/pypy/jit/backend/llsupport/gc.py	Wed Dec  1 12:06:57 2010
@@ -222,7 +222,7 @@
     LOC_EBP_MINUS = 3
 
     GCMAP_ARRAY = rffi.CArray(lltype.Signed)
-    CALLSHAPE_ARRAY = rffi.CArray(rffi.UCHAR)
+    CALLSHAPE_ARRAY_PTR = rffi.CArrayPtr(rffi.UCHAR)
 
     def __init__(self):
         # '_gcmap' is an array of length '_gcmap_maxlength' of addresses.
@@ -264,8 +264,7 @@
         self._gcmap_sorted = True
         return sorted
 
-    @rgc.no_collect
-    def _put(self, retaddr, callshapeaddr):
+    def put(self, retaddr, callshapeaddr):
         """'retaddr' is the address just after the CALL.
         'callshapeaddr' is the address of the raw 'shape' marker.
         Both addresses are actually integers here."""
@@ -308,37 +307,6 @@
                 lltype.free(oldgcmap, flavor='raw', track_allocation=False)
         return j
 
-    def add_raw_gcroot_markers(self, asmmemmgr, allblocks,
-                               markers, total_size, rawstart):
-        """The interface is a bit custom, but this routine writes the
-        shapes of gcroots (for the GC to use) into raw memory."""
-        # xxx so far, we never try to share them.  But right now
-        # the amount of potential sharing would not be too large.
-        dst = 1
-        stop = 0
-        for relpos, shape in markers:
-            #
-            if dst + len(shape) > stop:
-                # No more space in the previous raw block,
-                # allocate a raw block of memory big enough to fit
-                # as many of the remaining 'shapes' as possible
-                start, stop = asmmemmgr.malloc(len(shape), total_size)
-                # add the raw block to 'compiled_loop_token.asmmemmgr_blocks'
-                allblocks.append((start, stop))
-                dst = start
-            #
-            # add the entry 'pos_after_call -> dst' to the table
-            self._put(rawstart + relpos, dst)
-            # Copy 'shape' into the raw memory, reversing the order
-            # of the bytes.  Similar to compress_callshape() in
-            # trackgcroot.py.
-            total_size -= len(shape)
-            src = len(shape) - 1
-            while src >= 0:
-                rffi.cast(rffi.CCHARP, dst)[0] = shape[src]
-                dst += 1
-                src -= 1
-
     @rgc.no_collect
     def freeing_block(self, start, stop):
         # if [start:stop] is a raw block of assembler, then look up the
@@ -409,6 +377,16 @@
         assert reg_index > 0
         shape.append(chr(self.LOC_REG | (reg_index << 2)))
 
+    def compress_callshape(self, shape, datablockwrapper):
+        # Similar to compress_callshape() in trackgcroot.py.
+        # Returns an address to raw memory (as an integer).
+        length = len(shape)
+        rawaddr = datablockwrapper.malloc_aligned(length, 1)
+        p = rffi.cast(self.CALLSHAPE_ARRAY_PTR, rawaddr)
+        for i in range(length):
+            p[length-1-i] = rffi.cast(rffi.UCHAR, shape[i])
+        return rawaddr
+
 
 class WriteBarrierDescr(AbstractDescr):
     def __init__(self, gc_ll_descr):

Modified: pypy/trunk/pypy/jit/backend/llsupport/test/test_asmmemmgr.py
==============================================================================
--- pypy/trunk/pypy/jit/backend/llsupport/test/test_asmmemmgr.py	(original)
+++ pypy/trunk/pypy/jit/backend/llsupport/test/test_asmmemmgr.py	Wed Dec  1 12:06:57 2010
@@ -1,5 +1,6 @@
 import random
 from pypy.jit.backend.llsupport.asmmemmgr import AsmMemoryManager
+from pypy.jit.backend.llsupport.asmmemmgr import MachineDataBlockWrapper
 from pypy.jit.backend.llsupport.asmmemmgr import BlockBuilderMixin
 from pypy.rpython.lltypesystem import lltype, rffi
 
@@ -151,14 +152,10 @@
                     prev_total = new_total
 
     def test_insert_gcroot_marker(self):
+        puts = []
         class FakeGcRootMap:
-            def add_raw_gcroot_markers(self, asmmemmgr, allblocks, markers,
-                                       total_size, rawstart):
-                self.asmmemmgr = asmmemmgr
-                self.allblocks = allblocks
-                self.markers = markers
-                self.total_size = total_size
-                self.rawstart = rawstart
+            def put(self, retaddr, mark):
+                puts.append((retaddr, mark))
         #
         mc = BlockBuilderMixin()
         mc.writechar('X')
@@ -181,10 +178,8 @@
         assert p[4] == 'Z'
         assert p[5] == 'z'
         assert allblocks == [(rawstart, rawstart + 6)]
-        assert gcrootmap.markers == [(2, ['a', 'b', 'c', 'd']),
-                                     (4, ['e', 'f', 'g'])]
-        assert gcrootmap.total_size == 4 + 3
-        assert gcrootmap.rawstart == rawstart
+        assert puts == [(rawstart + 2, ['a', 'b', 'c', 'd']),
+                        (rawstart + 4, ['e', 'f', 'g'])]
 
 
 def test_blockbuildermixin(translated=True):
@@ -215,3 +210,41 @@
 
 def test_blockbuildermixin2():
     test_blockbuildermixin(translated=False)
+
+def test_machinedatablock():
+    ops = []
+    class FakeMemMgr:
+        _addr = 1597
+        def open_malloc(self, minsize):
+            result = (self._addr, self._addr + 100)
+            ops.append(('malloc', minsize) + result)
+            self._addr += 200
+            return result
+        def open_free(self, frm, to):
+            ops.append(('free', frm, to))
+            return to - frm >= 8
+    #
+    allblocks = []
+    md = MachineDataBlockWrapper(FakeMemMgr(), allblocks)
+    p = md.malloc_aligned(26, 16)
+    assert p == 1600
+    assert ops == [('malloc', 26 + 15, 1597, 1697)]
+    del ops[:]
+    #
+    p = md.malloc_aligned(26, 16)
+    assert p == 1632
+    p = md.malloc_aligned(26, 16)
+    assert p == 1664
+    assert allblocks == []
+    assert ops == []
+    #
+    p = md.malloc_aligned(27, 16)
+    assert p == 1808
+    assert allblocks == [(1597, 1697)]
+    assert ops == [('free', 1690, 1697),
+                   ('malloc', 27 + 15, 1797, 1897)]
+    del ops[:]
+    #
+    md.done()
+    assert allblocks == [(1597, 1697), (1797, 1835)]
+    assert ops == [('free', 1835, 1897)]

Modified: pypy/trunk/pypy/jit/backend/llsupport/test/test_gc.py
==============================================================================
--- pypy/trunk/pypy/jit/backend/llsupport/test/test_gc.py	(original)
+++ pypy/trunk/pypy/jit/backend/llsupport/test/test_gc.py	Wed Dec  1 12:06:57 2010
@@ -91,11 +91,27 @@
         assert shape == map(chr, [6, 7, 11, 15, 2, 0, num1a, num2b, num2a,
                                   4, 8, 12, 16])
 
+    def test_compress_callshape(self):
+        class FakeDataBlockWrapper:
+            def malloc_aligned(self, size, alignment):
+                assert alignment == 1    # here
+                assert size == 4
+                return rffi.cast(lltype.Signed, p)
+        datablockwrapper = FakeDataBlockWrapper()
+        p = lltype.malloc(rffi.CArray(lltype.Char), 4, immortal=True)
+        gcrootmap = GcRootMap_asmgcc()
+        shape = ['a', 'b', 'c', 'd']
+        gcrootmap.compress_callshape(shape, datablockwrapper)
+        assert p[0] == 'd'
+        assert p[1] == 'c'
+        assert p[2] == 'b'
+        assert p[3] == 'a'
+
     def test_put_basic(self):
         gcrootmap = GcRootMap_asmgcc()
         retaddr = 1234567890
         shapeaddr = 51627384
-        gcrootmap._put(retaddr, shapeaddr)
+        gcrootmap.put(retaddr, shapeaddr)
         assert gcrootmap._gcmap[0] == retaddr
         assert gcrootmap._gcmap[1] == shapeaddr
         p = rffi.cast(rffi.LONGP, gcrootmap.gcmapstart())
@@ -109,7 +125,7 @@
         for i in range(700):
             shapeaddr = i * 100 + 1
             retaddr = 123456789 + i
-            gcrootmap._put(retaddr, shapeaddr)
+            gcrootmap.put(retaddr, shapeaddr)
         for i in range(700):
             assert gcrootmap._gcmap[i*2+0] == 123456789 + i
             assert gcrootmap._gcmap[i*2+1] == i * 100 + 1
@@ -126,7 +142,7 @@
         for i in range(700):
             shapeaddr = i * 100       # 0 if i == 0
             retaddr = 123456789 + i
-            gcrootmap._put(retaddr, shapeaddr)
+            gcrootmap.put(retaddr, shapeaddr)
             if shapeaddr != 0:
                 expected.append((retaddr, shapeaddr))
         # at the first resize, the 0 should be removed
@@ -142,72 +158,11 @@
             # check that we can again insert 350 entries without a resize
             oldgcmap = gcrootmap._gcmap
             for i in range(0, 699, 2):
-                gcrootmap._put(515151 + i + repeat, 626262 + i)
+                gcrootmap.put(515151 + i + repeat, 626262 + i)
                 expected.append((515151 + i + repeat, 626262 + i))
             assert gcrootmap._gcmap == oldgcmap
             check()
 
-    def test_add_raw_gcroot_markers_maxalloc(self):
-        class FakeAsmMemMgr:
-            def malloc(self, minsize, maxsize):
-                assert minsize == 4
-                assert maxsize == 7
-                return (prawstart, prawstart + 8)
-        put = []
-        def fakeput(a, b):
-            put.append((a, b))
-        gcrootmap = GcRootMap_asmgcc()
-        gcrootmap._put = fakeput
-        memmgr = FakeAsmMemMgr()
-        allblocks = []
-        p = lltype.malloc(rffi.CArray(lltype.Char), 7, immortal=True)
-        prawstart = rffi.cast(lltype.Signed, p)
-        gcrootmap.add_raw_gcroot_markers(memmgr, allblocks,
-                                         [(2, ['a', 'b', 'c', 'd']),
-                                          (4, ['e', 'f', 'g'])],
-                                         4 + 3, 1200000)
-        assert allblocks == [(prawstart, prawstart + 8)]
-        assert ''.join([p[i] for i in range(7)]) == 'dcbagfe'
-        assert put == [(1200002, prawstart),
-                       (1200004, prawstart + 4)]
-
-    def test_add_raw_gcroot_markers_minalloc(self):
-        class FakeAsmMemMgr:
-            callnum = 0
-            def malloc(self, minsize, maxsize):
-                self.callnum += 1
-                if self.callnum == 1:
-                    assert minsize == 4
-                    assert maxsize == 7
-                    return (prawstart, prawstart + 6)
-                elif self.callnum == 2:
-                    assert minsize == 3
-                    assert maxsize == 3
-                    return (qrawstart, qrawstart + 5)
-                else:
-                    raise AssertionError
-        put = []
-        def fakeput(a, b):
-            put.append((a, b))
-        gcrootmap = GcRootMap_asmgcc()
-        gcrootmap._put = fakeput
-        memmgr = FakeAsmMemMgr()
-        allblocks = []
-        p = lltype.malloc(rffi.CArray(lltype.Char), 6, immortal=True)
-        prawstart = rffi.cast(lltype.Signed, p)
-        q = lltype.malloc(rffi.CArray(lltype.Char), 5, immortal=True)
-        qrawstart = rffi.cast(lltype.Signed, q)
-        gcrootmap.add_raw_gcroot_markers(memmgr, allblocks,
-                                         [(2, ['a', 'b', 'c', 'd']),
-                                          (4, ['e', 'f', 'g'])],
-                                         4 + 3, 1200000)
-        assert allblocks == [(prawstart, prawstart + 6),
-                             (qrawstart, qrawstart + 5)]
-        assert ''.join([p[i] for i in range(4)]) == 'dcba'
-        assert ''.join([q[i] for i in range(3)]) == 'gfe'
-        assert put == [(1200002, prawstart),
-                       (1200004, qrawstart)]
-
     def test_freeing_block(self):
         from pypy.jit.backend.llsupport import gc
         class Asmgcroot:

Modified: pypy/trunk/pypy/jit/backend/x86/assembler.py
==============================================================================
--- pypy/trunk/pypy/jit/backend/x86/assembler.py	(original)
+++ pypy/trunk/pypy/jit/backend/x86/assembler.py	Wed Dec  1 12:06:57 2010
@@ -1,5 +1,6 @@
 import sys, os
 from pypy.jit.backend.llsupport import symbolic
+from pypy.jit.backend.llsupport.asmmemmgr import MachineDataBlockWrapper
 from pypy.jit.metainterp.history import Const, Box, BoxInt, BoxPtr, BoxFloat
 from pypy.jit.metainterp.history import (AbstractFailDescr, INT, REF, FLOAT,
                                          LoopToken)
@@ -55,7 +56,6 @@
 DEBUG_COUNTER = lltype.Struct('DEBUG_COUNTER', ('i', lltype.Signed))
 
 class Assembler386(object):
-    _float_constants = None
     _regalloc = None
     _output_loop_log = None
 
@@ -83,6 +83,7 @@
         self.debug_counter_descr = cpu.fielddescrof(DEBUG_COUNTER, 'i')
         self.fail_boxes_count = 0
         self._current_depths_cache = (0, 0)
+        self.datablockwrapper = None
         self.teardown()
 
     def leave_jitted_hook(self):
@@ -125,10 +126,14 @@
         self.set_debug(have_debug_prints())
         debug_stop('jit-backend-counts')
 
-    def setup(self):
+    def setup(self, looptoken):
         assert self.memcpy_addr != 0, "setup_once() not called?"
         self.pending_guard_tokens = []
         self.mc = codebuf.MachineCodeBlockWrapper()
+        if self.datablockwrapper is None:
+            allblocks = self.get_asmmemmgr_blocks(looptoken)
+            self.datablockwrapper = MachineDataBlockWrapper(self.cpu.asmmemmgr,
+                                                            allblocks)
 
     def teardown(self):
         self.pending_guard_tokens = None
@@ -145,13 +150,9 @@
             debug_stop('jit-backend-counts')
 
     def _build_float_constants(self):
-        # 44 bytes: 32 bytes for the data, and up to 12 bytes for alignment
-        addr = lltype.malloc(rffi.CArray(lltype.Char), 44, flavor='raw',
-                             track_allocation=False)
-        if not we_are_translated():
-            self._keepalive_malloced_float_consts = addr
-        float_constants = rffi.cast(lltype.Signed, addr)
-        float_constants = (float_constants + 15) & ~15    # align to 16 bytes
+        datablockwrapper = MachineDataBlockWrapper(self.cpu.asmmemmgr, [])
+        float_constants = datablockwrapper.malloc_aligned(32, alignment=16)
+        datablockwrapper.done()
         addr = rffi.cast(rffi.CArrayPtr(lltype.Char), float_constants)
         qword_padding = '\x00\x00\x00\x00\x00\x00\x00\x00'
         # 0x8000000000000000
@@ -203,13 +204,18 @@
                _x86_arglocs
                _x86_debug_checksum
         '''
+        # XXX this function is too longish and contains some code
+        # duplication with assemble_bridge().  Also, we should think
+        # about not storing on 'self' attributes that will live only
+        # for the duration of compiling one loop or a one bridge.
+
         clt = CompiledLoopToken(self.cpu, looptoken.number)
         looptoken.compiled_loop_token = clt
         if not we_are_translated():
             # Arguments should be unique
             assert len(set(inputargs)) == len(inputargs)
 
-        self.setup()
+        self.setup(looptoken)
         self.currently_compiling_loop = looptoken
         funcname = self._find_debug_merge_point(operations)
         if log:
@@ -235,7 +241,7 @@
         self.write_pending_failure_recoveries()
         fullsize = self.mc.get_relative_pos()
         #
-        rawstart = self.materialize(looptoken)
+        rawstart = self.materialize_loop(looptoken)
         debug_print("Loop #%d (%s) has address %x to %x" % (
             looptoken.number, funcname,
             rawstart + self.looppos,
@@ -268,7 +274,7 @@
                         "was already compiled!")
             return
 
-        self.setup()
+        self.setup(original_loop_token)
         funcname = self._find_debug_merge_point(operations)
         if log:
             self._register_counter()
@@ -289,7 +295,7 @@
         self.write_pending_failure_recoveries()
         fullsize = self.mc.get_relative_pos()
         #
-        rawstart = self.materialize(original_loop_token)
+        rawstart = self.materialize_loop(original_loop_token)
 
         debug_print("Bridge out of guard %d (%s) has address %x to %x" %
                     (descr_number, funcname, rawstart, rawstart + codeendpos))
@@ -328,12 +334,17 @@
             p = rffi.cast(rffi.INTP, addr)
             p[0] = rffi.cast(rffi.INT, relative_target)
 
-    def materialize(self, looptoken):
+    def get_asmmemmgr_blocks(self, looptoken):
         clt = looptoken.compiled_loop_token
         if clt.asmmemmgr_blocks is None:
             clt.asmmemmgr_blocks = []
-        return self.mc.materialize(self.cpu.asmmemmgr,
-                                   clt.asmmemmgr_blocks,
+        return clt.asmmemmgr_blocks
+
+    def materialize_loop(self, looptoken):
+        self.datablockwrapper.done()      # finish using cpu.asmmemmgr
+        self.datablockwrapper = None
+        allblocks = self.get_asmmemmgr_blocks(looptoken)
+        return self.mc.materialize(self.cpu.asmmemmgr, allblocks,
                                    self.cpu.gc_ll_descr.gcrootmap)
 
     def _find_debug_merge_point(self, operations):

Modified: pypy/trunk/pypy/jit/backend/x86/regalloc.py
==============================================================================
--- pypy/trunk/pypy/jit/backend/x86/regalloc.py	(original)
+++ pypy/trunk/pypy/jit/backend/x86/regalloc.py	Wed Dec  1 12:06:57 2010
@@ -60,32 +60,6 @@
         r15: 5,
     }
 
-class FloatConstants(object):
-    BASE_CONSTANT_SIZE = 1000
-
-    def __init__(self):
-        self.cur_array_free = 0
-        self.const_id = 0
-
-    def _get_new_array(self):
-        n = self.BASE_CONSTANT_SIZE
-        # known to leak
-        self.cur_array = lltype.malloc(rffi.CArray(lltype.Float), n, # YYY leak
-                                       flavor='raw', track_allocation=False)
-        self.cur_array_free = n
-    _get_new_array._dont_inline_ = True
-
-    def record_float(self, floatval):
-        if self.cur_array_free == 0:
-            self._get_new_array()
-        arr = self.cur_array
-        n = self.cur_array_free - 1
-        arr[n] = floatval
-        self.cur_array_free = n
-        self.const_id += 1
-        return (self.const_id, rffi.cast(lltype.Signed, arr) + n * 8)
-
-
 class X86XMMRegisterManager(RegisterManager):
 
     box_types = [FLOAT]
@@ -93,20 +67,11 @@
     # we never need lower byte I hope
     save_around_call_regs = all_regs
 
-    def __init__(self, longevity, frame_manager=None, assembler=None):
-        RegisterManager.__init__(self, longevity, frame_manager=frame_manager,
-                                 assembler=assembler)
-        if assembler is None:
-            self.float_constants = FloatConstants()
-        else:
-            if assembler._float_constants is None:
-                assembler._float_constants = FloatConstants()
-            self.float_constants = assembler._float_constants
-
     def convert_to_imm(self, c):
-        const_id, adr = self.float_constants.record_float(c.getfloat())
-        return ConstFloatLoc(adr, const_id)
-        
+        adr = self.assembler.datablockwrapper.malloc_aligned(8, 8)
+        rffi.cast(rffi.CArrayPtr(rffi.DOUBLE), adr)[0] = c.getfloat()
+        return ConstFloatLoc(adr)
+
     def after_call(self, v):
         # the result is stored in st0, but we don't have this around,
         # so genop_call will move it to some frame location immediately
@@ -1108,7 +1073,8 @@
             if (isinstance(v, BoxPtr) and self.rm.stays_alive(v)):
                 assert reg in self.rm.REGLOC_TO_GCROOTMAP_REG_INDEX
                 gcrootmap.add_callee_save_reg(shape, self.rm.REGLOC_TO_GCROOTMAP_REG_INDEX[reg])
-        return shape
+        return gcrootmap.compress_callshape(shape,
+                                            self.assembler.datablockwrapper)
 
     def consider_force_token(self, op):
         loc = self.rm.force_allocate_reg(op.result)

Modified: pypy/trunk/pypy/jit/backend/x86/regloc.py
==============================================================================
--- pypy/trunk/pypy/jit/backend/x86/regloc.py	(original)
+++ pypy/trunk/pypy/jit/backend/x86/regloc.py	Wed Dec  1 12:06:57 2010
@@ -177,24 +177,15 @@
 
 class ConstFloatLoc(AssemblerLocation):
     # XXX: We have to use this class instead of just AddressLoc because
-    # AddressLoc is "untyped" and also we to have need some sort of unique
-    # identifier that we can use in _getregkey (for jump.py)
-
+    # we want a width of 8  (... I think.  Check this!)
     _immutable_ = True
-
     width = 8
 
-    def __init__(self, address, const_id):
+    def __init__(self, address):
         self.value = address
-        self.const_id = const_id
 
     def __repr__(self):
-        return '<ConstFloatLoc(%s, %s)>' % (self.value, self.const_id)
-
-    def _getregkey(self):
-        # XXX: 1000 is kind of magic: We just don't want to be confused
-        # with any registers
-        return 1000 + self.const_id
+        return '<ConstFloatLoc @%s>' % (self.value,)
 
     def location_code(self):
         return 'j'

Modified: pypy/trunk/pypy/jit/backend/x86/test/test_gc_integration.py
==============================================================================
--- pypy/trunk/pypy/jit/backend/x86/test/test_gc_integration.py	(original)
+++ pypy/trunk/pypy/jit/backend/x86/test/test_gc_integration.py	Wed Dec  1 12:06:57 2010
@@ -33,6 +33,10 @@
     def add_callee_save_reg(self, shape, reg_index):
         index_to_name = { 1: 'ebx', 2: 'esi', 3: 'edi' }
         shape.append(index_to_name[reg_index])
+    def compress_callshape(self, shape, datablockwrapper):
+        assert datablockwrapper == 'fakedatablockwrapper'
+        assert shape[0] == 'shape'
+        return ['compressed'] + shape[1:]
 
 class MockGcDescr(GcCache):
     def get_funcptr_for_new(self):
@@ -57,6 +61,7 @@
         cpu = CPU(None, None)
         cpu.setup_once()
         regalloc = RegAlloc(MockAssembler(cpu, MockGcDescr(False)))
+        regalloc.assembler.datablockwrapper = 'fakedatablockwrapper'
         boxes = [BoxPtr() for i in range(len(X86RegisterManager.all_regs))]
         longevity = {}
         for box in boxes:
@@ -79,7 +84,7 @@
         assert len(regalloc.assembler.movs) == 3
         #
         mark = regalloc.get_mark_gc_roots(cpu.gc_ll_descr.gcrootmap)
-        assert mark[0] == 'shape'
+        assert mark[0] == 'compressed'
         base = -WORD * FRAME_FIXED_SIZE
         expected = ['ebx', 'esi', 'edi', base, base-WORD, base-WORD*2]
         assert dict.fromkeys(mark[1:]) == dict.fromkeys(expected)



More information about the Pypy-commit mailing list