[pypy-commit] pypy op_malloc_gc: In-progress.
arigo
noreply at buildbot.pypy.org
Sun Dec 18 15:51:48 CET 2011
Author: Armin Rigo <arigo at tunes.org>
Branch: op_malloc_gc
Changeset: r50654:2fd85080ac75
Date: 2011-12-18 15:06 +0100
http://bitbucket.org/pypy/pypy/changeset/2fd85080ac75/
Log: In-progress.
diff --git a/pypy/jit/backend/llsupport/gc.py b/pypy/jit/backend/llsupport/gc.py
--- a/pypy/jit/backend/llsupport/gc.py
+++ b/pypy/jit/backend/llsupport/gc.py
@@ -14,7 +14,7 @@
from pypy.jit.metainterp.resoperation import ResOperation, rop
from pypy.jit.backend.llsupport import symbolic
from pypy.jit.backend.llsupport.symbolic import WORD
-##from pypy.jit.backend.llsupport.descr import SizeDescr, ArrayDescr
+from pypy.jit.backend.llsupport.descr import SizeDescr, ArrayDescr
from pypy.jit.backend.llsupport.descr import GcCache, get_field_descr
from pypy.jit.backend.llsupport.descr import get_array_descr
##from pypy.jit.backend.llsupport.descr import GcPtrFieldDescr
@@ -70,30 +70,18 @@
def gc_malloc(self, sizedescr):
"""Blackhole: do a 'bh_new'. Also used for 'bh_new_with_vtable',
with the vtable pointer set manually afterwards."""
- assert isinstance(sizedescr, BaseSizeDescr)
- return self._gc_malloc(sizedescr.size, sizedescr.tid)
+ assert isinstance(sizedescr, SizeDescr)
+ return self._bh_malloc(sizedescr)
def gc_malloc_array(self, arraydescr, num_elem):
- assert isinstance(arraydescr, BaseArrayDescr)
- ofs_length = arraydescr.get_ofs_length(self.translate_support_code)
- basesize = arraydescr.get_base_size(self.translate_support_code)
- itemsize = arraydescr.get_item_size(self.translate_support_code)
- return self._gc_malloc_array(basesize, num_elem, itemsize, ofs_length,
- arraydescr.tid)
+ assert isinstance(arraydescr, ArrayDescr)
+ return self._bh_malloc_array(arraydescr, num_elem)
def gc_malloc_str(self, num_elem):
- xxx
- return self._gc_malloc_array(self.str_basesize, num_elem,
- self.str_itemsize,
- self.str_ofs_length,
- self.str_type_id)
+ return self._bh_malloc_array(self.str_descr, num_elem)
def gc_malloc_unicode(self, num_elem):
- xxx
- return self._gc_malloc_array(self.unicode_basesize, num_elem,
- self.unicode_itemsize,
- self.unicode_ofs_length,
- self.unicode_type_id)
+ return self._bh_malloc_array(self.unicode_descr, num_elem)
def _record_constptrs(self, op, gcrefs_output_list):
for i in range(op.numargs()):
@@ -171,10 +159,9 @@
self._make_functions()
def _make_functions(self):
- malloc_fn_ptr = self.malloc_fn_ptr
def malloc_fixedsize(size):
- res = malloc_fn_ptr(size)
+ res = self.malloc_fn_ptr(size)
if not res:
raise MemoryError
return res
@@ -182,12 +169,11 @@
[lltype.Signed])
def malloc_array(basesize, num_elem, itemsize, ofs_length):
- xxx
try:
totalsize = ovfcheck(basesize + ovfcheck(itemsize * num_elem))
except OverflowError:
raise MemoryError
- res = malloc_fn_ptr(totalsize)
+ res = self.malloc_fn_ptr(totalsize)
if not res:
raise MemoryError
arrayptr = rffi.cast(rffi.CArrayPtr(lltype.Signed), res)
@@ -196,22 +182,13 @@
self.generate_function('malloc_array', malloc_array,
[lltype.Signed] * 4)
- def _gc_malloc(self, size, tid):
- # Boehm: 'tid' is ignored
- return self.malloc_fixedsize(size)
+ def _bh_malloc(self, sizedescr):
+ return self.malloc_fixedsize(sizedescr.size)
- def _gc_malloc_array(self, basesize, num_elem, itemsize, ofs_length, tid):
- # Boehm: 'tid' is ignored
- try:
- totalsize = ovfcheck(basesize + ovfcheck(itemsize * num_elem))
- except OverflowError:
- raise MemoryError
- res = self.malloc_fn_ptr(totalsize)
- if not res:
- raise MemoryError
- arrayptr = rffi.cast(rffi.CArrayPtr(lltype.Signed), res)
- arrayptr[ofs_length/WORD] = num_elem
- return res
+ def _bh_malloc_array(self, arraydescr, num_elem):
+ return self.malloc_array(arraydescr.basesize, num_elem,
+ arraydescr.itemsize,
+ arraydescr.lendescr.offset)
# ____________________________________________________________
@@ -581,12 +558,14 @@
class WriteBarrierDescr(AbstractDescr):
def __init__(self, gc_ll_descr):
- GCClass = gc_ll_descr.GCClass
self.llop1 = gc_ll_descr.llop1
self.WB_FUNCPTR = gc_ll_descr.WB_FUNCPTR
self.WB_ARRAY_FUNCPTR = gc_ll_descr.WB_ARRAY_FUNCPTR
- self.fielddescr_tid = get_field_descr(gc_ll_descr, GCClass.HDR, 'tid')
+ self.fielddescr_tid = gc_ll_descr.fielddescr_tid
#
+ GCClass = gc_ll_descr.GCClass
+ if GCClass is None: # for tests
+ return
self.jit_wb_if_flag = GCClass.JIT_WB_IF_FLAG
self.jit_wb_if_flag_byteofs, self.jit_wb_if_flag_singlebyte = (
self.extract_flag_byte(self.jit_wb_if_flag))
@@ -630,7 +609,6 @@
def __init__(self, gcdescr, translator, rtyper, llop1=llop,
really_not_translated=False):
- from pypy.rpython.memory.gctypelayout import check_typeid
GcLLDescription.__init__(self, gcdescr, translator, rtyper)
self.translator = translator
self.llop1 = llop1
@@ -643,20 +621,16 @@
self._make_gcrootmap()
self._make_layoutbuilder()
self._setup_gcclass()
+ self._setup_tid()
+ self._setup_write_barrier()
self._setup_str()
- self._setup_stuff(really_not_translated)
- self._make_functions()
+ self._make_functions(really_not_translated)
def _initialize_for_tests(self):
self.layoutbuilder = None
self.fielddescr_tid = AbstractDescr()
self.max_size_of_young_obj = 1000
- self.write_barrier_descr = None
-
- def _setup_stuff(self, really_not_translated):
- (self.standard_array_basesize, _, self.standard_array_length_ofs) = \
- symbolic.get_array_token(lltype.GcArray(lltype.Signed),
- not really_not_translated)
+ self.GCClass = None
def _check_valid_gc(self):
# we need the hybrid or minimark GC for rgc._make_sure_does_not_move()
@@ -699,8 +673,22 @@
assert self.GCClass.inline_simple_malloc
assert self.GCClass.inline_simple_malloc_varsize
- def _make_functions(self):
+ def _setup_tid(self):
+ self.fielddescr_tid = get_field_descr(self, self.GCClass.HDR, 'tid')
+
+ def _setup_write_barrier(self):
+ self.WB_FUNCPTR = lltype.Ptr(lltype.FuncType(
+ [llmemory.Address, llmemory.Address], lltype.Void))
+ self.WB_ARRAY_FUNCPTR = lltype.Ptr(lltype.FuncType(
+ [llmemory.Address, lltype.Signed, llmemory.Address], lltype.Void))
+ self.write_barrier_descr = WriteBarrierDescr(self)
+
+ def _make_functions(self, really_not_translated):
+ from pypy.rpython.memory.gctypelayout import check_typeid
llop1 = self.llop1
+ (self.standard_array_basesize, _, self.standard_array_length_ofs) = \
+ symbolic.get_array_token(lltype.GcArray(lltype.Signed),
+ not really_not_translated)
def malloc_nursery_slowpath(size):
"""Allocate 'size' null bytes out of the nursery.
@@ -762,73 +750,26 @@
self.generate_function('malloc_fixedsize', malloc_nursery_slowpath,
[lltype.Signed])
-## # make the fixed malloc function, with one argument
-## def malloc_gc_fixed(size):
-## type_id = rffi.cast(llgroup.HALFWORD, 0) # missing here
-## res = llop1.do_malloc_fixedsize_clear(llmemory.GCREF,
-## type_id, size,
-## False, False, False)
-## #llop.debug_print(lltype.Void, "\tmalloc_basic", size, "-->", res)
-## # In case the operation above failed, we are returning NULL
-## # from this function to assembler. There is also an RPython
-## # exception set, typically MemoryError; but it's easier and
-## # faster to check for the NULL return value, as done by
-## # translator/exceptiontransform.py.
-## return res
-## self.malloc_gc_fixed = malloc_gc_fixed
-## self.MALLOC_GC_FIXED = lltype.Ptr(
-## lltype.FuncType([lltype.Signed], llmemory.GCREF))
-## #
-## # make the varsize malloc function, with three arguments
-## def malloc_gc_variable(basesize, num_elem, itemsize):
-## xx
-## self.malloc_gc_variable = malloc_gc_variable
-## self.MALLOC_GC_VARIABLE = lltype.Ptr(
-## lltype.FuncType([lltype.Signed] * 3, llmemory.GCREF))
-## #
-## self.WB_FUNCPTR = lltype.Ptr(lltype.FuncType(
-## [llmemory.Address, llmemory.Address], lltype.Void))
-## self.WB_ARRAY_FUNCPTR = lltype.Ptr(lltype.FuncType(
-## [llmemory.Address, lltype.Signed, llmemory.Address], lltype.Void))
-## self.write_barrier_descr = WriteBarrierDescr(self)
-## self.fielddescr_tid = self.write_barrier_descr.fielddescr_tid
-## #
-## (str_basesize, str_itemsize, str_ofs_length
-## ) = symbolic.get_array_token(rstr.STR, True)
-## (unicode_basesize, unicode_itemsize, unicode_ofs_length
-## ) = symbolic.get_array_token(rstr.UNICODE, True)
-## self.str_type_id = self.layoutbuilder.get_type_id(rstr.STR)
-## self.unicode_type_id = self.layoutbuilder.get_type_id(rstr.UNICODE)
-## #
-## def malloc_str(length):
-## return llop1.do_malloc_varsize_clear(
-## llmemory.GCREF,
-## str_type_id, length, str_basesize, str_itemsize,
-## str_ofs_length)
-## def malloc_unicode(length):
-## return llop1.do_malloc_varsize_clear(
-## llmemory.GCREF,
-## unicode_type_id, length, unicode_basesize,unicode_itemsize,
-## unicode_ofs_length)
-## ###self.malloc_str = malloc_str
-## ###self.malloc_unicode = malloc_unicode
-## ###self.GC_MALLOC_STR_UNICODE = lltype.Ptr(lltype.FuncType(
-## ### [lltype.Signed], llmemory.GCREF))
-## #
-## #
-## def malloc_slowpath(size):
-## if self.DEBUG:
-## random_usage_of_xmm_registers()
-## assert size >= self.minimal_size_in_nursery
-## # NB. although we call do_malloc_fixedsize_clear() here,
-## # it's a bit of a hack because we set tid to 0 and may
-## # also use it to allocate varsized objects. The tid
-## # and possibly the length are both set afterward.
-## gcref = llop1.do_malloc_fixedsize_clear(llmemory.GCREF,
-## 0, size, False, False, False)
-## return rffi.cast(lltype.Signed, gcref)
-## self.malloc_slowpath = malloc_slowpath
-## self.MALLOC_SLOWPATH = lltype.FuncType([lltype.Signed], lltype.Signed)
+ def _bh_malloc(self, sizedescr):
+ from pypy.rpython.memory.gctypelayout import check_typeid
+ llop1 = self.llop1
+ type_id = llop.extract_ushort(llgroup.HALFWORD, sizedescr.tid)
+ check_typeid(type_id)
+ return llop1.do_malloc_fixedsize_clear(llmemory.GCREF,
+ type_id, sizedescr.size,
+ False, False, False)
+
+ def _bh_malloc_array(self, arraydescr, num_elem):
+ from pypy.rpython.memory.gctypelayout import check_typeid
+ llop1 = self.llop1
+ type_id = llop.extract_ushort(llgroup.HALFWORD, arraydescr.tid)
+ check_typeid(type_id)
+ return llop1.do_malloc_varsize_clear(llmemory.GCREF,
+ type_id, num_elem,
+ arraydescr.basesize,
+ arraydescr.itemsize,
+ arraydescr.lendescr.offset)
+
class ForTestOnly:
pass
@@ -842,14 +783,6 @@
x3 = x0 * 0.3
self.for_test_only.x = x0 + x1 + x2 + x3
- def get_funcptr_for_malloc_gc_fixed(self):
- """(size) -> GCREF"""
- return llhelper(self.MALLOC_GC_FIXED, self.malloc_gc_fixed)
-
- def get_funcptr_for_malloc_gc_variable(self):
- """(base_size, num_elem, item_size) -> GCREF"""
- return llhelper(self.MALLOC_GC_VARIABLE, self.malloc_gc_variable)
-
def get_nursery_free_addr(self):
nurs_addr = llop.gc_adr_of_nursery_free(llmemory.Address)
return rffi.cast(lltype.Signed, nurs_addr)
diff --git a/pypy/jit/backend/llsupport/rewrite.py b/pypy/jit/backend/llsupport/rewrite.py
--- a/pypy/jit/backend/llsupport/rewrite.py
+++ b/pypy/jit/backend/llsupport/rewrite.py
@@ -1,5 +1,5 @@
from pypy.rlib.rarithmetic import ovfcheck
-from pypy.jit.metainterp.history import ConstInt
+from pypy.jit.metainterp.history import ConstInt, BoxPtr, ConstPtr
from pypy.jit.metainterp.resoperation import ResOperation, rop
from pypy.jit.codewriter import heaptracker
from pypy.jit.backend.llsupport.symbolic import WORD
diff --git a/pypy/jit/backend/llsupport/test/test_gc.py b/pypy/jit/backend/llsupport/test/test_gc.py
--- a/pypy/jit/backend/llsupport/test/test_gc.py
+++ b/pypy/jit/backend/llsupport/test/test_gc.py
@@ -32,8 +32,8 @@
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)]
+ assert record == [(arraydescr.basesize +
+ 10 * arraydescr.itemsize, p)]
del record[:]
# ---------- gc_malloc_str ----------
p = gc_ll_descr.gc_malloc_str(10)
@@ -246,47 +246,50 @@
def __init__(self):
self.record = []
+ def _malloc(self, type_id, size):
+ tid = llop.combine_ushort(lltype.Signed, type_id, 0)
+ x = llmemory.raw_malloc(self.gcheaderbuilder.size_gc_header + size)
+ x += self.gcheaderbuilder.size_gc_header
+ return x, tid
+
def do_malloc_fixedsize_clear(self, RESTYPE, type_id, size,
has_finalizer, has_light_finalizer,
contains_weakptr):
assert not contains_weakptr
assert not has_finalizer
assert not has_light_finalizer
- assert rffi.cast(lltype.Signed, type_id) == 0
- x = llmemory.raw_malloc(self.gcheaderbuilder.size_gc_header + size)
- x += self.gcheaderbuilder.size_gc_header
- p = llmemory.cast_adr_to_ptr(x, RESTYPE)
- self.record.append(("fixedsize", repr(size), p))
+ p, tid = self._malloc(type_id, size)
+ p = llmemory.cast_adr_to_ptr(p, RESTYPE)
+ self.record.append(("fixedsize", repr(size), tid, p))
return p
-## def do_malloc_varsize_clear(self, RESTYPE, type_id, length, size,
-## itemsize, offset_to_length):
-## p = llmemory.raw_malloc(size + itemsize * length)
-## (p + offset_to_length).signed[0] = length
-## p = llmemory.cast_adr_to_ptr(p, RESTYPE)
-## tid = llop.combine_ushort(lltype.Signed, type_id, 0)
-## self.record.append(("varsize", tid, length,
-## repr(size), repr(itemsize),
-## repr(offset_to_length), p))
-## return p
+ def do_malloc_varsize_clear(self, RESTYPE, type_id, length, size,
+ itemsize, offset_to_length):
+ p, tid = self._malloc(type_id, size + itemsize * length)
+ (p + offset_to_length).signed[0] = length
+ p = llmemory.cast_adr_to_ptr(p, RESTYPE)
+ self.record.append(("varsize", tid, length,
+ repr(size), repr(itemsize),
+ repr(offset_to_length), p))
+ return p
-## def _write_barrier_failing_case(self, adr_struct, adr_newptr):
-## self.record.append(('barrier', adr_struct, adr_newptr))
+ def _write_barrier_failing_case(self, adr_struct, adr_newptr):
+ self.record.append(('barrier', adr_struct, adr_newptr))
-## def get_write_barrier_failing_case(self, FPTRTYPE):
-## return llhelper(FPTRTYPE, self._write_barrier_failing_case)
+ def get_write_barrier_failing_case(self, FPTRTYPE):
+ return llhelper(FPTRTYPE, self._write_barrier_failing_case)
-## _have_wb_from_array = False
+ _have_wb_from_array = False
-## def _write_barrier_from_array_failing_case(self, adr_struct, v_index):
-## self.record.append(('barrier_from_array', adr_struct, v_index))
+ def _write_barrier_from_array_failing_case(self, adr_struct, v_index):
+ self.record.append(('barrier_from_array', adr_struct, v_index))
-## def get_write_barrier_from_array_failing_case(self, FPTRTYPE):
-## if self._have_wb_from_array:
-## return llhelper(FPTRTYPE,
-## self._write_barrier_from_array_failing_case)
-## else:
-## return lltype.nullptr(FPTRTYPE.TO)
+ def get_write_barrier_from_array_failing_case(self, FPTRTYPE):
+ if self._have_wb_from_array:
+ return llhelper(FPTRTYPE,
+ self._write_barrier_from_array_failing_case)
+ else:
+ return lltype.nullptr(FPTRTYPE.TO)
class TestFramework(object):
@@ -345,22 +348,18 @@
sizedescr = get_size_descr(self.gc_ll_descr, S)
p = self.gc_ll_descr.gc_malloc(sizedescr)
assert lltype.typeOf(p) == llmemory.GCREF
- assert self.llop1.record == [("fixedsize", repr(sizedescr.size), p)]
- p1 = lltype.cast_opaque_ptr(lltype.Ptr(S), p)
- hdr = self.gc_ll_descr.gcheaderbuilder.header_of_object(p1)
- assert hdr.tid == sizedescr.tid
+ assert self.llop1.record == [("fixedsize", repr(sizedescr.size),
+ sizedescr.tid, p)]
def test_gc_malloc_array(self):
A = lltype.GcArray(lltype.Signed)
arraydescr = get_array_descr(self.gc_ll_descr, A)
p = self.gc_ll_descr.gc_malloc_array(arraydescr, 10)
assert self.llop1.record == [("varsize", arraydescr.tid, 10,
- repr(arraydescr.get_base_size(True)),
- repr(arraydescr.get_item_size(True)),
- repr(arraydescr.get_ofs_length(True)),
+ repr(arraydescr.basesize),
+ repr(arraydescr.itemsize),
+ repr(arraydescr.lendescr.offset),
p)]
- assert repr(self.gc_ll_descr.args_for_new_array(arraydescr)) == repr(
- [arraydescr.get_item_size(True), arraydescr.tid])
def test_gc_malloc_str(self):
p = self.gc_ll_descr.gc_malloc_str(10)
@@ -430,8 +429,7 @@
operations = gc_ll_descr.rewrite_assembler(None, operations, [])
assert len(operations) == 0
- def test_rewrite_assembler_1(self):
- # check recording of ConstPtrs
+ def test_record_constptrs(self):
class MyFakeCPU(object):
def cast_adr_to_int(self, adr):
assert adr == "some fake address"
@@ -552,8 +550,7 @@
def test_rewrite_assembler_5(self):
S = lltype.GcStruct('S')
A = lltype.GcArray(lltype.Struct('A', ('x', lltype.Ptr(S))))
- interiordescr = get_interiorfield_descr(self.gc_ll_descr, A,
- A.OF, 'x')
+ interiordescr = get_interiorfield_descr(self.gc_ll_descr, A, 'x')
wbdescr = self.gc_ll_descr.write_barrier_descr
ops = parse("""
[p1, p2]
@@ -572,19 +569,18 @@
equaloplists(operations, expected.operations)
def test_rewrite_assembler_initialization_store(self):
- S = lltype.GcStruct('S', ('parent', OBJECT),
- ('x', lltype.Signed))
- s_vtable = lltype.malloc(OBJECT_VTABLE, immortal=True)
+ S = lltype.GcStruct('S', ('x', lltype.Signed))
+ sdescr = get_size_descr(self.gc_ll_descr, S)
xdescr = get_field_descr(self.gc_ll_descr, S, 'x')
ops = parse("""
[p1]
- p0 = new_with_vtable(ConstClass(s_vtable))
+ p0 = new(descr=sdescr)
setfield_gc(p0, p1, descr=xdescr)
jump()
""", namespace=locals())
expected = parse("""
[p1]
- p0 = new_with_vtable(ConstClass(s_vtable))
+ p0 = new(descr=sdescr)
# no write barrier
setfield_gc(p0, p1, descr=xdescr)
jump()
diff --git a/pypy/jit/backend/llsupport/test/test_rewrite.py b/pypy/jit/backend/llsupport/test/test_rewrite.py
--- a/pypy/jit/backend/llsupport/test/test_rewrite.py
+++ b/pypy/jit/backend/llsupport/test/test_rewrite.py
@@ -21,10 +21,11 @@
sdescr.tid = 1234
#
T = lltype.GcStruct('T', ('y', lltype.Signed),
- ('z', lltype.Signed),
+ ('z', lltype.Ptr(S)),
('t', lltype.Signed))
tdescr = get_size_descr(self.gc_ll_descr, T)
tdescr.tid = 5678
+ tzdescr = get_field_descr(self.gc_ll_descr, T, 'z')
#
A = lltype.GcArray(lltype.Signed)
adescr = get_array_descr(self.gc_ll_descr, A)
@@ -47,6 +48,7 @@
register_known_gctype(self.cpu, o_vtable, O)
#
tiddescr = self.gc_ll_descr.fielddescr_tid
+ wbdescr = self.gc_ll_descr.write_barrier_descr
WORD = globals()['WORD']
#
strdescr = self.gc_ll_descr.str_descr
@@ -409,3 +411,15 @@
p3 = call_malloc_gc(ConstClass(malloc_str), i2)
jump()
""")
+
+ def test_write_barrier_before_setfield_gc(self):
+ self.check_rewrite("""
+ [p1, p2]
+ setfield_gc(p1, p2, descr=tzdescr)
+ jump()
+ """, """
+ [p1, p2]
+ cond_call_gc_wb(p1, p2, descr=wbdescr)
+ setfield_raw(p1, p2, descr=tzdescr)
+ jump()
+ """)
More information about the pypy-commit
mailing list