mirror of
https://github.com/sqlite/sqlite.git
synced 2025-11-12 13:01:09 +03:00
Free up the MEM_Frame bit in Mem.flags object. Store VdbeFrame objects
as MEM_Blob with a special Mem.xDel pointer instead. FossilOrigin-Name: 62db5fd47660bbc4fcf2c6d4a6c5a3077f12c6442a128d22b66b789a0409ef32
This commit is contained in:
18
manifest
18
manifest
@@ -1,5 +1,5 @@
|
|||||||
C Add\sthe\sgeopoly_group_bbox()\saggregate\sfunction\sto\sthe\sGeopoly\smodule.
|
C Free\sup\sthe\sMEM_Frame\sbit\sin\sMem.flags\sobject.\s\sStore\sVdbeFrame\sobjects\nas\sMEM_Blob\swith\sa\sspecial\sMem.xDel\spointer\sinstead.
|
||||||
D 2018-08-29T15:50:47.314
|
D 2018-08-29T18:47:22.883
|
||||||
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
|
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
|
||||||
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
|
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
|
||||||
F Makefile.in d06f463c5b623a61ac27f5cb8214fca9e53a6704d34d6b8f2124e2b1b293c88f
|
F Makefile.in d06f463c5b623a61ac27f5cb8214fca9e53a6704d34d6b8f2124e2b1b293c88f
|
||||||
@@ -571,13 +571,13 @@ F src/upsert.c 0dd81b40206841814d46942a7337786932475f085716042d0cb2fc7791bf8ca4
|
|||||||
F src/utf.c 810fbfebe12359f10bc2a011520a6e10879ab2a163bcb26c74768eab82ea62a5
|
F src/utf.c 810fbfebe12359f10bc2a011520a6e10879ab2a163bcb26c74768eab82ea62a5
|
||||||
F src/util.c d9eb0a6c4aae1b00a7369eadd7ca0bbe946cb4c953b6751aa20d357c2f482157
|
F src/util.c d9eb0a6c4aae1b00a7369eadd7ca0bbe946cb4c953b6751aa20d357c2f482157
|
||||||
F src/vacuum.c 36e7d21a20c0bf6ef4ef7c399d192b5239410b7c4d3c1070fba4e30810d0b855
|
F src/vacuum.c 36e7d21a20c0bf6ef4ef7c399d192b5239410b7c4d3c1070fba4e30810d0b855
|
||||||
F src/vdbe.c b11baa48b293dc48fbd51c6a9029f88bdf4cd117c01225b2a2b5e90e5928a8a3
|
F src/vdbe.c a44a1cd246f808d36ee0ce7dc031d9624a50242db96ac57f65ad93aea65ceaac
|
||||||
F src/vdbe.h 5081dcc497777efe5e9ebe7330d283a044a005e4bdda2e2e984f03bf89a0d907
|
F src/vdbe.h 5081dcc497777efe5e9ebe7330d283a044a005e4bdda2e2e984f03bf89a0d907
|
||||||
F src/vdbeInt.h 8ea493d994c6697cf7bccc60583a80a0222560490410f60f1113e90d36643ce0
|
F src/vdbeInt.h a660268d9e60dcd60abe8768c1582dd35f3d174ad12f742aee8c805af72dac03
|
||||||
F src/vdbeapi.c 2ba821c5929a2769e4b217dd85843479c718b8989d414723ec8af0616a83d611
|
F src/vdbeapi.c 2ba821c5929a2769e4b217dd85843479c718b8989d414723ec8af0616a83d611
|
||||||
F src/vdbeaux.c b64c699261611e3921de8bdf5a69d5559f0d1443dab8c4ba8e81a64d9219ac6a
|
F src/vdbeaux.c 20da0273e9bdb3f49dafa71123d7bdd63b2656134ecd73123562c028847d0e07
|
||||||
F src/vdbeblob.c f5c70f973ea3a9e915d1693278a5f890dc78594300cf4d54e64f2b0917c94191
|
F src/vdbeblob.c f5c70f973ea3a9e915d1693278a5f890dc78594300cf4d54e64f2b0917c94191
|
||||||
F src/vdbemem.c 0dc99941388a867a4dc77a8bed5dfc6024ee9c3ef147a09de844a6629086ec0c
|
F src/vdbemem.c 9a9aa4262f2c5620a552ad83902379d9b1dbb792eb4c1e8758ffffa7ab8a2e64
|
||||||
F src/vdbesort.c 90aad5a92608f2dd771c96749beabdb562c9d881131a860a7a5bccf66dc3be7f
|
F src/vdbesort.c 90aad5a92608f2dd771c96749beabdb562c9d881131a860a7a5bccf66dc3be7f
|
||||||
F src/vdbetrace.c 79d6dbbc479267b255a7de8080eee6e729928a0ef93ed9b0bfa5618875b48392
|
F src/vdbetrace.c 79d6dbbc479267b255a7de8080eee6e729928a0ef93ed9b0bfa5618875b48392
|
||||||
F src/vtab.c 678992ac8ec677a3f9b08126aaf891441083805e3b42574e3654d44538381c14
|
F src/vtab.c 678992ac8ec677a3f9b08126aaf891441083805e3b42574e3654d44538381c14
|
||||||
@@ -1758,7 +1758,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
|
|||||||
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
|
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
|
||||||
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
|
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
|
||||||
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
|
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
|
||||||
P 43efdd8c7e468405c9d4956a8caa66548059499289cbcc091628de7b055268cd
|
P 2d4debccbc027405a33aeb10f9d65f6fe4bfb5eb1be5a4d8b82158caba04643f
|
||||||
R 67d74f447410c9c096d1d977e8daccbd
|
R bd76e3ebc281873295239e9b6605a092
|
||||||
U drh
|
U drh
|
||||||
Z b43229d61c5d2506dfee2bf7cbf08d25
|
Z 6a1519aefdfc6d3a0da507442f0a767b
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
2d4debccbc027405a33aeb10f9d65f6fe4bfb5eb1be5a4d8b82158caba04643f
|
62db5fd47660bbc4fcf2c6d4a6c5a3077f12c6442a128d22b66b789a0409ef32
|
||||||
14
src/vdbe.c
14
src/vdbe.c
@@ -6050,7 +6050,7 @@ case OP_Program: { /* jump */
|
|||||||
** of the current program, and the memory required at runtime to execute
|
** of the current program, and the memory required at runtime to execute
|
||||||
** the trigger program. If this trigger has been fired before, then pRt
|
** the trigger program. If this trigger has been fired before, then pRt
|
||||||
** is already allocated. Otherwise, it must be initialized. */
|
** is already allocated. Otherwise, it must be initialized. */
|
||||||
if( (pRt->flags&MEM_Frame)==0 ){
|
if( (pRt->flags&MEM_Blob)==0 ){
|
||||||
/* SubProgram.nMem is set to the number of memory cells used by the
|
/* SubProgram.nMem is set to the number of memory cells used by the
|
||||||
** program stored in SubProgram.aOp. As well as these, one memory
|
** program stored in SubProgram.aOp. As well as these, one memory
|
||||||
** cell is required for each cursor used by the program. Set local
|
** cell is required for each cursor used by the program. Set local
|
||||||
@@ -6068,8 +6068,10 @@ case OP_Program: { /* jump */
|
|||||||
goto no_mem;
|
goto no_mem;
|
||||||
}
|
}
|
||||||
sqlite3VdbeMemRelease(pRt);
|
sqlite3VdbeMemRelease(pRt);
|
||||||
pRt->flags = MEM_Frame;
|
pRt->flags = MEM_Blob|MEM_Dyn;
|
||||||
pRt->u.pFrame = pFrame;
|
pRt->z = (char*)pFrame;
|
||||||
|
pRt->n = nByte;
|
||||||
|
pRt->xDel = sqlite3VdbeFrameMemDel;
|
||||||
|
|
||||||
pFrame->v = p;
|
pFrame->v = p;
|
||||||
pFrame->nChildMem = nMem;
|
pFrame->nChildMem = nMem;
|
||||||
@@ -6085,6 +6087,9 @@ case OP_Program: { /* jump */
|
|||||||
#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
|
#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
|
||||||
pFrame->anExec = p->anExec;
|
pFrame->anExec = p->anExec;
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef SQLITE_DEBUG
|
||||||
|
pFrame->iFrameMagic = SQLITE_FRAME_MAGIC;
|
||||||
|
#endif
|
||||||
|
|
||||||
pEnd = &VdbeFrameMem(pFrame)[pFrame->nChildMem];
|
pEnd = &VdbeFrameMem(pFrame)[pFrame->nChildMem];
|
||||||
for(pMem=VdbeFrameMem(pFrame); pMem!=pEnd; pMem++){
|
for(pMem=VdbeFrameMem(pFrame); pMem!=pEnd; pMem++){
|
||||||
@@ -6092,7 +6097,8 @@ case OP_Program: { /* jump */
|
|||||||
pMem->db = db;
|
pMem->db = db;
|
||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
pFrame = pRt->u.pFrame;
|
pFrame = (VdbeFrame*)pRt->z;
|
||||||
|
assert( pRt->xDel==sqlite3VdbeFrameMemDel );
|
||||||
assert( pProgram->nMem+pProgram->nCsr==pFrame->nChildMem
|
assert( pProgram->nMem+pProgram->nCsr==pFrame->nChildMem
|
||||||
|| (pProgram->nCsr==0 && pProgram->nMem+1==pFrame->nChildMem) );
|
|| (pProgram->nCsr==0 && pProgram->nMem+1==pFrame->nChildMem) );
|
||||||
assert( pProgram->nCsr==pFrame->nChildCsr );
|
assert( pProgram->nCsr==pFrame->nChildCsr );
|
||||||
|
|||||||
@@ -169,6 +169,9 @@ struct VdbeFrame {
|
|||||||
void *token; /* Copy of SubProgram.token */
|
void *token; /* Copy of SubProgram.token */
|
||||||
i64 lastRowid; /* Last insert rowid (sqlite3.lastRowid) */
|
i64 lastRowid; /* Last insert rowid (sqlite3.lastRowid) */
|
||||||
AuxData *pAuxData; /* Linked list of auxdata allocations */
|
AuxData *pAuxData; /* Linked list of auxdata allocations */
|
||||||
|
#if SQLITE_DEBUG
|
||||||
|
u32 iFrameMagic; /* magic number for sanity checking */
|
||||||
|
#endif
|
||||||
int nCursor; /* Number of entries in apCsr */
|
int nCursor; /* Number of entries in apCsr */
|
||||||
int pc; /* Program Counter in parent (calling) frame */
|
int pc; /* Program Counter in parent (calling) frame */
|
||||||
int nOp; /* Size of aOp array */
|
int nOp; /* Size of aOp array */
|
||||||
@@ -179,6 +182,13 @@ struct VdbeFrame {
|
|||||||
int nDbChange; /* Value of db->nChange */
|
int nDbChange; /* Value of db->nChange */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* Magic number for sanity checking on VdbeFrame objects */
|
||||||
|
#define SQLITE_FRAME_MAGIC 0x879fb71e
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Return a pointer to the array of registers allocated for use
|
||||||
|
** by a VdbeFrame.
|
||||||
|
*/
|
||||||
#define VdbeFrameMem(p) ((Mem *)&((u8 *)p)[ROUND8(sizeof(VdbeFrame))])
|
#define VdbeFrameMem(p) ((Mem *)&((u8 *)p)[ROUND8(sizeof(VdbeFrame))])
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -194,7 +204,6 @@ struct sqlite3_value {
|
|||||||
const char *zPType; /* Pointer type when MEM_Term|MEM_Subtype|MEM_Null */
|
const char *zPType; /* Pointer type when MEM_Term|MEM_Subtype|MEM_Null */
|
||||||
FuncDef *pDef; /* Used only when flags==MEM_Agg */
|
FuncDef *pDef; /* Used only when flags==MEM_Agg */
|
||||||
RowSet *pRowSet; /* Used only when flags==MEM_RowSet */
|
RowSet *pRowSet; /* Used only when flags==MEM_RowSet */
|
||||||
VdbeFrame *pFrame; /* Used when flags==MEM_Frame */
|
|
||||||
} u;
|
} u;
|
||||||
u16 flags; /* Some combination of MEM_Null, MEM_Str, MEM_Dyn, etc. */
|
u16 flags; /* Some combination of MEM_Null, MEM_Str, MEM_Dyn, etc. */
|
||||||
u8 enc; /* SQLITE_UTF8, SQLITE_UTF16BE, SQLITE_UTF16LE */
|
u8 enc; /* SQLITE_UTF8, SQLITE_UTF16BE, SQLITE_UTF16LE */
|
||||||
@@ -239,7 +248,7 @@ struct sqlite3_value {
|
|||||||
#define MEM_Blob 0x0010 /* Value is a BLOB */
|
#define MEM_Blob 0x0010 /* Value is a BLOB */
|
||||||
#define MEM_AffMask 0x001f /* Mask of affinity bits */
|
#define MEM_AffMask 0x001f /* Mask of affinity bits */
|
||||||
#define MEM_RowSet 0x0020 /* Value is a RowSet object */
|
#define MEM_RowSet 0x0020 /* Value is a RowSet object */
|
||||||
#define MEM_Frame 0x0040 /* Value is a VdbeFrame object */
|
/* Available 0x0040 */
|
||||||
#define MEM_Undefined 0x0080 /* Value is undefined */
|
#define MEM_Undefined 0x0080 /* Value is undefined */
|
||||||
#define MEM_Cleared 0x0100 /* NULL set by OP_Null, not from data */
|
#define MEM_Cleared 0x0100 /* NULL set by OP_Null, not from data */
|
||||||
#define MEM_TypeMask 0xc1ff /* Mask of type bits */
|
#define MEM_TypeMask 0xc1ff /* Mask of type bits */
|
||||||
@@ -266,7 +275,7 @@ struct sqlite3_value {
|
|||||||
** that needs to be deallocated to avoid a leak.
|
** that needs to be deallocated to avoid a leak.
|
||||||
*/
|
*/
|
||||||
#define VdbeMemDynamic(X) \
|
#define VdbeMemDynamic(X) \
|
||||||
(((X)->flags&(MEM_Agg|MEM_Dyn|MEM_RowSet|MEM_Frame))!=0)
|
(((X)->flags&(MEM_Agg|MEM_Dyn|MEM_RowSet))!=0)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Clear any existing type flags from a Mem and replace them with f
|
** Clear any existing type flags from a Mem and replace them with f
|
||||||
@@ -500,7 +509,11 @@ const char *sqlite3OpcodeName(int);
|
|||||||
int sqlite3VdbeMemGrow(Mem *pMem, int n, int preserve);
|
int sqlite3VdbeMemGrow(Mem *pMem, int n, int preserve);
|
||||||
int sqlite3VdbeMemClearAndResize(Mem *pMem, int n);
|
int sqlite3VdbeMemClearAndResize(Mem *pMem, int n);
|
||||||
int sqlite3VdbeCloseStatement(Vdbe *, int);
|
int sqlite3VdbeCloseStatement(Vdbe *, int);
|
||||||
void sqlite3VdbeFrameDelete(VdbeFrame*);
|
#ifdef SQLITE_DEBUG
|
||||||
|
int sqlite3VdbeFrameIsValid(VdbeFrame*);
|
||||||
|
#endif
|
||||||
|
void sqlite3VdbeFrameMemDel(void*); /* Destructor on Mem */
|
||||||
|
void sqlite3VdbeFrameDelete(VdbeFrame*); /* Actually deletes the Frame */
|
||||||
int sqlite3VdbeFrameRestore(VdbeFrame *);
|
int sqlite3VdbeFrameRestore(VdbeFrame *);
|
||||||
#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
|
#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
|
||||||
void sqlite3VdbePreUpdateHook(Vdbe*,VdbeCursor*,int,const char*,Table*,i64,int);
|
void sqlite3VdbePreUpdateHook(Vdbe*,VdbeCursor*,int,const char*,Table*,i64,int);
|
||||||
|
|||||||
@@ -1661,9 +1661,9 @@ static void releaseMemArray(Mem *p, int N){
|
|||||||
*/
|
*/
|
||||||
testcase( p->flags & MEM_Agg );
|
testcase( p->flags & MEM_Agg );
|
||||||
testcase( p->flags & MEM_Dyn );
|
testcase( p->flags & MEM_Dyn );
|
||||||
testcase( p->flags & MEM_Frame );
|
testcase( p->xDel==sqlite3VdbeFrameMemDel );
|
||||||
testcase( p->flags & MEM_RowSet );
|
testcase( p->flags & MEM_RowSet );
|
||||||
if( p->flags&(MEM_Agg|MEM_Dyn|MEM_Frame|MEM_RowSet) ){
|
if( p->flags&(MEM_Agg|MEM_Dyn|MEM_RowSet) ){
|
||||||
sqlite3VdbeMemRelease(p);
|
sqlite3VdbeMemRelease(p);
|
||||||
}else if( p->szMalloc ){
|
}else if( p->szMalloc ){
|
||||||
sqlite3DbFreeNN(db, p->zMalloc);
|
sqlite3DbFreeNN(db, p->zMalloc);
|
||||||
@@ -1675,6 +1675,35 @@ static void releaseMemArray(Mem *p, int N){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef SQLITE_DEBUG
|
||||||
|
/*
|
||||||
|
** Verify that pFrame is a valid VdbeFrame pointer. Return true if it is
|
||||||
|
** and false if something is wrong.
|
||||||
|
**
|
||||||
|
** This routine is intended for use inside of assert() statements only.
|
||||||
|
*/
|
||||||
|
int sqlite3VdbeFrameIsValid(VdbeFrame *pFrame){
|
||||||
|
if( pFrame->iFrameMagic!=SQLITE_FRAME_MAGIC ) return 0;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
** This is a destructor on a Mem object (which is really an sqlite3_value)
|
||||||
|
** that deletes the Frame object that is attached to it as a blob.
|
||||||
|
**
|
||||||
|
** This routine does not delete the Frame right away. It merely adds the
|
||||||
|
** frame to a list of frames to be deleted when the Vdbe halts.
|
||||||
|
*/
|
||||||
|
void sqlite3VdbeFrameMemDel(void *pArg){
|
||||||
|
VdbeFrame *pFrame = (VdbeFrame*)pArg;
|
||||||
|
assert( sqlite3VdbeFrameIsValid(pFrame) );
|
||||||
|
pFrame->pParent = pFrame->v->pDelFrame;
|
||||||
|
pFrame->v->pDelFrame = pFrame;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Delete a VdbeFrame object and its contents. VdbeFrame objects are
|
** Delete a VdbeFrame object and its contents. VdbeFrame objects are
|
||||||
** allocated by the OP_Program opcode in sqlite3VdbeExec().
|
** allocated by the OP_Program opcode in sqlite3VdbeExec().
|
||||||
@@ -1683,6 +1712,7 @@ void sqlite3VdbeFrameDelete(VdbeFrame *p){
|
|||||||
int i;
|
int i;
|
||||||
Mem *aMem = VdbeFrameMem(p);
|
Mem *aMem = VdbeFrameMem(p);
|
||||||
VdbeCursor **apCsr = (VdbeCursor **)&aMem[p->nChildMem];
|
VdbeCursor **apCsr = (VdbeCursor **)&aMem[p->nChildMem];
|
||||||
|
assert( sqlite3VdbeFrameIsValid(p) );
|
||||||
for(i=0; i<p->nChildCsr; i++){
|
for(i=0; i<p->nChildCsr; i++){
|
||||||
sqlite3VdbeFreeCursor(p->v, apCsr[i]);
|
sqlite3VdbeFreeCursor(p->v, apCsr[i]);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ int sqlite3VdbeCheckMemInvariants(Mem *p){
|
|||||||
if( p->flags & MEM_Null ){
|
if( p->flags & MEM_Null ){
|
||||||
/* Cannot be both MEM_Null and some other type */
|
/* Cannot be both MEM_Null and some other type */
|
||||||
assert( (p->flags & (MEM_Int|MEM_Real|MEM_Str|MEM_Blob
|
assert( (p->flags & (MEM_Int|MEM_Real|MEM_Str|MEM_Blob
|
||||||
|MEM_RowSet|MEM_Frame|MEM_Agg))==0 );
|
|MEM_RowSet|MEM_Agg))==0 );
|
||||||
|
|
||||||
/* If MEM_Null is set, then either the value is a pure NULL (the usual
|
/* If MEM_Null is set, then either the value is a pure NULL (the usual
|
||||||
** case) or it is a pointer set using sqlite3_bind_pointer() or
|
** case) or it is a pointer set using sqlite3_bind_pointer() or
|
||||||
@@ -467,10 +467,6 @@ static SQLITE_NOINLINE void vdbeMemClearExternAndSetNull(Mem *p){
|
|||||||
p->xDel((void *)p->z);
|
p->xDel((void *)p->z);
|
||||||
}else if( p->flags&MEM_RowSet ){
|
}else if( p->flags&MEM_RowSet ){
|
||||||
sqlite3RowSetClear(p->u.pRowSet);
|
sqlite3RowSetClear(p->u.pRowSet);
|
||||||
}else if( p->flags&MEM_Frame ){
|
|
||||||
VdbeFrame *pFrame = p->u.pFrame;
|
|
||||||
pFrame->pParent = pFrame->v->pDelFrame;
|
|
||||||
pFrame->v->pDelFrame = pFrame;
|
|
||||||
}
|
}
|
||||||
p->flags = MEM_Null;
|
p->flags = MEM_Null;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user