Author: Remi Meier <[email protected]>
Branch: stmgc-c4
Changeset: r66120:547adb48566a
Date: 2013-08-13 18:00 +0200
http://bitbucket.org/pypy/pypy/changeset/547adb48566a/
Log: implement fastpath in read and write barriers of gc.py, but fail at
testing them
diff --git a/rpython/jit/backend/llsupport/gc.py
b/rpython/jit/backend/llsupport/gc.py
--- a/rpython/jit/backend/llsupport/gc.py
+++ b/rpython/jit/backend/llsupport/gc.py
@@ -442,16 +442,52 @@
def __init__(self, gc_ll_descr, stmcat):
assert stmcat == 'P2R'
STMBarrierDescr.__init__(self, gc_ll_descr, stmcat,
- 'stm_read_barrier')
+ 'stm_DirectReadBarrier')
# XXX: implement fastpath then change to stm_DirectReadBarrier
+ @specialize.arg(2)
+ def _do_barrier(self, gcref_struct, returns_modified_object):
+ assert returns_modified_object
+ from rpython.memory.gc.stmgc import get_hdr_revision
+ objadr = llmemory.cast_ptr_to_adr(gcref_struct)
+
+ # if h_revision == privat_rev of transaction
+ rev = get_hdr_revision(objadr)
+ priv_rev = self.llop1.stm_get_adr_of_private_rev_num(rffi.SIGNEDP)
+ if rev[0] == priv_rev[0]:
+ return gcref_struct
+
+ # XXX: readcache!
+ funcptr = self.get_barrier_funcptr(returns_modified_object)
+ res = funcptr(objadr)
+ return llmemory.cast_adr_to_ptr(res, llmemory.GCREF)
+
class STMWriteBarrierDescr(STMBarrierDescr):
def __init__(self, gc_ll_descr, stmcat):
assert stmcat in ['P2W']
STMBarrierDescr.__init__(self, gc_ll_descr, stmcat,
- 'stm_write_barrier')
- # XXX: implement fastpath, then change to stm_WriteBarrier
+ 'stm_WriteBarrier')
+
+ @specialize.arg(2)
+ def _do_barrier(self, gcref_struct, returns_modified_object):
+ assert returns_modified_object
+ from rpython.memory.gc.stmgc import (StmGC, get_hdr_revision,
+ get_hdr_tid)
+ objadr = llmemory.cast_ptr_to_adr(gcref_struct)
+
+ # if h_revision == privat_rev of transaction
+ rev = get_hdr_revision(objadr)
+ priv_rev = self.llop1.stm_get_adr_of_private_rev_num(rffi.SIGNEDP)
+ if rev[0] == priv_rev[0]:
+ # also WRITE_BARRIER not set?
+ tid = get_hdr_tid(objadr)[0]
+ if not (tid & StmGC.GCFLAG_WRITE_BARRIER):
+ return gcref_struct
+
+ funcptr = self.get_barrier_funcptr(returns_modified_object)
+ res = funcptr(objadr)
+ return llmemory.cast_adr_to_ptr(res, llmemory.GCREF)
class GcLLDescr_framework(GcLLDescription):
diff --git a/rpython/jit/backend/llsupport/stmrewrite.py
b/rpython/jit/backend/llsupport/stmrewrite.py
--- a/rpython/jit/backend/llsupport/stmrewrite.py
+++ b/rpython/jit/backend/llsupport/stmrewrite.py
@@ -143,7 +143,7 @@
self.known_category[v] = 'P'
def gen_malloc_nursery_varsize_frame(self, sizebox, v_result, tid):
- """ Generate CALL_MALLOC_NURSERY_VARSIZE_FRAME
+ """ For now don't generate CALL_MALLOC_NURSERY_VARSIZE_FRAME
"""
addr = self.gc_ll_descr.get_malloc_fn_addr('malloc_big_fixedsize')
args = [ConstInt(addr), sizebox, ConstInt(tid)]
diff --git a/rpython/jit/backend/x86/test/test_stm_integration.py
b/rpython/jit/backend/x86/test/test_stm_integration.py
--- a/rpython/jit/backend/x86/test/test_stm_integration.py
+++ b/rpython/jit/backend/x86/test/test_stm_integration.py
@@ -258,6 +258,57 @@
s.h_tid = rffi.cast(lltype.Unsigned, StmGC.PREBUILT_FLAGS | tid)
s.h_revision = rffi.cast(lltype.Signed, StmGC.PREBUILT_REVISION)
return s
+
+ def test_gc_read_barrier_fastpath(self):
+ from rpython.jit.backend.llsupport.gc import STMReadBarrierDescr
+ descr = STMReadBarrierDescr(self.cpu.gc_ll_descr, 'P2R')
+
+ called = []
+ def read(obj):
+ called.append(obj)
+ return obj
+
+ PRIV_REV = 66
+ class fakellop:
+ def stm_get_adr_of_private_rev_num(self, _):
+ TP = rffi.SIGNEDP
+ p = lltype.malloc(TP, n=1, flavor='raw',
+ track_allocation=False, zero=True)
+ p[0] = PRIV_REV
+ return rffi.cast(llmemory.Address, p)
+
+ functype = lltype.Ptr(lltype.FuncType(
+ [llmemory.Address], llmemory.Address))
+ funcptr = llhelper(functype, read)
+ descr.b_failing_case_ptr = funcptr
+ descr.llop1 = fakellop()
+
+ # -------- TEST --------
+ for rev in [PRIV_REV+4, PRIV_REV]:
+ called[:] = []
+
+ s = self.allocate_prebuilt_s()
+ sgcref = lltype.cast_opaque_ptr(llmemory.GCREF, s)
+ s.h_revision = rev
+
+ descr._do_barrier(llmemory.AddressAsInt(sgcref),
+ returns_modified_object=True)
+
+ # check if rev-fastpath worked
+ if rev == PRIV_REV:
+ # fastpath
+ assert sgcref not in called
+ else:
+ assert sgcref in called
+
+ # XXX: read_cache test!
+ # # now add it to the read-cache and check
+ # # that it will never call the read_barrier
+ # assert not called_on
+
+
+
+
def test_read_barrier_fastpath(self):
cpu = self.cpu
diff --git a/rpython/memory/gc/stmgc.py b/rpython/memory/gc/stmgc.py
--- a/rpython/memory/gc/stmgc.py
+++ b/rpython/memory/gc/stmgc.py
@@ -15,6 +15,18 @@
first_gcflag = 1 << (LONG_BIT//2)
+
+
+def get_hdr_tid(addr):
+ return llmemory.cast_adr_to_ptr(addr + StmGC.H_TID, rffi.SIGNEDP)
+
+def get_hdr_revision(addr):
+ return llmemory.cast_adr_to_ptr(addr + StmGC.H_REVISION, rffi.SIGNEDP)
+
+def get_hdr_original(addr):
+ return llmemory.cast_adr_to_ptr(addr + StmGC.H_ORIGINAL, rffi.SIGNEDP)
+
+
class StmGC(MovingGCBase):
_alloc_flavor_ = "raw"
inline_simple_malloc = True
@@ -58,6 +70,8 @@
FX_MASK = 65535
+ def get_type_id(self, obj):
+ return llop.stm_get_tid(llgroup.HALFWORD, obj)
def setup(self):
# Hack: MovingGCBase.setup() sets up stuff related to id(), which
@@ -67,24 +81,12 @@
llop.stm_initialize(lltype.Void)
- def get_type_id(self, obj):
- return llop.stm_get_tid(llgroup.HALFWORD, obj)
-
- def get_hdr_tid(self, addr):
- return llmemory.cast_adr_to_ptr(addr + self.H_TID, rffi.SIGNEDP)
-
- def get_hdr_revision(self, addr):
- return llmemory.cast_adr_to_ptr(addr + self.H_REVISION, rffi.SIGNEDP)
-
- def get_hdr_original(self, addr):
- return llmemory.cast_adr_to_ptr(addr + self.H_ORIGINAL, rffi.SIGNEDP)
-
def get_original_copy(self, obj):
addr = llmemory.cast_ptr_to_adr(obj)
- if bool(self.get_hdr_tid(addr)[0] & self.GCFLAG_PREBUILT_ORIGINAL):
+ if bool(get_hdr_tid(addr)[0] & StmGC.GCFLAG_PREBUILT_ORIGINAL):
return obj
#
- orig = self.get_hdr_original(addr)[0]
+ orig = get_hdr_original(addr)[0]
if orig == 0:
return obj
#
@@ -127,11 +129,12 @@
return llop.stm_weakref_allocate(llmemory.GCREF, size,
typeid16, obj)
+
def can_move(self, obj):
"""Means the reference will stay valid, except if not
seen by the GC, then it can get collected."""
- tid = self.get_hdr_tid(obj)[0]
- if bool(tid & self.GCFLAG_OLD):
+ tid = get_hdr_tid(obj)[0]
+ if bool(tid & StmGC.GCFLAG_OLD):
return False # XXX wrong so far. We should add a flag to the
# object that means "don't ever kill this copy"
return True
@@ -157,7 +160,7 @@
source_start, dest_start, length):
ll_assert(False, 'XXX')
return False
-
+
def id(self, gcobj):
return llop.stm_id(lltype.Signed, gcobj)
diff --git a/rpython/translator/stm/src_stm/stmgc.h
b/rpython/translator/stm/src_stm/stmgc.h
--- a/rpython/translator/stm/src_stm/stmgc.h
+++ b/rpython/translator/stm/src_stm/stmgc.h
@@ -167,23 +167,6 @@
#define UNLIKELY(test) __builtin_expect(test, 0)
-
-static inline gcptr stm_read_barrier(gcptr obj) {
- /* XXX optimize to get the smallest code */
- if (UNLIKELY((obj->h_revision != stm_private_rev_num) &&
- (FXCACHE_AT(obj) != obj)))
- obj = stm_DirectReadBarrier(obj);
- return obj;
-}
-
-static inline gcptr stm_write_barrier(gcptr obj) {
- if (UNLIKELY((obj->h_revision != stm_private_rev_num) |
- ((obj->h_tid & GCFLAG_WRITE_BARRIER) != 0)))
- obj = stm_WriteBarrier(obj);
- return obj;
-}
-
-#if 0
#define stm_read_barrier(obj) \
(UNLIKELY(((obj)->h_revision != stm_private_rev_num) && \
(FXCACHE_AT(obj) != (obj))) ? \
@@ -195,6 +178,6 @@
(((obj)->h_tid & GCFLAG_WRITE_BARRIER) != 0)) ? \
stm_WriteBarrier(obj) \
: (obj))
-#endif
+
#endif
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit