[pypy-commit] pypy stm-jit: gc_load, stm_gc_load, gc_store: the most generic operations on GC objects,
arigo
noreply at buildbot.pypy.org
Sun Aug 5 18:40:01 CEST 2012
Author: Armin Rigo <arigo at tunes.org>
Branch: stm-jit
Changeset: r56588:777f095f8f84
Date: 2012-08-05 17:26 +0200
http://bitbucket.org/pypy/pypy/changeset/777f095f8f84/
Log: gc_load, stm_gc_load, gc_store: the most generic operations on GC
objects, reading or writing a field of any type in a given GC object
at a given offset.
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
@@ -635,14 +635,16 @@
def get_write_barrier_from_array_fn(self, cpu):
# returns a function with arguments [array, index, newvalue]
+ assert not self.returns_modified_object
llop1 = self.llop1
funcptr = llop1.get_write_barrier_from_array_failing_case(
self.WB_FUNCPTR)
funcaddr = llmemory.cast_ptr_to_adr(funcptr)
- assert not (funcaddr and self.returns_modified_object)
return cpu.cast_adr_to_int(funcaddr) # this may return 0
def has_write_barrier_from_array(self, cpu):
+ if self.returns_modified_object:
+ return False
return self.get_write_barrier_from_array_fn(cpu) != 0
diff --git a/pypy/jit/backend/llsupport/llmodel.py b/pypy/jit/backend/llsupport/llmodel.py
--- a/pypy/jit/backend/llsupport/llmodel.py
+++ b/pypy/jit/backend/llsupport/llmodel.py
@@ -394,8 +394,8 @@
for TYPE, _, itemsize in unroll_basic_sizes:
if size == itemsize:
ofs += itemsize * itemindex
- llop.stm_gc_store(lltype.Void, gcref, ofs,
- rffi.cast(TYPE, newvalue))
+ llop.gc_store(lltype.Void, gcref, ofs,
+ rffi.cast(TYPE, newvalue))
return
else:
raise NotImplementedError("size = %d" % size)
@@ -406,7 +406,7 @@
else:
ofs = self.unpack_arraydescr(arraydescr)
ofs += llmemory.sizeof(llmemory.GCREF) * itemindex
- llop.stm_gc_store(lltype.Void, gcref, ofs, newvalue)
+ llop.gc_store(lltype.Void, gcref, ofs, newvalue)
def bh_setarrayitem_gc_f(self, arraydescr, gcref, itemindex, newvalue):
if not self.gc_ll_descr.stm:
@@ -414,7 +414,7 @@
else:
ofs = self.unpack_arraydescr(arraydescr)
ofs += llmemory.sizeof(longlong.FLOATSTORAGE) * itemindex
- llop.stm_gc_store(lltype.Void, gcref, ofs, newvalue)
+ llop.gc_store(lltype.Void, gcref, ofs, newvalue)
bh_setarrayitem_raw_i = _base_setarrayitem_i
bh_setarrayitem_raw_f = _base_setarrayitem_f
@@ -428,10 +428,10 @@
if size == itemsize:
ofs += itemsize * itemindex
if sign:
- val = llop.stm_gc_load(STYPE, gcref, ofs)
+ val = llop.gc_load(STYPE, gcref, ofs)
val = rffi.cast(lltype.Signed, val)
else:
- val = llop.stm_gc_load(UTYPE, gcref, ofs)
+ val = llop.gc_load(UTYPE, gcref, ofs)
val = rffi.cast(lltype.Signed, val)
return val
else:
@@ -443,7 +443,7 @@
else:
ofs = self.unpack_arraydescr(arraydescr)
ofs += llmemory.sizeof(llmemory.GCREF) * itemindex
- return llop.stm_gc_load(llmemory.GCREF, gcref, ofs)
+ return llop.gc_load(llmemory.GCREF, gcref, ofs)
def bh_getarrayitem_gc_f(self, arraydescr, gcref, itemindex):
if not self.gc_ll_descr.stm:
@@ -451,7 +451,7 @@
else:
ofs = self.unpack_arraydescr(arraydescr)
ofs += llmemory.sizeof(longlong.FLOATSTORAGE) * itemindex
- return llop.stm_gc_load(longlong.FLOATSTORAGE, gcref, ofs)
+ return llop.gc_load(longlong.FLOATSTORAGE, gcref, ofs)
bh_getarrayitem_raw_i = _base_getarrayitem_i
bh_getarrayitem_raw_f = _base_getarrayitem_f
@@ -469,10 +469,10 @@
for STYPE, UTYPE, itemsize in unroll_basic_sizes:
if fieldsize == itemsize:
if sign:
- val = llop.stm_gc_load(STYPE, gcref, fullofs)
+ val = llop.gc_load(STYPE, gcref, fullofs)
val = rffi.cast(lltype.Signed, val)
else:
- val = llop.stm_gc_load(UTYPE, gcref, fullofs)
+ val = llop.gc_load(UTYPE, gcref, fullofs)
val = rffi.cast(lltype.Signed, val)
return val
else:
@@ -501,7 +501,7 @@
ofs += descr.fielddescr.offset + size * itemindex
#
if self.gc_ll_descr.stm:
- return llop.stm_gc_load(llmemory.GCREF, gcref, ofs)
+ return llop.gc_load(llmemory.GCREF, gcref, ofs)
# --- start of GC unsafe code (no GC operation!) ---
items = rffi.ptradd(rffi.cast(rffi.CCHARP, gcref), ofs)
items = rffi.cast(rffi.CArrayPtr(lltype.Signed), items)
@@ -516,7 +516,7 @@
ofs += descr.fielddescr.offset + size * itemindex
#
if self.gc_ll_descr.stm:
- return llop.stm_gc_load(longlong.FLOATSTORAGE, gcref, ofs)
+ return llop.gc_load(longlong.FLOATSTORAGE, gcref, ofs)
# --- start of GC unsafe code (no GC operation!) ---
items = rffi.ptradd(rffi.cast(rffi.CCHARP, gcref), ofs)
items = rffi.cast(rffi.CArrayPtr(longlong.FLOATSTORAGE), items)
@@ -535,8 +535,8 @@
if self.gc_ll_descr.stm:
for TYPE, _, itemsize in unroll_basic_sizes:
if fieldsize == itemsize:
- llop.stm_gc_store(lltype.Void, gcref, ofs,
- rffi.cast(TYPE, value))
+ llop.gc_store(lltype.Void, gcref, ofs,
+ rffi.cast(TYPE, value))
return
else:
raise NotImplementedError("size = %d" % fieldsize)
@@ -558,7 +558,7 @@
ofs += descr.fielddescr.offset + size * itemindex
#
if self.gc_ll_descr.stm:
- llop.stm_gc_store(llmemory.GCREF, gcref, ofs, newvalue)
+ llop.gc_store(llmemory.GCREF, gcref, ofs, newvalue)
return
#
self.gc_ll_descr.do_write_barrier(gcref, newvalue)
@@ -575,7 +575,7 @@
ofs += descr.fielddescr.offset + size * itemindex
#
if self.gc_ll_descr.stm:
- llop.stm_gc_store(longlong.FLOATSTORAGE, gcref, ofs, newvalue)
+ llop.gc_store(longlong.FLOATSTORAGE, gcref, ofs, newvalue)
return
# --- start of GC unsafe code (no GC operation!) ---
items = rffi.ptradd(rffi.cast(rffi.CCHARP, gcref), ofs)
@@ -647,10 +647,10 @@
for STYPE, UTYPE, itemsize in unroll_basic_sizes:
if size == itemsize:
if sign:
- val = llop.stm_gc_load(STYPE, struct, ofs)
+ val = llop.gc_load(STYPE, struct, ofs)
val = rffi.cast(lltype.Signed, val)
else:
- val = llop.stm_gc_load(UTYPE, struct, ofs)
+ val = llop.gc_load(UTYPE, struct, ofs)
val = rffi.cast(lltype.Signed, val)
return val
else:
@@ -661,14 +661,14 @@
return self._base_do_getfield_r(struct, fielddescr)
else:
ofs = self.unpack_fielddescr(fielddescr)
- return llop.stm_gc_load(llmemory.GCREF, struct, ofs)
+ return llop.gc_load(llmemory.GCREF, struct, ofs)
def bh_getfield_gc_f(self, struct, fielddescr):
if not self.gc_ll_descr.stm:
return self._base_do_getfield_f(struct, fielddescr)
else:
ofs = self.unpack_fielddescr(fielddescr)
- return llop.stm_gc_load(longlong.FLOATSTORAGE, struct, ofs)
+ return llop.gc_load(longlong.FLOATSTORAGE, struct, ofs)
bh_getfield_raw_i = _base_do_getfield_i
bh_getfield_raw_f = _base_do_getfield_f
@@ -712,8 +712,8 @@
ofs, size, sign = self.unpack_fielddescr_size(fielddescr)
for TYPE, _, itemsize in unroll_basic_sizes:
if size == itemsize:
- llop.stm_gc_store(lltype.Void, struct, ofs,
- rffi.cast(TYPE, newvalue))
+ llop.gc_store(lltype.Void, struct, ofs,
+ rffi.cast(TYPE, newvalue))
return
else:
raise NotImplementedError("size = %d" % size)
@@ -723,14 +723,14 @@
self._base_do_setfield_r(struct, fielddescr, newvalue)
else:
ofs = self.unpack_fielddescr(fielddescr)
- llop.stm_gc_store(lltype.Void, struct, ofs, newvalue)
+ llop.gc_store(lltype.Void, struct, ofs, newvalue)
def bh_setfield_gc_f(self, struct, fielddescr, newvalue):
if not self.gc_ll_descr.stm:
self._base_do_setfield_f(struct, fielddescr, newvalue)
else:
ofs = self.unpack_fielddescr(fielddescr)
- llop.stm_gc_store(lltype.Void, struct, ofs, newvalue)
+ llop.gc_store(lltype.Void, struct, ofs, newvalue)
bh_setfield_raw_i = _base_do_setfield_i
bh_setfield_raw_f = _base_do_setfield_f
diff --git a/pypy/rpython/lltypesystem/lloperation.py b/pypy/rpython/lltypesystem/lloperation.py
--- a/pypy/rpython/lltypesystem/lloperation.py
+++ b/pypy/rpython/lltypesystem/lloperation.py
@@ -409,8 +409,9 @@
'stm_start_transaction': LLOp(canrun=True, canmallocgc=True),
'stm_stop_transaction': LLOp(canrun=True, canmallocgc=True),
+ 'gc_load': LLOp(sideeffects=False), # so far, only if stm
+ 'gc_store': LLOp(), # so far, only if stm
'stm_gc_load': LLOp(sideeffects=False),
- 'stm_gc_store': LLOp(),
# __________ address operations __________
diff --git a/pypy/rpython/lltypesystem/lltype.py b/pypy/rpython/lltypesystem/lltype.py
--- a/pypy/rpython/lltypesystem/lltype.py
+++ b/pypy/rpython/lltypesystem/lltype.py
@@ -206,7 +206,7 @@
assert isinstance(T, Struct)
T = getattr(T, fieldname)
else:
- assert isinstance(T, Array)
+ assert isinstance(T, (Array, FixedSizeArray))
T = T.OF
return False
diff --git a/pypy/translator/c/funcgen.py b/pypy/translator/c/funcgen.py
--- a/pypy/translator/c/funcgen.py
+++ b/pypy/translator/c/funcgen.py
@@ -610,6 +610,7 @@
OP_STM_GETINTERIORFIELD = _OP_STM
OP_STM_SETINTERIORFIELD = _OP_STM
OP_STM_BECOME_INEVITABLE = _OP_STM
+ OP_STM_GC_LOAD = _OP_STM
def OP_PTR_NONZERO(self, op):
diff --git a/pypy/translator/stm/funcgen.py b/pypy/translator/stm/funcgen.py
--- a/pypy/translator/stm/funcgen.py
+++ b/pypy/translator/stm/funcgen.py
@@ -55,6 +55,16 @@
access_info = (None, ptr, expr)
return _stm_generic_get(funcgen, op, access_info)
+def stm_gc_load(funcgen, op):
+ ptr = funcgen.expr(op.args[0])
+ ofs = funcgen.expr(op.args[1])
+ T = funcgen.lltypemap(op.result)
+ resulttypename = funcgen.db.gettype(T)
+ cresulttypename_ptr = cdecl(resulttypename, ' *')
+ expr = '(*(%s)(((char *)(%s)) + (%s)))' % (cresulttypename_ptr, ptr, ofs)
+ access_info = (None, ptr, expr)
+ return _stm_generic_get(funcgen, op, access_info)
+
def stm_become_inevitable(funcgen, op):
try:
diff --git a/pypy/translator/stm/transform.py b/pypy/translator/stm/transform.py
--- a/pypy/translator/stm/transform.py
+++ b/pypy/translator/stm/transform.py
@@ -203,6 +203,12 @@
def stt_setinteriorfield(self, newoperations, op):
self.transform_set(newoperations, op)
+ def stt_gc_load(self, newoperations, op):
+ self.transform_get(newoperations, op, 'stm_gc_load')
+
+ def stt_gc_store(self, newoperations, op):
+ self.transform_set(newoperations, op)
+
def stt_stm_writebarrier(self, newoperations, op):
if self.localtracker.try_ensure_local(op.args[0]):
op = SpaceOperation('same_as', op.args, op.result)
More information about the pypy-commit
mailing list