aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authordrh <drh@noemail.net>2018-12-29 14:23:22 +0000
committerdrh <drh@noemail.net>2018-12-29 14:23:22 +0000
commitd1d158bf5abbab97ee65462c7ee391693ce7ffd7 (patch)
tree6e7199d17f28adb26417cd9f416e17a34d9f36dd /src
parentec4ccdbcb1bd9d129888b38f209ed36bbe38a5d8 (diff)
downloadsqlite-d1d158bf5abbab97ee65462c7ee391693ce7ffd7.tar.gz
sqlite-d1d158bf5abbab97ee65462c7ee391693ce7ffd7.zip
Additional small performance increase and size reduction to the
sqlite3VdbeMakeLabel() mechanism. FossilOrigin-Name: 1bdee199a71e0a6c247b85e72de9e3a3099b7179c33288735721facef3b96459
Diffstat (limited to 'src')
-rw-r--r--src/sqliteInt.h2
-rw-r--r--src/vdbe.h9
-rw-r--r--src/vdbeaux.c23
3 files changed, 22 insertions, 12 deletions
diff --git a/src/sqliteInt.h b/src/sqliteInt.h
index 1db0bc4c8..e056088fc 100644
--- a/src/sqliteInt.h
+++ b/src/sqliteInt.h
@@ -3068,7 +3068,7 @@ struct Parse {
int szOpAlloc; /* Bytes of memory space allocated for Vdbe.aOp[] */
int iSelfTab; /* Table associated with an index on expr, or negative
** of the base register during check-constraint eval */
- int nLabel; /* Number of labels used */
+ int nLabel; /* The *negative* of the number of labels used */
int nLabelAlloc; /* Number of slots in aLabel */
int *aLabel; /* Space to hold the labels */
ExprList *pConstExpr;/* Constant expressions */
diff --git a/src/vdbe.h b/src/vdbe.h
index 7a0312a04..8928798f1 100644
--- a/src/vdbe.h
+++ b/src/vdbe.h
@@ -156,12 +156,11 @@ typedef struct VdbeOpList VdbeOpList;
#endif
/*
-** The following macro converts a relative address in the p2 field
-** of a VdbeOp structure into a negative number so that
-** sqlite3VdbeAddOpList() knows that the address is relative. Calling
-** the macro again restores the address.
+** The following macro converts a label returned by sqlite3VdbeMakeLabel()
+** into an index into the Parse.aLabel[] array that contains the resolved
+** address of that label.
*/
-#define ADDR(X) (-1-(X))
+#define ADDR(X) (~(X))
/*
** The makefile scans the vdbe.c source file and creates the "opcodes.h"
diff --git a/src/vdbeaux.c b/src/vdbeaux.c
index 77e72e046..193b24db8 100644
--- a/src/vdbeaux.c
+++ b/src/vdbeaux.c
@@ -445,11 +445,22 @@ void sqlite3VdbeEndCoroutine(Vdbe *v, int regYield){
** The VDBE knows that a P2 value is a label because labels are
** always negative and P2 values are suppose to be non-negative.
** Hence, a negative P2 value is a label that has yet to be resolved.
+** (Later:) This is only true for opcodes that have the OPFLG_JUMP
+** property.
**
-** Zero is returned if a malloc() fails.
+** Variable usage notes:
+**
+** Parse.aLabel[x] Stores the address that the x-th label resolves
+** into. For testing (SQLITE_DEBUG), unresolved
+** labels stores -1, but that is not required.
+** Parse.nLabelAlloc Number of slots allocated to Parse.aLabel[]
+** Parse.nLabel The *negative* of the number of labels that have
+** been issued. The negative is stored because
+** that gives a performance improvement over storing
+** the equivalent positive value.
*/
int sqlite3VdbeMakeLabel(Parse *pParse){
- return ADDR(pParse->nLabel++);
+ return --pParse->nLabel;
}
/*
@@ -458,7 +469,7 @@ int sqlite3VdbeMakeLabel(Parse *pParse){
** a prior call to sqlite3VdbeMakeLabel().
*/
static SQLITE_NOINLINE void resizeResolveLabel(Parse *p, Vdbe *v, int j){
- int nNewSize = p->nLabel+10;
+ int nNewSize = 10 - p->nLabel;
p->aLabel = sqlite3DbReallocOrFree(p->db, p->aLabel,
nNewSize*sizeof(p->aLabel[0]));
if( p->aLabel==0 ){
@@ -476,14 +487,14 @@ void sqlite3VdbeResolveLabel(Vdbe *v, int x){
Parse *p = v->pParse;
int j = ADDR(x);
assert( v->magic==VDBE_MAGIC_INIT );
- assert( j<p->nLabel );
+ assert( j<-p->nLabel );
assert( j>=0 );
#ifdef SQLITE_DEBUG
if( p->db->flags & SQLITE_VdbeAddopTrace ){
printf("RESOLVE LABEL %d to %d\n", x, v->nOp);
}
#endif
- if( p->nLabelAlloc < p->nLabel ){
+ if( p->nLabelAlloc + p->nLabel < 0 ){
resizeResolveLabel(p,v,j);
}else{
assert( p->aLabel[j]==(-1) ); /* Labels may only be resolved once */
@@ -761,7 +772,7 @@ static void resolveP2Values(Vdbe *p, int *pMaxFuncArgs){
** non-jump opcodes less than SQLITE_MX_JUMP_CODE are guaranteed to
** have non-negative values for P2. */
assert( (sqlite3OpcodeProperty[pOp->opcode] & OPFLG_JUMP)!=0 );
- assert( ADDR(pOp->p2)<pParse->nLabel );
+ assert( ADDR(pOp->p2)<-pParse->nLabel );
pOp->p2 = aLabel[ADDR(pOp->p2)];
}
break;