From b84b65f49a83dd2409278f59c82fc6c79d466819 Mon Sep 17 00:00:00 2001 From: dkf Date: Thu, 29 Apr 2010 15:08:03 +0000 Subject: * generic/tclBinary.c (TclAppendBytesToByteArray): [Bug 2992970]: Make * generic/tclStringObj.c (Tcl_AppendObjToObj): an append of a byte array to another into an efficent operation. The problem was the (lack of) a proper growth management strategy for the byte array. --- ChangeLog | 61 +++++++++++++++++++++++---------------- generic/tclBinary.c | 77 +++++++++++++++++++++++++++++++++++++++++++++++++- generic/tclInt.h | 4 ++- generic/tclStringObj.c | 7 ++--- 4 files changed, 118 insertions(+), 31 deletions(-) diff --git a/ChangeLog b/ChangeLog index 78b35b1..74f6a87 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,24 +1,30 @@ +2010-04-29 Donal K. Fellows + + * generic/tclBinary.c (TclAppendBytesToByteArray): [Bug 2992970]: Make + * generic/tclStringObj.c (Tcl_AppendObjToObj): an append of a byte + array to another into an efficent operation. The problem was the (lack + of) a proper growth management strategy for the byte array. + 2010-04-29 Jan Nijtmans - * compat/dirent2.h Include "tcl.h", not , - * compat/dlfcn.h like everywhere else, to insure - * compat/stdlib.h that the version in the Tcl - * compat/string.h distribution is used, not some - * compat/unistd.h version from somewhere else. + * compat/dirent2.h: Include "tcl.h", not , like everywhere + * compat/dlfcn.h: else, to ensure that the version in the Tcl + * compat/stdlib.h: distribution is used, not some version from + * compat/string.h: somewhere else. + * compat/unistd.h: 2010-04-28 Jan Nijtmans - * win/Makefile.in Remove unused @MAN2TCLFLAGS@ - * win/tclWinPort.h Move include from - * generic/tclInt.h tclInt.h to tclWinPort.h, and - * generic/tclEnv.c eliminate unneeded , - and , which are already in - tclInt.h - * generic/regcustom.h Move "tclInt.h" from regcustom.h - * generic/regex.h up to regex.h. - * generic/tclAlloc.c Unneeded include - * generic/tclExecute.c Fix gcc warning: comparison between - signed and unsigned + * win/Makefile.in: Remove unused @MAN2TCLFLAGS@ + * win/tclWinPort.h: Move include from tclInt.h to + * generic/tclInt.h: tclWinPort.h, and eliminate unneeded + * generic/tclEnv.c: , and , which + are already in tclInt.h + * generic/regcustom.h: Move "tclInt.h" from regcustom.h up to + * generic/regex.h: regex.h. + * generic/tclAlloc.c: Unneeded include. + * generic/tclExecute.c: Fix gcc warning: comparison between signed and + unsigned. 2010-04-28 Donal K. Fellows @@ -45,7 +51,7 @@ tclIOUtil.c assignment type mismatch compiler warning * generic/regguts.h: If tclInt.h or tclPort.h is already * generic/tclBasic.c: included, don't include - * generic/tclExecute.c: again. Follow-up to [Bug 2991415]: + * generic/tclExecute.c: again. Follow-up to [Bug 2991415]: * generic/tclIORChan.c: tclport.h #included before limits.h * generic/tclIORTrans.c: See comments in [Bug 2991415] * generic/tclObj.c: @@ -62,7 +68,7 @@ * unix/tclLoadDl.c (FindSymbol): [Bug 2992295]: Simplified the logic so that the casts added in Donal Fellows's change for the same bug are no longer necessary. - + 2010-04-26 Donal K. Fellows * unix/tclLoadDl.c (FindSymbol): [Bug 2992295]: Added an explicit cast @@ -75,8 +81,13 @@ 2010-04-25 Miguel Sofer +<<<<<<< ChangeLog + * generic/tclBasic.c: Add unsupported [yieldm] command. + * generic/tclInt.h: +======= * generic/tclBasic.c: Add unsupported [yieldm] command. Credit * generic/tclInt.h: Lars Hellstrom for the basic idea. +>>>>>>> 1.5083 2010-04-24 Miguel Sofer @@ -223,7 +234,7 @@ TIP #357 IMPLEMENTATION TIP #362 IMPLEMENTATION - + * generic/tclStrToD.c: [Bug 2952904]: Defer creation of the smallest floating point number until it is actually used. (This change avoids a bogus syslog message regarding a 'floating point software assist @@ -252,7 +263,7 @@ * unix/tclUnixPipe.c: * win/Makefile.in: * win/tclWinLoad.c: - + 2010-03-31 Donal K. Fellows * doc/registry.n: Added missing documentation of TIP#362 flags. @@ -331,7 +342,7 @@ * unix/tclUnixFCmd.c (TclUnixCopyFile): [Bug 2976504]: Corrected number of arguments to fstatfs() call. - * macosx/tclMacOSXBundle.c, macosx/tclMacOSXFCmd.c: + * macosx/tclMacOSXBundle.c, macosx/tclMacOSXFCmd.c: * macosx/tclMacOSXNotify.c: Reduce the level of ifdeffery in the functions of these files to improve readability. They need to be audited for whether complexity can be removed based on the minimum @@ -949,7 +960,7 @@ * tools/genStubs.tcl: No longer generate a space after "*" and immediately after a function name, so the - format of function definitions in tcl*Decls.h + format of function definitions in tcl*Decls.h match all other tcl*.h header files. * doc/ParseArgs.3: Change Tcl_ArgvFuncProc, Tcl_ArgvGenFuncProc * generic/tcl.h: and GetFrameInfoValueProc to be function @@ -1012,7 +1023,7 @@ 2010-01-21 Miguel Sofer - * generic/tclCompile.h: NRE-enable direct eval on BC spoilage + * generic/tclCompile.h: NRE-enable direct eval on BC spoilage * generic/tclExecute.c: [Bug 2910748] * tests/nre.test: @@ -1124,7 +1135,7 @@ * generic/tclNamesp.c: leak, and also a test for leaks on namespace * tests/coroutine.test: deletion. * tests/namespace.test: - + 2009-12-30 Donal K. Fellows * library/safe.tcl (AliasSource): [Bug 2923613]: Make the safer @@ -1186,7 +1197,7 @@ 2009-12-23 Jan Nijtmans - * unix/tcl.m4: Install libtcl8.6.dll in bin directory + * unix/tcl.m4: Install libtcl8.6.dll in bin directory * unix/Makefile.in: * unix/configure: (regenerated) diff --git a/generic/tclBinary.c b/generic/tclBinary.c index 62f8f46..1d46902 100644 --- a/generic/tclBinary.c +++ b/generic/tclBinary.c @@ -10,7 +10,7 @@ * See the file "license.terms" for information on usage and redistribution of * this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tclBinary.c,v 1.60 2010/03/05 14:34:03 dkf Exp $ + * RCS: @(#) $Id: tclBinary.c,v 1.61 2010/04/29 15:08:05 dkf Exp $ */ #include "tclInt.h" @@ -577,6 +577,81 @@ UpdateStringOfByteArray( /* *---------------------------------------------------------------------- * + * TclAppendBytesToByteArray -- + * + * This function appends an array of bytes to a byte array object. Note + * that the object *must* be unshared, and the array of bytes *must not* + * refer to the object being appended to. + * + * Results: + * None. + * + * Side effects: + * Allocates enough memory for an array of bytes of the requested total + * size, or possibly larger. [Bug 2992970] + * + *---------------------------------------------------------------------- + */ + +void +TclAppendBytesToByteArray( + Tcl_Obj *objPtr, + const unsigned char *bytes, + unsigned len) +{ + ByteArray *byteArrayPtr; + + if (Tcl_IsShared(objPtr)) { + Tcl_Panic("%s called with shared object","TclAppendBytesToByteArray"); + } + if (objPtr->typePtr != &tclByteArrayType) { + SetByteArrayFromAny(NULL, objPtr); + } + byteArrayPtr = GET_BYTEARRAY(objPtr); + + /* + * If we need to, resize the allocated space in the byte array. + */ + + if (byteArrayPtr->used+len > byteArrayPtr->allocated) { + unsigned int attempt, used = byteArrayPtr->used; + ByteArray *tmpByteArrayPtr; + + attempt = byteArrayPtr->allocated; + do { + attempt *= 2; + } while (attempt < used+len); + + tmpByteArrayPtr = (ByteArray *) + attemptckrealloc((char *) byteArrayPtr, + BYTEARRAY_SIZE(attempt)); + + if (tmpByteArrayPtr == NULL) { + attempt = used + len; + tmpByteArrayPtr = (ByteArray *) ckrealloc((char *) byteArrayPtr, + BYTEARRAY_SIZE(attempt)); + } + + byteArrayPtr = tmpByteArrayPtr; + byteArrayPtr->allocated = attempt; + byteArrayPtr->used = used; + SET_BYTEARRAY(objPtr, byteArrayPtr); + } + + /* + * Do the append if there's any point. + */ + + if (len > 0) { + memcpy(byteArrayPtr->bytes + byteArrayPtr->used, bytes, len); + byteArrayPtr->used += len; + Tcl_InvalidateStringRep(objPtr); + } +} + +/* + *---------------------------------------------------------------------- + * * TclInitBinaryCmd -- * * This function is called to create the "binary" Tcl command. See the diff --git a/generic/tclInt.h b/generic/tclInt.h index 3ca58d7..9c5ec7f 100644 --- a/generic/tclInt.h +++ b/generic/tclInt.h @@ -15,7 +15,7 @@ * See the file "license.terms" for information on usage and redistribution of * this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tclInt.h,v 1.473 2010/04/28 11:50:53 nijtmans Exp $ + * RCS: @(#) $Id: tclInt.h,v 1.474 2010/04/29 15:08:06 dkf Exp $ */ #ifndef _TCLINT @@ -2801,6 +2801,8 @@ struct Tcl_LoadHandle_ { *---------------------------------------------------------------- */ +MODULE_SCOPE void TclAppendBytesToByteArray(Tcl_Obj *objPtr, + const unsigned char *bytes, unsigned len); MODULE_SCOPE int TclNREvalCmd(Tcl_Interp *interp, Tcl_Obj *objPtr, int flags); MODULE_SCOPE void TclPushTailcallPoint(Tcl_Interp *interp); diff --git a/generic/tclStringObj.c b/generic/tclStringObj.c index e075d77..e91b8a4 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.135 2010/03/29 21:58:58 dgp Exp $ */ + * RCS: @(#) $Id: tclStringObj.c,v 1.136 2010/04/29 15:08:07 dkf Exp $ */ #include "tclInt.h" #include "tommath.h" @@ -1235,7 +1235,7 @@ Tcl_AppendObjToObj( */ if (TclIsPureByteArray(objPtr) && TclIsPureByteArray(appendObjPtr)) { - unsigned char *bytesDst, *bytesSrc; + unsigned char *bytesSrc; int lengthSrc, lengthTotal; /* @@ -1250,9 +1250,8 @@ Tcl_AppendObjToObj( 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); + TclAppendBytesToByteArray(objPtr, bytesSrc, (unsigned) lengthSrc); return; } -- cgit v0.12