summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordkf <donal.k.fellows@manchester.ac.uk>2009-02-05 01:21:59 (GMT)
committerdkf <donal.k.fellows@manchester.ac.uk>2009-02-05 01:21:59 (GMT)
commit1508a4647865986ad56b7f73c13f7829e1a23c3f (patch)
treecf97f1975768f44df104d0ecba464d863f2fed11
parent14af5bfacb1ca6bee54d51c398e8df0adf092d41 (diff)
downloadtcl-1508a4647865986ad56b7f73c13f7829e1a23c3f.zip
tcl-1508a4647865986ad56b7f73c13f7829e1a23c3f.tar.gz
tcl-1508a4647865986ad56b7f73c13f7829e1a23c3f.tar.bz2
Improve efficiency of Tcl_AppendObjToObj's bytearray handling.
-rw-r--r--ChangeLog7
-rw-r--r--generic/tclStringObj.c31
2 files changed, 37 insertions, 1 deletions
diff --git a/ChangeLog b/ChangeLog
index 9136545..65a4067 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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);
/*