@@ -42,11 +42,10 @@ template<unsigned BASE_CAPACITY, unsigned POOL_SIZE> struct TableRepMap {
4242 TableRepMap ()
4343 : entries(static_cast <ustring::TableRep**>(
4444 calloc (BASE_CAPACITY, sizeof (ustring::TableRep*))))
45- , pool(static_cast <char *>(malloc(POOL_SIZE)))
46- , memory_usage(sizeof (*this ) + POOL_SIZE
45+ , memory_usage(sizeof (*this )
4746 + sizeof(ustring::TableRep*) * BASE_CAPACITY)
4847 {
49- all_pools. push_back (pool );
48+ allocate_pool_block ( );
5049 }
5150
5251 ~TableRepMap ()
@@ -63,23 +62,19 @@ template<unsigned BASE_CAPACITY, unsigned POOL_SIZE> struct TableRepMap {
6362 entries[i]->~TableRep ();
6463 }
6564 // Free all pool allocations and large individual allocations.
66- for (char * p : all_pools)
67- free (p);
6865 all_pools.clear ();
69- for (char * p : large_allocs)
70- free (p);
66+ all_pools.shrink_to_fit ();
7167 large_allocs.clear ();
68+ large_allocs.shrink_to_fit ();
7269 free (entries);
7370 // Re-initialize to a fresh, usable state.
7471 mask = BASE_CAPACITY - 1 ;
7572 entries = static_cast <ustring::TableRep**>(
7673 calloc (BASE_CAPACITY, sizeof (ustring::TableRep*)));
77- pool = static_cast <char *>(malloc (POOL_SIZE));
78- pool_offset = 0 ;
7974 num_entries = 0 ;
80- memory_usage = sizeof (*this ) + POOL_SIZE
75+ memory_usage = sizeof (*this )
8176 + sizeof (ustring::TableRep*) * BASE_CAPACITY;
82- all_pools. push_back (pool );
77+ allocate_pool_block ( );
8378 }
8479
8580 size_t get_memory_usage ()
@@ -212,6 +207,9 @@ template<unsigned BASE_CAPACITY, unsigned POOL_SIZE> struct TableRepMap {
212207 return new (repmem) ustring::TableRep (str, hash);
213208 }
214209
210+ // Allocate `len` bytes from the pool. Allocate a new pool block if len
211+ // doesn't fit in the current block. In the unlikely even that len > the
212+ // pool block size, do a separate allocation just for it.
215213 char * pool_alloc (size_t len)
216214 {
217215 // round up to nearest multiple of pointer size to guarantee proper alignment of TableRep objects
@@ -220,30 +218,36 @@ template<unsigned BASE_CAPACITY, unsigned POOL_SIZE> struct TableRepMap {
220218
221219 if (len >= POOL_SIZE) {
222220 memory_usage += len;
223- char * p = ( char *) malloc ( len) ;
224- large_allocs.push_back (p);
221+ char * p = new char [ len] ;
222+ large_allocs.emplace_back (p);
225223 return p;
226224 }
227225 if (pool_offset + len > POOL_SIZE) {
228- memory_usage += POOL_SIZE;
229- pool = (char *)malloc (POOL_SIZE);
230- pool_offset = 0 ;
231- all_pools.push_back (pool);
226+ allocate_pool_block ();
232227 }
233228 char * result = pool + pool_offset;
234229 pool_offset += len;
235230 return result;
236231 }
237232
233+ // Allocate one more standard POOL_SIZE block for `pool`
234+ void allocate_pool_block ()
235+ {
236+ memory_usage += POOL_SIZE;
237+ pool = new char [POOL_SIZE];
238+ pool_offset = 0 ;
239+ all_pools.emplace_back (pool);
240+ }
241+
238242 OIIO_CACHE_ALIGN mutable ustring_mutex_t mutex;
239- size_t mask = BASE_CAPACITY - 1 ;
240- ustring::TableRep** entries;
241- size_t num_entries = 0 ;
242- char * pool;
243- size_t pool_offset = 0 ;
244- size_t memory_usage;
245- std::vector<char * > all_pools;
246- std::vector<char * > large_allocs;
243+ size_t mask = BASE_CAPACITY - 1 ;
244+ ustring::TableRep** entries = nullptr ;
245+ size_t num_entries = 0 ;
246+ char * pool = nullptr ; // Current pool block we're using
247+ size_t pool_offset = 0 ; // Next offset within current block
248+ size_t memory_usage = 0 ; // Total memory usage
249+ std::vector<std::unique_ptr< char []> > all_pools;
250+ std::vector<std::unique_ptr< char []> > large_allocs;
247251#ifdef USTRING_TRACK_NUM_LOOKUPS
248252 size_t num_lookups = 0 ;
249253#endif
@@ -741,6 +745,10 @@ OIIO_UTIL_API int oiio_ustring_cleanup = Strutil::stoi(
741745static int ustring_cleanup_atexit_registered = []() {
742746 std::atexit ([]() {
743747 if (pvt::oiio_ustring_cleanup) {
748+ #ifndef NDEBUG
749+ OIIO::print (" ustring: freeing table resources ({} bytes)\n " ,
750+ v3_1::ustring_table ().get_memory_usage ());
751+ #endif
744752 v3_1::ustring_table ().clear ();
745753 v3_1::reverse_map ().clear ();
746754 }
0 commit comments