SQLite

Check-in [2589955507]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Speed improvements by removing unnecessary memset() operations. Also: do not resize the opcode array of a virtual machine to its minimum size after code generation completes. The extra resize merely uses time. (CVS 4987)
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 2589955507fc1717891c4e07d1d658eb41660b87
User & Date: drh 2008-04-11 14:56:53.000
Context
2008-04-11
15:36
Additional reductions in the use of memset(). (CVS 4988) (check-in: 38746c5438 user: drh tags: trunk)
14:56
Speed improvements by removing unnecessary memset() operations. Also: do not resize the opcode array of a virtual machine to its minimum size after code generation completes. The extra resize merely uses time. (CVS 4987) (check-in: 2589955507 user: drh tags: trunk)
2008-04-10
18:44
Enhancements to the change counter tests. Ticket #3013. (CVS 4986) (check-in: 1aaed6a469 user: drh tags: trunk)
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/vdbe.h.
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
*************************************************************************
** Header file for the Virtual DataBase Engine (VDBE)
**
** This header defines the interface to the virtual database engine
** or VDBE.  The VDBE implements an abstract machine that runs a
** simple program to access and modify the underlying database.
**
** $Id: vdbe.h,v 1.129 2008/03/26 18:34:43 danielk1977 Exp $
*/
#ifndef _SQLITE_VDBE_H_
#define _SQLITE_VDBE_H_
#include <stdio.h>

/*
** A single VDBE is an opaque structure named "Vdbe".  Only routines







|







11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
*************************************************************************
** Header file for the Virtual DataBase Engine (VDBE)
**
** This header defines the interface to the virtual database engine
** or VDBE.  The VDBE implements an abstract machine that runs a
** simple program to access and modify the underlying database.
**
** $Id: vdbe.h,v 1.130 2008/04/11 14:56:53 drh Exp $
*/
#ifndef _SQLITE_VDBE_H_
#define _SQLITE_VDBE_H_
#include <stdio.h>

/*
** A single VDBE is an opaque structure named "Vdbe".  Only routines
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
** A single instruction of the virtual machine has an opcode
** and as many as three operands.  The instruction is recorded
** as an instance of the following structure:
*/
struct VdbeOp {
  u8 opcode;          /* What operation to perform */
  signed char p4type; /* One of the P4_xxx constants for p4 */
  u8 flags;           /* Flags for internal use */
  u8 p5;              /* Fifth parameter is an unsigned character */
  int p1;             /* First operand */
  int p2;             /* Second parameter (often the jump destination) */
  int p3;             /* The third parameter */
  union {             /* forth parameter */
    int i;                 /* Integer value if p4type==P4_INT32 */
    void *p;               /* Generic pointer */







|







40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
** A single instruction of the virtual machine has an opcode
** and as many as three operands.  The instruction is recorded
** as an instance of the following structure:
*/
struct VdbeOp {
  u8 opcode;          /* What operation to perform */
  signed char p4type; /* One of the P4_xxx constants for p4 */
  u8 opflags;         /* Not currently used */
  u8 p5;              /* Fifth parameter is an unsigned character */
  int p1;             /* First operand */
  int p2;             /* Second parameter (often the jump destination) */
  int p3;             /* The third parameter */
  union {             /* forth parameter */
    int i;                 /* Integer value if p4type==P4_INT32 */
    void *p;               /* Generic pointer */
Changes to src/vdbeaux.c.
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
static void resizeOpArray(Vdbe *p, int N){
  VdbeOp *pNew;
  int oldSize = p->nOpAlloc;
  pNew = sqlite3DbRealloc(p->db, p->aOp, N*sizeof(Op));
  if( pNew ){
    p->nOpAlloc = N;
    p->aOp = pNew;
    if( N>oldSize ){
      memset(&p->aOp[oldSize], 0, (N-oldSize)*sizeof(Op));
    }
  }
}

/*
** Add a new instruction to the list of instructions current in the
** VDBE.  Return the address of the new instruction.
**







<
<
<







109
110
111
112
113
114
115



116
117
118
119
120
121
122
static void resizeOpArray(Vdbe *p, int N){
  VdbeOp *pNew;
  int oldSize = p->nOpAlloc;
  pNew = sqlite3DbRealloc(p->db, p->aOp, N*sizeof(Op));
  if( pNew ){
    p->nOpAlloc = N;
    p->aOp = pNew;



  }
}

/*
** Add a new instruction to the list of instructions current in the
** VDBE.  Return the address of the new instruction.
**
146
147
148
149
150
151
152

153
154
155
156
157
158
159

160




161
162
163
164
165
166
167
    if( p->db->mallocFailed ){
      return 0;
    }
  }
  p->nOp++;
  pOp = &p->aOp[i];
  pOp->opcode = op;

  pOp->p1 = p1;
  pOp->p2 = p2;
  pOp->p3 = p3;
  pOp->p4.p = 0;
  pOp->p4type = P4_NOTUSED;
  p->expired = 0;
#ifdef SQLITE_DEBUG

  if( sqlite3VdbeAddopTrace ) sqlite3VdbePrintOp(0, i, &p->aOp[i]);




#endif
  return i;
}
int sqlite3VdbeAddOp0(Vdbe *p, int op){
  return sqlite3VdbeAddOp3(p, op, 0, 0, 0);
}
int sqlite3VdbeAddOp1(Vdbe *p, int op, int p1){







>







>

>
>
>
>







143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
    if( p->db->mallocFailed ){
      return 0;
    }
  }
  p->nOp++;
  pOp = &p->aOp[i];
  pOp->opcode = op;
  pOp->p5 = 0;
  pOp->p1 = p1;
  pOp->p2 = p2;
  pOp->p3 = p3;
  pOp->p4.p = 0;
  pOp->p4type = P4_NOTUSED;
  p->expired = 0;
#ifdef SQLITE_DEBUG
  pOp->zComment = 0;
  if( sqlite3VdbeAddopTrace ) sqlite3VdbePrintOp(0, i, &p->aOp[i]);
#endif
#ifdef VDBE_PROFILE
  pOp->cycles = 0;
  pOp->cnt = 0;
#endif
  return i;
}
int sqlite3VdbeAddOp0(Vdbe *p, int op){
  return sqlite3VdbeAddOp3(p, op, 0, 0, 0);
}
int sqlite3VdbeAddOp1(Vdbe *p, int op, int p1){
356
357
358
359
360
361
362

363
364
365
366
367
368
369
        pOut->p2 = p2;
      }
      pOut->p3 = pIn->p3;
      pOut->p4type = P4_NOTUSED;
      pOut->p4.p = 0;
      pOut->p5 = 0;
#ifdef SQLITE_DEBUG

      if( sqlite3VdbeAddopTrace ){
        sqlite3VdbePrintOp(0, i+addr, &p->aOp[i+addr]);
      }
#endif
    }
    p->nOp += nOp;
  }







>







359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
        pOut->p2 = p2;
      }
      pOut->p3 = pIn->p3;
      pOut->p4type = P4_NOTUSED;
      pOut->p4.p = 0;
      pOut->p5 = 0;
#ifdef SQLITE_DEBUG
      pOut->zComment = 0;
      if( sqlite3VdbeAddopTrace ){
        sqlite3VdbePrintOp(0, i+addr, &p->aOp[i+addr]);
      }
#endif
    }
    p->nOp += nOp;
  }
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007

  /*
  ** Allocation space for registers.
  */
  if( p->aMem==0 ){
    int nArg;       /* Maximum number of args passed to a user function. */
    resolveP2Values(p, &nArg);
    resizeOpArray(p, p->nOp);
    assert( nVar>=0 );
    if( isExplain && nMem<10 ){
      p->nMem = nMem = 10;
    }
    p->aMem = sqlite3DbMallocZero(db,
        nMem*sizeof(Mem)               /* aMem */
      + nVar*sizeof(Mem)               /* aVar */







|







997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011

  /*
  ** Allocation space for registers.
  */
  if( p->aMem==0 ){
    int nArg;       /* Maximum number of args passed to a user function. */
    resolveP2Values(p, &nArg);
    /*resizeOpArray(p, p->nOp);*/
    assert( nVar>=0 );
    if( isExplain && nMem<10 ){
      p->nMem = nMem = 10;
    }
    p->aMem = sqlite3DbMallocZero(db,
        nMem*sizeof(Mem)               /* aMem */
      + nVar*sizeof(Mem)               /* aVar */
Changes to test/quick.test.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#
#    May you do good and not evil.
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
# This file runs all tests.
#
# $Id: quick.test,v 1.76 2008/03/31 23:51:35 drh Exp $

proc lshift {lvar} {
  upvar $lvar l
  set ret [lindex $l 0]
  set l [lrange $l 1 end]
  return $ret
}








|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#
#    May you do good and not evil.
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
# This file runs all tests.
#
# $Id: quick.test,v 1.77 2008/04/11 14:56:53 drh Exp $

proc lshift {lvar} {
  upvar $lvar l
  set ret [lindex $l 0]
  set l [lrange $l 1 end]
  return $ret
}
65
66
67
68
69
70
71

72
73
74
75
76
77
78
79
80
  misuse.test
  onefile.test
  quick.test
  soak.test
  speed1.test
  speed1p.test
  speed2.test

  speed4.test
  soeed4p.test
  sqllimits1.test

  thread001.test
  thread002.test

  incrvacuum_ioerr.test
  autovacuum_crash.test







>

|







65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
  misuse.test
  onefile.test
  quick.test
  soak.test
  speed1.test
  speed1p.test
  speed2.test
  speed3.test
  speed4.test
  speed4p.test
  sqllimits1.test

  thread001.test
  thread002.test

  incrvacuum_ioerr.test
  autovacuum_crash.test
Changes to tool/lempar.c.
55
56
57
58
59
60
61




62
63
64
65
66
67
68
**    YYERRORSYMBOL      is the code number of the error symbol.  If not
**                       defined, then do no error processing.
*/
%%
#define YY_NO_ACTION      (YYNSTATE+YYNRULE+2)
#define YY_ACCEPT_ACTION  (YYNSTATE+YYNRULE+1)
#define YY_ERROR_ACTION   (YYNSTATE+YYNRULE)





/* Next are that tables used to determine what action to take based on the
** current state and lookahead token.  These tables are used to implement
** functions that take a state number and lookahead value and return an
** action integer.  
**
** Suppose the action integer is N.  Then the action is determined as







>
>
>
>







55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
**    YYERRORSYMBOL      is the code number of the error symbol.  If not
**                       defined, then do no error processing.
*/
%%
#define YY_NO_ACTION      (YYNSTATE+YYNRULE+2)
#define YY_ACCEPT_ACTION  (YYNSTATE+YYNRULE+1)
#define YY_ERROR_ACTION   (YYNSTATE+YYNRULE)

/* The yyzerominor constant is used to initialize instances of
** YYMINORTYPE objects to zero. */
static const YYMINORTYPE yyzerominor;

/* Next are that tables used to determine what action to take based on the
** current state and lookahead token.  These tables are used to implement
** functions that take a state number and lookahead value and return an
** action integer.  
**
** Suppose the action integer is N.  Then the action is determined as
514
515
516
517
518
519
520
521

522
523
524
525
526
527
528
  **
  ** 2007-01-16:  The wireshark project (www.wireshark.org) reports that
  ** without this code, their parser segfaults.  I'm not sure what there
  ** parser is doing to make this happen.  This is the second bug report
  ** from wireshark this week.  Clearly they are stressing Lemon in ways
  ** that it has not been previously stressed...  (SQLite ticket #2172)
  */
  memset(&yygotominor, 0, sizeof(yygotominor));



  switch( yyruleno ){
  /* Beginning here are the reduction cases.  A typical example
  ** follows:
  **   case 0:
  **  #line <lineno> <grammarfile>







|
>







518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
  **
  ** 2007-01-16:  The wireshark project (www.wireshark.org) reports that
  ** without this code, their parser segfaults.  I'm not sure what there
  ** parser is doing to make this happen.  This is the second bug report
  ** from wireshark this week.  Clearly they are stressing Lemon in ways
  ** that it has not been previously stressed...  (SQLite ticket #2172)
  */
  /*memset(&yygotominor, 0, sizeof(yygotominor));*/
  yygotominor = yyzerominor;


  switch( yyruleno ){
  /* Beginning here are the reduction cases.  A typical example
  ** follows:
  **   case 0:
  **  #line <lineno> <grammarfile>
645
646
647
648
649
650
651
652

653
654
655
656
657
658
659
  yyParser *yypParser;  /* The parser */

  /* (re)initialize the parser, if necessary */
  yypParser = (yyParser*)yyp;
  if( yypParser->yyidx<0 ){
#if YYSTACKDEPTH<=0
    if( yypParser->yystksz <=0 ){
      memset(&yyminorunion, 0, sizeof(yyminorunion));

      yyStackOverflow(yypParser, &yyminorunion);
      return;
    }
#endif
    yypParser->yyidx = 0;
    yypParser->yyerrcnt = -1;
    yypParser->yystack[0].stateno = 0;







|
>







650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
  yyParser *yypParser;  /* The parser */

  /* (re)initialize the parser, if necessary */
  yypParser = (yyParser*)yyp;
  if( yypParser->yyidx<0 ){
#if YYSTACKDEPTH<=0
    if( yypParser->yystksz <=0 ){
      /*memset(&yyminorunion, 0, sizeof(yyminorunion));*/
      yyminorunion = yyzerominor;
      yyStackOverflow(yypParser, &yyminorunion);
      return;
    }
#endif
    yypParser->yyidx = 0;
    yypParser->yyerrcnt = -1;
    yypParser->yystack[0].stateno = 0;