1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
|
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
|
+
+
+
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
+
+
-
-
-
+
-
-
-
+
-
-
+
+
-
-
-
-
-
-
-
+
+
-
+
-
+
-
-
-
+
+
+
-
+
|
}
z[j] = 0;
sqlite3IoTrace("SQL %s\n", z);
}
}
#endif /* !SQLITE_OMIT_TRACE && SQLITE_ENABLE_IOTRACE */
/* An instance of this object describes bulk memory available for use
** by subcomponents of a prepared statement. Space is allocated out
** of a ReusableSpace object by the allocSpace() routine below.
/*
** Allocate space from a fixed size buffer and return a pointer to
** that space. If insufficient space is available, return NULL.
*/
struct ReusableSpace {
u8 *pSpace; /* Available memory */
int nFree; /* Bytes of available memory */
int nNeeded; /* Total bytes that could not be allocated */
};
/* Try to allocate nByte bytes of 8-byte aligned bulk memory for pBuf
** from the ReusableSpace object. Return a pointer to the allocated
** memory on success. If insufficient memory is available in the
** ReusableSpace object, increase the ReusableSpace.nNeeded
** value by the amount needed and return NULL.
**
** The pBuf parameter is the initial value of a pointer which will
** receive the new memory. pBuf is normally NULL. If pBuf is not
** NULL, it means that memory space has already been allocated and that
** If pBuf is not initially NULL, that means that the memory has already
** been allocated by a prior call to this routine, so just return a copy
** this routine should not allocate any new memory. When pBuf is not
** NULL simply return pBuf. Only allocate new memory space when pBuf
** is NULL.
** of pBuf and leave ReusableSpace unchanged.
**
** nByte is the number of bytes of space needed.
**
** pFrom points to *pnFrom bytes of available space. New space is allocated
** This allocator is employed to repurpose unused slots at the end of the
** from the end of the pFrom buffer and *pnFrom is decremented.
**
** opcode array of prepared state for other memory needs of the prepared
** statement.
** *pnNeeded is a counter of the number of bytes of space that have failed
** to allocate. If there is insufficient space in pFrom to satisfy the
** request, then increment *pnNeeded by the amount of the request.
*/
static void *allocSpace(
void *pBuf, /* Where return pointer will be stored */
int nByte, /* Number of bytes to allocate */
u8 *pFrom, /* Memory available for allocation */
int *pnFrom, /* IN/OUT: Space available at pFrom */
struct ReusableSpace *p, /* Bulk memory available for allocation */
void *pBuf, /* Pointer to a prior allocation */
int *pnNeeded /* If allocation cannot be made, increment *pnByte */
int nByte /* Bytes of memory needed */
){
assert( EIGHT_BYTE_ALIGNMENT(pFrom) );
assert( EIGHT_BYTE_ALIGNMENT(p->pSpace) );
if( pBuf==0 ){
nByte = ROUND8(nByte);
if( nByte <= *pnFrom ){
*pnFrom -= nByte;
pBuf = &pFrom[*pnFrom];
if( nByte <= p->nFree ){
p->nFree -= nByte;
pBuf = &p->pSpace[p->nFree];
}else{
*pnNeeded += nByte;
p->nNeeded += nByte;
}
}
assert( EIGHT_BYTE_ALIGNMENT(pBuf) );
return pBuf;
}
/*
|
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
|
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
|
-
+
-
-
-
+
-
-
+
+
-
-
-
+
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
-
-
+
+
-
+
-
+
-
-
-
-
-
+
+
+
+
+
-
-
+
-
+
-
-
+
+
-
-
-
-
+
+
|
sqlite3 *db; /* The database connection */
int nVar; /* Number of parameters */
int nMem; /* Number of VM memory registers */
int nCursor; /* Number of cursors required */
int nArg; /* Number of arguments in subprograms */
int nOnce; /* Number of OP_Once instructions */
int n; /* Loop counter */
int nFree; /* Available free space */
struct ReusableSpace x; /* Reusable bulk memory */
u8 *zCsr; /* Memory available for allocation */
int nByte; /* How much extra memory is needed */
assert( p!=0 );
assert( p->nOp>0 );
assert( pParse!=0 );
assert( p->magic==VDBE_MAGIC_INIT );
assert( pParse==p->pParse );
db = p->db;
assert( db->mallocFailed==0 );
nVar = pParse->nVar;
nMem = pParse->nMem;
nCursor = pParse->nTab;
nArg = pParse->nMaxArg;
nOnce = pParse->nOnce;
if( nOnce==0 ) nOnce = 1; /* Ensure at least one byte in p->aOnceFlag[] */
/* For each cursor required, also allocate a memory cell. Memory
** cells (nMem+1-nCursor)..nMem, inclusive, will never be used by
** the vdbe program. Instead they are used to allocate space for
** the vdbe program. Instead they are used to allocate memory for
** VdbeCursor/BtCursor structures. The blob of memory associated with
** cursor 0 is stored in memory cell nMem. Memory cell (nMem-1)
** stores the blob of memory associated with cursor 1, etc.
**
** See also: allocateCursor().
*/
nMem += nCursor;
/* zCsr will initially point to nFree bytes of unused space at the
** end of the opcode array, p->aOp. The computation of nFree is
/* Figure out how much reusable memory is available at the end of the
** opcode array. This extra memory will be reallocated for other elements
** conservative - it might be smaller than the true number of free
** bytes, but never larger. nFree must be a multiple of 8 - it is
** rounded down if is not.
** of the prepared statement.
*/
n = ROUND8(sizeof(Op)*p->nOp); /* Bytes of opcode space used */
zCsr = &((u8*)p->aOp)[n]; /* Unused opcode space */
assert( EIGHT_BYTE_ALIGNMENT(zCsr) );
nFree = ROUNDDOWN8(pParse->szOpAlloc - n); /* Bytes of unused space */
assert( nFree>=0 );
if( nFree>0 ){
memset(zCsr, 0, nFree);
assert( EIGHT_BYTE_ALIGNMENT(&zCsr[nFree]) );
n = ROUND8(sizeof(Op)*p->nOp); /* Bytes of opcode memory used */
x.pSpace = &((u8*)p->aOp)[n]; /* Unused opcode memory */
assert( EIGHT_BYTE_ALIGNMENT(x.pSpace) );
x.nFree = ROUNDDOWN8(pParse->szOpAlloc - n); /* Bytes of unused memory */
assert( x.nFree>=0 );
if( x.nFree>0 ){
memset(x.pSpace, 0, x.nFree);
assert( EIGHT_BYTE_ALIGNMENT(&x.pSpace[x.nFree]) );
}
resolveP2Values(p, &nArg);
p->usesStmtJournal = (u8)(pParse->isMultiWrite && pParse->mayAbort);
if( pParse->explain && nMem<10 ){
nMem = 10;
}
p->expired = 0;
/* Memory for registers, parameters, cursor, etc, is allocated in two
** passes. On the first pass, we try to reuse unused space at the
/* Memory for registers, parameters, cursor, etc, is allocated in one or two
** passes. On the first pass, we try to reuse unused memory at the
** end of the opcode array. If we are unable to satisfy all memory
** requirements by reusing the opcode array tail, then the second
** pass will fill in the rest using a fresh allocation.
** pass will fill in the remainder using a fresh memory allocation.
**
** This two-pass approach that reuses as much memory as possible from
** the leftover space at the end of the opcode array can significantly
** the leftover memory at the end of the opcode array. This can significantly
** reduce the amount of memory held by a prepared statement.
*/
do {
nByte = 0;
p->aMem = allocSpace(p->aMem, nMem*sizeof(Mem), zCsr, &nFree, &nByte);
p->aVar = allocSpace(p->aVar, nVar*sizeof(Mem), zCsr, &nFree, &nByte);
p->apArg = allocSpace(p->apArg, nArg*sizeof(Mem*), zCsr, &nFree, &nByte);
p->apCsr = allocSpace(p->apCsr, nCursor*sizeof(VdbeCursor*),
x.nNeeded = 0;
p->aMem = allocSpace(&x, p->aMem, nMem*sizeof(Mem));
p->aVar = allocSpace(&x, p->aVar, nVar*sizeof(Mem));
p->apArg = allocSpace(&x, p->apArg, nArg*sizeof(Mem*));
p->apCsr = allocSpace(&x, p->apCsr, nCursor*sizeof(VdbeCursor*));
zCsr, &nFree, &nByte);
p->aOnceFlag = allocSpace(p->aOnceFlag, nOnce, zCsr, &nFree, &nByte);
p->aOnceFlag = allocSpace(&x, p->aOnceFlag, nOnce);
#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
p->anExec = allocSpace(p->anExec, p->nOp*sizeof(i64), zCsr, &nFree, &nByte);
p->anExec = allocSpace(&x, p->anExec, p->nOp*sizeof(i64));
#endif
if( nByte ){
p->pFree = sqlite3DbMallocZero(db, nByte);
if( x.nNeeded==0 ) break;
x.pSpace = p->pFree = sqlite3DbMallocZero(db, x.nNeeded);
}
zCsr = p->pFree;
nFree = nByte;
}while( nByte && !db->mallocFailed );
x.nFree = x.nNeeded;
}while( !db->mallocFailed );
p->nCursor = nCursor;
p->nOnceFlag = nOnce;
if( p->aVar ){
p->nVar = (ynVar)nVar;
for(n=0; n<nVar; n++){
p->aVar[n].flags = MEM_Null;
|