Author: Armin Rigo <[email protected]>
Branch: callback-stacklet
Changeset: r64150:392c42ce5054
Date: 2013-05-15 14:37 +0200
http://bitbucket.org/pypy/pypy/changeset/392c42ce5054/
Log: Raaah. That's far, far, far more messy than it looks.
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
@@ -189,16 +189,26 @@
initialframedata.address[0] = llmemory.NULL
anchor.address[0] = anchor
anchor.address[1] = anchor
+ #
+ c = initialframedata
+ while c:
+ rffi.stackcounter.stacks_counter -= 1
+ c = c.address[1]
+ ll_assert(rffi.stackcounter.stacks_counter == 1,
+ "detach_callback_pieces: hum")
return initialframedata
#
def gc_reattach_callback_pieces(pieces):
- ll_assert(pieces != llmemory.NULL, "should not be called if NULL")
+ if pieces == llmemory.NULL:
+ return
ll_assert(pieces.address[0] == llmemory.NULL,
"not a correctly detached stack piece")
anchor = llmemory.cast_ptr_to_adr(gcrootanchor)
lastpiece = pieces
+ rffi.stackcounter.stacks_counter += 1
while lastpiece.address[1]:
lastpiece = lastpiece.address[1]
+ rffi.stackcounter.stacks_counter += 1
anchor_next = anchor.address[1]
lastpiece.address[1] = anchor_next
pieces.address[0] = anchor
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
@@ -59,7 +59,9 @@
return False
else:
anchor = self.next_callback_piece
- self.next_callback_piece = anchor.address[1] # next
+ nextaddr = anchor + sizeofaddr
+ nextaddr = self.translateptr(nextaddr)
+ self.next_callback_piece = nextaddr.address[0]
self.fill_initial_frame(self.curframe, anchor)
return True
@@ -196,6 +198,7 @@
# stacklet with stacklet_new(). If this call fails, then we
# are just returning NULL.
_stack_just_closed()
+ #
return _c.new(gcrootfinder.newthrd, llhelper(_c.run_fn, _new_runfn),
llmemory.NULL)
@@ -208,8 +211,6 @@
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.
@@ -263,17 +264,38 @@
# 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
+ #
+ callback_pieces = llop.gc_detach_callback_pieces(llmemory.Address)
+ newsuspstack.callback_pieces = callback_pieces
+ #
h = pypy_asm_stackwalk2(llhelper(FUNCNOARG_P, _new_callback),
alternateanchor)
+ #
+ llop.gc_reattach_callback_pieces(lltype.Void, callback_pieces)
return self.get_result_suspstack(h)
def switch(self, suspstack):
+ # Immediately before the switch, 'suspstack' describes the suspended
+ # state of the *target* of the switch. Then it is theoretically
+ # freed. In fact what occurs is that we reuse the same 'suspstack'
+ # object in the target, just after the switch, to store the
+ # description of where we came from. Then that "other" 'suspstack'
+ # object is returned.
self.suspstack = suspstack
+ #
+ callback_pieces = llop.gc_detach_callback_pieces(llmemory.Address)
+ old_callback_pieces = suspstack.callback_pieces
+ suspstack.callback_pieces = callback_pieces
+ #
h = pypy_asm_stackwalk2(llhelper(FUNCNOARG_P, _switch_callback),
alternateanchor)
+ #
+ llop.gc_reattach_callback_pieces(lltype.Void, callback_pieces)
+ if not h:
+ self.suspstack.callback_pieces = old_callback_pieces
+ #
return self.get_result_suspstack(h)
def attach_handle_on_suspstack(self, handle):
@@ -288,10 +310,6 @@
#
# 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):
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit