Author: Armin Rigo <ar...@tunes.org> 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 pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit