[pypy-svn] r67331 - in pypy/branch/pyjitpl5-llmodel/pypy: jit/backend jit/backend/llsupport jit/backend/llsupport/test jit/backend/x86 jit/backend/x86/test jit/metainterp rpython/memory/gctransform
arigo at codespeak.net
arigo at codespeak.net
Sat Aug 29 23:00:30 CEST 2009
Author: arigo
Date: Sat Aug 29 23:00:29 2009
New Revision: 67331
Added:
pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/test/test_gc.py (contents, props changed)
Modified:
pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/descr.py
pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/gc.py
pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/llmodel.py
pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/test/test_descr.py
pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/model.py
pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/x86/runner.py
pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/x86/test/test_zrpy_gc.py
pypy/branch/pyjitpl5-llmodel/pypy/jit/metainterp/warmspot.py
pypy/branch/pyjitpl5-llmodel/pypy/rpython/memory/gctransform/framework.py
Log:
In-progress. We can now at least test directly the code in gc.py.
Modified: pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/descr.py
==============================================================================
--- pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/descr.py (original)
+++ pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/descr.py Sat Aug 29 23:00:29 2009
@@ -1,4 +1,3 @@
-import weakref
from pypy.rpython.lltypesystem import lltype
from pypy.jit.backend.llsupport import symbolic
from pypy.jit.metainterp.history import AbstractDescr, getkind, BoxInt, BoxPtr
@@ -11,6 +10,21 @@
# (in methods actually) using a few classes instead of just one.
+class GcCache(object):
+ def __init__(self, translate_support_code):
+ self.translate_support_code = translate_support_code
+ self._cache_size = {}
+ self._cache_field = {}
+ self._cache_array = {}
+ self._cache_call = {}
+
+ def init_size_descr(self, STRUCT, sizedescr):
+ pass
+
+ def init_array_descr(self, ARRAY, arraydescr):
+ pass
+
+
# ____________________________________________________________
# SizeDescrs
@@ -23,15 +37,15 @@
BaseSizeDescr = SizeDescr
-def get_size_descr(STRUCT, translate_support_code,
- _cache=weakref.WeakKeyDictionary()):
+def get_size_descr(gccache, STRUCT):
+ cache = gccache._cache_size
try:
- return _cache[STRUCT][translate_support_code]
+ return cache[STRUCT]
except KeyError:
- size = symbolic.get_size(STRUCT, translate_support_code)
+ size = symbolic.get_size(STRUCT, gccache.translate_support_code)
sizedescr = SizeDescr(size)
- cachedict = _cache.setdefault(STRUCT, {})
- cachedict[translate_support_code] = sizedescr
+ gccache.init_size_descr(STRUCT, sizedescr)
+ cache[STRUCT] = sizedescr
return sizedescr
@@ -70,17 +84,17 @@
return getDescrClass(TYPE, BaseFieldDescr, GcPtrFieldDescr,
NonGcPtrFieldDescr, 'Field')
-def get_field_descr(STRUCT, fieldname, translate_support_code,
- _cache=weakref.WeakKeyDictionary()):
+def get_field_descr(gccache, STRUCT, fieldname):
+ cache = gccache._cache_field
try:
- return _cache[STRUCT][fieldname, translate_support_code]
+ return cache[STRUCT][fieldname]
except KeyError:
offset, _ = symbolic.get_field_token(STRUCT, fieldname,
- translate_support_code)
+ gccache.translate_support_code)
FIELDTYPE = getattr(STRUCT, fieldname)
fielddescr = getFieldDescrClass(FIELDTYPE)(offset)
- cachedict = _cache.setdefault(STRUCT, {})
- cachedict[fieldname, translate_support_code] = fielddescr
+ cachedict = cache.setdefault(STRUCT, {})
+ cachedict[fieldname] = fielddescr
return fielddescr
@@ -91,6 +105,7 @@
class BaseArrayDescr(AbstractDescr):
+ _clsname = ''
def get_base_size(self, translate_support_code):
basesize, _, _ = symbolic.get_array_token(_A, translate_support_code)
@@ -124,9 +139,10 @@
return getDescrClass(ARRAY.OF, BaseArrayDescr, GcPtrArrayDescr,
NonGcPtrArrayDescr, 'Array')
-def get_array_descr(ARRAY, _cache=weakref.WeakKeyDictionary()):
+def get_array_descr(gccache, ARRAY):
+ cache = gccache._cache_array
try:
- return _cache[ARRAY]
+ return cache[ARRAY]
except KeyError:
arraydescr = getArrayDescrClass(ARRAY)()
# verify basic assumption that all arrays' basesize and ofslength
@@ -135,7 +151,8 @@
assert basesize == arraydescr.get_base_size(False)
assert itemsize == arraydescr.get_item_size(False)
assert ofslength == arraydescr.get_ofs_length(False)
- _cache[ARRAY] = arraydescr
+ gccache.init_array_descr(ARRAY, arraydescr)
+ cache[ARRAY] = arraydescr
return arraydescr
@@ -144,6 +161,7 @@
class BaseCallDescr(AbstractDescr):
call_loop = None
+ arg_classes = [] # <-- annotation hack
def __init__(self, arg_classes):
self.arg_classes = arg_classes # list of BoxInt/BoxPtr classes
@@ -196,7 +214,7 @@
return self.result_size
-def get_call_descr(ARGS, RESULT, translate_support_code, cache):
+def get_call_descr(gccache, ARGS, RESULT):
arg_classes = []
for ARG in ARGS:
kind = getkind(ARG)
@@ -207,9 +225,10 @@
if RESULT is lltype.Void:
result_size = 0
else:
- result_size = symbolic.get_size(RESULT, translate_support_code)
+ result_size = symbolic.get_size(RESULT, gccache.translate_support_code)
ptr = isinstance(RESULT, lltype.Ptr) and RESULT.TO._gckind == 'gc'
- key = (translate_support_code, tuple(arg_classes), result_size, ptr)
+ key = (tuple(arg_classes), result_size, ptr)
+ cache = gccache._cache_call
try:
return cache[key]
except KeyError:
Modified: pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/gc.py
==============================================================================
--- pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/gc.py (original)
+++ pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/gc.py Sat Aug 29 23:00:29 2009
@@ -1,4 +1,5 @@
from pypy.rlib import rgc
+from pypy.rlib.objectmodel import we_are_translated
from pypy.rpython.lltypesystem import lltype, llmemory, rffi, rclass, rstr
from pypy.rpython.lltypesystem.lloperation import llop
from pypy.rpython.annlowlevel import llhelper
@@ -6,11 +7,13 @@
from pypy.jit.backend.llsupport import symbolic
from pypy.jit.backend.llsupport.symbolic import WORD
from pypy.jit.backend.llsupport.descr import BaseSizeDescr, BaseArrayDescr
+from pypy.jit.backend.llsupport.descr import GcCache, get_field_descr
# ____________________________________________________________
-class GcLLDescription:
- def __init__(self, gcdescr, cpu):
+class GcLLDescription(GcCache):
+ def __init__(self, gcdescr, translator=None):
+ GcCache.__init__(self, translator is not None)
self.gcdescr = gcdescr
def _freeze_(self):
return True
@@ -24,11 +27,10 @@
class GcLLDescr_boehm(GcLLDescription):
moving_gc = False
gcrootmap = None
- array_length_ofs = 0
- def __init__(self, gcdescr, cpu):
+ def __init__(self, gcdescr, translator):
+ GcLLDescription.__init__(self, gcdescr, translator)
# grab a pointer to the Boehm 'malloc' function
- self.translate_support_code = cpu.translate_support_code
compilation_info = ExternalCompilationInfo(libraries=['gc'])
malloc_fn_ptr = rffi.llexternal("GC_local_malloc",
[lltype.Signed], # size_t, but good enough
@@ -90,7 +92,10 @@
get_funcptr_for_newstr = None
get_funcptr_for_newunicode = None
+
# ____________________________________________________________
+# All code below is for the hybrid GC
+
class GcRefList:
"""Handles all references from the generated assembler to GC objects.
@@ -104,7 +109,9 @@
HASHTABLE_SIZE = 1 << HASHTABLE_BITS
def __init__(self):
- self.list = self.alloc_gcref_list(2000)
+ if we_are_translated(): n = 2000
+ else: n = 10 # tests only
+ self.list = self.alloc_gcref_list(n)
self.nextindex = 0
self.oldlists = []
# A pseudo dictionary: it is fixed size, and it may contain
@@ -122,8 +129,11 @@
def alloc_gcref_list(self, n):
# Important: the GRREF_LISTs allocated are *non-movable*. This
# requires support in the gc (only the hybrid GC supports it so far).
- list = rgc.malloc_nonmovable(self.GCREF_LIST, n)
- assert list, "malloc_nonmovable failed!"
+ if we_are_translated():
+ list = rgc.malloc_nonmovable(self.GCREF_LIST, n)
+ assert list, "malloc_nonmovable failed!"
+ else:
+ list = lltype.malloc(self.GCREF_LIST, n) # for tests only
return list
def get_address_of_gcref(self, gcref):
@@ -136,7 +146,9 @@
hash &= self.HASHTABLE_SIZE - 1
addr_ref = self.hashtable[hash]
# the following test is safe anyway, because the addresses found
- # in the hashtable are always the addresses of nonmovable stuff:
+ # in the hashtable are always the addresses of nonmovable stuff
+ # ('addr_ref' is an address inside self.list, not directly the
+ # address of a real moving GC object -- that's 'addr_ref.address[0]'.)
if addr_ref.address[0] == addr:
return addr_ref
# if it fails, add an entry to the list
@@ -198,7 +210,7 @@
self._gcmap_curlength = index + 2
def _enlarge_gcmap(self):
- newlength = 128 + self._gcmap_maxlength * 5 // 4
+ newlength = 250 + self._gcmap_maxlength * 2
newgcmap = lltype.malloc(self.GCMAP_ARRAY, newlength, flavor='raw')
oldgcmap = self._gcmap
for i in range(self._gcmap_curlength):
@@ -210,7 +222,7 @@
def encode_callshape(self, gclocs):
"""Encode a callshape from the list of locations containing GC
- pointers."""
+ pointers. 'gclocs' is a list of offsets relative to EBP."""
shape = self._get_callshape(gclocs)
return self._compress_callshape(shape)
@@ -222,9 +234,7 @@
self.LOC_EBP_BASED | 0, # saved %ebp: at (%ebp)
0]
for loc in gclocs:
- assert isinstance(loc, MODRM)
- assert loc.is_relative_to_ebp()
- shape.append(self.LOC_EBP_BASED | (-4 * (4 + loc.position)))
+ shape.append(self.LOC_EBP_BASED | loc)
return shape
def _compress_callshape(self, shape):
@@ -254,11 +264,13 @@
class GcLLDescr_framework(GcLLDescription):
GcRefList = GcRefList
- def __init__(self, gcdescr, cpu):
+ def __init__(self, gcdescr, translator, llop1=llop):
from pypy.rpython.memory.gc.base import choose_gc_from_config
from pypy.rpython.memory.gctransform import framework
- self.cpu = cpu
- self.translator = cpu.mixlevelann.rtyper.annotator.translator
+ GcLLDescription.__init__(self, gcdescr, translator)
+ assert self.translate_support_code, "required with the framework GC"
+ self.translator = translator
+ self.llop1 = llop1
# we need the hybrid GC for GcRefList.alloc_gcref_list() to work
if gcdescr.config.translation.gc != 'hybrid':
@@ -287,15 +299,15 @@
self.GCClass, _ = choose_gc_from_config(gcdescr.config)
self.moving_gc = self.GCClass.moving_gc
self.HDRPTR = lltype.Ptr(self.GCClass.HDR)
- self.fielddescr_tid = cpu.fielddescrof(self.GCClass.HDR, 'tid')
- _, _, self.array_length_ofs = symbolic.get_array_token(
- lltype.GcArray(lltype.Signed), True)
+ self.fielddescr_tid = get_field_descr(self, self.GCClass.HDR, 'tid')
+ (self.array_basesize, _, self.array_length_ofs) = \
+ symbolic.get_array_token(lltype.GcArray(lltype.Signed), True)
# make a malloc function, with three arguments
def malloc_basic(size, type_id, has_finalizer):
- res = llop.do_malloc_fixedsize_clear(llmemory.GCREF,
- type_id, size, True,
- has_finalizer, False)
+ res = llop1.do_malloc_fixedsize_clear(llmemory.GCREF,
+ type_id, size, True,
+ has_finalizer, False)
#llop.debug_print(lltype.Void, "\tmalloc_basic", size, type_id,
# "-->", res)
return res
@@ -305,10 +317,10 @@
self.WB_FUNCPTR = lltype.Ptr(lltype.FuncType(
[llmemory.Address, llmemory.Address], lltype.Void))
#
- def malloc_array(basesize, itemsize, type_id, num_elem):
- return llop.do_malloc_varsize_clear(
+ def malloc_array(itemsize, type_id, num_elem):
+ return llop1.do_malloc_varsize_clear(
llmemory.GCREF,
- type_id, num_elem, basesize, itemsize,
+ type_id, num_elem, self.array_basesize, itemsize,
self.array_length_ofs, True, False)
self.malloc_array = malloc_array
self.GC_MALLOC_ARRAY = lltype.Ptr(lltype.FuncType(
@@ -322,12 +334,12 @@
unicode_type_id = self.layoutbuilder.get_type_id(rstr.UNICODE)
#
def malloc_str(length):
- return llop.do_malloc_varsize_clear(
+ return llop1.do_malloc_varsize_clear(
llmemory.GCREF,
str_type_id, length, str_basesize, str_itemsize,
str_ofs_length, True, False)
def malloc_unicode(length):
- return llop.do_malloc_varsize_clear(
+ return llop1.do_malloc_varsize_clear(
llmemory.GCREF,
unicode_type_id, length, unicode_basesize, unicode_itemsize,
unicode_ofs_length, True, False)
@@ -336,57 +348,41 @@
self.GC_MALLOC_STR_UNICODE = lltype.Ptr(lltype.FuncType(
[lltype.Signed], llmemory.GCREF))
- def sizeof(self, S, translate_support_code):
+ def init_size_descr(self, S, descr):
from pypy.rpython.memory.gctypelayout import weakpointer_offset
- assert translate_support_code, "required with the framework GC"
- size = symbolic.get_size(S, True)
type_id = self.layoutbuilder.get_type_id(S)
has_finalizer = bool(self.layoutbuilder.has_finalizer(S))
assert weakpointer_offset(S) == -1 # XXX
- descr = ConstDescr3(size, 0, has_finalizer)
descr.type_id = type_id
- return descr
+ descr.has_finalizer = has_finalizer
- def arraydescrof(self, A, translate_support_code):
- assert translate_support_code, "required with the framework GC"
- basesize, itemsize, ofs_length = symbolic.get_array_token(A, True)
- assert rffi.sizeof(A.OF) in [1, 2, WORD]
- # assert ofs_length == self.array_length_ofs --- but it's symbolics...
- if isinstance(A.OF, lltype.Ptr) and A.OF.TO._gckind == 'gc':
- ptr = True
- else:
- ptr = False
+ def init_array_descr(self, A, descr):
type_id = self.layoutbuilder.get_type_id(A)
- descr = ConstDescr3(basesize, itemsize, ptr)
descr.type_id = type_id
- return descr
- def gc_malloc(self, descrsize):
- assert isinstance(descrsize, ConstDescr3)
- size = descrsize.v0
- type_id = descrsize.type_id
- has_finalizer = descrsize.flag2
+ def gc_malloc(self, sizedescr):
+ assert isinstance(sizedescr, BaseSizeDescr)
+ size = sizedescr.size
+ type_id = sizedescr.type_id
+ has_finalizer = sizedescr.has_finalizer
assert type_id > 0
return self.malloc_basic(size, type_id, has_finalizer)
def gc_malloc_array(self, arraydescr, num_elem):
- assert isinstance(arraydescr, ConstDescr3)
- basesize = arraydescr.v0
- itemsize = arraydescr.v1
+ assert isinstance(arraydescr, BaseArrayDescr)
+ itemsize = arraydescr.get_item_size(self.translate_support_code)
type_id = arraydescr.type_id
assert type_id > 0
- return self.malloc_array(basesize, itemsize, type_id, num_elem)
+ return self.malloc_array(itemsize, type_id, num_elem)
- def gc_malloc_str(self, num_elem, translate_support_code):
- assert translate_support_code, "required with the framework GC"
+ def gc_malloc_str(self, num_elem):
return self.malloc_str(num_elem)
- def gc_malloc_unicode(self, num_elem, translate_support_code):
- assert translate_support_code, "required with the framework GC"
+ def gc_malloc_unicode(self, num_elem):
return self.malloc_unicode(num_elem)
- def args_for_new(self, descrsize):
- assert isinstance(descrsize, ConstDescr3)
+ def args_for_new(self, sizedescr):
+ assert isinstance(sizedescr, BaseSizeDescr)
size = descrsize.v0
type_id = descrsize.type_id
has_finalizer = descrsize.flag2
@@ -417,7 +413,8 @@
if hdr.tid & self.GCClass.JIT_WB_IF_FLAG:
# get a pointer to the 'remember_young_pointer' function from
# the GC, and call it immediately
- funcptr = llop.get_write_barrier_failing_case(self.WB_FUNCPTR)
+ llop1 = self.llop1
+ funcptr = llop1.get_write_barrier_failing_case(self.WB_FUNCPTR)
funcptr(llmemory.cast_ptr_to_adr(gcref_struct),
llmemory.cast_ptr_to_adr(gcref_newptr))
@@ -449,7 +446,7 @@
mc.PUSHA() # 1 byte
mc.PUSH(value_reg) # 1 or 5 bytes
mc.PUSH(base_reg) # 1 or 5 bytes
- funcptr = llop.get_write_barrier_failing_case(self.WB_FUNCPTR)
+ funcptr = self.llop1.get_write_barrier_failing_case(self.WB_FUNCPTR)
funcaddr = rffi.cast(lltype.Signed, funcptr)
mc.CALL(rel32(funcaddr)) # 5 bytes
mc.POP(eax) # 1 byte
@@ -460,7 +457,8 @@
# ____________________________________________________________
-def get_ll_description(gcdescr, cpu):
+def get_ll_description(gcdescr, translator=None):
+ # translator is None if translate_support_code is False.
if gcdescr is not None:
name = gcdescr.config.translation.gctransformer
else:
@@ -469,5 +467,5 @@
cls = globals()['GcLLDescr_' + name]
except KeyError:
raise NotImplementedError("GC transformer %r not supported by "
- "the x86 backend" % (name,))
- return cls(gcdescr, cpu)
+ "the JIT backend" % (name,))
+ return cls(gcdescr, translator)
Modified: pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/llmodel.py
==============================================================================
--- pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/llmodel.py (original)
+++ pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/llmodel.py Sat Aug 29 23:00:29 2009
@@ -28,8 +28,11 @@
self.rtyper = rtyper
self.stats = stats
self.translate_support_code = translate_support_code
- self._call_cache = {}
- self.gc_ll_descr = get_ll_description(gcdescr, self)
+ if translate_support_code:
+ translator = rtyper.annotator.translator
+ else:
+ translator = None
+ self.gc_ll_descr = get_ll_description(gcdescr, translator)
self.vtable_offset, _ = symbolic.get_field_token(rclass.OBJECT,
'typeptr',
translate_support_code)
@@ -58,11 +61,6 @@
# ------------------- helpers and descriptions --------------------
@staticmethod
- def cast_adr_to_int(x):
- res = rffi.cast(lltype.Signed, x)
- return res
-
- @staticmethod
def cast_int_to_gcref(x):
if not we_are_translated():
_check_addr_range(x)
@@ -78,11 +76,15 @@
_check_addr_range(x)
return rffi.cast(llmemory.Address, x)
+ @staticmethod
+ def cast_adr_to_int(x):
+ return rffi.cast(lltype.Signed, x)
+
def sizeof(self, S):
- return get_size_descr(S, self.translate_support_code)
+ return get_size_descr(self.gc_ll_descr, S)
def fielddescrof(self, STRUCT, fieldname):
- return get_field_descr(STRUCT, fieldname, self.translate_support_code)
+ return get_field_descr(self.gc_ll_descr, STRUCT, fieldname)
def unpack_fielddescr(self, fielddescr):
assert isinstance(fielddescr, BaseFieldDescr)
@@ -93,7 +95,7 @@
unpack_fielddescr._always_inline_ = True
def arraydescrof(self, A):
- return get_array_descr(A)
+ return get_array_descr(self.gc_ll_descr, A)
def unpack_arraydescr(self, arraydescr):
assert isinstance(arraydescr, BaseArrayDescr)
@@ -104,8 +106,7 @@
unpack_arraydescr._always_inline_ = True
def calldescrof(self, FUNC, ARGS, RESULT):
- return get_call_descr(ARGS, RESULT, self.translate_support_code,
- self._call_cache)
+ return get_call_descr(self.gc_ll_descr, ARGS, RESULT)
def get_overflow_error(self):
ovf_vtable = self.cast_adr_to_int(self._ovf_error_vtable)
Modified: pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/test/test_descr.py
==============================================================================
--- pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/test/test_descr.py (original)
+++ pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/test/test_descr.py Sat Aug 29 23:00:29 2009
@@ -5,17 +5,19 @@
def test_get_size_descr():
+ c0 = GcCache(False)
+ c1 = GcCache(True)
T = lltype.GcStruct('T')
S = lltype.GcStruct('S', ('x', lltype.Char),
('y', lltype.Ptr(T)))
- descr_s = get_size_descr(S, False)
- descr_t = get_size_descr(T, False)
+ descr_s = get_size_descr(c0, S)
+ descr_t = get_size_descr(c0, T)
assert descr_s.size == symbolic.get_size(S, False)
assert descr_t.size == symbolic.get_size(T, False)
- assert descr_s == get_size_descr(S, False)
- assert descr_s != get_size_descr(S, True)
+ assert descr_s == get_size_descr(c0, S)
+ assert descr_s != get_size_descr(c1, S)
#
- descr_s = get_size_descr(S, True)
+ descr_s = get_size_descr(c1, S)
assert isinstance(descr_s.size, Symbolic)
@@ -31,12 +33,15 @@
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)
+ c0 = GcCache(False)
+ c1 = GcCache(True)
+ assert get_field_descr(c0, S, 'y') == get_field_descr(c0, S, 'y')
+ assert get_field_descr(c0, S, 'y') != get_field_descr(c1, S, 'y')
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)
+ c2 = GcCache(tsc)
+ descr_x = get_field_descr(c2, S, 'x')
+ descr_y = get_field_descr(c2, S, 'y')
+ descr_z = get_field_descr(c2, S, 'z')
assert descr_x.__class__ is cls
assert descr_y.__class__ is GcPtrFieldDescr
assert descr_z.__class__ is NonGcPtrFieldDescr
@@ -70,13 +75,14 @@
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)
+ c0 = GcCache(False)
+ descr1 = get_array_descr(c0, A1)
+ descr2 = get_array_descr(c0, A2)
+ descr3 = get_array_descr(c0, 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 descr1 == get_array_descr(c0, lltype.GcArray(lltype.Char))
assert not descr1.is_array_of_pointers()
assert descr2.is_array_of_pointers()
assert not descr3.is_array_of_pointers()
@@ -104,52 +110,49 @@
def test_get_call_descr():
- cache = {}
- descr1 = get_call_descr([lltype.Char, lltype.Signed], lltype.Char, False,
- cache)
+ c0 = GcCache(False)
+ descr1 = get_call_descr(c0, [lltype.Char, lltype.Signed], lltype.Char)
assert descr1.get_result_size(False) == rffi.sizeof(lltype.Char)
assert not descr1.returns_a_pointer()
assert descr1.arg_classes == [BoxInt, BoxInt]
#
T = lltype.GcStruct('T')
- descr2 = get_call_descr([lltype.Ptr(T)], lltype.Ptr(T), False, cache)
+ descr2 = get_call_descr(c0, [lltype.Ptr(T)], lltype.Ptr(T))
assert descr2.get_result_size(False) == rffi.sizeof(lltype.Ptr(T))
assert descr2.returns_a_pointer()
assert descr2.arg_classes == [BoxPtr]
#
U = lltype.GcStruct('U', ('x', lltype.Signed))
- assert descr2 == get_call_descr([lltype.Ptr(U)], lltype.Ptr(U), False,
- cache)
+ assert descr2 == get_call_descr(c0, [lltype.Ptr(U)], lltype.Ptr(U))
def test_repr_of_descr():
+ c0 = GcCache(False)
T = lltype.GcStruct('T')
S = lltype.GcStruct('S', ('x', lltype.Char),
('y', lltype.Ptr(T)),
('z', lltype.Ptr(T)))
- descr1 = get_size_descr(S, False)
+ descr1 = get_size_descr(c0, S)
s = symbolic.get_size(S, False)
assert descr1.repr_of_descr() == '<SizeDescr %d>' % s
#
- descr2 = get_field_descr(S, 'y', False)
+ descr2 = get_field_descr(c0, S, 'y')
o, _ = symbolic.get_field_token(S, 'y', False)
assert descr2.repr_of_descr() == '<GcPtrFieldDescr %d>' % o
#
- descr2i = get_field_descr(S, 'x', False)
+ descr2i = get_field_descr(c0, S, 'x')
o, _ = symbolic.get_field_token(S, 'x', False)
assert descr2i.repr_of_descr() == '<CharFieldDescr %d>' % o
#
- descr3 = get_array_descr(lltype.GcArray(lltype.Ptr(S)))
+ descr3 = get_array_descr(c0, lltype.GcArray(lltype.Ptr(S)))
assert descr3.repr_of_descr() == '<GcPtrArrayDescr>'
#
- descr3i = get_array_descr(lltype.GcArray(lltype.Char))
+ descr3i = get_array_descr(c0, lltype.GcArray(lltype.Char))
assert descr3i.repr_of_descr() == '<CharArrayDescr>'
#
cache = {}
- descr4 = get_call_descr([lltype.Char, lltype.Ptr(S)], lltype.Ptr(S),
- False, cache)
+ descr4 = get_call_descr(c0, [lltype.Char, lltype.Ptr(S)], lltype.Ptr(S))
assert 'GcPtrCallDescr' in descr4.repr_of_descr()
#
- descr4i = get_call_descr([lltype.Char, lltype.Ptr(S)], lltype.Char,
- False, cache)
+ descr4i = get_call_descr(c0, [lltype.Char, lltype.Ptr(S)], lltype.Char)
assert 'IntCallDescr' in descr4i.repr_of_descr()
Added: pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/test/test_gc.py
==============================================================================
--- (empty file)
+++ pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/test/test_gc.py Sat Aug 29 23:00:29 2009
@@ -0,0 +1,170 @@
+import random
+from pypy.rpython.lltypesystem import lltype, llmemory, rffi, rstr
+from pypy.jit.backend.llsupport.descr import *
+from pypy.jit.backend.llsupport.gc import *
+from pypy.jit.backend.llsupport import symbolic
+from pypy.jit.metainterp.gc import get_description
+
+
+def test_boehm():
+ gc_ll_descr = GcLLDescr_boehm(None, None)
+ #
+ record = []
+ prev_funcptr_for_new = gc_ll_descr.funcptr_for_new
+ def my_funcptr_for_new(size):
+ p = prev_funcptr_for_new(size)
+ record.append((size, p))
+ return p
+ gc_ll_descr.funcptr_for_new = my_funcptr_for_new
+ #
+ # ---------- gc_malloc ----------
+ S = lltype.GcStruct('S', ('x', lltype.Signed))
+ sizedescr = get_size_descr(gc_ll_descr, S)
+ p = gc_ll_descr.gc_malloc(sizedescr)
+ assert record == [(sizedescr.size, p)]
+ del record[:]
+ # ---------- gc_malloc_array ----------
+ A = lltype.GcArray(lltype.Signed)
+ arraydescr = get_array_descr(gc_ll_descr, A)
+ p = gc_ll_descr.gc_malloc_array(arraydescr, 10)
+ assert record == [(arraydescr.get_base_size(False) +
+ 10 * arraydescr.get_item_size(False), p)]
+ del record[:]
+ # ---------- gc_malloc_str ----------
+ p = gc_ll_descr.gc_malloc_str(10)
+ basesize, itemsize, ofs_length = symbolic.get_array_token(rstr.STR, False)
+ assert record == [(basesize + 10 * itemsize, p)]
+ del record[:]
+ # ---------- gc_malloc_unicode ----------
+ p = gc_ll_descr.gc_malloc_unicode(10)
+ basesize, itemsize, ofs_length = symbolic.get_array_token(rstr.UNICODE,
+ False)
+ assert record == [(basesize + 10 * itemsize, p)]
+ del record[:]
+
+# ____________________________________________________________
+
+def test_GcRefList():
+ S = lltype.GcStruct('S')
+ order = range(50) * 4
+ random.shuffle(order)
+ allocs = [lltype.cast_opaque_ptr(llmemory.GCREF, lltype.malloc(S))
+ for i in range(50)]
+ allocs = [allocs[i] for i in order]
+ #
+ gcrefs = GcRefList()
+ addrs = [gcrefs.get_address_of_gcref(ptr) for ptr in allocs]
+ for i in range(len(allocs)):
+ assert addrs[i].address[0] == llmemory.cast_ptr_to_adr(allocs[i])
+
+def test_GcRootMap_asmgcc():
+ def stack_pos(n):
+ return -4*(4+n)
+ gcrootmap = GcRootMap_asmgcc()
+ num1 = stack_pos(1)
+ num2 = stack_pos(55)
+ shape = gcrootmap._get_callshape([num1, num2])
+ assert shape == [6, -2, -6, -10, 2, 0, num1|2, num2|2]
+ #
+ shapeaddr = gcrootmap.encode_callshape([num1, num2])
+ 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([num2a, num2b, num1a, 0, 4, 19, 11, 3, 12]):
+ assert p[i] == expected
+ #
+ retaddr = rffi.cast(llmemory.Address, 1234567890)
+ gcrootmap.put(retaddr, shapeaddr)
+ assert gcrootmap._gcmap[0] == retaddr
+ assert gcrootmap._gcmap[1] == shapeaddr
+ assert gcrootmap.gcmapstart().address[0] == retaddr
+ #
+ # the same as before, but enough times to trigger a few resizes
+ expected_shapeaddr = {}
+ for i in range(1, 600):
+ shapeaddr = gcrootmap.encode_callshape([stack_pos(i)])
+ expected_shapeaddr[i] = shapeaddr
+ retaddr = rffi.cast(llmemory.Address, 123456789 + i)
+ gcrootmap.put(retaddr, shapeaddr)
+ for i in range(1, 600):
+ 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]
+
+
+class FakeLLOp:
+ def __init__(self):
+ self.record = []
+
+ def do_malloc_fixedsize_clear(self, RESTYPE, type_id, size, can_collect,
+ has_finalizer, contains_weakptr):
+ assert can_collect
+ assert not contains_weakptr
+ p = llmemory.raw_malloc(size)
+ p = llmemory.cast_adr_to_ptr(p, RESTYPE)
+ self.record.append(("fixedsize", type_id, repr(size),
+ has_finalizer, p))
+ return p
+
+ def do_malloc_varsize_clear(self, RESTYPE, type_id, length, size,
+ itemsize, offset_to_length, can_collect,
+ has_finalizer):
+ assert can_collect
+ assert not has_finalizer
+ p = llmemory.raw_malloc(size + itemsize * length)
+ (p + offset_to_length).signed[0] = length
+ p = llmemory.cast_adr_to_ptr(p, RESTYPE)
+ self.record.append(("varsize", type_id, length,
+ repr(size), repr(itemsize),
+ repr(offset_to_length), p))
+ return p
+
+
+def test_framework_malloc():
+ class FakeTranslator:
+ pass
+ class config:
+ class translation:
+ gc = 'hybrid'
+ gcrootfinder = 'asmgcc'
+ gctransformer = 'framework'
+ gcdescr = get_description(config)
+ translator = FakeTranslator()
+ llop1 = FakeLLOp()
+ gc_ll_descr = GcLLDescr_framework(gcdescr, FakeTranslator(), llop1)
+ #
+ # ---------- gc_malloc ----------
+ S = lltype.GcStruct('S', ('x', lltype.Signed))
+ sizedescr = get_size_descr(gc_ll_descr, S)
+ p = gc_ll_descr.gc_malloc(sizedescr)
+ assert llop1.record == [("fixedsize", sizedescr.type_id,
+ repr(sizedescr.size), False, p)]
+ del llop1.record[:]
+ # ---------- gc_malloc_array ----------
+ A = lltype.GcArray(lltype.Signed)
+ arraydescr = get_array_descr(gc_ll_descr, A)
+ p = gc_ll_descr.gc_malloc_array(arraydescr, 10)
+ assert llop1.record == [("varsize", arraydescr.type_id, 10,
+ repr(arraydescr.get_base_size(True)),
+ repr(arraydescr.get_item_size(True)),
+ repr(arraydescr.get_ofs_length(True)), p)]
+ del llop1.record[:]
+ # ---------- gc_malloc_str ----------
+ p = gc_ll_descr.gc_malloc_str(10)
+ type_id = gc_ll_descr.layoutbuilder.get_type_id(rstr.STR)
+ basesize, itemsize, ofs_length = symbolic.get_array_token(rstr.STR, True)
+ assert llop1.record == [("varsize", type_id, 10,
+ repr(basesize), repr(itemsize), repr(ofs_length),
+ p)]
+ del llop1.record[:]
+ # ---------- gc_malloc_unicode ----------
+ p = gc_ll_descr.gc_malloc_unicode(10)
+ type_id = gc_ll_descr.layoutbuilder.get_type_id(rstr.UNICODE)
+ basesize, itemsize, ofs_length = symbolic.get_array_token(rstr.UNICODE,
+ True)
+ assert llop1.record == [("varsize", type_id, 10,
+ repr(basesize), repr(itemsize), repr(ofs_length),
+ p)]
+ del llop1.record[:]
Modified: pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/model.py
==============================================================================
--- pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/model.py (original)
+++ pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/model.py Sat Aug 29 23:00:29 2009
@@ -92,11 +92,11 @@
def typedescrof(TYPE):
raise NotImplementedError
- def cast_adr_to_int(self, adr):
- raise NotImplementedError
+ #def cast_adr_to_int(self, adr):
+ # raise NotImplementedError
- def cast_int_to_adr(self, int):
- raise NotImplementedError
+ #def cast_int_to_adr(self, int):
+ # raise NotImplementedError
# ---------- the backend-dependent operations ----------
Modified: pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/x86/runner.py
==============================================================================
--- pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/x86/runner.py (original)
+++ pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/x86/runner.py Sat Aug 29 23:00:29 2009
@@ -18,13 +18,10 @@
BOOTSTRAP_TP = lltype.FuncType([], lltype.Signed)
def __init__(self, rtyper, stats, translate_support_code=False,
- mixlevelann=None, gcdescr=None):
+ gcdescr=None):
AbstractLLCPU.__init__(self, rtyper, stats, translate_support_code,
gcdescr)
- if translate_support_code:
- assert mixlevelann
- self.mixlevelann = mixlevelann
- else:
+ if not translate_support_code:
self.current_interpreter = LLInterpreter(self.rtyper)
def _store_exception(lle):
Modified: pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/x86/test/test_zrpy_gc.py
==============================================================================
--- pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/x86/test/test_zrpy_gc.py (original)
+++ pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/x86/test/test_zrpy_gc.py Sat Aug 29 23:00:29 2009
@@ -11,7 +11,7 @@
from pypy.rpython.lltypesystem.lloperation import llop
from pypy.rlib.jit import JitDriver
from pypy.jit.backend.x86.runner import CPU386
-from pypy.jit.backend.x86.gc import GcRefList, GcRootMap_asmgcc
+from pypy.jit.backend.llsupport.gc import GcRefList, GcRootMap_asmgcc
from pypy.jit.backend.x86.regalloc import stack_pos
@@ -82,22 +82,6 @@
res = compile_and_run(get_test(main), "boehm", jit=True)
assert int(res) >= 16
-def test_GcRefList():
- S = lltype.GcStruct('S')
- order = range(20000) * 4
- random.shuffle(order)
- def fn(args):
- allocs = [lltype.cast_opaque_ptr(llmemory.GCREF, lltype.malloc(S))
- for i in range(20000)]
- allocs = [allocs[i] for i in order]
- #
- gcrefs = GcRefList()
- addrs = [gcrefs.get_address_of_gcref(ptr) for ptr in allocs]
- for i in range(len(allocs)):
- assert addrs[i].address[0] == llmemory.cast_ptr_to_adr(allocs[i])
- return 0
- compile_and_run(fn, "hybrid", gcrootfinder="asmgcc", jit=False)
-
def test_compile_hybrid_1():
# a moving GC. Supports malloc_varsize_nonmovable. Simple test, works
# without write_barriers and root stack enumeration.
@@ -113,39 +97,8 @@
jit=True)
assert int(res) == 20
-def test_GcRootMap_asmgcc():
- gcrootmap = GcRootMap_asmgcc()
- shape = gcrootmap._get_callshape([stack_pos(1), stack_pos(55)])
- num1 = stack_pos(1).ofs_relative_to_ebp()
- num2 = stack_pos(55).ofs_relative_to_ebp()
- assert shape == [6, -2, -6, -10, 2, 0, num1|2, num2|2]
- #
- shapeaddr = gcrootmap.encode_callshape([stack_pos(1), stack_pos(55)])
- 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([num2a, num2b, num1a, 0, 4, 19, 11, 3, 12]):
- assert p[i] == expected
- #
- retaddr = rffi.cast(llmemory.Address, 1234567890)
- gcrootmap.put(retaddr, shapeaddr)
- assert gcrootmap._gcmap[0] == retaddr
- assert gcrootmap._gcmap[1] == shapeaddr
- assert gcrootmap.gcmapstart().address[0] == retaddr
- #
- # the same as before, but enough times to trigger a few resizes
- expected_shapeaddr = {}
- for i in range(1, 600):
- shapeaddr = gcrootmap.encode_callshape([stack_pos(i)])
- expected_shapeaddr[i] = shapeaddr
- retaddr = rffi.cast(llmemory.Address, 123456789 + i)
- gcrootmap.put(retaddr, shapeaddr)
- for i in range(1, 600):
- 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]
+def test_get_callshape():
+ xxx #test that _get_callshape() is called with the right arguments
def test_compile_hybrid_2():
# More complex test, requires root stack enumeration but
Modified: pypy/branch/pyjitpl5-llmodel/pypy/jit/metainterp/warmspot.py
==============================================================================
--- pypy/branch/pyjitpl5-llmodel/pypy/jit/metainterp/warmspot.py (original)
+++ pypy/branch/pyjitpl5-llmodel/pypy/jit/metainterp/warmspot.py Sat Aug 29 23:00:29 2009
@@ -222,7 +222,7 @@
else:
annhelper = None
cpu = CPUClass(self.translator.rtyper, self.stats,
- translate_support_code, annhelper, self.gcdescr)
+ translate_support_code, gcdescr=self.gcdescr)
self.cpu = cpu
self.metainterp_sd = MetaInterpStaticData(self.portal_graph,
self.translator.graphs, cpu,
Modified: pypy/branch/pyjitpl5-llmodel/pypy/rpython/memory/gctransform/framework.py
==============================================================================
--- pypy/branch/pyjitpl5-llmodel/pypy/rpython/memory/gctransform/framework.py (original)
+++ pypy/branch/pyjitpl5-llmodel/pypy/rpython/memory/gctransform/framework.py Sat Aug 29 23:00:29 2009
@@ -607,7 +607,7 @@
resultvar=op.result)
def gct_do_malloc_fixedsize_clear(self, hop):
- # used by the JIT (see the x86 backend)
+ # used by the JIT (see pypy.jit.backend.llsupport.gc)
op = hop.spaceop
[v_typeid, v_size, v_can_collect,
v_has_finalizer, v_contains_weakptr] = op.args
@@ -620,7 +620,7 @@
self.pop_roots(hop, livevars)
def gct_do_malloc_varsize_clear(self, hop):
- # used by the JIT (see the x86 backend)
+ # used by the JIT (see pypy.jit.backend.llsupport.gc)
op = hop.spaceop
[v_typeid, v_length, v_size, v_itemsize,
v_offset_to_length, v_can_collect, v_has_finalizer] = op.args
More information about the Pypy-commit
mailing list