summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordgp <dgp@users.sourceforge.net>2013-01-17 16:41:29 (GMT)
committerdgp <dgp@users.sourceforge.net>2013-01-17 16:41:29 (GMT)
commitd47f7eb3d95c51b2d997423c45170dc9af21113c (patch)
tree4d8a44ff7dfddba80aa3f1b26c7a6cb85dca0f88
parent5183004618b076623516cc260ae3e9e283252186 (diff)
downloadtcl-novem_purge_literals.zip
tcl-novem_purge_literals.tar.gz
tcl-novem_purge_literals.tar.bz2
Branch to investigate what happens when we no longer maintain sharednovem_purge_literals
literal tables. First checkin - disable/eliminate the global table in each interp. Makes tests encoding-11.1 and resolver-1.[1-6] fail.
-rw-r--r--generic/tclBasic.c8
-rw-r--r--generic/tclExecute.c42
-rw-r--r--generic/tclInt.h5
-rw-r--r--generic/tclLiteral.c127
4 files changed, 47 insertions, 135 deletions
diff --git a/generic/tclBasic.c b/generic/tclBasic.c
index c15d3c1..b8134ad 100644
--- a/generic/tclBasic.c
+++ b/generic/tclBasic.c
@@ -553,7 +553,6 @@ Tcl_CreateInterp(void)
}
iPtr->cmdCount = 0;
- TclInitLiteralTable(&iPtr->literalTable);
iPtr->compileEpoch = 0;
iPtr->compiledProcPtr = NULL;
iPtr->resolverPtr = NULL;
@@ -1508,13 +1507,6 @@ DeleteInterpProc(
}
/*
- * Free up literal objects created for scripts compiled by the
- * interpreter.
- */
-
- TclDeleteLiteralTable(interp, &iPtr->literalTable);
-
- /*
* TIP #280 - Release the arrays for ByteCode/Proc extension, and
* contents.
*/
diff --git a/generic/tclExecute.c b/generic/tclExecute.c
index 964f04f..baef21f 100644
--- a/generic/tclExecute.c
+++ b/generic/tclExecute.c
@@ -8940,7 +8940,9 @@ EvalStatsCmd(
Tcl_Obj *const objv[]) /* The argument strings. */
{
Interp *iPtr = (Interp *) interp;
+#if 0
LiteralTable *globalTablePtr = &iPtr->literalTable;
+#endif
ByteCodeStats *statsPtr = &iPtr->stats;
double totalCodeBytes, currentCodeBytes;
double totalLiteralBytes, currentLiteralBytes;
@@ -8968,7 +8970,9 @@ EvalStatsCmd(
}
totalLiteralBytes = sizeof(LiteralTable)
+#if 0
+ iPtr->literalTable.numBuckets * sizeof(LiteralEntry *)
+#endif
+ (statsPtr->numLiteralsCreated * sizeof(LiteralEntry))
+ (statsPtr->numLiteralsCreated * sizeof(Tcl_Obj))
+ statsPtr->totalLitStringBytes;
@@ -8979,10 +8983,15 @@ EvalStatsCmd(
currentHeaderBytes = numCurrentByteCodes
* (sizeof(ByteCode) - sizeof(size_t) - sizeof(Tcl_Time));
literalMgmtBytes = sizeof(LiteralTable)
+#if 0
+ (iPtr->literalTable.numBuckets * sizeof(LiteralEntry *))
- + (iPtr->literalTable.numEntries * sizeof(LiteralEntry));
+ + (iPtr->literalTable.numEntries * sizeof(LiteralEntry))
+#endif
+;
currentLiteralBytes = literalMgmtBytes
+#if 0
+ iPtr->literalTable.numEntries * sizeof(Tcl_Obj)
+#endif
+ statsPtr->currentLitStringBytes;
currentCodeBytes = statsPtr->currentByteCodeBytes + currentLiteralBytes;
@@ -9021,7 +9030,11 @@ EvalStatsCmd(
totalLiteralBytes);
Tcl_AppendPrintfToObj(objPtr, " table %lu + bkts %lu + entries %lu + objects %lu + strings %.6g\n",
(unsigned long) sizeof(LiteralTable),
+#if 0
(unsigned long) (iPtr->literalTable.numBuckets * sizeof(LiteralEntry *)),
+#else
+(unsigned long) 0,
+#endif
(unsigned long) (statsPtr->numLiteralsCreated * sizeof(LiteralEntry)),
(unsigned long) (statsPtr->numLiteralsCreated * sizeof(Tcl_Obj)),
statsPtr->totalLitStringBytes);
@@ -9042,9 +9055,13 @@ EvalStatsCmd(
currentLiteralBytes);
Tcl_AppendPrintfToObj(objPtr, " table %lu + bkts %lu + entries %lu + objects %lu + strings %.6g\n",
(unsigned long) sizeof(LiteralTable),
+#if 0
(unsigned long) (iPtr->literalTable.numBuckets * sizeof(LiteralEntry *)),
(unsigned long) (iPtr->literalTable.numEntries * sizeof(LiteralEntry)),
(unsigned long) (iPtr->literalTable.numEntries * sizeof(Tcl_Obj)),
+#else
+(unsigned long)0, (unsigned long)0, (unsigned long)0,
+#endif
statsPtr->currentLitStringBytes);
Tcl_AppendPrintfToObj(objPtr, " Mean code/source\t\t%.1f\n",
currentCodeBytes / statsPtr->currentSrcBytes);
@@ -9086,6 +9103,7 @@ EvalStatsCmd(
strBytesIfUnshared = 0.0;
strBytesSharedMultX = 0.0;
strBytesSharedOnce = 0.0;
+#if 0
for (i = 0; i < globalTablePtr->numBuckets; i++) {
for (entryPtr = globalTablePtr->buckets[i]; entryPtr != NULL;
entryPtr = entryPtr->nextPtr) {
@@ -9105,6 +9123,7 @@ EvalStatsCmd(
}
}
}
+#endif
sharingBytesSaved = (objBytesIfUnshared + strBytesIfUnshared)
- currentLiteralBytes;
@@ -9116,15 +9135,19 @@ EvalStatsCmd(
statsPtr->numLiteralsCreated);
Tcl_AppendPrintfToObj(objPtr, "\nCurrent literal objects\t\t%d (%0.1f%% of current objects)\n",
+#if 0
globalTablePtr->numEntries,
Percent(globalTablePtr->numEntries, tclObjsAlloced-tclObjsFreed));
+#else
+0, Percent(0, 1));
+#endif
Tcl_AppendPrintfToObj(objPtr, " ByteCode literals\t\t%ld (%0.1f%% of current literals)\n",
numByteCodeLits,
- Percent(numByteCodeLits, globalTablePtr->numEntries));
+ Percent(numByteCodeLits, /*globalTablePtr->numEntries*/1));
Tcl_AppendPrintfToObj(objPtr, " Literals reused > 1x\t\t%d\n",
numSharedMultX);
Tcl_AppendPrintfToObj(objPtr, " Mean reference count\t\t%.2f\n",
- ((double) refCountSum) / globalTablePtr->numEntries);
+ ((double) refCountSum) / /*globalTablePtr->numEntries*/ 1);
Tcl_AppendPrintfToObj(objPtr, " Mean len, str reused >1x \t%.2f\n",
(numSharedMultX ? strBytesSharedMultX/numSharedMultX : 0.0));
Tcl_AppendPrintfToObj(objPtr, " Mean len, str used 1x\t\t%.2f\n",
@@ -9136,9 +9159,13 @@ EvalStatsCmd(
currentLiteralBytes);
Tcl_AppendPrintfToObj(objPtr, " table %lu + bkts %lu + entries %lu + objects %lu + strings %.6g\n",
(unsigned long) sizeof(LiteralTable),
+#if 0
(unsigned long) (iPtr->literalTable.numBuckets * sizeof(LiteralEntry *)),
(unsigned long) (iPtr->literalTable.numEntries * sizeof(LiteralEntry)),
(unsigned long) (iPtr->literalTable.numEntries * sizeof(Tcl_Obj)),
+#else
+(unsigned long)0, (unsigned long)0, (unsigned long)0,
+#endif
statsPtr->currentLitStringBytes);
Tcl_AppendPrintfToObj(objPtr, " Bytes if no sharing\t\t%.6g = objects %.6g + strings %.6g\n",
(objBytesIfUnshared + strBytesIfUnshared),
@@ -9151,8 +9178,13 @@ EvalStatsCmd(
Percent(literalMgmtBytes, currentLiteralBytes));
Tcl_AppendPrintfToObj(objPtr, " table %lu + buckets %lu + entries %lu\n",
(unsigned long) sizeof(LiteralTable),
+#if 0
(unsigned long) (iPtr->literalTable.numBuckets * sizeof(LiteralEntry *)),
- (unsigned long) (iPtr->literalTable.numEntries * sizeof(LiteralEntry)));
+ (unsigned long) (iPtr->literalTable.numEntries * sizeof(LiteralEntry))
+#else
+(unsigned long) 0, (unsigned long) 0
+#endif
+);
/*
* Breakdown of current ByteCode space requirements.
@@ -9210,10 +9242,12 @@ EvalStatsCmd(
decadeHigh, Percent(sum, statsPtr->numLiteralsCreated));
}
+/*
litTableStats = TclLiteralStats(globalTablePtr);
Tcl_AppendPrintfToObj(objPtr, "\nCurrent literal table statistics:\n%s\n",
litTableStats);
ckfree(litTableStats);
+*/
/*
* Source and ByteCode size distributions.
diff --git a/generic/tclInt.h b/generic/tclInt.h
index df1507d..a4d7f90 100644
--- a/generic/tclInt.h
+++ b/generic/tclInt.h
@@ -1888,11 +1888,6 @@ typedef struct Interp {
* Normally zero, but may be set before
* calling Tcl_Eval. See below for valid
* values. */
- LiteralTable literalTable; /* Contains LiteralEntry's describing all Tcl
- * objects holding literals of scripts
- * compiled by the interpreter. Indexed by the
- * string representations of literals. Used to
- * avoid creating duplicate objects. */
int compileEpoch; /* Holds the current "compilation epoch" for
* this interpreter. This is incremented to
* invalidate existing ByteCodes when, e.g., a
diff --git a/generic/tclLiteral.c b/generic/tclLiteral.c
index 441ea91..70b1f04 100644
--- a/generic/tclLiteral.c
+++ b/generic/tclLiteral.c
@@ -180,43 +180,8 @@ TclCreateLiteral(
int flags,
LiteralEntry **globalPtrPtr)
{
- LiteralTable *globalTablePtr = &iPtr->literalTable;
- LiteralEntry *globalPtr;
- int globalHash;
Tcl_Obj *objPtr;
- /*
- * Is it in the interpreter's global literal table?
- */
-
- if (hash == (unsigned) -1) {
- hash = HashString(bytes, length);
- }
- globalHash = (hash & globalTablePtr->mask);
- for (globalPtr=globalTablePtr->buckets[globalHash] ; globalPtr!=NULL;
- globalPtr = globalPtr->nextPtr) {
- objPtr = globalPtr->objPtr;
- if ((globalPtr->nsPtr == nsPtr)
- && (objPtr->length == length) && ((length == 0)
- || ((objPtr->bytes[0] == bytes[0])
- && (memcmp(objPtr->bytes, bytes, (unsigned) length) == 0)))) {
- /*
- * A literal was found: return it
- */
-
- if (newPtr) {
- *newPtr = 0;
- }
- if (globalPtrPtr) {
- *globalPtrPtr = globalPtr;
- }
- if (flags & LITERAL_ON_HEAP) {
- ckfree(bytes);
- }
- globalPtr->refCount++;
- return objPtr;
- }
- }
if (!newPtr) {
if (flags & LITERAL_ON_HEAP) {
ckfree(bytes);
@@ -224,13 +189,7 @@ TclCreateLiteral(
return NULL;
}
- /*
- * The literal is new to the interpreter. Add it to the global literal
- * table.
- */
-
TclNewObj(objPtr);
- Tcl_IncrRefCount(objPtr);
if (flags & LITERAL_ON_HEAP) {
objPtr->bytes = bytes;
objPtr->length = length;
@@ -238,62 +197,6 @@ TclCreateLiteral(
TclInitStringRep(objPtr, bytes, length);
}
-#ifdef TCL_COMPILE_DEBUG
- if (TclLookupLiteralEntry((Tcl_Interp *) iPtr, objPtr) != NULL) {
- Tcl_Panic("%s: literal \"%.*s\" found globally but shouldn't be",
- "TclRegisterLiteral", (length>60? 60 : length), bytes);
- }
-#endif
-
- globalPtr = ckalloc(sizeof(LiteralEntry));
- globalPtr->objPtr = objPtr;
- globalPtr->refCount = 1;
- globalPtr->nsPtr = nsPtr;
- globalPtr->nextPtr = globalTablePtr->buckets[globalHash];
- globalTablePtr->buckets[globalHash] = globalPtr;
- globalTablePtr->numEntries++;
-
- /*
- * If the global literal table has exceeded a decent size, rebuild it with
- * more buckets.
- */
-
- if (globalTablePtr->numEntries >= globalTablePtr->rebuildSize) {
- RebuildLiteralTable(globalTablePtr);
- }
-
-#ifdef TCL_COMPILE_DEBUG
- TclVerifyGlobalLiteralTable(iPtr);
- {
- LiteralEntry *entryPtr;
- int found, i;
-
- found = 0;
- for (i=0 ; i<globalTablePtr->numBuckets ; i++) {
- for (entryPtr=globalTablePtr->buckets[i]; entryPtr!=NULL ;
- entryPtr=entryPtr->nextPtr) {
- if ((entryPtr == globalPtr) && (entryPtr->objPtr == objPtr)) {
- found = 1;
- }
- }
- }
- if (!found) {
- Tcl_Panic("%s: literal \"%.*s\" wasn't global",
- "TclRegisterLiteral", (length>60? 60 : length), bytes);
- }
- }
-#endif /*TCL_COMPILE_DEBUG*/
-
-#ifdef TCL_COMPILE_STATS
- iPtr->stats.numLiteralsCreated++;
- iPtr->stats.totalLitStringBytes += (double) (length + 1);
- iPtr->stats.currentLitStringBytes += (double) (length + 1);
- iPtr->stats.literalCount[TclLog2(length)]++;
-#endif /*TCL_COMPILE_STATS*/
-
- if (globalPtrPtr) {
- *globalPtrPtr = globalPtr;
- }
*newPtr = 1;
return objPtr;
}
@@ -343,7 +246,7 @@ TclRegisterLiteral(
{
Interp *iPtr = envPtr->iPtr;
LiteralTable *localTablePtr = &envPtr->localLitTable;
- LiteralEntry *globalPtr, *localPtr;
+ LiteralEntry *localPtr;
Tcl_Obj *objPtr;
unsigned hash;
int localHash, objIndex, new;
@@ -400,15 +303,10 @@ TclRegisterLiteral(
*/
objPtr = TclCreateLiteral(iPtr, bytes, length, hash, &new, nsPtr, flags,
- &globalPtr);
+ NULL);
objIndex = AddLocalLiteralEntry(envPtr, objPtr, localHash);
#ifdef TCL_COMPILE_DEBUG
- if (globalPtr->refCount < 1) {
- Tcl_Panic("%s: global literal \"%.*s\" had bad refCount %d",
- "TclRegisterLiteral", (length>60? 60 : length), bytes,
- globalPtr->refCount);
- }
TclVerifyLocalLiteralTable(envPtr);
#endif /*TCL_COMPILE_DEBUG*/
return objIndex;
@@ -439,20 +337,6 @@ TclLookupLiteralEntry(
* that was previously created by a call to
* TclRegisterLiteral. */
{
- Interp *iPtr = (Interp *) interp;
- LiteralTable *globalTablePtr = &iPtr->literalTable;
- register LiteralEntry *entryPtr;
- const char *bytes;
- int length, globalHash;
-
- bytes = TclGetStringFromObj(objPtr, &length);
- globalHash = (HashString(bytes, length) & globalTablePtr->mask);
- for (entryPtr=globalTablePtr->buckets[globalHash] ; entryPtr!=NULL;
- entryPtr=entryPtr->nextPtr) {
- if (entryPtr->objPtr == objPtr) {
- return entryPtr;
- }
- }
return NULL;
}
@@ -749,6 +633,7 @@ TclReleaseLiteral(
* previously created by a call to
* TclRegisterLiteral. */
{
+#if 0
Interp *iPtr = (Interp *) interp;
LiteralTable *globalTablePtr = &iPtr->literalTable;
register LiteralEntry *entryPtr, *prevPtr;
@@ -793,6 +678,7 @@ TclReleaseLiteral(
break;
}
}
+#endif
/*
* Remove the reference corresponding to the local literal table entry.
@@ -1090,6 +976,7 @@ TclVerifyLocalLiteralTable(
"TclVerifyLocalLiteralTable",
(length>60? 60 : length), bytes, localPtr->refCount);
}
+#if 0
if (TclLookupLiteralEntry((Tcl_Interp *) envPtr->iPtr,
localPtr->objPtr) == NULL) {
bytes = Tcl_GetStringFromObj(localPtr->objPtr, &length);
@@ -1097,6 +984,7 @@ TclVerifyLocalLiteralTable(
"TclVerifyLocalLiteralTable",
(length>60? 60 : length), bytes);
}
+#endif
if (localPtr->objPtr->bytes == NULL) {
Tcl_Panic("%s: literal has NULL string rep",
"TclVerifyLocalLiteralTable");
@@ -1131,6 +1019,7 @@ TclVerifyGlobalLiteralTable(
Interp *iPtr) /* Points to interpreter whose global literal
* table is to be validated. */
{
+#if 0
register LiteralTable *globalTablePtr = &iPtr->literalTable;
register LiteralEntry *globalPtr;
char *bytes;
@@ -1159,6 +1048,8 @@ TclVerifyGlobalLiteralTable(
"TclVerifyGlobalLiteralTable", count,
globalTablePtr->numEntries);
}
+#else
+#endif
}
#endif /*TCL_COMPILE_DEBUG*/