mirror of
https://github.com/sqlite/sqlite.git
synced 2025-11-12 13:01:09 +03:00
Reuse space left-over opcode space at the end of the VDBE opcode array to
store memory cells, VDBE cursors, and other content needed by the VDBE. This reduces the memory required by a prepared statement. (CVS 6307) FossilOrigin-Name: 58a1809257ccfb7d9112a35f79ca2f82b3daa878
This commit is contained in:
14
manifest
14
manifest
@@ -1,5 +1,5 @@
|
|||||||
C Remove\scode\sin\smalloc.c\sthat\swas\salready\scommented\sout\susing\s#if\s0.\s(CVS\s6306)
|
C Reuse\sspace\sleft-over\sopcode\sspace\sat\sthe\send\sof\sthe\sVDBE\sopcode\sarray\sto\nstore\smemory\scells,\sVDBE\scursors,\sand\sother\scontent\sneeded\sby\sthe\sVDBE.\nThis\sreduces\sthe\smemory\srequired\sby\sa\sprepared\sstatement.\s(CVS\s6307)
|
||||||
D 2009-02-19T20:50:15
|
D 2009-02-20T01:28:59
|
||||||
F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0
|
F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0
|
||||||
F Makefile.in 1d83fa2b1fd326b9e121012bd1ff9740537e12b3
|
F Makefile.in 1d83fa2b1fd326b9e121012bd1ff9740537e12b3
|
||||||
F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
|
F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
|
||||||
@@ -202,9 +202,9 @@ F src/util.c 1363f64351f3b544790f3c523439354c02f8c4e9
|
|||||||
F src/vacuum.c 4929a585ef0fb1dfaf46302f8a9c4aa30c2d9cf5
|
F src/vacuum.c 4929a585ef0fb1dfaf46302f8a9c4aa30c2d9cf5
|
||||||
F src/vdbe.c d7b996a5b75753ade4471fbe0452a684dc047d72
|
F src/vdbe.c d7b996a5b75753ade4471fbe0452a684dc047d72
|
||||||
F src/vdbe.h d70a68bee196ab228914a3902c79dbd24342a0f2
|
F src/vdbe.h d70a68bee196ab228914a3902c79dbd24342a0f2
|
||||||
F src/vdbeInt.h 9dd984cf80ef4f2970266b05f1dbb5622ac3817b
|
F src/vdbeInt.h d12bc259b34d3d610ebf05d648eb6346d48478c3
|
||||||
F src/vdbeapi.c f94fe2eb6f48687e918f0df7eed1409cff9dcf58
|
F src/vdbeapi.c f94fe2eb6f48687e918f0df7eed1409cff9dcf58
|
||||||
F src/vdbeaux.c f636fd01adbab85675167a25cf194eddd58b13dd
|
F src/vdbeaux.c dd5fc23bae4647d40b00ac308acd85f5c862f01e
|
||||||
F src/vdbeblob.c b0dcebfafedcf9c0addc7901ad98f6f986c08935
|
F src/vdbeblob.c b0dcebfafedcf9c0addc7901ad98f6f986c08935
|
||||||
F src/vdbemem.c 543a79d722734d2f8b7ad70f08218c30bcc5bbf5
|
F src/vdbemem.c 543a79d722734d2f8b7ad70f08218c30bcc5bbf5
|
||||||
F src/vtab.c e39e011d7443a8d574b1b9cde207a35522e6df43
|
F src/vtab.c e39e011d7443a8d574b1b9cde207a35522e6df43
|
||||||
@@ -701,7 +701,7 @@ F tool/speedtest16.c c8a9c793df96db7e4933f0852abb7a03d48f2e81
|
|||||||
F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
|
F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
|
||||||
F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
|
F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
|
||||||
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
|
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
|
||||||
P d9f6ffbc5ea090ba0daac571fc9a6c68b9c864e4
|
P e1ad757ec0abead25265f9251c954d2497bccc06
|
||||||
R 71113436f434e40594eca0b6cc7e07b2
|
R 0a182bd5291018e602b666bb6aa5e2e4
|
||||||
U drh
|
U drh
|
||||||
Z 7f8f808d7025e6cd7278ce47c4e4464a
|
Z 9760075414da00e3d0c2807d9c7bc689
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
e1ad757ec0abead25265f9251c954d2497bccc06
|
58a1809257ccfb7d9112a35f79ca2f82b3daa878
|
||||||
@@ -15,7 +15,7 @@
|
|||||||
** 6000 lines long) it was split up into several smaller files and
|
** 6000 lines long) it was split up into several smaller files and
|
||||||
** this header information was factored out.
|
** this header information was factored out.
|
||||||
**
|
**
|
||||||
** $Id: vdbeInt.h,v 1.163 2009/02/19 14:39:25 danielk1977 Exp $
|
** $Id: vdbeInt.h,v 1.164 2009/02/20 01:28:59 drh Exp $
|
||||||
*/
|
*/
|
||||||
#ifndef _VDBEINT_H_
|
#ifndef _VDBEINT_H_
|
||||||
#define _VDBEINT_H_
|
#define _VDBEINT_H_
|
||||||
@@ -304,6 +304,7 @@ struct Vdbe {
|
|||||||
BtreeMutexArray aMutex; /* An array of Btree used here and needing locks */
|
BtreeMutexArray aMutex; /* An array of Btree used here and needing locks */
|
||||||
int aCounter[2]; /* Counters used by sqlite3_stmt_status() */
|
int aCounter[2]; /* Counters used by sqlite3_stmt_status() */
|
||||||
char *zSql; /* Text of the SQL statement that generated this */
|
char *zSql; /* Text of the SQL statement that generated this */
|
||||||
|
void *pFree; /* Free this when deleting the vdbe */
|
||||||
#ifdef SQLITE_DEBUG
|
#ifdef SQLITE_DEBUG
|
||||||
FILE *trace; /* Write an execution trace here, if not NULL */
|
FILE *trace; /* Write an execution trace here, if not NULL */
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -14,7 +14,7 @@
|
|||||||
** to version 2.8.7, all this code was combined into the vdbe.c source file.
|
** to version 2.8.7, all this code was combined into the vdbe.c source file.
|
||||||
** But that file was getting too big so this subroutines were split out.
|
** But that file was getting too big so this subroutines were split out.
|
||||||
**
|
**
|
||||||
** $Id: vdbeaux.c,v 1.436 2009/02/19 14:39:25 danielk1977 Exp $
|
** $Id: vdbeaux.c,v 1.437 2009/02/20 01:28:59 drh Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
#include "vdbeInt.h"
|
#include "vdbeInt.h"
|
||||||
@@ -114,7 +114,7 @@ static int growOpArray(Vdbe *p){
|
|||||||
int nNew = (p->nOpAlloc ? p->nOpAlloc*2 : (int)(1024/sizeof(Op)));
|
int nNew = (p->nOpAlloc ? p->nOpAlloc*2 : (int)(1024/sizeof(Op)));
|
||||||
pNew = sqlite3DbRealloc(p->db, p->aOp, nNew*sizeof(Op));
|
pNew = sqlite3DbRealloc(p->db, p->aOp, nNew*sizeof(Op));
|
||||||
if( pNew ){
|
if( pNew ){
|
||||||
p->nOpAlloc = nNew;
|
p->nOpAlloc = sqlite3MallocSize(pNew)/sizeof(Op);
|
||||||
p->aOp = pNew;
|
p->aOp = pNew;
|
||||||
}
|
}
|
||||||
return (pNew ? SQLITE_OK : SQLITE_NOMEM);
|
return (pNew ? SQLITE_OK : SQLITE_NOMEM);
|
||||||
@@ -1000,6 +1000,39 @@ void sqlite3VdbeIOTraceSql(Vdbe *p){
|
|||||||
}
|
}
|
||||||
#endif /* !SQLITE_OMIT_TRACE && SQLITE_ENABLE_IOTRACE */
|
#endif /* !SQLITE_OMIT_TRACE && SQLITE_ENABLE_IOTRACE */
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Allocate space from a fixed size buffer. Make *pp point to the
|
||||||
|
** allocated space. (Note: pp is a char* rather than a void** to
|
||||||
|
** work around the pointer aliasing rules of C.) *pp should initially
|
||||||
|
** be zero. If *pp is not zero, that means that the space has already
|
||||||
|
** been allocated and this routine is a noop.
|
||||||
|
**
|
||||||
|
** nByte is the number of bytes of space needed.
|
||||||
|
**
|
||||||
|
** *ppFrom point to available space and pEnd points to the end of the
|
||||||
|
** available space.
|
||||||
|
**
|
||||||
|
** *pnByte is a counter of the number of bytes of space that have failed
|
||||||
|
** to allocate. If there is insufficient space in *ppFrom to satisfy the
|
||||||
|
** request, then increate *pnByte by the amount of the request.
|
||||||
|
*/
|
||||||
|
static void allocSpace(
|
||||||
|
char *pp, /* IN/OUT: Set *pp to point to allocated buffer */
|
||||||
|
int nByte, /* Number of bytes to allocate */
|
||||||
|
u8 **ppFrom, /* IN/OUT: Allocate from *ppFrom */
|
||||||
|
u8 *pEnd, /* Pointer to 1 byte passed end of *ppFrom buffer */
|
||||||
|
int *pnByte /* If allocation cannot be made, increment *pnByte */
|
||||||
|
){
|
||||||
|
if( (*(void**)pp)==0 ){
|
||||||
|
nByte = (nByte+7)&~7;
|
||||||
|
if( (pEnd - *ppFrom)>=nByte ){
|
||||||
|
*(void**)pp = (void *)*ppFrom;
|
||||||
|
*ppFrom += nByte;
|
||||||
|
}else{
|
||||||
|
*pnByte += nByte;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Prepare a virtual machine for execution. This involves things such
|
** Prepare a virtual machine for execution. This involves things such
|
||||||
@@ -1054,35 +1087,44 @@ void sqlite3VdbeMakeReady(
|
|||||||
** first time this function is called for a given VDBE, not when it is
|
** first time this function is called for a given VDBE, not when it is
|
||||||
** being called from sqlite3_reset() to reset the virtual machine.
|
** being called from sqlite3_reset() to reset the virtual machine.
|
||||||
*/
|
*/
|
||||||
if( nVar>=0 ){
|
if( nVar>=0 && !db->mallocFailed ){
|
||||||
|
u8 *zCsr = (u8 *)&p->aOp[p->nOp];
|
||||||
|
u8 *zEnd = (u8 *)&p->aOp[p->nOpAlloc];
|
||||||
int nByte;
|
int nByte;
|
||||||
int nArg; /* Maximum number of args passed to a user function. */
|
int nArg; /* Maximum number of args passed to a user function. */
|
||||||
resolveP2Values(p, &nArg);
|
resolveP2Values(p, &nArg);
|
||||||
if( isExplain && nMem<10 ){
|
if( isExplain && nMem<10 ){
|
||||||
nMem = 10;
|
nMem = 10;
|
||||||
}
|
}
|
||||||
nByte = nMem*sizeof(Mem) /* aMem */
|
|
||||||
+ nVar*sizeof(Mem) /* aVar */
|
do {
|
||||||
+ nArg*sizeof(Mem*) /* apArg */
|
memset(zCsr, 0, zEnd-zCsr);
|
||||||
+ nVar*sizeof(char*) /* azVar */
|
nByte = 0;
|
||||||
+ nCursor*sizeof(VdbeCursor*); /* apCsr */
|
allocSpace((char*)&p->aMem, nMem*sizeof(Mem), &zCsr, zEnd, &nByte);
|
||||||
if( nByte ){
|
allocSpace((char*)&p->aVar, nVar*sizeof(Mem), &zCsr, zEnd, &nByte);
|
||||||
p->aMem = sqlite3DbMallocZero(db, nByte);
|
allocSpace((char*)&p->apArg, nArg*sizeof(Mem*), &zCsr, zEnd, &nByte);
|
||||||
}
|
allocSpace((char*)&p->azVar, nVar*sizeof(char*), &zCsr, zEnd, &nByte);
|
||||||
if( !db->mallocFailed ){
|
allocSpace((char*)&p->apCsr,
|
||||||
p->aMem--; /* aMem[] goes from 1..nMem */
|
nCursor*sizeof(VdbeCursor*), &zCsr, zEnd, &nByte
|
||||||
p->nMem = nMem; /* not from 0..nMem-1 */
|
);
|
||||||
p->aVar = &p->aMem[nMem+1];
|
if( nByte ){
|
||||||
|
p->pFree = sqlite3DbMallocRaw(db, nByte);
|
||||||
|
}
|
||||||
|
zCsr = p->pFree;
|
||||||
|
zEnd = &zCsr[nByte];
|
||||||
|
}while( nByte && !db->mallocFailed );
|
||||||
|
|
||||||
|
p->nCursor = nCursor;
|
||||||
|
if( p->aVar ){
|
||||||
p->nVar = nVar;
|
p->nVar = nVar;
|
||||||
p->okVar = 0;
|
|
||||||
p->apArg = (Mem**)&p->aVar[nVar];
|
|
||||||
p->azVar = (char**)&p->apArg[nArg];
|
|
||||||
p->apCsr = (VdbeCursor**)&p->azVar[nVar];
|
|
||||||
p->nCursor = nCursor;
|
|
||||||
for(n=0; n<nVar; n++){
|
for(n=0; n<nVar; n++){
|
||||||
p->aVar[n].flags = MEM_Null;
|
p->aVar[n].flags = MEM_Null;
|
||||||
p->aVar[n].db = db;
|
p->aVar[n].db = db;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
if( p->aMem ){
|
||||||
|
p->aMem--; /* aMem[] goes from 1..nMem */
|
||||||
|
p->nMem = nMem; /* not from 0..nMem-1 */
|
||||||
for(n=1; n<=nMem; n++){
|
for(n=1; n<=nMem; n++){
|
||||||
p->aMem[n].flags = MEM_Null;
|
p->aMem[n].flags = MEM_Null;
|
||||||
p->aMem[n].db = db;
|
p->aMem[n].db = db;
|
||||||
@@ -1859,17 +1901,15 @@ void sqlite3VdbeDelete(Vdbe *p){
|
|||||||
sqlite3DbFree(db, pOp->zComment);
|
sqlite3DbFree(db, pOp->zComment);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
sqlite3DbFree(db, p->aOp);
|
|
||||||
}
|
}
|
||||||
releaseMemArray(p->aVar, p->nVar);
|
releaseMemArray(p->aVar, p->nVar);
|
||||||
sqlite3DbFree(db, p->aLabel);
|
sqlite3DbFree(db, p->aLabel);
|
||||||
if( p->aMem ){
|
|
||||||
sqlite3DbFree(db, &p->aMem[1]);
|
|
||||||
}
|
|
||||||
releaseMemArray(p->aColName, p->nResColumn*COLNAME_N);
|
releaseMemArray(p->aColName, p->nResColumn*COLNAME_N);
|
||||||
sqlite3DbFree(db, p->aColName);
|
sqlite3DbFree(db, p->aColName);
|
||||||
sqlite3DbFree(db, p->zSql);
|
sqlite3DbFree(db, p->zSql);
|
||||||
p->magic = VDBE_MAGIC_DEAD;
|
p->magic = VDBE_MAGIC_DEAD;
|
||||||
|
sqlite3DbFree(db, p->aOp);
|
||||||
|
sqlite3DbFree(db, p->pFree);
|
||||||
sqlite3DbFree(db, p);
|
sqlite3DbFree(db, p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user