mirror of
https://github.com/sqlite/sqlite.git
synced 2025-08-07 02:42:48 +03:00
Move the sqlite3VdbeSerialType() routine in-line in the OP_MakeRecord opcode.
Optimizing compilers were doing this already. By doing it manually, we can omit some redundant tests and make the whole thing run a million cycles faster and use about 80 bytes less code space. FossilOrigin-Name: d837ab0da52632699abc09320980606aef020df5020c253f99c97e24bf3c6d00
This commit is contained in:
84
src/vdbe.c
84
src/vdbe.c
@@ -2932,9 +2932,8 @@ case OP_MakeRecord: {
|
||||
pRec = pLast;
|
||||
do{
|
||||
assert( memIsValid(pRec) );
|
||||
serial_type = sqlite3VdbeSerialType(pRec, file_format, &len);
|
||||
if( pRec->flags & MEM_Zero ){
|
||||
if( serial_type==0 ){
|
||||
if( pRec->flags & MEM_Null ){
|
||||
if( pRec->flags & MEM_Zero ){
|
||||
/* Values with MEM_Null and MEM_Zero are created by xColumn virtual
|
||||
** table methods that never invoke sqlite3_result_xxxxx() while
|
||||
** computing an unchanging column value in an UPDATE statement.
|
||||
@@ -2942,19 +2941,78 @@ case OP_MakeRecord: {
|
||||
** so that they can be passed through to xUpdate and have
|
||||
** a true sqlite3_value_nochange(). */
|
||||
assert( pOp->p5==OPFLAG_NOCHNG_MAGIC || CORRUPT_DB );
|
||||
serial_type = 10;
|
||||
}else if( nData ){
|
||||
if( sqlite3VdbeMemExpandBlob(pRec) ) goto no_mem;
|
||||
pRec->uTemp = 10;
|
||||
}else{
|
||||
nZero += pRec->u.nZero;
|
||||
len -= pRec->u.nZero;
|
||||
pRec->uTemp = 0; /* Serial-type 0 means NULL */
|
||||
}
|
||||
nHdr++;
|
||||
}else if( pRec->flags & (MEM_Int|MEM_IntReal) ){
|
||||
/* Figure out whether to use 1, 2, 4, 6 or 8 bytes. */
|
||||
i64 i = pRec->u.i;
|
||||
u64 u;
|
||||
testcase( pRec->flags & MEM_Int );
|
||||
testcase( pRec->flags & MEM_IntReal );
|
||||
if( i<0 ){
|
||||
u = ~i;
|
||||
}else{
|
||||
u = i;
|
||||
}
|
||||
nHdr++;
|
||||
if( u<=127 ){
|
||||
if( (i&1)==i && file_format>=4 ){
|
||||
pRec->uTemp = 8+(u32)u;
|
||||
}else{
|
||||
nData++;
|
||||
pRec->uTemp = 1;
|
||||
}
|
||||
}else if( u<=32767 ){
|
||||
nData += 2;
|
||||
pRec->uTemp = 2;
|
||||
}else if( u<=8388607 ){
|
||||
nData += 3;
|
||||
pRec->uTemp = 3;
|
||||
}else if( u<=2147483647 ){
|
||||
nData += 4;
|
||||
pRec->uTemp = 4;
|
||||
}else if( u<=140737488355327LL ){
|
||||
nData += 6;
|
||||
pRec->uTemp = 5;
|
||||
}else{
|
||||
nData += 8;
|
||||
if( pRec->flags & MEM_IntReal ){
|
||||
/* If the value is IntReal and is going to take up 8 bytes to store
|
||||
** as an integer, then we might as well make it an 8-byte floating
|
||||
** point value */
|
||||
pRec->u.r = (double)pRec->u.i;
|
||||
pRec->flags &= ~MEM_IntReal;
|
||||
pRec->flags |= MEM_Real;
|
||||
pRec->uTemp = 7;
|
||||
}else{
|
||||
pRec->uTemp = 6;
|
||||
}
|
||||
}
|
||||
}else if( pRec->flags & MEM_Real ){
|
||||
nHdr++;
|
||||
nData += 8;
|
||||
pRec->uTemp = 7;
|
||||
}else{
|
||||
assert( db->mallocFailed || pRec->flags&(MEM_Str|MEM_Blob) );
|
||||
assert( pRec->n>=0 );
|
||||
len = (u32)pRec->n;
|
||||
serial_type = (len*2) + 12 + ((pRec->flags & MEM_Str)!=0);
|
||||
if( pRec->flags & MEM_Zero ){
|
||||
serial_type += pRec->u.nZero*2;
|
||||
if( nData ){
|
||||
if( sqlite3VdbeMemExpandBlob(pRec) ) goto no_mem;
|
||||
len += pRec->u.nZero;
|
||||
}else{
|
||||
nZero += pRec->u.nZero;
|
||||
}
|
||||
}
|
||||
nData += len;
|
||||
nHdr += sqlite3VarintLen(serial_type);
|
||||
pRec->uTemp = serial_type;
|
||||
}
|
||||
nData += len;
|
||||
testcase( serial_type==127 );
|
||||
testcase( serial_type==128 );
|
||||
nHdr += serial_type<=127 ? 1 : sqlite3VarintLen(serial_type);
|
||||
pRec->uTemp = serial_type;
|
||||
if( pRec==pData0 ) break;
|
||||
pRec--;
|
||||
}while(1);
|
||||
|
Reference in New Issue
Block a user