summaryrefslogtreecommitdiffstats
path: root/generic/tclExecute.c
diff options
context:
space:
mode:
authorgahr <gahr@gahr.ch>2016-06-10 12:10:41 (GMT)
committergahr <gahr@gahr.ch>2016-06-10 12:10:41 (GMT)
commit74cee16544d00f49288f1819fb71e1c5c74ce5ad (patch)
treed77bcc9fb09de474104b1fc59dde7cc6c20b4031 /generic/tclExecute.c
parent8377ed833a9566731442ef744b419425638d5040 (diff)
parent03462e2c1dfc9da26f049ee17a3001df257442e4 (diff)
downloadtcl-74cee16544d00f49288f1819fb71e1c5c74ce5ad.zip
tcl-74cee16544d00f49288f1819fb71e1c5c74ce5ad.tar.gz
tcl-74cee16544d00f49288f1819fb71e1c5c74ce5ad.tar.bz2
Merge trunk
Diffstat (limited to 'generic/tclExecute.c')
-rw-r--r--generic/tclExecute.c83
1 files changed, 36 insertions, 47 deletions
diff --git a/generic/tclExecute.c b/generic/tclExecute.c
index dacc9e2..cd28a92 100644
--- a/generic/tclExecute.c
+++ b/generic/tclExecute.c
@@ -19,6 +19,7 @@
#include "tclCompile.h"
#include "tclOOInt.h"
#include "tommath.h"
+#include "tclStringRep.h"
#include <math.h>
#include <assert.h>
@@ -34,14 +35,14 @@
#endif
/*
- * A mask (should be 2**n-1) that is used to work out when the bytecode engine
- * should call Tcl_AsyncReady() to see whether there is a signal that needs
- * handling.
+ * A counter that is used to work out when the bytecode engine should call
+ * Tcl_AsyncReady() to see whether there is a signal that needs handling, and
+ * other expensive periodic operations.
*/
-#ifndef ASYNC_CHECK_COUNT_MASK
-# define ASYNC_CHECK_COUNT_MASK 63
-#endif /* !ASYNC_CHECK_COUNT_MASK */
+#ifndef ASYNC_CHECK_COUNT
+# define ASYNC_CHECK_COUNT 64
+#endif /* !ASYNC_CHECK_COUNT */
/*
* Boolean flag indicating whether the Tcl bytecode interpreter has been
@@ -1498,11 +1499,9 @@ ExprObjCallback(
*
* Results:
* A (ByteCode *) is returned pointing to the resulting ByteCode.
- * The caller must manage its refCount and arrange for a call to
- * TclCleanupByteCode() when the last reference disappears.
*
* Side effects:
- * The Tcl_ObjType of objPtr is changed to the "bytecode" type,
+ * The Tcl_ObjType of objPtr is changed to the "exprcode" type,
* and the ByteCode is kept in the internal rep (along with context
* data for checking validity) for faster operations the next time
* CompileExprObj is called on the same value.
@@ -1535,7 +1534,7 @@ CompileExprObj(
|| (codePtr->nsPtr != namespacePtr)
|| (codePtr->nsEpoch != namespacePtr->resolverEpoch)
|| (codePtr->localCachePtr != iPtr->varFramePtr->localCachePtr)) {
- FreeExprCodeInternalRep(objPtr);
+ TclFreeIntRep(objPtr);
}
}
if (objPtr->typePtr != &exprCodeType) {
@@ -1566,10 +1565,8 @@ CompileExprObj(
*/
TclEmitOpcode(INST_DONE, &compEnv);
- TclInitByteCodeObj(objPtr, &compEnv);
- objPtr->typePtr = &exprCodeType;
+ codePtr = TclInitByteCodeObj(objPtr, &exprCodeType, &compEnv);
TclFreeCompileEnv(&compEnv);
- codePtr = objPtr->internalRep.twoPtrValue.ptr1;
if (iPtr->varFramePtr->localCachePtr) {
codePtr->localCachePtr = iPtr->varFramePtr->localCachePtr;
codePtr->localCachePtr->refCount++;
@@ -1643,10 +1640,7 @@ FreeExprCodeInternalRep(
{
ByteCode *codePtr = objPtr->internalRep.twoPtrValue.ptr1;
- objPtr->typePtr = NULL;
- if (codePtr->refCount-- <= 1) {
- TclCleanupByteCode(codePtr);
- }
+ TclReleaseByteCode(codePtr);
}
/*
@@ -2032,7 +2026,7 @@ TclNRExecuteByteCode(
* sizeof(void *);
int numWords = (size + sizeof(Tcl_Obj *) - 1) / sizeof(Tcl_Obj *);
- codePtr->refCount++;
+ TclPreserveByteCode(codePtr);
/*
* Reserve the stack, setup the TEBCdataPtr (TD) and CallFrame
@@ -2114,8 +2108,14 @@ TEBCresume(
* sporadically: no special need for speed.
*/
- int instructionCount = 0; /* Counter that is used to work out when to
- * call Tcl_AsyncReady() */
+ unsigned interruptCounter = 1;
+ /* Counter that is used to work out when to
+ * call Tcl_AsyncReady(). This must be 1
+ * initially so that we call the async-check
+ * stanza early, otherwise there are command
+ * sequences that can make the interpreter
+ * busy-loop without an opportunity to
+ * recognise an interrupt. */
const char *curInstName;
#ifdef TCL_COMPILE_DEBUG
int traceInstructions; /* Whether we are doing instruction-level
@@ -2313,10 +2313,11 @@ TEBCresume(
/*
* Check for asynchronous handlers [Bug 746722]; we do the check every
- * ASYNC_CHECK_COUNT_MASK instruction, of the form (2**n-1).
+ * ASYNC_CHECK_COUNT instructions.
*/
- if ((instructionCount++ & ASYNC_CHECK_COUNT_MASK) == 0) {
+ if ((--interruptCounter) == 0) {
+ interruptCounter = ASYNC_CHECK_COUNT;
DECACHE_STACK_INFO();
if (TclAsyncReady(iPtr)) {
result = Tcl_AsyncInvoke(interp, result);
@@ -5737,6 +5738,16 @@ TEBCresume(
if (length3 - 1 == toIdx - fromIdx) {
unsigned char *bytes1, *bytes2;
+ /*
+ * Flush the info in the string internal rep that refers to the
+ * about-to-be-invalidated UTF-8 rep. This indicates that a new
+ * buffer needs to be allocated, and assumes that the value is
+ * already of tclStringTypePtr type, which should be true provided
+ * we call it after Tcl_GetUnicodeFromObj.
+ */
+#define MarkStringInternalRepForFlush(objPtr) \
+ (GET_STRING(objPtr)->allocated = 0)
+
if (Tcl_IsShared(valuePtr)) {
objResultPtr = Tcl_DuplicateObj(valuePtr);
if (TclIsPureByteArray(objResultPtr)
@@ -5749,17 +5760,7 @@ TEBCresume(
ustring2 = Tcl_GetUnicodeFromObj(value3Ptr, NULL);
memcpy(ustring1 + fromIdx, ustring2,
length3 * sizeof(Tcl_UniChar));
-
- /*
- * Magic! Flush the info in the string internal rep that
- * refers to the about-to-be-invalidated UTF-8 rep. This
- * sets the 'allocated' field of the String structure to 0
- * to indicate that a new buffer needs to be allocated.
- * This is safe; we know we've got a tclStringTypePtr set
- * at this point (post Tcl_GetUnicodeFromObj).
- */
-
- ((int *) objResultPtr->internalRep.twoPtrValue.ptr1)[1] = 0;
+ MarkStringInternalRepForFlush(objResultPtr);
}
Tcl_InvalidateStringRep(objResultPtr);
TclDecrRefCount(value3Ptr);
@@ -5776,17 +5777,7 @@ TEBCresume(
ustring2 = Tcl_GetUnicodeFromObj(value3Ptr, NULL);
memcpy(ustring1 + fromIdx, ustring2,
length3 * sizeof(Tcl_UniChar));
-
- /*
- * Magic! Flush the info in the string internal rep that
- * refers to the about-to-be-invalidated UTF-8 rep. This
- * sets the 'allocated' field of the String structure to 0
- * to indicate that a new buffer needs to be allocated.
- * This is safe; we know we've got a tclStringTypePtr set
- * at this point (post Tcl_GetUnicodeFromObj).
- */
-
- ((int *) objResultPtr->internalRep.twoPtrValue.ptr1)[1] = 0;
+ MarkStringInternalRepForFlush(valuePtr);
}
Tcl_InvalidateStringRep(valuePtr);
TclDecrRefCount(value3Ptr);
@@ -8191,9 +8182,7 @@ TEBCresume(
}
iPtr->cmdFramePtr = bcFramePtr->nextPtr;
- if (codePtr->refCount-- <= 1) {
- TclCleanupByteCode(codePtr);
- }
+ TclReleaseByteCode(codePtr);
TclStackFree(interp, TD); /* free my stack */
return result;