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?");
}