diff options
-rw-r--r-- | ChangeLog | 7 | ||||
-rw-r--r-- | generic/tclCompExpr.c | 26 |
2 files changed, 31 insertions, 2 deletions
@@ -1,3 +1,10 @@ +2011-09-15 Don Porter <dgp@users.sourceforge.net> + + * generic/tclCompExpr.c: [Bug 3408408] Partial improvement by + sharing as literals the computed values of constant subexpressions + when we can do so without incurring the cost of string rep + generation. + 2011-09-13 Don Porter <dgp@users.sourceforge.net> * generic/tclUtil.c: [Bug 3390638] Workaround broken solaris diff --git a/generic/tclCompExpr.c b/generic/tclCompExpr.c index 80f21e4..d96670c 100644 --- a/generic/tclCompExpr.c +++ b/generic/tclCompExpr.c @@ -2471,8 +2471,30 @@ CompileExprTree( if (ExecConstantExprTree(interp, nodes, next, litObjvPtr) == TCL_OK) { - TclEmitPush(TclAddLiteralObj(envPtr, - Tcl_GetObjResult(interp), NULL), envPtr); + int index; + Tcl_Obj *objPtr = Tcl_GetObjResult(interp); + + /* + * Don't generate a string rep, but if we have one + * already, then use it to share via the literal table. + */ + if (objPtr->bytes) { + Tcl_Obj *tableValue; + + index = TclRegisterNewLiteral(envPtr, objPtr->bytes, + objPtr->length); + tableValue = envPtr->literalArrayPtr[index].objPtr; + if ((tableValue->typePtr == NULL) && + (objPtr->typePtr != NULL)) { + /* Same intrep surgery as for OT_LITERAL */ + tableValue->typePtr = objPtr->typePtr; + tableValue->internalRep = objPtr->internalRep; + objPtr->typePtr = NULL; + } + } else { + index = TclAddLiteralObj(envPtr, objPtr, NULL); + } + TclEmitPush(index, envPtr); } else { TclCompileSyntaxError(interp, envPtr); } |