diff options
author | drh <drh@noemail.net> | 2009-06-02 21:31:38 +0000 |
---|---|---|
committer | drh <drh@noemail.net> | 2009-06-02 21:31:38 +0000 |
commit | e98c9049a0a56ea8c3a704a986298f1dc5a9af2f (patch) | |
tree | c2050cc77cfe5f1db7bd7619d17453b97a025cba /src | |
parent | c54a617e1ff59a717960a876977b7c56f2276715 (diff) | |
download | sqlite-e98c9049a0a56ea8c3a704a986298f1dc5a9af2f.tar.gz sqlite-e98c9049a0a56ea8c3a704a986298f1dc5a9af2f.zip |
Further reductions in the amount of stack space required. (CVS 6707)
FossilOrigin-Name: 04bad9eb6dd8bf7cafc9f3918b676e95d5b1c984
Diffstat (limited to 'src')
-rw-r--r-- | src/backup.c | 25 | ||||
-rw-r--r-- | src/bitvec.c | 41 | ||||
-rw-r--r-- | src/pager.c | 5 | ||||
-rw-r--r-- | src/sqliteInt.h | 4 | ||||
-rw-r--r-- | src/vtab.c | 60 |
5 files changed, 80 insertions, 55 deletions
diff --git a/src/backup.c b/src/backup.c index e0ab5d882..a1cb85503 100644 --- a/src/backup.c +++ b/src/backup.c @@ -12,7 +12,7 @@ ** This file contains the implementation of the sqlite3_backup_XXX() ** API functions and the related features. ** -** $Id: backup.c,v 1.15 2009/05/14 19:26:51 drh Exp $ +** $Id: backup.c,v 1.16 2009/06/02 21:31:39 drh Exp $ */ #include "sqliteInt.h" #include "btreeInt.h" @@ -91,15 +91,24 @@ static Btree *findBtree(sqlite3 *pErrorDb, sqlite3 *pDb, const char *zDb){ int i = sqlite3FindDbName(pDb, zDb); if( i==1 ){ - Parse sParse; - memset(&sParse, 0, sizeof(sParse)); - sParse.db = pDb; - if( sqlite3OpenTempDatabase(&sParse) ){ - sqlite3ErrorClear(&sParse); - sqlite3Error(pErrorDb, sParse.rc, "%s", sParse.zErrMsg); + Parse *pParse; + int rc = 0; + pParse = sqlite3StackAllocZero(pErrorDb, sizeof(*pParse)); + if( pParse==0 ){ + sqlite3Error(pErrorDb, SQLITE_NOMEM, "out of memory"); + rc = SQLITE_NOMEM; + }else{ + pParse->db = pDb; + if( sqlite3OpenTempDatabase(pParse) ){ + sqlite3ErrorClear(pParse); + sqlite3Error(pErrorDb, pParse->rc, "%s", pParse->zErrMsg); + rc = SQLITE_ERROR; + } + sqlite3StackFree(pErrorDb, pParse); + } + if( rc ){ return 0; } - assert( sParse.zErrMsg==0 ); } if( i<0 ){ diff --git a/src/bitvec.c b/src/bitvec.c index b6420a7f2..616c2adc5 100644 --- a/src/bitvec.c +++ b/src/bitvec.c @@ -34,7 +34,7 @@ ** start of a transaction, and is thus usually less than a few thousand, ** but can be as large as 2 billion for a really big database. ** -** @(#) $Id: bitvec.c,v 1.14 2009/04/01 23:49:04 drh Exp $ +** @(#) $Id: bitvec.c,v 1.15 2009/06/02 21:31:39 drh Exp $ */ #include "sqliteInt.h" @@ -209,15 +209,20 @@ bitvec_set_rehash: if( p->nSet>=BITVEC_MXHASH ){ unsigned int j; int rc; - u32 aiValues[BITVEC_NINT]; - memcpy(aiValues, p->u.aHash, sizeof(aiValues)); - memset(p->u.apSub, 0, sizeof(aiValues)); - p->iDivisor = (p->iSize + BITVEC_NPTR - 1)/BITVEC_NPTR; - rc = sqlite3BitvecSet(p, i); - for(j=0; j<BITVEC_NINT; j++){ - if( aiValues[j] ) rc |= sqlite3BitvecSet(p, aiValues[j]); + u32 *aiValues = sqlite3StackAllocRaw(0, sizeof(p->u.aHash)); + if( aiValues==0 ){ + return SQLITE_NOMEM; + }else{ + memcpy(aiValues, p->u.aHash, sizeof(p->u.aHash)); + memset(p->u.apSub, 0, sizeof(p->u.apSub)); + p->iDivisor = (p->iSize + BITVEC_NPTR - 1)/BITVEC_NPTR; + rc = sqlite3BitvecSet(p, i); + for(j=0; j<BITVEC_NINT; j++){ + if( aiValues[j] ) rc |= sqlite3BitvecSet(p, aiValues[j]); + } + sqlite3StackFree(0, aiValues); + return rc; } - return rc; } bitvec_set_end: p->nSet++; @@ -227,8 +232,11 @@ bitvec_set_end: /* ** Clear the i-th bit. +** +** pBuf must be a pointer to at least BITVEC_SZ bytes of temporary storage +** that BitvecClear can use to rebuilt its hash table. */ -void sqlite3BitvecClear(Bitvec *p, u32 i){ +void sqlite3BitvecClear(Bitvec *p, u32 i, void *pBuf){ assert( p!=0 ); assert( i>0 ); i--; @@ -244,9 +252,9 @@ void sqlite3BitvecClear(Bitvec *p, u32 i){ p->u.aBitmap[i/BITVEC_SZELEM] &= ~(1 << (i&(BITVEC_SZELEM-1))); }else{ unsigned int j; - u32 aiValues[BITVEC_NINT]; - memcpy(aiValues, p->u.aHash, sizeof(aiValues)); - memset(p->u.aHash, 0, sizeof(aiValues)); + u32 *aiValues = pBuf; + memcpy(aiValues, p->u.aHash, sizeof(p->u.aHash)); + memset(p->u.aHash, 0, sizeof(p->u.aHash)); p->nSet = 0; for(j=0; j<BITVEC_NINT; j++){ if( aiValues[j] && aiValues[j]!=(i+1) ){ @@ -330,12 +338,14 @@ int sqlite3BitvecBuiltinTest(int sz, int *aOp){ unsigned char *pV = 0; int rc = -1; int i, nx, pc, op; + void *pTmpSpace; /* Allocate the Bitvec to be tested and a linear array of ** bits to act as the reference */ pBitvec = sqlite3BitvecCreate( sz ); pV = sqlite3_malloc( (sz+7)/8 + 1 ); - if( pBitvec==0 || pV==0 ) goto bitvec_end; + pTmpSpace = sqlite3_malloc(BITVEC_SZ); + if( pBitvec==0 || pV==0 || pTmpSpace==0 ) goto bitvec_end; memset(pV, 0, (sz+7)/8 + 1); /* Run the program */ @@ -368,7 +378,7 @@ int sqlite3BitvecBuiltinTest(int sz, int *aOp){ } }else{ CLEARBIT(pV, (i+1)); - sqlite3BitvecClear(pBitvec, i+1); + sqlite3BitvecClear(pBitvec, i+1, pTmpSpace); } } @@ -389,6 +399,7 @@ int sqlite3BitvecBuiltinTest(int sz, int *aOp){ /* Free allocated structure */ bitvec_end: + sqlite3_free(pTmpSpace); sqlite3_free(pV); sqlite3BitvecDestroy(pBitvec); return rc; diff --git a/src/pager.c b/src/pager.c index 274949043..16cc70c81 100644 --- a/src/pager.c +++ b/src/pager.c @@ -18,7 +18,7 @@ ** file simultaneously, or one process from reading the database while ** another is writing. ** -** @(#) $Id: pager.c,v 1.590 2009/05/29 11:57:38 drh Exp $ +** @(#) $Id: pager.c,v 1.591 2009/06/02 21:31:39 drh Exp $ */ #ifndef SQLITE_OMIT_DISKIO #include "sqliteInt.h" @@ -5166,7 +5166,8 @@ int sqlite3PagerMovepage(Pager *pPager, DbPage *pPg, Pgno pgno, int isCommit){ rc = sqlite3PagerGet(pPager, needSyncPgno, &pPgHdr); if( rc!=SQLITE_OK ){ if( pPager->pInJournal && needSyncPgno<=pPager->dbOrigSize ){ - sqlite3BitvecClear(pPager->pInJournal, needSyncPgno); + assert( pPager->pTmpSpace!=0 ); + sqlite3BitvecClear(pPager->pInJournal, needSyncPgno, pPager->pTmpSpace); } return rc; } diff --git a/src/sqliteInt.h b/src/sqliteInt.h index d6b150630..eaf35872f 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -11,7 +11,7 @@ ************************************************************************* ** Internal interface definitions for SQLite. ** -** @(#) $Id: sqliteInt.h,v 1.880 2009/06/01 18:18:21 drh Exp $ +** @(#) $Id: sqliteInt.h,v 1.881 2009/06/02 21:31:39 drh Exp $ */ #ifndef _SQLITEINT_H_ #define _SQLITEINT_H_ @@ -2455,7 +2455,7 @@ void sqlite3EndTable(Parse*,Token*,Token*,Select*); Bitvec *sqlite3BitvecCreate(u32); int sqlite3BitvecTest(Bitvec*, u32); int sqlite3BitvecSet(Bitvec*, u32); -void sqlite3BitvecClear(Bitvec*, u32); +void sqlite3BitvecClear(Bitvec*, u32, void*); void sqlite3BitvecDestroy(Bitvec*); u32 sqlite3BitvecSize(Bitvec*); int sqlite3BitvecBuiltinTest(int,int*); diff --git a/src/vtab.c b/src/vtab.c index 3c7316c02..10a168162 100644 --- a/src/vtab.c +++ b/src/vtab.c @@ -11,7 +11,7 @@ ************************************************************************* ** This file contains code used to help implement virtual tables. ** -** $Id: vtab.c,v 1.89 2009/05/20 20:10:47 drh Exp $ +** $Id: vtab.c,v 1.90 2009/06/02 21:31:39 drh Exp $ */ #ifndef SQLITE_OMIT_VIRTUALTABLE #include "sqliteInt.h" @@ -550,7 +550,7 @@ int sqlite3VtabCallCreate(sqlite3 *db, int iDb, const char *zTab, char **pzErr){ ** virtual table module. */ int sqlite3_declare_vtab(sqlite3 *db, const char *zCreateTable){ - Parse sParse; + Parse *pParse; int rc = SQLITE_OK; Table *pTab; @@ -565,33 +565,37 @@ int sqlite3_declare_vtab(sqlite3 *db, const char *zCreateTable){ } assert((pTab->tabFlags & TF_Virtual)!=0 && pTab->nCol==0 && pTab->aCol==0); - memset(&sParse, 0, sizeof(Parse)); - sParse.declareVtab = 1; - sParse.db = db; - - if( - SQLITE_OK == sqlite3RunParser(&sParse, zCreateTable, &zErr) && - sParse.pNewTable && - !sParse.pNewTable->pSelect && - (sParse.pNewTable->tabFlags & TF_Virtual)==0 - ){ - pTab->aCol = sParse.pNewTable->aCol; - pTab->nCol = sParse.pNewTable->nCol; - sParse.pNewTable->nCol = 0; - sParse.pNewTable->aCol = 0; - db->pVTab = 0; - } else { - sqlite3Error(db, SQLITE_ERROR, zErr); - sqlite3DbFree(db, zErr); - rc = SQLITE_ERROR; - } - sParse.declareVtab = 0; - - if( sParse.pVdbe ){ - sqlite3VdbeFinalize(sParse.pVdbe); + pParse = sqlite3StackAllocZero(db, sizeof(*pParse)); + if( pParse==0 ){ + rc = SQLITE_NOMEM; + }else{ + pParse->declareVtab = 1; + pParse->db = db; + + if( + SQLITE_OK == sqlite3RunParser(pParse, zCreateTable, &zErr) && + pParse->pNewTable && + !pParse->pNewTable->pSelect && + (pParse->pNewTable->tabFlags & TF_Virtual)==0 + ){ + pTab->aCol = pParse->pNewTable->aCol; + pTab->nCol = pParse->pNewTable->nCol; + pParse->pNewTable->nCol = 0; + pParse->pNewTable->aCol = 0; + db->pVTab = 0; + } else { + sqlite3Error(db, SQLITE_ERROR, zErr); + sqlite3DbFree(db, zErr); + rc = SQLITE_ERROR; + } + pParse->declareVtab = 0; + + if( pParse->pVdbe ){ + sqlite3VdbeFinalize(pParse->pVdbe); + } + sqlite3DeleteTable(pParse->pNewTable); + sqlite3StackFree(db, pParse); } - sqlite3DeleteTable(sParse.pNewTable); - sParse.pNewTable = 0; assert( (rc&0xff)==rc ); rc = sqlite3ApiExit(db, rc); |