Fossil SCM

More TH1 performance optimizations: Go directly to malloc() rather than through the Th_Malloc() intermediary.

drh 2021-01-27 13:32 UTC trunk
Commit 9b4f2d8e98d86d12cf220bc8e2561c27be4466f71be80a7baf8fc956cb31d7c3
-1
--- src/main.c
+++ src/main.c
@@ -385,11 +385,10 @@
385385
*/
386386
if( fossil_getenv("TH1_DELETE_INTERP")!=0 ){
387387
if( g.interp ){
388388
Th_DeleteInterp(g.interp); g.interp = 0;
389389
}
390
- assert( Th_GetOutstandingMalloc()==0 );
391390
}
392391
}
393392
394393
/*
395394
** Convert all arguments from mbcs (or unicode) to UTF-8. Then
396395
--- src/main.c
+++ src/main.c
@@ -385,11 +385,10 @@
385 */
386 if( fossil_getenv("TH1_DELETE_INTERP")!=0 ){
387 if( g.interp ){
388 Th_DeleteInterp(g.interp); g.interp = 0;
389 }
390 assert( Th_GetOutstandingMalloc()==0 );
391 }
392 }
393
394 /*
395 ** Convert all arguments from mbcs (or unicode) to UTF-8. Then
396
--- src/main.c
+++ src/main.c
@@ -385,11 +385,10 @@
385 */
386 if( fossil_getenv("TH1_DELETE_INTERP")!=0 ){
387 if( g.interp ){
388 Th_DeleteInterp(g.interp); g.interp = 0;
389 }
 
390 }
391 }
392
393 /*
394 ** Convert all arguments from mbcs (or unicode) to UTF-8. Then
395
+3 -25
--- src/th.c
+++ src/th.c
@@ -221,17 +221,13 @@
221221
Th_Interp *interp,
222222
Buffer *pBuffer,
223223
const char *zAdd,
224224
int nAdd
225225
){
226
- char *zNew;
227226
int nNew = (pBuffer->nBuf+nAdd)*2+32;
228
- zNew = (char *)Th_Malloc(interp, nNew);
229
- th_memcpy(zNew, pBuffer->zBuf, pBuffer->nBuf);
230
- Th_Free(interp, pBuffer->zBuf);
227
+ pBuffer->zBuf = Th_Realloc(interp, pBuffer->zBuf, nNew);
231228
pBuffer->nBufAlloc = nNew;
232
- pBuffer->zBuf = zNew;
233229
th_memcpy(&pBuffer->zBuf[pBuffer->nBuf], zAdd, nAdd);
234230
pBuffer->nBuf += nAdd;
235231
}
236232
static void thBufferWriteFast(
237233
Th_Interp *interp,
@@ -1539,27 +1535,10 @@
15391535
}else{
15401536
return (char *)Th_Malloc(pInterp, 1);
15411537
}
15421538
}
15431539
1544
-
1545
-/*
1546
-** Wrappers around the supplied malloc() and free()
1547
-*/
1548
-void *Th_Malloc(Th_Interp *pInterp, int nByte){
1549
- void *p = pInterp->pVtab->xMalloc(nByte);
1550
- if( p ){
1551
- memset(p, 0, nByte);
1552
- }
1553
- return p;
1554
-}
1555
-void Th_Free(Th_Interp *pInterp, void *z){
1556
- if( z ){
1557
- pInterp->pVtab->xFree(z);
1558
- }
1559
-}
1560
-
15611540
/*
15621541
** Install a new th1 command.
15631542
**
15641543
** If a command of the same name already exists, it is deleted automatically.
15651544
*/
@@ -1842,17 +1821,16 @@
18421821
}
18431822
18441823
/*
18451824
** Create a new interpreter.
18461825
*/
1847
-Th_Interp * Th_CreateInterp(Th_Vtab *pVtab){
1826
+Th_Interp * Th_CreateInterp(void){
18481827
Th_Interp *p;
18491828
18501829
/* Allocate and initialise the interpreter and the global frame */
1851
- p = pVtab->xMalloc(sizeof(Th_Interp) + sizeof(Th_Frame));
1830
+ p = Th_Malloc(0, sizeof(Th_Interp) + sizeof(Th_Frame));
18521831
memset(p, 0, sizeof(Th_Interp));
1853
- p->pVtab = pVtab;
18541832
p->paCmd = Th_HashNew(p);
18551833
thPushFrame(p, (Th_Frame *)&p[1]);
18561834
thInitialize(p);
18571835
18581836
return p;
18591837
--- src/th.c
+++ src/th.c
@@ -221,17 +221,13 @@
221 Th_Interp *interp,
222 Buffer *pBuffer,
223 const char *zAdd,
224 int nAdd
225 ){
226 char *zNew;
227 int nNew = (pBuffer->nBuf+nAdd)*2+32;
228 zNew = (char *)Th_Malloc(interp, nNew);
229 th_memcpy(zNew, pBuffer->zBuf, pBuffer->nBuf);
230 Th_Free(interp, pBuffer->zBuf);
231 pBuffer->nBufAlloc = nNew;
232 pBuffer->zBuf = zNew;
233 th_memcpy(&pBuffer->zBuf[pBuffer->nBuf], zAdd, nAdd);
234 pBuffer->nBuf += nAdd;
235 }
236 static void thBufferWriteFast(
237 Th_Interp *interp,
@@ -1539,27 +1535,10 @@
1539 }else{
1540 return (char *)Th_Malloc(pInterp, 1);
1541 }
1542 }
1543
1544
1545 /*
1546 ** Wrappers around the supplied malloc() and free()
1547 */
1548 void *Th_Malloc(Th_Interp *pInterp, int nByte){
1549 void *p = pInterp->pVtab->xMalloc(nByte);
1550 if( p ){
1551 memset(p, 0, nByte);
1552 }
1553 return p;
1554 }
1555 void Th_Free(Th_Interp *pInterp, void *z){
1556 if( z ){
1557 pInterp->pVtab->xFree(z);
1558 }
1559 }
1560
1561 /*
1562 ** Install a new th1 command.
1563 **
1564 ** If a command of the same name already exists, it is deleted automatically.
1565 */
@@ -1842,17 +1821,16 @@
1842 }
1843
1844 /*
1845 ** Create a new interpreter.
1846 */
1847 Th_Interp * Th_CreateInterp(Th_Vtab *pVtab){
1848 Th_Interp *p;
1849
1850 /* Allocate and initialise the interpreter and the global frame */
1851 p = pVtab->xMalloc(sizeof(Th_Interp) + sizeof(Th_Frame));
1852 memset(p, 0, sizeof(Th_Interp));
1853 p->pVtab = pVtab;
1854 p->paCmd = Th_HashNew(p);
1855 thPushFrame(p, (Th_Frame *)&p[1]);
1856 thInitialize(p);
1857
1858 return p;
1859
--- src/th.c
+++ src/th.c
@@ -221,17 +221,13 @@
221 Th_Interp *interp,
222 Buffer *pBuffer,
223 const char *zAdd,
224 int nAdd
225 ){
 
226 int nNew = (pBuffer->nBuf+nAdd)*2+32;
227 pBuffer->zBuf = Th_Realloc(interp, pBuffer->zBuf, nNew);
 
 
228 pBuffer->nBufAlloc = nNew;
 
229 th_memcpy(&pBuffer->zBuf[pBuffer->nBuf], zAdd, nAdd);
230 pBuffer->nBuf += nAdd;
231 }
232 static void thBufferWriteFast(
233 Th_Interp *interp,
@@ -1539,27 +1535,10 @@
1535 }else{
1536 return (char *)Th_Malloc(pInterp, 1);
1537 }
1538 }
1539
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1540 /*
1541 ** Install a new th1 command.
1542 **
1543 ** If a command of the same name already exists, it is deleted automatically.
1544 */
@@ -1842,17 +1821,16 @@
1821 }
1822
1823 /*
1824 ** Create a new interpreter.
1825 */
1826 Th_Interp * Th_CreateInterp(void){
1827 Th_Interp *p;
1828
1829 /* Allocate and initialise the interpreter and the global frame */
1830 p = Th_Malloc(0, sizeof(Th_Interp) + sizeof(Th_Frame));
1831 memset(p, 0, sizeof(Th_Interp));
 
1832 p->paCmd = Th_HashNew(p);
1833 thPushFrame(p, (Th_Frame *)&p[1]);
1834 thInitialize(p);
1835
1836 return p;
1837
+7 -3
--- src/th.h
+++ src/th.h
@@ -21,11 +21,11 @@
2121
typedef struct Th_Interp Th_Interp;
2222
2323
/*
2424
** Create and delete interpreters.
2525
*/
26
-Th_Interp * Th_CreateInterp(Th_Vtab *pVtab);
26
+Th_Interp * Th_CreateInterp(void);
2727
void Th_DeleteInterp(Th_Interp *);
2828
2929
/*
3030
** Evaluate an TH program in the stack frame identified by parameter
3131
** iFrame, according to the following rules:
@@ -121,12 +121,16 @@
121121
122122
/*
123123
** Access the memory management functions associated with the specified
124124
** interpreter.
125125
*/
126
-void *Th_Malloc(Th_Interp *, int);
127
-void Th_Free(Th_Interp *, void *);
126
+void *fossil_malloc_zero(size_t);
127
+void *fossil_realloc(void*,size_t);
128
+void fossil_free(void*);
129
+#define Th_Malloc(I,N) fossil_malloc_zero(N)
130
+#define Th_Realloc(I,P,N) fossil_realloc(P,N)
131
+#define Th_Free(I,P) fossil_free(P)
128132
129133
/*
130134
** Functions for handling TH lists.
131135
*/
132136
int Th_ListAppend(Th_Interp *, char **, int *, const char *, int);
133137
--- src/th.h
+++ src/th.h
@@ -21,11 +21,11 @@
21 typedef struct Th_Interp Th_Interp;
22
23 /*
24 ** Create and delete interpreters.
25 */
26 Th_Interp * Th_CreateInterp(Th_Vtab *pVtab);
27 void Th_DeleteInterp(Th_Interp *);
28
29 /*
30 ** Evaluate an TH program in the stack frame identified by parameter
31 ** iFrame, according to the following rules:
@@ -121,12 +121,16 @@
121
122 /*
123 ** Access the memory management functions associated with the specified
124 ** interpreter.
125 */
126 void *Th_Malloc(Th_Interp *, int);
127 void Th_Free(Th_Interp *, void *);
 
 
 
 
128
129 /*
130 ** Functions for handling TH lists.
131 */
132 int Th_ListAppend(Th_Interp *, char **, int *, const char *, int);
133
--- src/th.h
+++ src/th.h
@@ -21,11 +21,11 @@
21 typedef struct Th_Interp Th_Interp;
22
23 /*
24 ** Create and delete interpreters.
25 */
26 Th_Interp * Th_CreateInterp(void);
27 void Th_DeleteInterp(Th_Interp *);
28
29 /*
30 ** Evaluate an TH program in the stack frame identified by parameter
31 ** iFrame, according to the following rules:
@@ -121,12 +121,16 @@
121
122 /*
123 ** Access the memory management functions associated with the specified
124 ** interpreter.
125 */
126 void *fossil_malloc_zero(size_t);
127 void *fossil_realloc(void*,size_t);
128 void fossil_free(void*);
129 #define Th_Malloc(I,N) fossil_malloc_zero(N)
130 #define Th_Realloc(I,P,N) fossil_realloc(P,N)
131 #define Th_Free(I,P) fossil_free(P)
132
133 /*
134 ** Functions for handling TH lists.
135 */
136 int Th_ListAppend(Th_Interp *, char **, int *, const char *, int);
137
+1 -32
--- src/th_main.c
+++ src/th_main.c
@@ -68,41 +68,10 @@
6868
** configuration ("user") database are currently open.
6969
*/
7070
#define Th_IsRepositoryOpen() (g.repositoryOpen)
7171
#define Th_IsConfigOpen() (g.zConfigDbName!=0)
7272
73
-/*
74
-** Global variable counting the number of outstanding calls to malloc()
75
-** made by the th1 implementation. This is used to catch memory leaks
76
-** in the interpreter. Obviously, it also means th1 is not threadsafe.
77
-*/
78
-static int nOutstandingMalloc = 0;
79
-
80
-/*
81
-** Implementations of malloc() and free() to pass to the interpreter.
82
-*/
83
-static void *xMalloc(unsigned int n){
84
- void *p = fossil_malloc(n);
85
- if( p ){
86
- nOutstandingMalloc++;
87
- }
88
- return p;
89
-}
90
-static void xFree(void *p){
91
- if( p ){
92
- nOutstandingMalloc--;
93
- }
94
- free(p);
95
-}
96
-static Th_Vtab vtab = { xMalloc, xFree };
97
-
98
-/*
99
-** Returns the number of outstanding TH1 memory allocations.
100
-*/
101
-int Th_GetOutstandingMalloc(){
102
- return nOutstandingMalloc;
103
-}
10473
10574
/*
10675
** Generate a TH1 trace message if debugging is enabled.
10776
*/
10877
void Th_Trace(const char *zFormat, ...){
@@ -2387,11 +2356,11 @@
23872356
}
23882357
if( forceReset || forceTcl || g.interp==0 ){
23892358
int created = 0;
23902359
int i;
23912360
if( g.interp==0 ){
2392
- g.interp = Th_CreateInterp(&vtab);
2361
+ g.interp = Th_CreateInterp();
23932362
created = 1;
23942363
}
23952364
if( forceReset || created ){
23962365
th_register_language(g.interp); /* Basic scripting commands. */
23972366
}
23982367
--- src/th_main.c
+++ src/th_main.c
@@ -68,41 +68,10 @@
68 ** configuration ("user") database are currently open.
69 */
70 #define Th_IsRepositoryOpen() (g.repositoryOpen)
71 #define Th_IsConfigOpen() (g.zConfigDbName!=0)
72
73 /*
74 ** Global variable counting the number of outstanding calls to malloc()
75 ** made by the th1 implementation. This is used to catch memory leaks
76 ** in the interpreter. Obviously, it also means th1 is not threadsafe.
77 */
78 static int nOutstandingMalloc = 0;
79
80 /*
81 ** Implementations of malloc() and free() to pass to the interpreter.
82 */
83 static void *xMalloc(unsigned int n){
84 void *p = fossil_malloc(n);
85 if( p ){
86 nOutstandingMalloc++;
87 }
88 return p;
89 }
90 static void xFree(void *p){
91 if( p ){
92 nOutstandingMalloc--;
93 }
94 free(p);
95 }
96 static Th_Vtab vtab = { xMalloc, xFree };
97
98 /*
99 ** Returns the number of outstanding TH1 memory allocations.
100 */
101 int Th_GetOutstandingMalloc(){
102 return nOutstandingMalloc;
103 }
104
105 /*
106 ** Generate a TH1 trace message if debugging is enabled.
107 */
108 void Th_Trace(const char *zFormat, ...){
@@ -2387,11 +2356,11 @@
2387 }
2388 if( forceReset || forceTcl || g.interp==0 ){
2389 int created = 0;
2390 int i;
2391 if( g.interp==0 ){
2392 g.interp = Th_CreateInterp(&vtab);
2393 created = 1;
2394 }
2395 if( forceReset || created ){
2396 th_register_language(g.interp); /* Basic scripting commands. */
2397 }
2398
--- src/th_main.c
+++ src/th_main.c
@@ -68,41 +68,10 @@
68 ** configuration ("user") database are currently open.
69 */
70 #define Th_IsRepositoryOpen() (g.repositoryOpen)
71 #define Th_IsConfigOpen() (g.zConfigDbName!=0)
72
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
73
74 /*
75 ** Generate a TH1 trace message if debugging is enabled.
76 */
77 void Th_Trace(const char *zFormat, ...){
@@ -2387,11 +2356,11 @@
2356 }
2357 if( forceReset || forceTcl || g.interp==0 ){
2358 int created = 0;
2359 int i;
2360 if( g.interp==0 ){
2361 g.interp = Th_CreateInterp();
2362 created = 1;
2363 }
2364 if( forceReset || created ){
2365 th_register_language(g.interp); /* Basic scripting commands. */
2366 }
2367
+6
--- src/util.c
+++ src/util.c
@@ -58,10 +58,16 @@
5858
*/
5959
void *fossil_malloc(size_t n){
6060
void *p = malloc(n==0 ? 1 : n);
6161
if( p==0 ) fossil_panic("out of memory");
6262
return p;
63
+}
64
+void *fossil_malloc_zero(size_t n){
65
+ void *p = malloc(n==0 ? 1 : n);
66
+ if( p==0 ) fossil_panic("out of memory");
67
+ memset(p, 0, n);
68
+ return p;
6369
}
6470
void fossil_free(void *p){
6571
free(p);
6672
}
6773
void *fossil_realloc(void *p, size_t n){
6874
--- src/util.c
+++ src/util.c
@@ -58,10 +58,16 @@
58 */
59 void *fossil_malloc(size_t n){
60 void *p = malloc(n==0 ? 1 : n);
61 if( p==0 ) fossil_panic("out of memory");
62 return p;
 
 
 
 
 
 
63 }
64 void fossil_free(void *p){
65 free(p);
66 }
67 void *fossil_realloc(void *p, size_t n){
68
--- src/util.c
+++ src/util.c
@@ -58,10 +58,16 @@
58 */
59 void *fossil_malloc(size_t n){
60 void *p = malloc(n==0 ? 1 : n);
61 if( p==0 ) fossil_panic("out of memory");
62 return p;
63 }
64 void *fossil_malloc_zero(size_t n){
65 void *p = malloc(n==0 ? 1 : n);
66 if( p==0 ) fossil_panic("out of memory");
67 memset(p, 0, n);
68 return p;
69 }
70 void fossil_free(void *p){
71 free(p);
72 }
73 void *fossil_realloc(void *p, size_t n){
74

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button