From: dan Date: Mon, 26 Jul 2010 12:05:17 +0000 (+0000) Subject: Change the way SubProgram objects are deleted so that the code is the same for deleti... X-Git-Tag: version-3.7.2~93^2~6 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=d19c933e8e5a8159f3857759d0b32756ace1c90e;p=thirdparty%2Fsqlite.git Change the way SubProgram objects are deleted so that the code is the same for deletion and measurement. FossilOrigin-Name: 00e55102a8309eb6df08ad4a8937ba02688bac62 --- diff --git a/manifest b/manifest index 339551f838..2314cb6168 100644 --- a/manifest +++ b/manifest @@ -1,8 +1,5 @@ ------BEGIN PGP SIGNED MESSAGE----- -Hash: SHA1 - -C Update\scomments\sto\sbetter\sdocumentation\sthe\snew\smemory\smeasurement\sfunctions. -D 2010-07-26T11:59:41 +C Change\sthe\sway\sSubProgram\sobjects\sare\sdeleted\sso\sthat\sthe\scode\sis\sthe\ssame\sfor\sdeletion\sand\smeasurement. +D 2010-07-26T12:05:17 F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0 F Makefile.in ec08dc838fd8110fe24c92e5130bcd91cbb1ff2e F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654 @@ -166,7 +163,7 @@ F src/pcache.c 1e9aa2dbc0845b52e1b51cc39753b6d1e041cb07 F src/pcache.h c683390d50f856d4cd8e24342ae62027d1bb6050 F src/pcache1.c 3a7c28f46a61b43ff0b5c087a7983c154f4b264c F src/pragma.c 8b24ce00a93de345b6c3bd1e1e2cfba9f63d2325 -F src/prepare.c f045aeff869d6409a2eae2fe08f7dc2df9528195 +F src/prepare.c ce4c35a2b1d5fe916e4a46b70d24a6e997d7c4c6 F src/printf.c 8ae5082dd38a1b5456030c3755ec3a392cd51506 F src/random.c cd4a67b3953b88019f8cd4ccd81394a8ddfaba50 F src/resolve.c 1c0f32b64f8e3f555fe1f732f9d6f501a7f05706 @@ -175,9 +172,9 @@ F src/select.c 74fef1334bec27e606ef0b19e5c41cd0a639e69c F src/shell.c fd4ccdb37c3b68de0623eb938a649e0990710714 F src/sqlite.h.in e789728101d821fd4307208aa11e332e51eedbf9 F src/sqlite3ext.h 69dfb8116af51b84a029cddb3b35062354270c89 -F src/sqliteInt.h 2a057459f689e23514f0ac2c414ef900f5d02a71 +F src/sqliteInt.h a9be6badc6cd6a3c1ae54475a98661cf351ecad5 F src/sqliteLimit.h 196e2f83c3b444c4548fc1874f52f84fdbda40f3 -F src/status.c 0fb0feca10d0b991b573a2d0cec909507388c9aa +F src/status.c ff0f61918f0c340ef5bc46154fdaadfd2646c196 F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e F src/tclsqlite.c ae1e4fb653c91ddad7e2534d209711a12604ccc4 F src/test1.c ff3b4533fc4d78d1bff2ef831a5791db55096ed3 @@ -216,16 +213,16 @@ F src/test_thread.c bedd05cad673dba53326f3aa468cc803038896c0 F src/test_vfs.c 7e291f85256516ebde6633bc381ff7eedfa30234 F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 F src/tokenize.c 604607d6813e9551cf5189d899e0a25c12681080 -F src/trigger.c 67e95c76d625b92d43409ace771c8e0d02a09ac2 +F src/trigger.c b8bedb9c0084ceb51a40f54fcca2ce048c8de852 F src/update.c 19c899c23cd29fd102c9068e0b0ff5b087204beb F src/utf.c 1baeeac91707a4df97ccc6141ec0f808278af685 F src/util.c 32aebf04c10e51ad3977a928b7416bed671b620b F src/vacuum.c 241a8386727c1497eba4955933356dfba6ff8c9f F src/vdbe.c cefff41564b68a412e65e6a1013ec1b1c1ece6c4 -F src/vdbe.h 7c5de1c7e2e6bc1f301bb95297aeb5d1b8455764 -F src/vdbeInt.h 19ebc8c2a2e938340051ee65af3f377fb99102d1 +F src/vdbe.h e1b91019c807519b8060199f6341ad4255066ae8 +F src/vdbeInt.h ffd68c4d4229227a5089bec53a1c635146177abc F src/vdbeapi.c dc3138f10afbc95ed3c21dd25abb154504b1db9d -F src/vdbeaux.c 1616d797183a7b803124697bb4dfa883b3b6c12a +F src/vdbeaux.c 41a4b2f9cd5fd5d459bee9095edd6b3072a12831 F src/vdbeblob.c 258a6010ba7a82b72b327fb24c55790655689256 F src/vdbemem.c 5e579abf6532001dfbee0e640dc34eae897a9807 F src/vdbetrace.c 864cef96919323482ebd9986f2132435115e9cc2 @@ -841,14 +838,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P 629e38a8c9e31111e351fe4625a5835576d23584 -R 80a7d5f9fa365532b65c8e170e351383 -U drh -Z b16bb922413ea0fca9b19fe4f93e9874 ------BEGIN PGP SIGNATURE----- -Version: GnuPG v1.4.6 (GNU/Linux) - -iD8DBQFMTXixoxKgR168RlERAl/DAJ9boDTlwMhZR5i1jAV24nxPvAFe6QCffw/4 -5JpbTS+Stpy5Ry5GR8Rpung= -=Daaj ------END PGP SIGNATURE----- +P 620bad035755449c4e6a762f01ef2b1d9e521c7c +R 14493e17a0baceac42c57619039e3d05 +U dan +Z 639bb9e1b1cea8e0a9149dd70998905a diff --git a/manifest.uuid b/manifest.uuid index dc43a1dbf6..195b31931e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -620bad035755449c4e6a762f01ef2b1d9e521c7c \ No newline at end of file +00e55102a8309eb6df08ad4a8937ba02688bac62 \ No newline at end of file diff --git a/src/prepare.c b/src/prepare.c index e51000120c..74accd761f 100644 --- a/src/prepare.c +++ b/src/prepare.c @@ -670,7 +670,6 @@ static int sqlite3Prepare( while( pParse->pTriggerPrg ){ TriggerPrg *pT = pParse->pTriggerPrg; pParse->pTriggerPrg = pT->pNext; - sqlite3VdbeProgramDelete(db, pT->pProgram, 0); sqlite3DbFree(db, pT); } diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 02705769c3..45b893b2dc 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -861,7 +861,6 @@ struct sqlite3 { u8 isTransactionSavepoint; /* True if the outermost savepoint is a TS */ i64 nDeferredCons; /* Net deferred constraints this transaction. */ int *pnBytesFreed; /* If not NULL, increment this in DbFree() */ - SubProgram *pSubProgram; /* List of sub-programs already visited*/ #ifdef SQLITE_ENABLE_UNLOCK_NOTIFY /* The following variables are all protected by the STATIC_MASTER diff --git a/src/status.c b/src/status.c index fce355b8f4..3ea8a95cbb 100644 --- a/src/status.c +++ b/src/status.c @@ -191,13 +191,7 @@ int sqlite3_db_status( db->pnBytesFreed = &nByte; for(pVdbe=db->pVdbe; pVdbe; pVdbe=pVdbe->pNext){ - SubProgram *pSub, *pNext; sqlite3VdbeDeleteObject(db, pVdbe); - for(pSub=db->pSubProgram; pSub; pSub=pNext){ - pNext = pSub->pNext; - pSub->pNext = 0; - } - db->pSubProgram = 0; } db->pnBytesFreed = 0; diff --git a/src/trigger.c b/src/trigger.c index 27fc708d7c..b1d43d06d2 100644 --- a/src/trigger.c +++ b/src/trigger.c @@ -800,6 +800,7 @@ static TriggerPrg *codeRowTrigger( int iEndTrigger = 0; /* Label to jump to if WHEN is false */ assert( pTrigger->zName==0 || pTab==tableOfTrigger(pTrigger) ); + assert( pTop->pVdbe ); /* Allocate the TriggerPrg and SubProgram objects. To ensure that they ** are freed if an error occurs, link them into the Parse.pTriggerPrg @@ -810,7 +811,7 @@ static TriggerPrg *codeRowTrigger( pTop->pTriggerPrg = pPrg; pPrg->pProgram = pProgram = sqlite3DbMallocZero(db, sizeof(SubProgram)); if( !pProgram ) return 0; - pProgram->nRef = 1; + sqlite3VdbeLinkSubProgram(pTop->pVdbe, pProgram); pPrg->pTrigger = pTrigger; pPrg->orconf = orconf; pPrg->aColmask[0] = 0xffffffff; @@ -944,8 +945,9 @@ void sqlite3CodeRowTriggerDirect( /* Code the OP_Program opcode in the parent VDBE. P4 of the OP_Program ** is a pointer to the sub-vdbe containing the trigger program. */ if( pPrg ){ + int bRecursive = (p->zName && 0==(pParse->db->flags&SQLITE_RecTriggers)); + sqlite3VdbeAddOp3(v, OP_Program, reg, ignoreJump, ++pParse->nMem); - pPrg->pProgram->nRef++; sqlite3VdbeChangeP4(v, -1, (const char *)pPrg->pProgram, P4_SUBPROGRAM); VdbeComment( (v, "Call: %s.%s", (p->zName?p->zName:"fkey"), onErrorText(orconf))); @@ -955,7 +957,7 @@ void sqlite3CodeRowTriggerDirect( ** invocation is disallowed if (a) the sub-program is really a trigger, ** not a foreign key action, and (b) the flag to enable recursive triggers ** is clear. */ - sqlite3VdbeChangeP5(v, (u8)(p->zName && !(pParse->db->flags&SQLITE_RecTriggers))); + sqlite3VdbeChangeP5(v, (u8)bRecursive); } } diff --git a/src/vdbe.h b/src/vdbe.h index be77e2ff6b..b22a85a53b 100644 --- a/src/vdbe.h +++ b/src/vdbe.h @@ -81,7 +81,6 @@ struct SubProgram { int nOp; /* Elements in aOp[] */ int nMem; /* Number of memory cells required */ int nCsr; /* Number of cursors required */ - int nRef; /* Number of pointers to this structure */ void *token; /* id that may be used to recursive triggers */ SubProgram *pNext; /* Next sub-program already visited */ }; @@ -214,6 +213,10 @@ UnpackedRecord *sqlite3VdbeRecordUnpack(KeyInfo*,int,const void*,char*,int); void sqlite3VdbeDeleteUnpackedRecord(UnpackedRecord*); int sqlite3VdbeRecordCompare(int,const void*,UnpackedRecord*); +#ifndef SQLITE_OMIT_TRIGGER +void sqlite3VdbeLinkSubProgram(Vdbe *, SubProgram *); +#endif + #ifndef NDEBUG void sqlite3VdbeComment(Vdbe*, const char*, ...); diff --git a/src/vdbeInt.h b/src/vdbeInt.h index e8e1585449..4a19f14c2d 100644 --- a/src/vdbeInt.h +++ b/src/vdbeInt.h @@ -323,6 +323,7 @@ struct Vdbe { VdbeFrame *pFrame; /* Parent frame */ int nFrame; /* Number of frames in pFrame list */ u32 expmask; /* Binding to these vars invalidates VM */ + SubProgram *pProgram; /* Linked list of all sub-programs used by VM */ }; /* diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 7359d18ab0..7d9f8c060a 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -614,24 +614,6 @@ static void freeP4(sqlite3 *db, int p4type, void *p4){ if( db->pnBytesFreed==0 ) sqlite3VtabUnlock((VTable *)p4); break; } - case P4_SUBPROGRAM : { - if( db->pnBytesFreed ){ - SubProgram *p = (SubProgram *)p4; - SubProgram *pDone; - for(pDone=db->pSubProgram; pDone; pDone=pDone->pNext){ - if( pDone==p ) break; - } - if( !pDone ){ - p->pNext = db->pSubProgram; - db->pSubProgram = p; - vdbeFreeOpArray(db, p->aOp, p->nOp); - sqlite3DbFree(db, p); - } - }else{ - sqlite3VdbeProgramDelete(db, (SubProgram *)p4, 1); - } - break; - } } } } @@ -655,35 +637,15 @@ static void vdbeFreeOpArray(sqlite3 *db, Op *aOp, int nOp){ } /* -** Decrement the ref-count on the SubProgram structure passed as the -** second argument. If the ref-count reaches zero, free the structure. -** -** The array of VDBE opcodes stored as SubProgram.aOp is freed if -** either the ref-count reaches zero or parameter freeop is non-zero. -** -** Since the array of opcodes pointed to by SubProgram.aOp may directly -** or indirectly contain a reference to the SubProgram structure itself. -** By passing a non-zero freeop parameter, the caller may ensure that all -** SubProgram structures and their aOp arrays are freed, even when there -** are such circular references. +** Link the SubProgram object passed as the second argument into the linked +** list at Vdbe.pSubProgram. This list is used to delete all sub-program +** objects when the VM is no longer required. */ -void sqlite3VdbeProgramDelete(sqlite3 *db, SubProgram *p, int freeop){ - if( p ){ - assert( p->nRef>0 ); - if( freeop || p->nRef==1 ){ - Op *aOp = p->aOp; - p->aOp = 0; - vdbeFreeOpArray(db, aOp, p->nOp); - p->nOp = 0; - } - p->nRef--; - if( p->nRef==0 ){ - sqlite3DbFree(db, p); - } - } +void sqlite3VdbeLinkSubProgram(Vdbe *pVdbe, SubProgram *p){ + p->pNext = pVdbe->pProgram; + pVdbe->pProgram = p; } - /* ** Change N opcodes starting at addr to No-ops. */ @@ -2367,9 +2329,15 @@ void sqlite3VdbeDeleteAuxData(VdbeFunc *pVdbeFunc, int mask){ ** the database connection. */ void sqlite3VdbeDeleteObject(sqlite3 *db, Vdbe *p){ + SubProgram *pSub, *pNext; assert( p->db==0 || p->db==db ); releaseMemArray(p->aVar, p->nVar); releaseMemArray(p->aColName, p->nResColumn*COLNAME_N); + for(pSub=p->pProgram; pSub; pSub=pNext){ + pNext = pSub->pNext; + vdbeFreeOpArray(db, pSub->aOp, pSub->nOp); + sqlite3DbFree(db, pSub); + } vdbeFreeOpArray(db, p->aOp, p->nOp); sqlite3DbFree(db, p->aLabel); sqlite3DbFree(db, p->aColName);