Tcl Source Code

Artifact [8386924e5b]
Login

Artifact 8386924e5b3f6868de81214baa4f0fcc58ae39b8:

Attachment "alloc2.patch" to ticket [1851832fff] added by msofer 2007-12-17 19:21:06.
Index: generic/tclExecute.c
===================================================================
RCS file: /cvsroot/tcl/tcl/generic/tclExecute.c,v
retrieving revision 1.357
diff -u -r1.357 tclExecute.c
--- generic/tclExecute.c	13 Dec 2007 15:23:16 -0000	1.357
+++ generic/tclExecute.c	17 Dec 2007 12:14:51 -0000
@@ -854,6 +854,19 @@
  *----------------------------------------------------------------------
  */
 
+
+/*
+ * Auxiliary code to insure that GrowEvaluationStack always returns 2-word
+ * aligned memory.
+ */
+
+#define PAD(markerPtr) \
+    (1 + !(PTR2INT(markerPtr) & 1))
+
+#define MEMSTART(markerPtr) \
+    ((markerPtr) + PAD(markerPtr))
+
+
 static Tcl_Obj **
 GrowEvaluationStack(
     ExecEnv *eePtr,		/* Points to the ExecEnv with an evaluation
@@ -865,25 +878,31 @@
     ExecStack *esPtr = eePtr->execStackPtr, *oldPtr = NULL;
     int newBytes, newElems, currElems;
     int needed = growth - (esPtr->endPtr - esPtr->tosPtr);
-    Tcl_Obj **markerPtr = esPtr->markerPtr;
+    Tcl_Obj **markerPtr = esPtr->markerPtr, **memStart;
 
     if (move) {
 	if (!markerPtr) {
 	    Tcl_Panic("STACK: Reallocating with no previous alloc");
 	}
 	if (needed <= 0) {
-	    return markerPtr + 1;
+	    return MEMSTART(markerPtr);
 	}
-    } else if (needed < 0) {
-	/*
-	 * Put a marker pointing to the previous marker in this stack, and
-	 * store it in esPtr as the current marker. Return a pointer to one
-	 * word past the marker.
-	 */
+    } else {
+	Tcl_Obj **tmpMarkerPtr = esPtr->tosPtr + 1;
 
-	esPtr->markerPtr = ++esPtr->tosPtr;
-	*esPtr->markerPtr = (Tcl_Obj *) markerPtr;
-	return esPtr->markerPtr + 1;
+	if (needed + PAD(tmpMarkerPtr) <= 0) {
+	    /*
+	     * Put a marker pointing to the previous marker in this stack, and 
+	     * store it in esPtr as the current marker. Return a pointer to
+	     * one the start of aligned memory.
+	     */
+
+	    esPtr->markerPtr = tmpMarkerPtr;
+	    memStart = MEMSTART(tmpMarkerPtr); 
+	    esPtr->tosPtr = memStart - 1;
+	    *esPtr->markerPtr = (Tcl_Obj *) markerPtr;
+	    return memStart;
+	}
     }
 
     /*
@@ -894,7 +913,7 @@
     if (move) {
 	move = esPtr->tosPtr - markerPtr;
     }
-    needed = growth + move + 1; /* Add the marker. */
+    needed = growth + move + 2; /* Add the marker and possible pad word. */
 
     /*
      * Check if there is enough room in the next stack (if there is one, it
@@ -949,10 +968,12 @@
      */
 
     esPtr->stackWords[0] = NULL;
-    esPtr->markerPtr = esPtr->tosPtr = &esPtr->stackWords[0];
-
+    esPtr->markerPtr = &esPtr->stackWords[0];
+    memStart = MEMSTART(esPtr->markerPtr);
+    esPtr->tosPtr = memStart - 1;
+    
     if (move) {
-	memcpy(&esPtr->stackWords[1], (markerPtr+1), move*sizeof(Tcl_Obj *));
+	memcpy(memStart, MEMSTART(markerPtr), move*sizeof(Tcl_Obj *));
 	esPtr->tosPtr += move;
 	oldPtr->markerPtr = (Tcl_Obj **) *markerPtr;
 	oldPtr->tosPtr = markerPtr-1;
@@ -966,7 +987,7 @@
 	DeleteExecStack(oldPtr);
     }
 
-    return &esPtr->stackWords[1];
+    return memStart;
 }
 
 /*
@@ -1043,7 +1064,7 @@
     esPtr = eePtr->execStackPtr;
     markerPtr = esPtr->markerPtr;
 
-    if ((markerPtr+1) != (Tcl_Obj **)freePtr) {
+    if (MEMSTART(markerPtr) != (Tcl_Obj **)freePtr) {
 	Tcl_Panic("TclStackFree: incorrect freePtr. Call out of sequence?");
     }
 
@@ -1104,7 +1125,7 @@
     esPtr = eePtr->execStackPtr;
     markerPtr = esPtr->markerPtr;
 
-    if ((markerPtr+1) != (Tcl_Obj **)ptr) {
+    if (MEMSTART(markerPtr) != (Tcl_Obj **)ptr) {
 	Tcl_Panic("TclStackRealloc: incorrect ptr. Call out of sequence?");
     }