[pypy-svn] r71788 - in pypy/trunk/pypy: jit/backend/llsupport jit/backend/llsupport/test rpython/memory/gctransform translator/c/gcc translator/c/gcc/test translator/c/gcc/test/elf

arigo at codespeak.net arigo at codespeak.net
Fri Mar 5 09:50:22 CET 2010


Author: arigo
Date: Fri Mar  5 09:50:21 2010
New Revision: 71788

Modified:
   pypy/trunk/pypy/jit/backend/llsupport/gc.py
   pypy/trunk/pypy/jit/backend/llsupport/test/test_gc.py
   pypy/trunk/pypy/rpython/memory/gctransform/asmgcroot.py
   pypy/trunk/pypy/translator/c/gcc/instruction.py
   pypy/trunk/pypy/translator/c/gcc/test/elf/track4.s
   pypy/trunk/pypy/translator/c/gcc/test/elf/track6.s
   pypy/trunk/pypy/translator/c/gcc/test/test_trackgcroot.py
   pypy/trunk/pypy/translator/c/gcc/trackgcroot.py
Log:
Simplify a bit the encoding used for the location of asmgcroots:
by separating the EBP+N and EBP-N cases we avoid the issue of
encoding possibly-negative integers.


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	Fri Mar  5 09:50:21 2010
@@ -202,10 +202,10 @@
     """Handles locating the stack roots in the assembler.
     This is the class supporting --gcrootfinder=asmgcc.
     """
-    LOC_NOWHERE   = 0
-    LOC_REG       = 1
-    LOC_EBP_BASED = 2
-    LOC_ESP_BASED = 3
+    LOC_REG       = 0
+    LOC_ESP_PLUS  = 1
+    LOC_EBP_PLUS  = 2
+    LOC_EBP_MINUS = 3
 
     GCMAP_ARRAY = rffi.CArray(llmemory.Address)
     CALLSHAPE_ARRAY = rffi.CArray(rffi.UCHAR)
@@ -252,37 +252,38 @@
             lltype.free(oldgcmap, flavor='raw')
 
     def get_basic_shape(self):
-        return [self.LOC_EBP_BASED | 4,     # return addr: at   4(%ebp)
-                self.LOC_EBP_BASED | (-4),  # saved %ebx:  at  -4(%ebp)
-                self.LOC_EBP_BASED | (-8),  # saved %esi:  at  -8(%ebp)
-                self.LOC_EBP_BASED | (-12), # saved %edi:  at -12(%ebp)
-                self.LOC_EBP_BASED | 0,     # saved %ebp:  at    (%ebp)
+        return [self.LOC_EBP_PLUS  | 4,     # return addr: at   4(%ebp)
+                self.LOC_EBP_MINUS | 4,     # saved %ebx:  at  -4(%ebp)
+                self.LOC_EBP_MINUS | 8,     # saved %esi:  at  -8(%ebp)
+                self.LOC_EBP_MINUS | 12,    # saved %edi:  at -12(%ebp)
+                self.LOC_EBP_PLUS  | 0,     # saved %ebp:  at    (%ebp)
                 0]
 
     def add_ebp_offset(self, shape, offset):
         assert (offset & 3) == 0
-        shape.append(self.LOC_EBP_BASED | offset)
+        if offset >= 0:
+            encoded = self.LOC_EBP_PLUS | offset
+        else:
+            encoded = self.LOC_EBP_MINUS | (-offset)
+        shape.append(encoded)
 
     def add_ebx(self, shape):
-        shape.append(self.LOC_REG | 0)
+        shape.append(self.LOC_REG | 4)
 
     def add_esi(self, shape):
-        shape.append(self.LOC_REG | 4)
+        shape.append(self.LOC_REG | 8)
 
     def add_edi(self, shape):
-        shape.append(self.LOC_REG | 8)
+        shape.append(self.LOC_REG | 12)
 
     def add_ebp(self, shape):
-        shape.append(self.LOC_REG | 12)
+        shape.append(self.LOC_REG | 16)
 
     def compress_callshape(self, shape):
         # Similar to compress_callshape() in trackgcroot.py.  XXX a bit slowish
         result = []
         for loc in shape:
-            if loc < 0:
-                loc = (-loc) * 2 - 1
-            else:
-                loc = loc * 2
+            assert loc >= 0
             flag = 0
             while loc >= 0x80:
                 result.append(int(loc & 0x7F) | flag)

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	Fri Mar  5 09:50:21 2010
@@ -64,29 +64,28 @@
     def frame_pos(n):
         return -4*(4+n)
     gcrootmap = GcRootMap_asmgcc()
-    num1 = frame_pos(1)
+    num1 = frame_pos(-5)
     num2 = frame_pos(55)
     shape = gcrootmap.get_basic_shape()
     gcrootmap.add_ebp_offset(shape, num1)
     gcrootmap.add_ebp_offset(shape, num2)
-    assert shape == [6, -2, -6, -10, 2, 0, num1|2, num2|2]
+    assert shape == [6, 7, 11, 15, 2, 0, num1|2, -num2|3]
     gcrootmap.add_ebx(shape)
-    assert shape == [6, -2, -6, -10, 2, 0, num1|2, num2|2, 0|1]
+    assert shape == [6, 7, 11, 15, 2, 0, num1|2, -num2|3, 4]
     gcrootmap.add_esi(shape)
-    assert shape == [6, -2, -6, -10, 2, 0, num1|2, num2|2, 0|1, 4|1]
+    assert shape == [6, 7, 11, 15, 2, 0, num1|2, -num2|3, 4, 8]
     gcrootmap.add_edi(shape)
-    assert shape == [6, -2, -6, -10, 2, 0, num1|2, num2|2, 0|1, 4|1, 8|1]
+    assert shape == [6, 7, 11, 15, 2, 0, num1|2, -num2|3, 4, 8, 12]
     gcrootmap.add_ebp(shape)
-    assert shape == [6, -2, -6, -10, 2, 0, num1|2, num2|2, 0|1, 4|1, 8|1, 12|1]
+    assert shape == [6, 7, 11, 15, 2, 0, num1|2, -num2|3, 4, 8, 12, 16]
     #
     shapeaddr = gcrootmap.compress_callshape(shape)
     PCALLSHAPE = lltype.Ptr(GcRootMap_asmgcc.CALLSHAPE_ARRAY)
     p = llmemory.cast_adr_to_ptr(shapeaddr, PCALLSHAPE)
-    num1a = -2*(num1|2)-1
-    num2a = ((-2*(num2|2)-1) >> 7) | 128
-    num2b = (-2*(num2|2)-1) & 127
-    for i, expected in enumerate([26, 18, 10, 2,
-                                  num2a, num2b, num1a, 0, 4, 19, 11, 3, 12]):
+    num2a = ((-num2|3) >> 7) | 128
+    num2b = (-num2|3) & 127
+    for i, expected in enumerate([16, 12, 8, 4,
+                                  num2a, num2b, num1|2, 0, 2, 15, 11, 7, 6]):
         assert p[i] == expected
     #
     retaddr = rffi.cast(llmemory.Address, 1234567890)
@@ -97,14 +96,14 @@
     #
     # the same as before, but enough times to trigger a few resizes
     expected_shapeaddr = {}
-    for i in range(1, 600):
+    for i in range(1, 700):
         shape = gcrootmap.get_basic_shape()
         gcrootmap.add_ebp_offset(shape, frame_pos(i))
         shapeaddr = gcrootmap.compress_callshape(shape)
         expected_shapeaddr[i] = shapeaddr
         retaddr = rffi.cast(llmemory.Address, 123456789 + i)
         gcrootmap.put(retaddr, shapeaddr)
-    for i in range(1, 600):
+    for i in range(1, 700):
         expected_retaddr = rffi.cast(llmemory.Address, 123456789 + i)
         assert gcrootmap._gcmap[i*2+0] == expected_retaddr
         assert gcrootmap._gcmap[i*2+1] == expected_shapeaddr[i]

Modified: pypy/trunk/pypy/rpython/memory/gctransform/asmgcroot.py
==============================================================================
--- pypy/trunk/pypy/rpython/memory/gctransform/asmgcroot.py	(original)
+++ pypy/trunk/pypy/rpython/memory/gctransform/asmgcroot.py	Fri Mar  5 09:50:21 2010
@@ -313,29 +313,32 @@
         on the integer 'location' that describes it.  All locations are
         computed based on information saved by the 'callee'.
         """
+        ll_assert(location >= 0, "negative location")
         kind = location & LOC_MASK
+        offset = location & ~ LOC_MASK
         if kind == LOC_REG:   # register
-            reg = location >> 2
-            ll_assert(0 <= reg < CALLEE_SAVED_REGS, "bad register location")
+            if location == LOC_NOWHERE:
+                return llmemory.NULL
+            reg = (location >> 2) - 1
+            ll_assert(reg < CALLEE_SAVED_REGS, "bad register location")
             return callee.regs_stored_at[reg]
-        elif kind == LOC_ESP_BASED:   # in the caller stack frame at N(%esp)
-            offset = location & ~ LOC_MASK
-            ll_assert(offset >= 0, "bad %esp-based location")
+        elif kind == LOC_ESP_PLUS:    # in the caller stack frame at N(%esp)
             esp_in_caller = callee.frame_address + 4
             return esp_in_caller + offset
-        elif kind == LOC_EBP_BASED:   # in the caller stack frame at N(%ebp)
-            offset = location & ~ LOC_MASK
+        elif kind == LOC_EBP_PLUS:    # in the caller stack frame at N(%ebp)
             ebp_in_caller = callee.regs_stored_at[INDEX_OF_EBP].address[0]
             return ebp_in_caller + offset
-        else:
-            return llmemory.NULL
+        else:  # kind == LOC_EBP_MINUS:   at -N(%ebp)
+            ebp_in_caller = callee.regs_stored_at[INDEX_OF_EBP].address[0]
+            return ebp_in_caller - offset
 
 
-LOC_NOWHERE   = 0
-LOC_REG       = 1
-LOC_EBP_BASED = 2
-LOC_ESP_BASED = 3
+LOC_REG       = 0
+LOC_ESP_PLUS  = 1
+LOC_EBP_PLUS  = 2
+LOC_EBP_MINUS = 3
 LOC_MASK      = 0x03
+LOC_NOWHERE   = LOC_REG | 0
 
 # ____________________________________________________________
 
@@ -440,9 +443,6 @@
                 break
             value = (value - 0x80) << 7
         self.addr = addr
-        if value & 1:
-            value = ~ value
-        value = value >> 1
         return value
 
 # ____________________________________________________________

Modified: pypy/trunk/pypy/translator/c/gcc/instruction.py
==============================================================================
--- pypy/trunk/pypy/translator/c/gcc/instruction.py	(original)
+++ pypy/trunk/pypy/translator/c/gcc/instruction.py	Fri Mar  5 09:50:21 2010
@@ -1,13 +1,21 @@
-LOC_NOWHERE   = 0
-LOC_REG       = 1
-LOC_EBP_BASED = 2
-LOC_ESP_BASED = 3
+LOC_REG       = 0
+LOC_ESP_PLUS  = 1
+LOC_EBP_PLUS  = 2
+LOC_EBP_MINUS = 3
 LOC_MASK      = 0x03
+LOC_NOWHERE   = LOC_REG | 0
 
-def frameloc(base, offset):
-    assert base in (LOC_EBP_BASED, LOC_ESP_BASED)
+def frameloc_esp(offset):
+    assert offset >= 0
     assert offset % 4 == 0
-    return base | offset
+    return LOC_ESP_PLUS | offset
+
+def frameloc_ebp(offset):
+    assert offset % 4 == 0
+    if offset >= 0:
+        return LOC_EBP_PLUS | offset
+    else:
+        return LOC_EBP_MINUS | (-offset)
 
 
 class SomeNewValue(object):
@@ -40,12 +48,12 @@
             # try to use esp-relative addressing
             ofs_from_esp = framesize + self.ofs_from_frame_end
             if ofs_from_esp % 2 == 0:
-                return frameloc(LOC_ESP_BASED, ofs_from_esp)
+                return frameloc_esp(ofs_from_esp)
             # we can get an odd value if the framesize is marked as bogus
             # by visit_andl()
         assert uses_frame_pointer
         ofs_from_ebp = self.ofs_from_frame_end + 4
-        return frameloc(LOC_EBP_BASED, ofs_from_ebp)
+        return frameloc_ebp(ofs_from_ebp)
 
 
 class Insn(object):

Modified: pypy/trunk/pypy/translator/c/gcc/test/elf/track4.s
==============================================================================
--- pypy/trunk/pypy/translator/c/gcc/test/elf/track4.s	(original)
+++ pypy/trunk/pypy/translator/c/gcc/test/elf/track4.s	Fri Mar  5 09:50:21 2010
@@ -26,7 +26,7 @@
 	movl	%esi, %ebx
 	movl	$nonsense, %esi
 	call	foobar
-	;; expected {4(%ebp) | -8(%ebp), %ebx, -4(%ebp), (%ebp) | -12(%ebp), 4(%esp)}
+	;; expected {4(%ebp) | -8(%ebp), %ebx, -4(%ebp), (%ebp) | 4(%esp), -12(%ebp)}
 	addl	%edi, %eax
 	movl	4(%esp), %eax
 	movl	%ebx, %esi

Modified: pypy/trunk/pypy/translator/c/gcc/test/elf/track6.s
==============================================================================
--- pypy/trunk/pypy/translator/c/gcc/test/elf/track6.s	(original)
+++ pypy/trunk/pypy/translator/c/gcc/test/elf/track6.s	Fri Mar  5 09:50:21 2010
@@ -13,7 +13,7 @@
 	movl	$globalptr2, (%esp)
 	pushl	$0
 	call	foobar
-	;; expected {4(%ebp) | %ebx, %esi, %edi, (%ebp) | -4(%ebp), 4(%esp)}
+	;; expected {4(%ebp) | %ebx, %esi, %edi, (%ebp) | 4(%esp), -4(%ebp)}
 	popl	%eax
 #APP
 	/* GCROOT -4(%ebp) */

Modified: pypy/trunk/pypy/translator/c/gcc/test/test_trackgcroot.py
==============================================================================
--- pypy/trunk/pypy/translator/c/gcc/test/test_trackgcroot.py	(original)
+++ pypy/trunk/pypy/translator/c/gcc/test/test_trackgcroot.py	Fri Mar  5 09:50:21 2010
@@ -3,7 +3,8 @@
 from pypy.translator.c.gcc.trackgcroot import format_location
 from pypy.translator.c.gcc.trackgcroot import format_callshape
 from pypy.translator.c.gcc.trackgcroot import LOC_NOWHERE, LOC_REG
-from pypy.translator.c.gcc.trackgcroot import LOC_EBP_BASED, LOC_ESP_BASED
+from pypy.translator.c.gcc.trackgcroot import LOC_EBP_PLUS, LOC_EBP_MINUS
+from pypy.translator.c.gcc.trackgcroot import LOC_ESP_PLUS
 from pypy.translator.c.gcc.trackgcroot import ElfAssemblerParser
 from pypy.translator.c.gcc.trackgcroot import DarwinAssemblerParser
 from pypy.translator.c.gcc.trackgcroot import compress_callshape
@@ -16,32 +17,31 @@
 
 def test_format_location():
     assert format_location(LOC_NOWHERE) == '?'
-    assert format_location(LOC_REG | (0<<2)) == '%ebx'
-    assert format_location(LOC_REG | (1<<2)) == '%esi'
-    assert format_location(LOC_REG | (2<<2)) == '%edi'
-    assert format_location(LOC_REG | (3<<2)) == '%ebp'
-    assert format_location(LOC_EBP_BASED + 0) == '(%ebp)'
-    assert format_location(LOC_EBP_BASED + 4) == '4(%ebp)'
-    assert format_location(LOC_EBP_BASED - 4) == '-4(%ebp)'
-    assert format_location(LOC_ESP_BASED + 0) == '(%esp)'
-    assert format_location(LOC_ESP_BASED + 4) == '4(%esp)'
-    assert format_location(LOC_ESP_BASED - 4) == '-4(%esp)'
+    assert format_location(LOC_REG | (1<<2)) == '%ebx'
+    assert format_location(LOC_REG | (2<<2)) == '%esi'
+    assert format_location(LOC_REG | (3<<2)) == '%edi'
+    assert format_location(LOC_REG | (4<<2)) == '%ebp'
+    assert format_location(LOC_EBP_PLUS + 0) == '(%ebp)'
+    assert format_location(LOC_EBP_PLUS + 4) == '4(%ebp)'
+    assert format_location(LOC_EBP_MINUS + 4) == '-4(%ebp)'
+    assert format_location(LOC_ESP_PLUS + 0) == '(%esp)'
+    assert format_location(LOC_ESP_PLUS + 4) == '4(%esp)'
 
 def test_format_callshape():
     expected = ('{4(%ebp) '               # position of the return address
                 '| 8(%ebp), 12(%ebp), 16(%ebp), 20(%ebp) '  # 4 saved regs
                 '| 24(%ebp), 28(%ebp)}')                    # GC roots
-    assert format_callshape((LOC_EBP_BASED+4,
-                             LOC_EBP_BASED+8,
-                             LOC_EBP_BASED+12,
-                             LOC_EBP_BASED+16,
-                             LOC_EBP_BASED+20,
-                             LOC_EBP_BASED+24,
-                             LOC_EBP_BASED+28)) == expected
+    assert format_callshape((LOC_EBP_PLUS+4,
+                             LOC_EBP_PLUS+8,
+                             LOC_EBP_PLUS+12,
+                             LOC_EBP_PLUS+16,
+                             LOC_EBP_PLUS+20,
+                             LOC_EBP_PLUS+24,
+                             LOC_EBP_PLUS+28)) == expected
 
 def test_compress_callshape():
-    shape = (1, -3, 0x1234, -0x5678, 0x234567,
-             -0x765432, 0x61626364, -0x41424344)
+    shape = (1, 127, 0x1234, 0x5678, 0x234567,
+             0x765432, 0x61626364, 0x41424344)
     bytes = list(compress_callshape(shape))
     print bytes
     assert len(bytes) == 1+1+2+3+4+4+5+5+1

Modified: pypy/trunk/pypy/translator/c/gcc/trackgcroot.py
==============================================================================
--- pypy/trunk/pypy/translator/c/gcc/trackgcroot.py	(original)
+++ pypy/trunk/pypy/translator/c/gcc/trackgcroot.py	Fri Mar  5 09:50:21 2010
@@ -9,9 +9,11 @@
 from pypy.translator.c.gcc.instruction import InsnGCROOT
 from pypy.translator.c.gcc.instruction import InsnStackAdjust
 from pypy.translator.c.gcc.instruction import InsnCannotFollowEsp
-from pypy.translator.c.gcc.instruction import LocalVar, somenewvalue, frameloc
+from pypy.translator.c.gcc.instruction import LocalVar, somenewvalue
+from pypy.translator.c.gcc.instruction import frameloc_esp, frameloc_ebp
 from pypy.translator.c.gcc.instruction import LOC_REG, LOC_NOWHERE, LOC_MASK
-from pypy.translator.c.gcc.instruction import LOC_EBP_BASED, LOC_ESP_BASED
+from pypy.translator.c.gcc.instruction import LOC_EBP_PLUS, LOC_EBP_MINUS
+from pypy.translator.c.gcc.instruction import LOC_ESP_PLUS
 
 class FunctionGcRootTracker(object):
     skip = 0
@@ -69,9 +71,9 @@
             if self.is_stack_bottom:
                 retaddr = LOC_NOWHERE     # end marker for asmgcroot.py
             elif self.uses_frame_pointer:
-                retaddr = frameloc(LOC_EBP_BASED, 4)
+                retaddr = frameloc_ebp(4)
             else:
-                retaddr = frameloc(LOC_ESP_BASED, insn.framesize)
+                retaddr = frameloc_esp(insn.framesize)
             shape = [retaddr]
             # the first gcroots are always the ones corresponding to
             # the callee-saved registers
@@ -736,7 +738,7 @@
     EBP     = '%ebp'
     EAX     = '%eax'
     CALLEE_SAVE_REGISTERS = ['%ebx', '%esi', '%edi', '%ebp']
-    REG2LOC = dict((_reg, LOC_REG | (_i<<2))
+    REG2LOC = dict((_reg, LOC_REG | ((_i+1)<<2))
                    for _i, _reg in enumerate(CALLEE_SAVE_REGISTERS))
     OPERAND = r'(?:[-\w$%+.:@"]+(?:[(][\w%,]+[)])?|[(][\w%,]+[)])'
     LABEL   = r'([a-zA-Z_$.][a-zA-Z0-9_$@.]*)'
@@ -808,7 +810,7 @@
     EBP = 'ebp'
     EAX = 'eax'
     CALLEE_SAVE_REGISTERS = ['ebx', 'esi', 'edi', 'ebp']
-    REG2LOC = dict((_reg, LOC_REG | (_i<<2))
+    REG2LOC = dict((_reg, LOC_REG | ((_i+1)<<2))
                    for _i, _reg in enumerate(CALLEE_SAVE_REGISTERS))
     TOP_OF_STACK = 'DWORD PTR [esp]'
 
@@ -1453,19 +1455,24 @@
     # in the stack frame at an address relative to either %esp or %ebp.
     # The last two bits of the location number are used to tell the cases
     # apart; see format_location().
+    assert loc >= 0
     kind = loc & LOC_MASK
-    if kind == LOC_NOWHERE:
-        return '?'
-    elif kind == LOC_REG:
-        reg = loc >> 2
-        assert 0 <= reg <= 3
+    if kind == LOC_REG:
+        if loc == LOC_NOWHERE:
+            return '?'
+        reg = (loc >> 2) - 1
         return ElfFunctionGcRootTracker.CALLEE_SAVE_REGISTERS[reg]
     else:
-        if kind == LOC_EBP_BASED:
+        offset = loc & ~ LOC_MASK
+        if kind == LOC_EBP_PLUS:
             result = '(%ebp)'
-        else:
+        elif kind == LOC_EBP_MINUS:
+            result = '(%ebp)'
+            offset = -offset
+        elif kind == LOC_ESP_PLUS:
             result = '(%esp)'
-        offset = loc & ~ LOC_MASK
+        else:
+            assert 0, kind
         if offset != 0:
             result = str(offset) + result
         return result
@@ -1531,10 +1538,7 @@
     shape.insert(5, 0)
     result = []
     for loc in shape:
-        if loc < 0:
-            loc = (-loc) * 2 - 1
-        else:
-            loc = loc * 2
+        assert loc >= 0
         flag = 0
         while loc >= 0x80:
             result.append(int(loc & 0x7F) | flag)
@@ -1557,9 +1561,6 @@
             if b < 0x80:
                 break
             value = (value - 0x80) << 7
-        if value & 1:
-            value = ~ value
-        value = value >> 1
         result.append(value)
     result.reverse()
     assert result[5] == 0



More information about the Pypy-commit mailing list