diff options
author | dkf <donal.k.fellows@manchester.ac.uk> | 2009-02-05 01:21:59 (GMT) |
---|---|---|
committer | dkf <donal.k.fellows@manchester.ac.uk> | 2009-02-05 01:21:59 (GMT) |
commit | 1508a4647865986ad56b7f73c13f7829e1a23c3f (patch) | |
tree | cf97f1975768f44df104d0ecba464d863f2fed11 | |
parent | 14af5bfacb1ca6bee54d51c398e8df0adf092d41 (diff) | |
download | tcl-1508a4647865986ad56b7f73c13f7829e1a23c3f.zip tcl-1508a4647865986ad56b7f73c13f7829e1a23c3f.tar.gz tcl-1508a4647865986ad56b7f73c13f7829e1a23c3f.tar.bz2 |
Improve efficiency of Tcl_AppendObjToObj's bytearray handling.
-rw-r--r-- | ChangeLog | 7 | ||||
-rw-r--r-- | generic/tclStringObj.c | 31 |
2 files changed, 37 insertions, 1 deletions
@@ -1,3 +1,10 @@ +2009-02-05 Donal K. Fellows <dkf@users.sf.net> + + * generic/tclStringObj.c (Tcl_AppendObjToObj): Special-case the + appending of one bytearray to another, which can be extremely rapid. + Part of scheme to address [Bug 1665628] by making the basic string + operations more efficient on byte arrays. + 2009-02-04 Don Porter <dgp@users.sourceforge.net> * generic/tclStringObj.c: Added overflow protections to the diff --git a/generic/tclStringObj.c b/generic/tclStringObj.c index fc19ce6..b7961b8 100644 --- a/generic/tclStringObj.c +++ b/generic/tclStringObj.c @@ -33,7 +33,7 @@ * See the file "license.terms" for information on usage and redistribution of * this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tclStringObj.c,v 1.84 2009/02/04 21:45:19 dgp Exp $ */ + * RCS: @(#) $Id: tclStringObj.c,v 1.85 2009/02/05 01:21:59 dkf Exp $ */ #include "tclInt.h" #include "tommath.h" @@ -1216,6 +1216,35 @@ Tcl_AppendObjToObj( int length, numChars, allOneByteChars; char *bytes; + /* + * Handle append of one bytearray object to another as a special case. + * Note that we only do this when the object being written doesn't have a + * string rep; if it did, then appending the byte arrays together could + * well lose information; this is a special-case optimization only. + */ + + if (objPtr->typePtr == &tclByteArrayType && objPtr->bytes == NULL + && appendObjPtr->typePtr == &tclByteArrayType) { + unsigned char *bytesDst, *bytesSrc; + int lengthSrc, lengthTotal; + + /* + * Note that we do not assume that objPtr and appendObjPtr must be + * distinct! + */ + + (void) Tcl_GetByteArrayFromObj(objPtr, &length); + (void) Tcl_GetByteArrayFromObj(appendObjPtr, &lengthSrc); + lengthTotal = length + lengthSrc; + if (((length > lengthSrc) ? length : lengthSrc) > lengthTotal) { + Tcl_Panic("overflow when calculating byte array size"); + } + bytesDst = Tcl_SetByteArrayLength(objPtr, lengthTotal); + bytesSrc = Tcl_GetByteArrayFromObj(appendObjPtr, NULL); + memcpy(bytesDst + length, bytesSrc, lengthSrc); + return; + } + SetStringFromAny(NULL, objPtr); /* |