diff options
author | dgp <dgp@users.sourceforge.net> | 2013-01-17 16:41:29 (GMT) |
---|---|---|
committer | dgp <dgp@users.sourceforge.net> | 2013-01-17 16:41:29 (GMT) |
commit | d47f7eb3d95c51b2d997423c45170dc9af21113c (patch) | |
tree | 4d8a44ff7dfddba80aa3f1b26c7a6cb85dca0f88 | |
parent | 5183004618b076623516cc260ae3e9e283252186 (diff) | |
download | tcl-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.c | 8 | ||||
-rw-r--r-- | generic/tclExecute.c | 42 | ||||
-rw-r--r-- | generic/tclInt.h | 5 | ||||
-rw-r--r-- | generic/tclLiteral.c | 127 |
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*/ |