Author: Armin Rigo <[email protected]>
Branch: callback-stacklet
Changeset: r64125:43633e9da628
Date: 2013-05-15 13:30 +0200
http://bitbucket.org/pypy/pypy/changeset/43633e9da628/
Log: in-progress
diff --git a/rpython/memory/gctransform/asmgcroot.py
b/rpython/memory/gctransform/asmgcroot.py
--- a/rpython/memory/gctransform/asmgcroot.py
+++ b/rpython/memory/gctransform/asmgcroot.py
@@ -172,10 +172,45 @@
self.gctransformer = gctransformer
def need_stacklet_support(self, gctransformer, getfn):
+ from rpython.annotator import model as annmodel
+ from rpython.rlib import _stacklet_asmgcc
# stacklet support: BIG HACK for rlib.rstacklet
- from rpython.rlib import _stacklet_asmgcc
_stacklet_asmgcc._asmstackrootwalker = self # as a global! argh
_stacklet_asmgcc.complete_destrptr(gctransformer)
+ #
+ def gc_detach_callback_pieces():
+ # XXX use belongs_to_current_thread() below
+ anchor = llmemory.cast_ptr_to_adr(gcrootanchor)
+ initialframedata = anchor.address[1]
+ if initialframedata == anchor:
+ return llmemory.NULL # empty
+ lastframedata = anchor.address[0]
+ lastframedata.address[1] = llmemory.NULL
+ initialframedata.address[0] = llmemory.NULL
+ anchor.address[0] = anchor
+ anchor.address[1] = anchor
+ return initialframedata
+ #
+ def gc_reattach_callback_pieces(pieces):
+ ll_assert(pieces != llmemory.NULL, "should not be called if NULL")
+ ll_assert(pieces.address[0] == llmemory.NULL,
+ "not a correctly detached stack piece")
+ anchor = llmemory.cast_ptr_to_adr(gcrootanchor)
+ lastpiece = pieces
+ while lastpiece.address[1]:
+ lastpiece = lastpiece.address[1]
+ anchor_next = anchor.address[1]
+ lastpiece.address[1] = anchor_next
+ pieces.address[0] = anchor
+ anchor.address[1] = pieces
+ anchor_next.address[0] = lastpiece
+ #
+ s_addr = annmodel.SomeAddress()
+ s_None = annmodel.s_None
+ self.gc_detach_callback_pieces_ptr = getfn(gc_detach_callback_pieces,
+ [], s_addr)
+ self.gc_reattach_callback_pieces_ptr=getfn(gc_reattach_callback_pieces,
+ [s_addr], s_None)
def need_thread_support(self, gctransformer, getfn):
# Threads supported "out of the box" by the rest of the code.
diff --git a/rpython/memory/gctransform/framework.py
b/rpython/memory/gctransform/framework.py
--- a/rpython/memory/gctransform/framework.py
+++ b/rpython/memory/gctransform/framework.py
@@ -800,6 +800,21 @@
def gct_gc_adr_of_root_stack_top(self, hop):
self._gc_adr_of_gcdata_attr(hop, 'root_stack_top')
+ def gct_gc_detach_callback_pieces(self, hop):
+ op = hop.spaceop
+ assert len(op.args) == 0
+ hop.genop("direct_call",
+ [self.root_walker.gc_detach_callback_pieces_ptr],
+ resultvar=op.result)
+
+ def gct_gc_reattach_callback_pieces(self, hop):
+ op = hop.spaceop
+ assert len(op.args) == 1
+ hop.genop("direct_call",
+ [self.root_walker.gc_reattach_callback_pieces_ptr,
+ op.args[0]],
+ resultvar=op.result)
+
def gct_gc_shadowstackref_new(self, hop):
op = hop.spaceop
livevars = self.push_roots(hop)
diff --git a/rpython/rlib/_stacklet_asmgcc.py b/rpython/rlib/_stacklet_asmgcc.py
--- a/rpython/rlib/_stacklet_asmgcc.py
+++ b/rpython/rlib/_stacklet_asmgcc.py
@@ -32,6 +32,7 @@
if not p.handle:
return False
self.context = llmemory.cast_ptr_to_adr(p.handle)
+ self.next_callback_piece = p.callback_pieces
anchor = p.anchor
del p
self.curframe = lltype.malloc(WALKFRAME, flavor='raw')
@@ -50,11 +51,17 @@
retaddraddr = self.translateptr(retaddraddr)
curframe.frame_address = retaddraddr.address[0]
- def teardown(self):
- lltype.free(self.curframe, flavor='raw')
- lltype.free(self.otherframe, flavor='raw')
- self.context = llmemory.NULL
- return llmemory.NULL
+ def fetch_next_stack_piece(self):
+ if self.next_callback_piece == llmemory.NULL:
+ lltype.free(self.curframe, flavor='raw')
+ lltype.free(self.otherframe, flavor='raw')
+ self.context = llmemory.NULL
+ return False
+ else:
+ anchor = self.next_callback_piece
+ self.next_callback_piece = anchor.address[1] # next
+ self.fill_initial_frame(self.curframe, anchor)
+ return True
def next(self, obj, prev):
#
@@ -117,7 +124,10 @@
location)
# ^^^ non-translated
if caller.frame_address == llmemory.NULL:
- return self.teardown() # completely done with this stack
+ # completely done with this piece of stack
+ if not self.fetch_next_stack_piece():
+ return llmemory.NULL
+ continue
#
self.otherframe = callee
self.curframe = caller
@@ -154,6 +164,7 @@
SUSPSTACK = lltype.GcStruct('SuspStack',
('handle', _c.handle),
('anchor', llmemory.Address),
+ ('callback_pieces', llmemory.Address),
rtti=True)
NULL_SUSPSTACK = lltype.nullptr(SUSPSTACK)
CUSTOMTRACEFUNC = lltype.FuncType([llmemory.Address, llmemory.Address],
@@ -197,6 +208,8 @@
gcrootfinder.suspstack.anchor = stackanchor
alternateanchor.prev = alternateanchor
alternateanchor.next = alternateanchor
+ gcrootfinder.suspstack.callback_pieces = (
+ llop.gc_detach_callback_pieces(llmemory.Address))
def _new_runfn(h, _):
# Here, we are in a fresh new stacklet.
@@ -250,6 +263,7 @@
# make a fresh new clean SUSPSTACK
newsuspstack = lltype.malloc(SUSPSTACK)
newsuspstack.handle = _c.null_handle
+ newsuspstack.callback_pieces = llmemory.NULL
self.suspstack = newsuspstack
# Invoke '_new_callback' by closing the stack
h = pypy_asm_stackwalk2(llhelper(FUNCNOARG_P, _new_callback),
@@ -274,6 +288,10 @@
#
# Return from a new() or a switch(): 'h' is a handle, possibly
# an empty one, that says from where we switched to.
+ if self.suspstack and self.suspstack.callback_pieces:
+ llop.gc_reattach_callback_pieces(lltype.Void,
+ self.suspstack.callback_pieces)
+ self.suspstack.callback_pieces = llmemory.NULL
if not h:
raise MemoryError
elif _c.is_empty_handle(h):
diff --git a/rpython/rtyper/llinterp.py b/rpython/rtyper/llinterp.py
--- a/rpython/rtyper/llinterp.py
+++ b/rpython/rtyper/llinterp.py
@@ -886,6 +886,11 @@
def op_gc_stack_bottom(self):
pass # marker for trackgcroot.py
+ def op_gc_detach_callback_pieces(self):
+ raise NotImplementedError("gc_detach_callback_pieces")
+ def op_gc_reattach_callback_pieces(self):
+ raise NotImplementedError("gc_reattach_callback_pieces")
+
def op_gc_shadowstackref_new(self): # stacklet+shadowstack
raise NotImplementedError("gc_shadowstackref_new")
def op_gc_shadowstackref_context(self):
diff --git a/rpython/rtyper/lltypesystem/lloperation.py
b/rpython/rtyper/lltypesystem/lloperation.py
--- a/rpython/rtyper/lltypesystem/lloperation.py
+++ b/rpython/rtyper/lltypesystem/lloperation.py
@@ -516,6 +516,10 @@
'gc_asmgcroot_static': LLOp(sideeffects=False),
'gc_stack_bottom': LLOp(canrun=True),
+ # for stacklet+asmgcroot support
+ 'gc_detach_callback_pieces': LLOp(),
+ 'gc_reattach_callback_pieces': LLOp(),
+
# for stacklet+shadowstack support
'gc_shadowstackref_new': LLOp(canmallocgc=True),
'gc_shadowstackref_context': LLOp(),
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit