aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/vdbeaux.c29
1 files changed, 24 insertions, 5 deletions
diff --git a/src/vdbeaux.c b/src/vdbeaux.c
index 42c86204e..45ab6cfd8 100644
--- a/src/vdbeaux.c
+++ b/src/vdbeaux.c
@@ -14,7 +14,7 @@
** 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.
**
-** $Id: vdbeaux.c,v 1.410 2008/09/16 09:09:20 danielk1977 Exp $
+** $Id: vdbeaux.c,v 1.411 2008/09/19 18:32:27 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>
@@ -761,13 +761,32 @@ void sqlite3VdbePrintOp(FILE *pOut, int pc, Op *pOp){
*/
static void releaseMemArray(Mem *p, int N){
if( p && N ){
+ Mem *pEnd;
sqlite3 *db = p->db;
int malloc_failed = db->mallocFailed;
- while( N-->0 ){
- assert( N<2 || p[0].db==p[1].db );
- sqlite3VdbeMemRelease(p);
+ for(pEnd=&p[N]; p<pEnd; p++){
+ assert( (&p[1])==pEnd || p[0].db==p[1].db );
+
+ /* This block is really an inlined version of sqlite3VdbeMemRelease()
+ ** that takes advantage of the fact that the memory cell value is
+ ** being set to NULL after releasing any dynamic resources.
+ **
+ ** The justification for duplicating code is that according to
+ ** callgrind, this causes a certain test case to hit the CPU 4.7
+ ** percent less (x86 linux, gcc version 4.1.2, -O6) than if
+ ** sqlite3MemRelease() were called from here. With -O2, this jumps
+ ** to 6.6 percent. The test case is inserting 1000 rows into a table
+ ** with no indexes using a single prepared INSERT statement, bind()
+ ** and reset(). Inserts are grouped into a transaction.
+ */
+ if( p->flags&(MEM_Agg|MEM_Dyn) ){
+ sqlite3VdbeMemRelease(p);
+ }else if( p->zMalloc ){
+ sqlite3DbFree(db, p->zMalloc);
+ p->zMalloc = 0;
+ }
+
p->flags = MEM_Null;
- p++;
}
db->mallocFailed = malloc_failed;
}