diff options
| author | donal.k.fellows@manchester.ac.uk <dkf> | 2012-02-16 13:51:02 (GMT) |
|---|---|---|
| committer | donal.k.fellows@manchester.ac.uk <dkf> | 2012-02-16 13:51:02 (GMT) |
| commit | 825e22dd18346fa55519a97393fb91c8919662c9 (patch) | |
| tree | b94afa1b480c83e5095e24e1d8596e4c76b8708a | |
| parent | 82b41f5b1e0c9dcb26ab71332dee31f9f962d86a (diff) | |
| download | tcl-825e22dd18346fa55519a97393fb91c8919662c9.zip tcl-825e22dd18346fa55519a97393fb91c8919662c9.tar.gz tcl-825e22dd18346fa55519a97393fb91c8919662c9.tar.bz2 | |
* 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.
| -rw-r--r-- | ChangeLog | 6 | ||||
| -rw-r--r-- | generic/tclExecute.c | 25 |
2 files changed, 29 insertions, 2 deletions
@@ -1,3 +1,9 @@ +2012-02-16 Donal K. Fellows <dkf@users.sf.net> + + * 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 <dkf@users.sf.net> * 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<objc && toIdx>=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 ; index<objc-1 ; index++) { + TclDecrRefCount(objv[index]); + } + listPtr->elemCount = 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); } |
