From b4ca6b5a992c406bbf4f3ef73ecb5ae2a8d878a6 Mon Sep 17 00:00:00 2001 From: dkf Date: Thu, 16 Feb 2012 13:51:02 +0000 Subject: * generic/tclExecute.c (INST_LIST_RANGE_IMM): Enhance implementation so that shortening a (not multiply-referenced) list by lopping the end off with [lrange] or [lreplace] is efficient. --- ChangeLog | 6 ++++++ generic/tclExecute.c | 25 +++++++++++++++++++++++-- 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index e5d23bf..7f8c443 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2012-02-16 Donal K. Fellows + + * generic/tclExecute.c (INST_LIST_RANGE_IMM): Enhance implementation + so that shortening a (not multiply-referenced) list by lopping the end + off with [lrange] or [lreplace] is efficient. + 2012-02-15 Donal K. Fellows * generic/tclCompCmds.c (TclCompileLreplaceCmd): Added a compilation diff --git a/generic/tclExecute.c b/generic/tclExecute.c index 92b6612..e402634 100644 --- a/generic/tclExecute.c +++ b/generic/tclExecute.c @@ -4310,12 +4310,33 @@ TEBCresume( */ if (fromIdx<=toIdx && fromIdx=0) { - if (fromIdx<0) { + if (fromIdx < 0) { fromIdx = 0; } if (toIdx >= objc) { toIdx = objc-1; } + if (fromIdx == 0 && toIdx != objc-1 && !Tcl_IsShared(valuePtr)) { + /* + * BEWARE! This is looking inside the implementation of the + * list type. + */ + + List *listPtr = valuePtr->internalRep.twoPtrValue.ptr1; + + if (listPtr->refCount == 1) { + TRACE(("\"%.30s\" %d %d => ", O2S(valuePtr), + TclGetInt4AtPtr(pc+1), TclGetInt4AtPtr(pc+5))); + for (index=toIdx+1 ; indexelemCount = toIdx+1; + listPtr->canonicalFlag = 1; + TclInvalidateStringRep(valuePtr); + TRACE_APPEND(("%.30s\n", O2S(valuePtr))); + NEXT_INST_F(9, 0, 0); + } + } objResultPtr = Tcl_NewListObj(toIdx-fromIdx+1, objv+fromIdx); } else { TclNewObj(objResultPtr); @@ -5716,7 +5737,7 @@ TEBCresume( } result = TclIncrObj(interp, valuePtr, value2Ptr); if (result == TCL_OK) { - Tcl_InvalidateStringRep(dictPtr); + TclInvalidateStringRep(dictPtr); } TclDecrRefCount(value2Ptr); } -- cgit v0.12