aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/malloc.c19
-rw-r--r--src/test_func.c4
-rw-r--r--src/utf.c1
-rw-r--r--src/vdbe.c11
-rw-r--r--src/vdbeInt.h4
-rw-r--r--src/vdbeapi.c2
-rw-r--r--src/vdbeaux.c29
-rw-r--r--src/vdbemem.c41
8 files changed, 62 insertions, 49 deletions
diff --git a/src/malloc.c b/src/malloc.c
index e0d5b5ff9..8ba5fa0a8 100644
--- a/src/malloc.c
+++ b/src/malloc.c
@@ -451,15 +451,18 @@ int sqlite3MallocSize(void *p){
return sqlite3GlobalConfig.m.xSize(p);
}
int sqlite3DbMallocSize(sqlite3 *db, void *p){
- assert( db!=0 );
- assert( sqlite3_mutex_held(db->mutex) );
- if( isLookaside(db, p) ){
- return db->lookaside.sz;
+ if( db==0 ){
+ return sqlite3MallocSize(p);
}else{
- assert( sqlite3MemdebugHasType(p, MEMTYPE_DB) );
- assert( sqlite3MemdebugHasType(p, MEMTYPE_LOOKASIDE|MEMTYPE_HEAP) );
- assert( db!=0 || sqlite3MemdebugNoType(p, MEMTYPE_LOOKASIDE) );
- return sqlite3GlobalConfig.m.xSize(p);
+ assert( sqlite3_mutex_held(db->mutex) );
+ if( isLookaside(db, p) ){
+ return db->lookaside.sz;
+ }else{
+ assert( sqlite3MemdebugHasType(p, MEMTYPE_DB) );
+ assert( sqlite3MemdebugHasType(p, MEMTYPE_LOOKASIDE|MEMTYPE_HEAP) );
+ assert( db!=0 || sqlite3MemdebugNoType(p, MEMTYPE_LOOKASIDE) );
+ return sqlite3GlobalConfig.m.xSize(p);
+ }
}
}
sqlite3_uint64 sqlite3_msize(void *p){
diff --git a/src/test_func.c b/src/test_func.c
index 9cf2f8002..c7850631d 100644
--- a/src/test_func.c
+++ b/src/test_func.c
@@ -504,7 +504,7 @@ static void test_extract(
sqlite3_result_value(context, &mem);
}
- sqlite3DbFree(db, mem.zMalloc);
+ if( mem.szMalloc ) sqlite3DbFree(db, mem.zMalloc);
}
}
@@ -591,7 +591,7 @@ static void test_decode(
Tcl_ListObjAppendElement(0, pRet, pVal);
- if( mem.zMalloc ){
+ if( mem.szMalloc ){
sqlite3DbFree(db, mem.zMalloc);
}
}
diff --git a/src/utf.c b/src/utf.c
index 549983f6f..25f4dadf0 100644
--- a/src/utf.c
+++ b/src/utf.c
@@ -320,6 +320,7 @@ SQLITE_NOINLINE int sqlite3VdbeMemTranslate(Mem *pMem, u8 desiredEnc){
pMem->enc = desiredEnc;
pMem->z = (char*)zOut;
pMem->zMalloc = pMem->z;
+ pMem->szMalloc = sqlite3DbMallocSize(pMem->db, pMem->z);
translate_out:
#if defined(TRANSLATE_TRACE) && defined(SQLITE_DEBUG)
diff --git a/src/vdbe.c b/src/vdbe.c
index 996cf8b9b..4a63f30af 100644
--- a/src/vdbe.c
+++ b/src/vdbe.c
@@ -1026,9 +1026,9 @@ case OP_String8: { /* same as TK_STRING, out2-prerelease */
rc = sqlite3VdbeMemSetStr(pOut, pOp->p4.z, -1, SQLITE_UTF8, SQLITE_STATIC);
if( rc==SQLITE_TOOBIG ) goto too_big;
if( SQLITE_OK!=sqlite3VdbeChangeEncoding(pOut, encoding) ) goto no_mem;
- assert( pOut->zMalloc==pOut->z );
+ assert( pOut->szMalloc>0 && pOut->zMalloc==pOut->z );
assert( VdbeMemDynamic(pOut)==0 );
- pOut->zMalloc = 0;
+ pOut->szMalloc = 0;
pOut->flags |= MEM_Static;
if( pOp->p4type==P4_DYNAMIC ){
sqlite3DbFree(db, pOp->p4.z);
@@ -1148,7 +1148,6 @@ case OP_Variable: { /* out2-prerelease */
** for P3 to be less than 1.
*/
case OP_Move: {
- char *zMalloc; /* Holding variable for allocated memory */
int n; /* Number of registers left to copy */
int p1; /* Register to copy from */
int p2; /* Register to copy to */
@@ -1166,16 +1165,12 @@ case OP_Move: {
assert( pIn1<=&aMem[(p->nMem-p->nCursor)] );
assert( memIsValid(pIn1) );
memAboutToChange(p, pOut);
- sqlite3VdbeMemRelease(pOut);
- zMalloc = pOut->zMalloc;
- memcpy(pOut, pIn1, sizeof(Mem));
+ sqlite3VdbeMemMove(pOut, pIn1);
#ifdef SQLITE_DEBUG
if( pOut->pScopyFrom>=&aMem[p1] && pOut->pScopyFrom<&aMem[p1+pOp->p3] ){
pOut->pScopyFrom += p1 - pOp->p2;
}
#endif
- pIn1->flags = MEM_Undefined;
- pIn1->zMalloc = zMalloc;
REGISTER_TRACE(p2++, pOut);
pIn1++;
pOut++;
diff --git a/src/vdbeInt.h b/src/vdbeInt.h
index 8e4405437..138e61d2c 100644
--- a/src/vdbeInt.h
+++ b/src/vdbeInt.h
@@ -174,7 +174,9 @@ struct Mem {
int n; /* Number of characters in string value, excluding '\0' */
char *z; /* String or BLOB value */
/* ShallowCopy only needs to copy the information above */
- char *zMalloc; /* Dynamic buffer allocated by sqlite3_malloc() */
+ char *zMalloc; /* Space to hold MEM_Str or MEM_Blob if szMalloc>0 */
+ int szMalloc; /* Size of the zMalloc allocation */
+ int iPadding1; /* Padding for 8-byte alignment */
sqlite3 *db; /* The associated database connection */
void (*xDel)(void*);/* Destructor for Mem.z - only valid if MEM_Dyn */
#ifdef SQLITE_DEBUG
diff --git a/src/vdbeapi.c b/src/vdbeapi.c
index aad64aa64..7d3ae9cb0 100644
--- a/src/vdbeapi.c
+++ b/src/vdbeapi.c
@@ -809,6 +809,8 @@ static const Mem *columnNullValue(void){
/* .n = */ 0,
/* .z = */ 0,
/* .zMalloc = */ 0,
+ /* .szMalloc = */ 0,
+ /* .iPadding1 = */ 0,
/* .db = */ 0,
/* .xDel = */ 0,
#ifdef SQLITE_DEBUG
diff --git a/src/vdbeaux.c b/src/vdbeaux.c
index ad57f4ccd..f990c40d4 100644
--- a/src/vdbeaux.c
+++ b/src/vdbeaux.c
@@ -698,7 +698,7 @@ static void freeP4(sqlite3 *db, int p4type, void *p4){
sqlite3ValueFree((sqlite3_value*)p4);
}else{
Mem *p = (Mem*)p4;
- sqlite3DbFree(db, p->zMalloc);
+ if( p->szMalloc ) sqlite3DbFree(db, p->zMalloc);
sqlite3DbFree(db, p);
}
break;
@@ -1231,7 +1231,7 @@ static void releaseMemArray(Mem *p, int N){
u8 malloc_failed = db->mallocFailed;
if( db->pnBytesFreed ){
for(pEnd=&p[N]; p<pEnd; p++){
- sqlite3DbFree(db, p->zMalloc);
+ if( p->szMalloc ) sqlite3DbFree(db, p->zMalloc);
}
return;
}
@@ -1257,9 +1257,9 @@ static void releaseMemArray(Mem *p, int N){
testcase( p->flags & MEM_RowSet );
if( p->flags&(MEM_Agg|MEM_Dyn|MEM_Frame|MEM_RowSet) ){
sqlite3VdbeMemRelease(p);
- }else if( p->zMalloc ){
+ }else if( p->szMalloc ){
sqlite3DbFree(db, p->zMalloc);
- p->zMalloc = 0;
+ p->szMalloc = 0;
}
p->flags = MEM_Undefined;
@@ -3167,7 +3167,7 @@ void sqlite3VdbeRecordUnpack(
pMem->enc = pKeyInfo->enc;
pMem->db = pKeyInfo->db;
/* pMem->flags = 0; // sqlite3VdbeSerialGet() will set this for us */
- pMem->zMalloc = 0;
+ pMem->szMalloc = 0;
d += sqlite3VdbeSerialGet(&aKey[d], serial_type, pMem);
pMem++;
if( (++u)>=p->nField ) break;
@@ -3207,7 +3207,7 @@ static int vdbeRecordCompareDebug(
mem1.enc = pKeyInfo->enc;
mem1.db = pKeyInfo->db;
/* mem1.flags = 0; // Will be initialized by sqlite3VdbeSerialGet() */
- VVA_ONLY( mem1.zMalloc = 0; ) /* Only needed by assert() statements */
+ VVA_ONLY( mem1.szMalloc = 0; ) /* Only needed by assert() statements */
/* Compilers may complain that mem1.u.i is potentially uninitialized.
** We could initialize it, as shown here, to silence those complaints.
@@ -3250,7 +3250,7 @@ static int vdbeRecordCompareDebug(
*/
rc = sqlite3MemCompare(&mem1, &pPKey2->aMem[i], pKeyInfo->aColl[i]);
if( rc!=0 ){
- assert( mem1.zMalloc==0 ); /* See comment below */
+ assert( mem1.szMalloc==0 ); /* See comment below */
if( pKeyInfo->aSortOrder[i] ){
rc = -rc; /* Invert the result for DESC sort order. */
}
@@ -3263,7 +3263,7 @@ static int vdbeRecordCompareDebug(
** the following assert(). If the assert() fails, it indicates a
** memory leak and a need to call sqlite3VdbeMemRelease(&mem1).
*/
- assert( mem1.zMalloc==0 );
+ assert( mem1.szMalloc==0 );
/* rc==0 here means that one of the keys ran out of fields and
** all the fields up to that point were equal. Return the default_rc
@@ -3302,9 +3302,8 @@ static int vdbeCompareMemString(
int n1, n2;
Mem c1;
Mem c2;
- c1.db = c2.db = pMem1->db;
- c1.flags = c2.flags = 0;
- c1.zMalloc = c2.zMalloc = 0;
+ sqlite3VdbeMemInit(&c1, pMem1->db, MEM_Null);
+ sqlite3VdbeMemInit(&c2, pMem1->db, MEM_Null);
sqlite3VdbeMemShallowCopy(&c1, pMem1, MEM_Ephem);
sqlite3VdbeMemShallowCopy(&c2, pMem2, MEM_Ephem);
v1 = sqlite3ValueText((sqlite3_value*)&c1, pColl->enc);
@@ -3516,7 +3515,7 @@ static int vdbeRecordCompareWithSkip(
i = 0;
}
- VVA_ONLY( mem1.zMalloc = 0; ) /* Only needed by assert() statements */
+ VVA_ONLY( mem1.szMalloc = 0; ) /* Only needed by assert() statements */
assert( pPKey2->pKeyInfo->nField+pPKey2->pKeyInfo->nXField>=pPKey2->nField
|| CORRUPT_DB );
assert( pPKey2->pKeyInfo->aSortOrder!=0 );
@@ -3639,7 +3638,7 @@ static int vdbeRecordCompareWithSkip(
rc = -rc;
}
assert( vdbeRecordCompareDebug(nKey1, pKey1, pPKey2, rc) );
- assert( mem1.zMalloc==0 ); /* See comment below */
+ assert( mem1.szMalloc==0 ); /* See comment below */
return rc;
}
@@ -3652,7 +3651,7 @@ static int vdbeRecordCompareWithSkip(
/* No memory allocation is ever used on mem1. Prove this using
** the following assert(). If the assert() fails, it indicates a
** memory leak and a need to call sqlite3VdbeMemRelease(&mem1). */
- assert( mem1.zMalloc==0 );
+ assert( mem1.szMalloc==0 );
/* rc==0 here means that one or both of the keys ran out of fields and
** all the fields up to that point were equal. Return the default_rc
@@ -3937,7 +3936,7 @@ int sqlite3VdbeIdxRowid(sqlite3 *db, BtCursor *pCur, i64 *rowid){
/* Jump here if database corruption is detected after m has been
** allocated. Free the m object and return SQLITE_CORRUPT. */
idx_rowid_corruption:
- testcase( m.zMalloc!=0 );
+ testcase( m.szMalloc!=0 );
sqlite3VdbeMemRelease(&m);
return SQLITE_CORRUPT_BKPT;
}
diff --git a/src/vdbemem.c b/src/vdbemem.c
index 780bc5286..4ea28f841 100644
--- a/src/vdbemem.c
+++ b/src/vdbemem.c
@@ -34,6 +34,10 @@ int sqlite3VdbeCheckMemInvariants(Mem *p){
/* Cannot be both MEM_Int and MEM_Real at the same time */
assert( (p->flags & (MEM_Int|MEM_Real))!=(MEM_Int|MEM_Real) );
+ /* The szMalloc field holds the correct memory allocation size */
+ assert( p->szMalloc==0
+ || p->szMalloc==sqlite3DbMallocSize(p->db,p->zMalloc) );
+
/* If p holds a string or blob, the Mem.z must point to exactly
** one of the following:
**
@@ -42,9 +46,9 @@ int sqlite3VdbeCheckMemInvariants(Mem *p){
** (3) An ephemeral string or blob
** (4) A static string or blob
*/
- if( (p->flags & (MEM_Str|MEM_Blob)) && p->z!=0 ){
+ if( (p->flags & (MEM_Str|MEM_Blob)) && p->n>0 ){
assert(
- ((p->z==p->zMalloc)? 1 : 0) +
+ ((p->szMalloc>0 && p->z==p->zMalloc)? 1 : 0) +
((p->flags&MEM_Dyn)!=0 ? 1 : 0) +
((p->flags&MEM_Ephem)!=0 ? 1 : 0) +
((p->flags&MEM_Static)!=0 ? 1 : 0) == 1
@@ -112,19 +116,24 @@ int sqlite3VdbeMemGrow(Mem *pMem, int n, int bPreserve){
assert( bPreserve==0 || pMem->flags&(MEM_Blob|MEM_Str) );
testcase( bPreserve && pMem->z==0 );
- if( pMem->zMalloc==0 || sqlite3DbMallocSize(pMem->db, pMem->zMalloc)<n ){
+ assert( pMem->szMalloc==0
+ || pMem->szMalloc==sqlite3DbMallocSize(pMem->db, pMem->zMalloc) );
+ if( pMem->szMalloc<n ){
if( n<32 ) n = 32;
- if( bPreserve && pMem->z==pMem->zMalloc ){
+ if( bPreserve && pMem->szMalloc>0 && pMem->z==pMem->zMalloc ){
pMem->z = pMem->zMalloc = sqlite3DbReallocOrFree(pMem->db, pMem->z, n);
bPreserve = 0;
}else{
- sqlite3DbFree(pMem->db, pMem->zMalloc);
+ if( pMem->szMalloc>0 ) sqlite3DbFree(pMem->db, pMem->zMalloc);
pMem->zMalloc = sqlite3DbMallocRaw(pMem->db, n);
}
if( pMem->zMalloc==0 ){
sqlite3VdbeMemSetNull(pMem);
pMem->z = 0;
+ pMem->szMalloc = 0;
return SQLITE_NOMEM;
+ }else{
+ pMem->szMalloc = sqlite3DbMallocSize(pMem->db, pMem->zMalloc);
}
}
@@ -155,7 +164,7 @@ int sqlite3VdbeMemMakeWriteable(Mem *pMem){
assert( (pMem->flags&MEM_RowSet)==0 );
ExpandBlob(pMem);
f = pMem->flags;
- if( (f&(MEM_Str|MEM_Blob)) && pMem->z!=pMem->zMalloc ){
+ if( (f&(MEM_Str|MEM_Blob)) && (pMem->szMalloc==0 || pMem->z!=pMem->zMalloc) ){
if( sqlite3VdbeMemGrow(pMem, pMem->n + 2, 1) ){
return SQLITE_NOMEM;
}
@@ -301,7 +310,7 @@ int sqlite3VdbeMemFinalize(Mem *pMem, FuncDef *pFunc){
ctx.pFunc = pFunc;
pFunc->xFinalize(&ctx); /* IMP: R-24505-23230 */
assert( (pMem->flags & MEM_Dyn)==0 );
- sqlite3DbFree(pMem->db, pMem->zMalloc);
+ if( pMem->szMalloc>0 ) sqlite3DbFree(pMem->db, pMem->zMalloc);
memcpy(pMem, &t, sizeof(t));
rc = ctx.isError;
}
@@ -351,9 +360,9 @@ static SQLITE_NOINLINE void vdbeMemClear(Mem *p){
if( VdbeMemDynamic(p) ){
vdbeMemClearExternAndSetNull(p);
}
- if( p->zMalloc ){
+ if( p->szMalloc ){
sqlite3DbFree(p->db, p->zMalloc);
- p->zMalloc = 0;
+ p->szMalloc = 0;
}
p->z = 0;
}
@@ -370,7 +379,7 @@ static SQLITE_NOINLINE void vdbeMemClear(Mem *p){
*/
void sqlite3VdbeMemRelease(Mem *p){
assert( sqlite3VdbeCheckMemInvariants(p) );
- if( VdbeMemDynamic(p) || p->zMalloc ){
+ if( VdbeMemDynamic(p) || p->szMalloc ){
vdbeMemClear(p);
}
}
@@ -592,7 +601,7 @@ void sqlite3VdbeMemInit(Mem *pMem, sqlite3 *db, u16 flags){
assert( (flags & ~MEM_TypeMask)==0 );
pMem->flags = flags;
pMem->db = db;
- pMem->zMalloc = 0;
+ pMem->szMalloc = 0;
}
@@ -683,10 +692,11 @@ void sqlite3VdbeMemSetRowSet(Mem *pMem){
pMem->zMalloc = sqlite3DbMallocRaw(db, 64);
if( db->mallocFailed ){
pMem->flags = MEM_Null;
+ pMem->szMalloc = 0;
}else{
assert( pMem->zMalloc );
- pMem->u.pRowSet = sqlite3RowSetInit(db, pMem->zMalloc,
- sqlite3DbMallocSize(db, pMem->zMalloc));
+ pMem->szMalloc = sqlite3DbMallocSize(db, pMem->zMalloc);
+ pMem->u.pRowSet = sqlite3RowSetInit(db, pMem->zMalloc, pMem->szMalloc);
assert( pMem->u.pRowSet!=0 );
pMem->flags = MEM_RowSet;
}
@@ -789,7 +799,7 @@ void sqlite3VdbeMemMove(Mem *pTo, Mem *pFrom){
sqlite3VdbeMemRelease(pTo);
memcpy(pTo, pFrom, sizeof(Mem));
pFrom->flags = MEM_Null;
- pFrom->zMalloc = 0;
+ pFrom->szMalloc = 0;
}
/*
@@ -863,6 +873,7 @@ int sqlite3VdbeMemSetStr(
}else if( xDel==SQLITE_DYNAMIC ){
sqlite3VdbeMemRelease(pMem);
pMem->zMalloc = pMem->z = (char *)z;
+ pMem->szMalloc = sqlite3DbMallocSize(pMem->db, pMem->zMalloc);
}else{
sqlite3VdbeMemRelease(pMem);
pMem->z = (char *)z;
@@ -1485,7 +1496,7 @@ void sqlite3Stat4ProbeFree(UnpackedRecord *pRec){
Mem *aMem = pRec->aMem;
sqlite3 *db = aMem[0].db;
for(i=0; i<nCol; i++){
- sqlite3DbFree(db, aMem[i].zMalloc);
+ if( aMem[i].szMalloc ) sqlite3DbFree(db, aMem[i].zMalloc);
}
sqlite3KeyInfoUnref(pRec->pKeyInfo);
sqlite3DbFree(db, pRec);