Tcl Source Code

Artifact [9b664d395e]
Login

Artifact 9b664d395e4aaf1593538f80f35a17783bdecd54:

Attachment "objReform.diff.1" to ticket [1772004fff] added by msofer 2007-08-11 04:43:02.
Index: generic/tcl.h
===================================================================
RCS file: /cvsroot/tcl/tcl/generic/tcl.h,v
retrieving revision 1.234
diff -u -r1.234 tcl.h
--- generic/tcl.h	31 Jul 2007 17:03:35 -0000	1.234
+++ generic/tcl.h	10 Aug 2007 21:34:57 -0000
@@ -742,7 +742,8 @@
  * An object stores a value as either a string, some internal representation,
  * or both.
  */
-
+#define TCL_OBJ_STRING_AREA_SIZE 8
+    
 typedef struct Tcl_Obj {
     int refCount;		/* When 0 the object will be freed. */
     char *bytes;		/* This points to the first byte of the
@@ -778,6 +779,7 @@
 				 * single word */
 	} ptrAndLongRep;
     } internalRep;
+    char reserved[TCL_OBJ_STRING_AREA_SIZE];
 } Tcl_Obj;
 
 /*
Index: generic/tclIndexObj.c
===================================================================
RCS file: /cvsroot/tcl/tcl/generic/tclIndexObj.c,v
retrieving revision 1.35
diff -u -r1.35 tclIndexObj.c
--- generic/tclIndexObj.c	20 Jun 2007 18:46:13 -0000	1.35
+++ generic/tclIndexObj.c	10 Aug 2007 21:34:57 -0000
@@ -332,15 +332,11 @@
     Tcl_Obj *objPtr)
 {
     IndexRep *indexRep = (IndexRep *) objPtr->internalRep.otherValuePtr;
-    register char *buf;
     register unsigned len;
     register CONST char *indexStr = EXPAND_OF(indexRep);
 
     len = strlen(indexStr);
-    buf = (char *) ckalloc(len + 1);
-    memcpy(buf, indexStr, len+1);
-    objPtr->bytes = buf;
-    objPtr->length = len;
+    TclInitStringRep(objPtr, indexStr, len);
 }
 
 /*
Index: generic/tclInt.h
===================================================================
RCS file: /cvsroot/tcl/tcl/generic/tclInt.h,v
retrieving revision 1.331
diff -u -r1.331 tclInt.h
--- generic/tclInt.h	10 Aug 2007 18:40:24 -0000	1.331
+++ generic/tclInt.h	10 Aug 2007 21:34:58 -0000
@@ -3068,6 +3068,19 @@
  *----------------------------------------------------------------
  */
 
+#define TclSetEmptyStringRep(objPtr) \
+    (objPtr)->bytes    = (objPtr)->reserved; \
+    (objPtr)->length   = 0; \
+    *((int *)(objPtr)->reserved) = 0
+
+#define TclObjEmbeddedString(objPtr) \
+    ((objPtr)->bytes == (objPtr)->reserved)
+
+#define TclFreeStringRep(objPtr) \
+    if (objPtr->bytes && !TclObjEmbeddedString(objPtr)) { \
+        ckfree((char *) (objPtr)->bytes); \
+    }
+
 #ifdef TCL_COMPILE_STATS
 #  define TclIncrObjsAllocated() \
     tclObjsAlloced++
@@ -3083,9 +3096,10 @@
     TclIncrObjsAllocated(); \
     TclAllocObjStorage(objPtr); \
     (objPtr)->refCount = 0; \
-    (objPtr)->bytes    = tclEmptyStringRep; \
+    (objPtr)->bytes = (objPtr)->reserved; \
     (objPtr)->length   = 0; \
-    (objPtr)->typePtr  = NULL
+    (objPtr)->typePtr  = NULL; \
+    *((int *)(objPtr)->reserved) = 0
 
 /*
  * Invalidate the string rep first so we can use the bytes value for our
@@ -3097,10 +3111,7 @@
 # define TclDecrRefCount(objPtr) \
     if (--(objPtr)->refCount > 0) ; else { \
 	if (!(objPtr)->typePtr || !(objPtr)->typePtr->freeIntRepProc) { \
-  	    if ((objPtr)->bytes \
-	            && ((objPtr)->bytes != tclEmptyStringRep)) { \
-	        ckfree((char *) (objPtr)->bytes); \
-	    } \
+  	    TclFreeStringRep(objPtr); \
             (objPtr)->length = -1; \
 	    TclFreeObjStorage(objPtr); \
 	    TclIncrObjsFreed(); \
@@ -3207,16 +3218,15 @@
  */
 
 #define TclInitStringRep(objPtr, bytePtr, len) \
-    if ((len) == 0) { \
-	(objPtr)->bytes	 = tclEmptyStringRep; \
-	(objPtr)->length = 0; \
+    if ((len) < TCL_OBJ_STRING_AREA_SIZE) { \
+	(objPtr)->bytes = (objPtr)->reserved; \
     } else { \
 	(objPtr)->bytes = (char *) ckalloc((unsigned) ((len) + 1)); \
-	memcpy((void *) (objPtr)->bytes, (void *) (bytePtr), \
-		(unsigned) (len)); \
-	(objPtr)->bytes[len] = '\0'; \
-	(objPtr)->length = (len); \
-    }
+    } \
+    memcpy((void *) (objPtr)->bytes, (void *) (bytePtr), \
+	     (unsigned) (len)); \
+    (objPtr)->bytes[len] = '\0'; \
+    (objPtr)->length = (len)
 
 /*
  *----------------------------------------------------------------
@@ -3260,9 +3270,7 @@
 
 #define TclInvalidateStringRep(objPtr) \
     if (objPtr->bytes != NULL) { \
-	if (objPtr->bytes != tclEmptyStringRep) {\
-	    ckfree((char *) objPtr->bytes);\
-	}\
+	TclFreeStringRep(objPtr);\
 	objPtr->bytes = NULL;\
     }\
 
Index: generic/tclListObj.c
===================================================================
RCS file: /cvsroot/tcl/tcl/generic/tclListObj.c,v
retrieving revision 1.46
diff -u -r1.46 tclListObj.c
--- generic/tclListObj.c	24 Apr 2007 22:31:39 -0000	1.46
+++ generic/tclListObj.c	10 Aug 2007 21:34:58 -0000
@@ -337,8 +337,7 @@
 	objPtr->typePtr = &tclListType;
 	listRepPtr->refCount++;
     } else {
-	objPtr->bytes = tclEmptyStringRep;
-	objPtr->length = 0;
+	TclSetEmptyStringRep(objPtr);
     }
 }
 
Index: generic/tclNamesp.c
===================================================================
RCS file: /cvsroot/tcl/tcl/generic/tclNamesp.c,v
retrieving revision 1.148
diff -u -r1.148 tclNamesp.c
--- generic/tclNamesp.c	3 Aug 2007 13:51:40 -0000	1.148
+++ generic/tclNamesp.c	10 Aug 2007 21:34:59 -0000
@@ -4800,13 +4800,13 @@
      */
 
     if (length == 0) {
-	objPtr->bytes = tclEmptyStringRep;
+	TclSetEmptyStringRep(objPtr);
     } else {
 	objPtr->bytes = (char *) ckalloc((unsigned) (length + 1));
 	memcpy(objPtr->bytes, name, (unsigned) length);
 	objPtr->bytes[length] = '\0';
+	objPtr->length = length;
     }
-    objPtr->length = length;
 }
 
 /*
Index: generic/tclObj.c
===================================================================
RCS file: /cvsroot/tcl/tcl/generic/tclObj.c,v
retrieving revision 1.131
diff -u -r1.131 tclObj.c
--- generic/tclObj.c	31 Jul 2007 17:03:39 -0000	1.131
+++ generic/tclObj.c	10 Aug 2007 21:34:59 -0000
@@ -609,8 +609,7 @@
     register Tcl_Obj *objPtr)
 {
     objPtr->refCount = 0;
-    objPtr->bytes = tclEmptyStringRep;
-    objPtr->length = 0;
+    TclSetEmptyStringRep(objPtr);
     objPtr->typePtr = NULL;
 
 #ifdef TCL_THREADS
@@ -1014,7 +1013,7 @@
 
     if (objPtr->bytes == NULL) {
 	dupPtr->bytes = NULL;
-    } else if (objPtr->bytes != tclEmptyStringRep) {
+    } else {
 	TclInitStringRep(dupPtr, objPtr->bytes, objPtr->length);
     }
 
@@ -1777,10 +1776,7 @@
 
     Tcl_PrintDouble(NULL, objPtr->internalRep.doubleValue, buffer);
     len = strlen(buffer);
-
-    objPtr->bytes = (char *) ckalloc((unsigned) len + 1);
-    strcpy(objPtr->bytes, buffer);
-    objPtr->length = len;
+    TclInitStringRep(objPtr, buffer, len);
 }
 
 /*
@@ -1968,10 +1964,7 @@
     register int len;
 
     len = TclFormatInt(buffer, objPtr->internalRep.longValue);
-
-    objPtr->bytes = ckalloc((unsigned) len + 1);
-    strcpy(objPtr->bytes, buffer);
-    objPtr->length = len;
+    TclInitStringRep(objPtr, buffer, len);
 }
 
 /*
@@ -2272,9 +2265,7 @@
 
     sprintf(buffer, "%" TCL_LL_MODIFIER "d", wideVal);
     len = strlen(buffer);
-    objPtr->bytes = ckalloc((unsigned) len + 1);
-    memcpy(objPtr->bytes, buffer, len + 1);
-    objPtr->length = len;
+    TclInitStringRep(objPtr, buffer, len);
 }
 #endif /* !NO_WIDE_TYPE */
 
@@ -2767,7 +2758,7 @@
 		objPtr->internalRep.ptrAndLongRep.value = 0;
 		objPtr->typePtr = NULL;
 		if (objPtr->bytes == NULL) {
-		    TclInitStringRep(objPtr, tclEmptyStringRep, 0);
+		    TclSetEmptyStringRep(objPtr);		    
 		}
 	    }
 	    return TCL_OK;
Index: generic/tclPathObj.c
===================================================================
RCS file: /cvsroot/tcl/tcl/generic/tclPathObj.c,v
retrieving revision 1.63
diff -u -r1.63 tclPathObj.c
--- generic/tclPathObj.c	2 May 2007 21:30:36 -0000	1.63
+++ generic/tclPathObj.c	10 Aug 2007 21:34:59 -0000
@@ -2624,8 +2624,7 @@
     Tcl_AppendObjToObj(copy, fsPathPtr->normPathPtr);
     pathPtr->bytes = Tcl_GetStringFromObj(copy, &cwdLen);
     pathPtr->length = cwdLen;
-    copy->bytes = tclEmptyStringRep;
-    copy->length = 0;
+    TclSetEmptyStringRep(copy);
     TclDecrRefCount(copy);
 }
 
Index: generic/tclResult.c
===================================================================
RCS file: /cvsroot/tcl/tcl/generic/tclResult.c,v
retrieving revision 1.37
diff -u -r1.37 tclResult.c
--- generic/tclResult.c	5 Jun 2007 17:57:08 -0000	1.37
+++ generic/tclResult.c	10 Aug 2007 21:34:59 -0000
@@ -962,12 +962,8 @@
 	Tcl_IncrRefCount(objResultPtr);
 	iPtr->objResultPtr = objResultPtr;
     } else {
-	if ((objResultPtr->bytes != NULL)
-		&& (objResultPtr->bytes != tclEmptyStringRep)) {
-	    ckfree((char *) objResultPtr->bytes);
-	}
-	objResultPtr->bytes = tclEmptyStringRep;
-	objResultPtr->length = 0;
+	TclFreeStringRep(objResultPtr);
+	TclSetEmptyStringRep(objResultPtr);
 	TclFreeIntRep(objResultPtr);
 	objResultPtr->typePtr = NULL;
     }
Index: generic/tclStringObj.c
===================================================================
RCS file: /cvsroot/tcl/tcl/generic/tclStringObj.c,v
retrieving revision 1.65
diff -u -r1.65 tclStringObj.c
--- generic/tclStringObj.c	28 Mar 2007 19:03:42 -0000	1.65
+++ generic/tclStringObj.c	10 Aug 2007 21:35:00 -0000
@@ -767,7 +767,7 @@
 	 * free the old string.
 	 */
 
-	if (objPtr->bytes != tclEmptyStringRep) {
+	if (!TclObjEmbeddedString(objPtr)) {
 	    objPtr->bytes = ckrealloc((char *)objPtr->bytes,
 		    (unsigned)(length+1));
 	} else {
@@ -790,13 +790,7 @@
 
     if (objPtr->bytes != NULL) {
 	objPtr->length = length;
-	if (objPtr->bytes != tclEmptyStringRep) {
-	    /*
-	     * Ensure the string is NUL-terminated.
-	     */
-
-	    objPtr->bytes[length] = 0;
-	}
+	objPtr->bytes[length] = 0;
 
 	/*
 	 * Invalidate the unicode data.
@@ -883,7 +877,7 @@
 	 * free the old string.
 	 */
 
-	if (objPtr->bytes != tclEmptyStringRep) {
+	if (!TclObjEmbeddedString(objPtr)) {
 	    new = attemptckrealloc(objPtr->bytes, (unsigned)(length+1));
 	    if (new == NULL) {
 		return 0;
@@ -911,13 +905,7 @@
 
     if (objPtr->bytes != NULL) {
 	objPtr->length = length;
-	if (objPtr->bytes != tclEmptyStringRep) {
-	    /*
-	     * Ensure the string is NULL-terminated.
-	     */
-
-	    objPtr->bytes[length] = 0;
-	}
+	objPtr->bytes[length] = 0;
 
 	/*
 	 * Invalidate the unicode data.
@@ -2825,8 +2813,7 @@
 	     * the string rep to an empty string.
 	     */
 
-	    objPtr->bytes = tclEmptyStringRep;
-	    objPtr->length = 0;
+	    TclSetEmptyStringRep(objPtr);
 	    return;
 	}
 
Index: generic/tclUtil.c
===================================================================
RCS file: /cvsroot/tcl/tcl/generic/tclUtil.c,v
retrieving revision 1.82
diff -u -r1.82 tclUtil.c
--- generic/tclUtil.c	7 May 2007 19:45:33 -0000	1.82
+++ generic/tclUtil.c	10 Aug 2007 21:35:00 -0000
@@ -2417,9 +2417,7 @@
 	buffer[len++] = '-';
 	len += TclFormatInt(buffer+len, -(objPtr->internalRep.longValue));
     }
-    objPtr->bytes = ckalloc((unsigned) (len+1));
-    strcpy(objPtr->bytes, buffer);
-    objPtr->length = len;
+    TclInitStringRep(objPtr, buffer, len);
 }
 
 /*