[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