From: SourceForge.net <no...@so...> - 2008-06-19 22:51:40
|
Patches item #1998273, was opened at 2008-06-19 23:55 Message generated for change (Comment added) made by ferrieux You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=310894&aid=1998273&group_id=10894 Please note that this message will contain a full copy of the comment thread, including the initial issue submission, for this request, not just the latest update. Category: 10. Objects Group: None Status: Open Resolution: None Priority: 5 Private: No Submitted By: Alexandre Ferrieux (ferrieux) Assigned to: miguel sofer (msofer) Summary: Making a proc arg's unshared Initial Comment: Inside a proc, a value passed as argument typically has a refcount of three. Of the two unwanted ones, one is easily removed: the local var foo $x[unset x] but the other is harder: it is in the CallFrame's objv, basically [info level 0]. The attached patch provides [info zaplevel] which prematurely neutralizes the [info level 0] data for that purpose. Thus, in proc pop x { info zaplevel lrange $x[unset x] 0 end-1 } The $x value is effectively passed unshared, provided it is passed unshared by the caller. The patch works by downing the refcounts of all members of [info level 0] except the head (to keep the proc name visible, should someone call [info level 0] after [info zaplevel]), and replacing them with references to a shared empty Tcl_Obj. Hence an [info level 0] of "foo a b c" becomes "foo {} {} {}". This gives us safety in the event of callers cacheing CallFrame->objc,objv in locals/registers. ---------------------------------------------------------------------- >Comment By: Alexandre Ferrieux (ferrieux) Date: 2008-06-20 00:51 Message: Logged In: YES user_id=496139 Originator: YES Correction: the K-free K idea and name were given by Don, in the comments of 1890831. ---------------------------------------------------------------------- Comment By: Alexandre Ferrieux (ferrieux) Date: 2008-06-20 00:32 Message: Logged In: YES user_id=496139 Originator: YES No. [take x] is exactly the same as $x[unset x], but in less efficient ;-) To witness that you still have an extra ref: % proc K {x y} { set x } % proc take {v} { upvar 1 $v x ; K $x [unset x] } % proc pop x {lrange [::tcl::unsupported::debugobj [take x]] 0 end-1} % pop [list d f g h] Obj:0x9F2340(2) (list):0x9F1000-0x0 <<<?>>> d f g Now with [info zaplevel]: % proc pop x {info zaplevel;lrange [::tcl::unsupported::debugobj [take x]] 0 end-1} % pop [list d f g h] Obj:0x9DB658(1) (list):0x9EF4C8-0x0 <<<?>>> d f g PS: A side note: the $x[unset x] idiom is the K-free K given to me by Kevin IIRC. It is very efficient because the concatenation of the empty string has a shortcut and causes no duplication nor shimmering. ---------------------------------------------------------------------- Comment By: Andreas Kupries (andreas_kupries) Date: 2008-06-20 00:05 Message: Logged In: YES user_id=75003 Originator: NO Does the following do the same? proc K {x y} { set x } proc take {v} { upvar 1 $v x ; K $x [unset x] } proc pop x { lrange [take x] 0 end-1 } ---------------------------------------------------------------------- You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=310894&aid=1998273&group_id=10894 |