[pypy-svn] r67300 - in pypy/branch/pyjitpl5-llmodel/pypy/jit/backend: llsupport llsupport/test x86

arigo at codespeak.net arigo at codespeak.net
Sat Aug 29 13:00:21 CEST 2009


Author: arigo
Date: Sat Aug 29 13:00:19 2009
New Revision: 67300

Added:
   pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/   (props changed)
   pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/__init__.py   (contents, props changed)
   pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/descr.py   (contents, props changed)
   pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/gc.py
      - copied, changed from r67299, pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/x86/gc.py
   pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/llmodel.py   (contents, props changed)
   pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/symbolic.py
      - copied, changed from r67299, pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/x86/symbolic.py
   pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/test/   (props changed)
   pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/test/__init__.py   (contents, props changed)
   pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/test/test_descr.py   (contents, props changed)
Removed:
   pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/x86/gc.py
   pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/x86/symbolic.py
Log:
Start to move some things from the x86 backend to a generic
llsupport directory.  Write an optimized implementation
of field and array descrs.


Added: pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/__init__.py
==============================================================================

Added: pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/descr.py
==============================================================================
--- (empty file)
+++ pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/descr.py	Sat Aug 29 13:00:19 2009
@@ -0,0 +1,117 @@
+from pypy.rpython.lltypesystem import lltype
+from pypy.jit.backend.llsupport import symbolic
+from pypy.jit.metainterp.history import AbstractDescr
+
+# The point of the class organization in this file is to make instances
+# as compact as possible.  This is done by not storing the field size or
+# the 'is_pointer_field' flag in the instance itself but in the class
+# (in methods actually) using a few classes instead of just one.
+
+
+# ____________________________________________________________
+# FieldDescrs
+
+class AbstractFieldDescr(AbstractDescr):
+
+    def __init__(self, offset):
+        self.offset = offset
+
+    def sort_key(self):
+        return self.offset
+
+    def get_field_size(self, translate_support_code):
+        raise NotImplementedError
+
+    def is_pointer_field(self):
+        return False        # unless overridden by GcPtrFieldDescr
+
+
+class NonGcPtrFieldDescr(AbstractFieldDescr):
+    def get_field_size(self, translate_support_code):
+        return symbolic.get_size_of_ptr(translate_support_code)
+
+class GcPtrFieldDescr(NonGcPtrFieldDescr):
+    def is_pointer_field(self):
+        return True
+
+def getFieldDescrClass(TYPE):
+    return getDescrClass(TYPE, AbstractFieldDescr, GcPtrFieldDescr,
+                         NonGcPtrFieldDescr, 'Field')
+
+def get_field_descr(STRUCT, fieldname, translate_support_code, _cache={}):
+    try:
+        return _cache[STRUCT, fieldname, translate_support_code]
+    except KeyError:
+        offset, _ = symbolic.get_field_token(STRUCT, fieldname,
+                                             translate_support_code)
+        FIELDTYPE = getattr(STRUCT, fieldname)
+        fielddescr = getFieldDescrClass(FIELDTYPE)(offset)
+        _cache[STRUCT, fieldname, translate_support_code] = fielddescr
+        return fielddescr
+
+
+# ____________________________________________________________
+# ArrayDescrs
+
+_A = lltype.GcArray(lltype.Signed)     # a random gcarray
+
+
+class AbstractArrayDescr(AbstractDescr):
+
+    def get_base_size(self, translate_support_code):
+        basesize, _, _ = symbolic.get_array_token(_A, translate_support_code)
+        return basesize
+
+    def get_ofs_length(self, translate_support_code):
+        _, _, ofslength = symbolic.get_array_token(_A, translate_support_code)
+        return ofslength
+
+    def get_item_size(self, translate_support_code):
+        raise NotImplementedError
+
+    def is_array_of_pointers(self):
+        return False        # unless overridden by GcPtrArrayDescr
+
+
+class NonGcPtrArrayDescr(AbstractArrayDescr):
+    def get_item_size(self, translate_support_code):
+        return symbolic.get_size_of_ptr(translate_support_code)
+
+class GcPtrArrayDescr(NonGcPtrArrayDescr):
+    def is_array_of_pointers(self):
+        return True
+
+def getArrayDescrClass(ARRAY):
+    return getDescrClass(ARRAY.OF, AbstractArrayDescr, GcPtrArrayDescr,
+                         NonGcPtrArrayDescr, 'Array')
+
+def get_array_descr(ARRAY, _cache={}):
+    try:
+        return _cache[ARRAY]
+    except KeyError:
+        arraydescr = getArrayDescrClass(ARRAY)()
+        _cache[ARRAY] = arraydescr
+        return arraydescr
+
+
+# ____________________________________________________________
+
+def getDescrClass(TYPE, AbstractDescr, GcPtrDescr, NonGcPtrDescr,
+                  nameprefix, _cache={}):
+    if isinstance(TYPE, lltype.Ptr):
+        if TYPE.TO._gckind == 'gc':
+            return GcPtrDescr
+        else:
+            return NonGcPtrDescr
+    try:
+        return _cache[nameprefix, TYPE]
+    except KeyError:
+        #
+        class Descr(AbstractDescr):
+            def get_field_size(self, translate_support_code):
+                return symbolic.get_size(TYPE, translate_support_code)
+            get_item_size = get_field_size
+        #
+        Descr.__name__ = '%s%sDescr' % (TYPE._name, nameprefix)
+        _cache[nameprefix, TYPE] = Descr
+        return Descr

Copied: pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/gc.py (from r67299, pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/x86/gc.py)
==============================================================================
--- pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/x86/gc.py	(original)
+++ pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/gc.py	Sat Aug 29 13:00:19 2009
@@ -3,11 +3,7 @@
 from pypy.rpython.lltypesystem.lloperation import llop
 from pypy.rpython.annlowlevel import llhelper
 from pypy.translator.tool.cbuild import ExternalCompilationInfo
-from pypy.jit.backend.x86 import symbolic
-from pypy.jit.backend.x86.runner import ConstDescr3
-from pypy.jit.backend.x86.ri386 import MODRM, IMM32, mem, imm32, rel32, heap
-from pypy.jit.backend.x86.ri386 import REG, eax, ecx, edx
-from pypy.jit.backend.x86.assembler import WORD
+from pypy.jit.backend.llsupport import symbolic
 
 # ____________________________________________________________
 

Added: pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/llmodel.py
==============================================================================
--- (empty file)
+++ pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/llmodel.py	Sat Aug 29 13:00:19 2009
@@ -0,0 +1,19 @@
+from pypy.jit.backend.model import AbstractCPU
+from pypy.jit.backend.llsupport.descr import get_field_descr, get_array_descr
+
+
+class AbstractLLCPU(AbstractCPU):
+
+    def __init__(self, rtyper, stats, translate_support_code=False,
+                 gcdescr=None):
+        from pypy.jit.backend.llsupport.gc import get_ll_description
+        self.rtyper = rtyper
+        self.stats = stats
+        self.translate_support_code = translate_support_code
+        self.gc_ll_descr = get_ll_description(gcdescr, self)
+
+    def fielddescrof(self, STRUCT, fieldname):
+        return get_field_descr(STRUCT, fieldname, self.translate_support_code)
+
+    def arraydescrof(self, A):
+        return get_array_descr(A)

Copied: pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/symbolic.py (from r67299, pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/x86/symbolic.py)
==============================================================================
--- pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/x86/symbolic.py	(original)
+++ pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/symbolic.py	Sat Aug 29 13:00:19 2009
@@ -21,6 +21,10 @@
     return ctypes.sizeof(ctype)
 
 @specialize.memo()
+def get_size_of_ptr(translate_support_code):
+    return get_size(llmemory.GCREF, translate_support_code)
+
+ at specialize.memo()
 def get_array_token(T, translate_support_code):
     # T can be an array or a var-sized structure
     if translate_support_code:

Added: pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/test/__init__.py
==============================================================================

Added: pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/test/test_descr.py
==============================================================================
--- (empty file)
+++ pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/test/test_descr.py	Sat Aug 29 13:00:19 2009
@@ -0,0 +1,86 @@
+from pypy.rpython.lltypesystem import lltype, rffi
+from pypy.jit.backend.llsupport.descr import *
+from pypy.rlib.objectmodel import Symbolic
+
+
+def test_get_field_descr():
+    U = lltype.Struct('U')
+    T = lltype.GcStruct('T')
+    S = lltype.GcStruct('S', ('x', lltype.Char),
+                             ('y', lltype.Ptr(T)),
+                             ('z', lltype.Ptr(U)))
+    assert getFieldDescrClass(lltype.Ptr(T)) is GcPtrFieldDescr
+    assert getFieldDescrClass(lltype.Ptr(U)) is NonGcPtrFieldDescr
+    cls = getFieldDescrClass(lltype.Char)
+    assert cls != getFieldDescrClass(lltype.Signed)
+    assert cls == getFieldDescrClass(lltype.Char)
+    #
+    assert get_field_descr(S, 'y', False) == get_field_descr(S, 'y', False)
+    assert get_field_descr(S, 'y', False) != get_field_descr(S, 'y', True)
+    for tsc in [False, True]:
+        descr_x = get_field_descr(S, 'x', tsc)
+        descr_y = get_field_descr(S, 'y', tsc)
+        descr_z = get_field_descr(S, 'z', tsc)
+        assert descr_x.__class__ is cls
+        assert descr_y.__class__ is GcPtrFieldDescr
+        assert descr_z.__class__ is NonGcPtrFieldDescr
+        if not tsc:
+            assert descr_x.offset < descr_y.offset < descr_z.offset
+            assert descr_x.get_field_size(False) == rffi.sizeof(lltype.Char)
+            assert descr_y.get_field_size(False) == rffi.sizeof(lltype.Ptr(T))
+            assert descr_z.get_field_size(False) == rffi.sizeof(lltype.Ptr(U))
+        else:
+            assert isinstance(descr_x.offset, Symbolic)
+            assert isinstance(descr_y.offset, Symbolic)
+            assert isinstance(descr_z.offset, Symbolic)
+            assert isinstance(descr_x.get_field_size(True), Symbolic)
+            assert isinstance(descr_y.get_field_size(True), Symbolic)
+            assert isinstance(descr_z.get_field_size(True), Symbolic)
+        assert not descr_x.is_pointer_field()
+        assert     descr_y.is_pointer_field()
+        assert not descr_z.is_pointer_field()
+
+
+def test_get_array_descr():
+    U = lltype.Struct('U')
+    T = lltype.GcStruct('T')
+    A1 = lltype.GcArray(lltype.Char)
+    A2 = lltype.GcArray(lltype.Ptr(T))
+    A3 = lltype.GcArray(lltype.Ptr(U))
+    assert getArrayDescrClass(A2) is GcPtrArrayDescr
+    assert getArrayDescrClass(A3) is NonGcPtrArrayDescr
+    cls = getArrayDescrClass(A1)
+    assert cls != getArrayDescrClass(lltype.GcArray(lltype.Signed))
+    assert cls == getArrayDescrClass(lltype.GcArray(lltype.Char))
+    #
+    descr1 = get_array_descr(A1)
+    descr2 = get_array_descr(A2)
+    descr3 = get_array_descr(A3)
+    assert descr1.__class__ is cls
+    assert descr2.__class__ is GcPtrArrayDescr
+    assert descr3.__class__ is NonGcPtrArrayDescr
+    assert descr1 == get_array_descr(lltype.GcArray(lltype.Char))
+    assert not descr1.is_array_of_pointers()
+    assert     descr2.is_array_of_pointers()
+    assert not descr3.is_array_of_pointers()
+    #
+    WORD = rffi.sizeof(lltype.Signed)
+    assert descr1.get_base_size(False) == WORD
+    assert descr2.get_base_size(False) == WORD
+    assert descr3.get_base_size(False) == WORD
+    assert descr1.get_ofs_length(False) == 0
+    assert descr2.get_ofs_length(False) == 0
+    assert descr3.get_ofs_length(False) == 0
+    assert descr1.get_item_size(False) == rffi.sizeof(lltype.Char)
+    assert descr2.get_item_size(False) == rffi.sizeof(lltype.Ptr(T))
+    assert descr3.get_item_size(False) == rffi.sizeof(lltype.Ptr(U))
+    #
+    assert isinstance(descr1.get_base_size(True), Symbolic)
+    assert isinstance(descr2.get_base_size(True), Symbolic)
+    assert isinstance(descr3.get_base_size(True), Symbolic)
+    assert isinstance(descr1.get_ofs_length(True), Symbolic)
+    assert isinstance(descr2.get_ofs_length(True), Symbolic)
+    assert isinstance(descr3.get_ofs_length(True), Symbolic)
+    assert isinstance(descr1.get_item_size(True), Symbolic)
+    assert isinstance(descr2.get_item_size(True), Symbolic)
+    assert isinstance(descr3.get_item_size(True), Symbolic)



More information about the Pypy-commit mailing list