/ Check-in [e5ecb159]
Login

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

Overview
Comment:Additional malloc sanity changes. Use sqlite3MemLink() on Index.zColAff and Table.zColAff as a proof of concept.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | malloc-enhancement
Files: files | file ages | folders
SHA1:e5ecb15984e433b102e82eadb127d50ba2dc2ce3
User & Date: drh 2010-07-24 19:08:13
Context
2010-07-25
02:12
Further examples of using automatic deallocation to replace "delete" methods. check-in: da2f62c5 user: drh tags: malloc-enhancement
2010-07-24
19:08
Additional malloc sanity changes. Use sqlite3MemLink() on Index.zColAff and Table.zColAff as a proof of concept. check-in: e5ecb159 user: drh tags: malloc-enhancement
18:25
Add infrastructure to support a hierarchy of memory allocations with automatic deallocation of substructure. check-in: 48ef221c user: drh tags: malloc-enhancement
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/build.c.

345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
...
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
....
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
/*
** Reclaim the memory used by an index
*/
static void freeIndex(sqlite3 *db, Index *p){
#ifndef SQLITE_OMIT_ANALYZE
  sqlite3DeleteIndexSamples(p);
#endif
  sqlite3DbFree(db, p->zColAff);
  sqlite3DbFree(db, p);
}

/*
** Remove the given index from the index hash table, and free
** its memory structures.
**
................................................................................
  /* Delete any foreign keys attached to this table. */
  sqlite3FkDelete(db, pTable);

  /* Delete the Table structure itself.
  */
  sqliteResetColumnNames(db, pTable);
  sqlite3DbFree(db, pTable->zName);
  sqlite3DbFree(db, pTable->zColAff);
  sqlite3SelectDelete(db, pTable->pSelect);
#ifndef SQLITE_OMIT_CHECK
  sqlite3ExprDelete(db, pTable->pCheck);
#endif
  sqlite3VtabClear(db, pTable);
  sqlite3DbFree(db, pTable);
}
................................................................................
    }
    pRet = pIndex;
    pIndex = 0;
  }

  /* Clean up before exiting */
exit_create_index:
  if( pIndex ){
    sqlite3DbFree(db, pIndex->zColAff);
    sqlite3DbFree(db, pIndex);
  }
  sqlite3ExprListDelete(db, pList);
  sqlite3SrcListDelete(db, pTblName);
  sqlite3DbFree(db, zName);
  return pRet;
}

/*







<







 







<







 







<
<
|
<







345
346
347
348
349
350
351

352
353
354
355
356
357
358
...
519
520
521
522
523
524
525

526
527
528
529
530
531
532
....
2807
2808
2809
2810
2811
2812
2813


2814

2815
2816
2817
2818
2819
2820
2821
/*
** Reclaim the memory used by an index
*/
static void freeIndex(sqlite3 *db, Index *p){
#ifndef SQLITE_OMIT_ANALYZE
  sqlite3DeleteIndexSamples(p);
#endif

  sqlite3DbFree(db, p);
}

/*
** Remove the given index from the index hash table, and free
** its memory structures.
**
................................................................................
  /* Delete any foreign keys attached to this table. */
  sqlite3FkDelete(db, pTable);

  /* Delete the Table structure itself.
  */
  sqliteResetColumnNames(db, pTable);
  sqlite3DbFree(db, pTable->zName);

  sqlite3SelectDelete(db, pTable->pSelect);
#ifndef SQLITE_OMIT_CHECK
  sqlite3ExprDelete(db, pTable->pCheck);
#endif
  sqlite3VtabClear(db, pTable);
  sqlite3DbFree(db, pTable);
}
................................................................................
    }
    pRet = pIndex;
    pIndex = 0;
  }

  /* Clean up before exiting */
exit_create_index:


  sqlite3DbFree(db, pIndex);

  sqlite3ExprListDelete(db, pList);
  sqlite3SrcListDelete(db, pTblName);
  sqlite3DbFree(db, zName);
  return pRet;
}

/*

Changes to src/insert.c.

68
69
70
71
72
73
74

75
76
77
78
79
80
81
...
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
    Table *pTab = pIdx->pTable;
    sqlite3 *db = sqlite3VdbeDb(v);
    pIdx->zColAff = (char *)sqlite3DbMallocRaw(0, pIdx->nColumn+2);
    if( !pIdx->zColAff ){
      db->mallocFailed = 1;
      return 0;
    }

    for(n=0; n<pIdx->nColumn; n++){
      pIdx->zColAff[n] = pTab->aCol[pIdx->aiColumn[n]].affinity;
    }
    pIdx->zColAff[n++] = SQLITE_AFF_NONE;
    pIdx->zColAff[n] = 0;
  }
 
................................................................................
    sqlite3 *db = sqlite3VdbeDb(v);

    zColAff = (char *)sqlite3DbMallocRaw(0, pTab->nCol+1);
    if( !zColAff ){
      db->mallocFailed = 1;
      return;
    }

    for(i=0; i<pTab->nCol; i++){
      zColAff[i] = pTab->aCol[i].affinity;
    }
    zColAff[pTab->nCol] = '\0';

    pTab->zColAff = zColAff;
  }







>







 







|







68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
...
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
    Table *pTab = pIdx->pTable;
    sqlite3 *db = sqlite3VdbeDb(v);
    pIdx->zColAff = (char *)sqlite3DbMallocRaw(0, pIdx->nColumn+2);
    if( !pIdx->zColAff ){
      db->mallocFailed = 1;
      return 0;
    }
    sqlite3MemLink(pIdx, pIdx->zColAff);
    for(n=0; n<pIdx->nColumn; n++){
      pIdx->zColAff[n] = pTab->aCol[pIdx->aiColumn[n]].affinity;
    }
    pIdx->zColAff[n++] = SQLITE_AFF_NONE;
    pIdx->zColAff[n] = 0;
  }
 
................................................................................
    sqlite3 *db = sqlite3VdbeDb(v);

    zColAff = (char *)sqlite3DbMallocRaw(0, pTab->nCol+1);
    if( !zColAff ){
      db->mallocFailed = 1;
      return;
    }
    sqlite3MemLink(pTab, zColAff);
    for(i=0; i<pTab->nCol; i++){
      zColAff[i] = pTab->aCol[i].affinity;
    }
    zColAff[pTab->nCol] = '\0';

    pTab->zColAff = zColAff;
  }

Changes to src/malloc.c.

542
543
544
545
546
547
548




549
550
551
552
553

554
555
556


557

558
559
560
561
562
563
564
    sqlite3GlobalConfig.m.xFree(p);
  }
}

/*
** Free memory that might be associated with a particular database
** connection.  All child allocations are also freed.




*/
void sqlite3DbFree(sqlite3 *db, void *pObj){
  EMemHdr *p = (EMemHdr*)pObj;
  assert( db==0 || sqlite3_mutex_held(db->mutex) );
  if( p ) p--;

  while( p ){
    EMemHdr *pNext = p->pESibling;
    assert( isValidEMem(p) );


    if( p->pEChild ) sqlite3DbFree(db, (void*)&p->pEChild[1]);

    if( isLookaside(db, p) ){
      LookasideSlot *pBuf = (LookasideSlot*)p;
      clearValidEMem(p);
      pBuf->pNext = db->lookaside.pFree;
      db->lookaside.pFree = pBuf;
      db->lookaside.nOut--;
    }else{







>
>
>
>





>


|
>
>
|
>







542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
    sqlite3GlobalConfig.m.xFree(p);
  }
}

/*
** Free memory that might be associated with a particular database
** connection.  All child allocations are also freed.
**
** pObj must be a top-level allocation in the heirarchy.  It is not
** allowed to delete a child allocation since that would leave a
** dangling child pointer in the parent.
*/
void sqlite3DbFree(sqlite3 *db, void *pObj){
  EMemHdr *p = (EMemHdr*)pObj;
  assert( db==0 || sqlite3_mutex_held(db->mutex) );
  if( p ) p--;
  assert( p==0 || !isChildEMem(p) );  /* pObj is not child allocation */
  while( p ){
    EMemHdr *pNext = p->pESibling;
    assert( isValidEMem(p) );   /* pObj and all siblings are valid */
    if( p->pEChild ){
      clearChildEMem(p->pEChild);
      sqlite3DbFree(db, (void*)&p->pEChild[1]);
    }
    if( isLookaside(db, p) ){
      LookasideSlot *pBuf = (LookasideSlot*)p;
      clearValidEMem(p);
      pBuf->pNext = db->lookaside.pFree;
      db->lookaside.pFree = pBuf;
      db->lookaside.nOut--;
    }else{

Changes to src/where.c.

3801
3802
3803
3804
3805
3806
3807
3808
3809
3810
3811
3812
3813
3814
3815
3816
3817
3818
        if( pInfo->needToFreeIdxStr ){
          sqlite3_free(pInfo->idxStr);
        }
        sqlite3DbFree(db, pInfo);
      }
      if( pWInfo->a[i].plan.wsFlags & WHERE_TEMP_INDEX ){
        Index *pIdx = pWInfo->a[i].plan.u.pIdx;
        if( pIdx ){
          sqlite3DbFree(db, pIdx->zColAff);
          sqlite3DbFree(db, pIdx);
        }
      }
    }
    whereClauseClear(pWInfo->pWC);
    sqlite3DbFree(db, pWInfo);
  }
}








<
<
|
<







3801
3802
3803
3804
3805
3806
3807


3808

3809
3810
3811
3812
3813
3814
3815
        if( pInfo->needToFreeIdxStr ){
          sqlite3_free(pInfo->idxStr);
        }
        sqlite3DbFree(db, pInfo);
      }
      if( pWInfo->a[i].plan.wsFlags & WHERE_TEMP_INDEX ){
        Index *pIdx = pWInfo->a[i].plan.u.pIdx;


        sqlite3DbFree(db, pIdx);

      }
    }
    whereClauseClear(pWInfo->pWC);
    sqlite3DbFree(db, pWInfo);
  }
}