From 46550a475b3efb3dacd58e3df8635f41dfa9b0c4 Mon Sep 17 00:00:00 2001 From: Aaron Giles Date: Thu, 10 Mar 2011 07:06:21 +0000 Subject: [PATCH] Non-debug builds need to free those memory_entries. Fixes enormous memory consumption when iterating through all drivers like -romident does. Also moved softlist scanning into the main loop so that machine_configs are only constructed once. --- src/emu/clifront.c | 68 ++++++-------- src/emu/emualloc.c | 142 +++++++++++++++------------- src/emu/emualloc.h | 226 ++++++++++++++++++++++----------------------- 3 files changed, 219 insertions(+), 217 deletions(-) diff --git a/src/emu/clifront.c b/src/emu/clifront.c index d21a32e994b..84ef0745d35 100644 --- a/src/emu/clifront.c +++ b/src/emu/clifront.c @@ -1068,49 +1068,43 @@ static void info_listsoftware(emu_options &options, const char *gamename) softlist_match_roms - scan for a matching software ROM by hash -------------------------------------------------*/ -static void softlist_match_roms(emu_options &options, const hash_collection &hashes, int length, int *found) +void softlist_match_roms(machine_config &config, emu_options &options, const hash_collection &hashes, int length, int *found) { - /* iterate over drivers */ - for (int drvindex = 0; drivers[drvindex] != NULL; drvindex++) + for (const device_config *dev = config.m_devicelist.first(SOFTWARE_LIST); dev != NULL; dev = dev->typenext()) { - machine_config config(*drivers[drvindex]); + software_list_config *swlist = (software_list_config *)downcast(dev)->inline_config(); - for (const device_config *dev = config.m_devicelist.first(SOFTWARE_LIST); dev != NULL; dev = dev->typenext()) + for ( int i = 0; i < DEVINFO_STR_SWLIST_MAX - DEVINFO_STR_SWLIST_0; i++ ) { - software_list_config *swlist = (software_list_config *)downcast(dev)->inline_config(); - - for ( int i = 0; i < DEVINFO_STR_SWLIST_MAX - DEVINFO_STR_SWLIST_0; i++ ) + if ( swlist->list_name[i] ) { - if ( swlist->list_name[i] ) + software_list *list = software_list_open( options, swlist->list_name[i], FALSE, NULL ); + + for ( software_info *swinfo = software_list_find( list, "*", NULL ); swinfo != NULL; swinfo = software_list_find( list, "*", swinfo ) ) { - software_list *list = software_list_open( options, swlist->list_name[i], FALSE, NULL ); - - for ( software_info *swinfo = software_list_find( list, "*", NULL ); swinfo != NULL; swinfo = software_list_find( list, "*", swinfo ) ) + for ( software_part *part = software_find_part( swinfo, NULL, NULL ); part != NULL; part = software_part_next( part ) ) { - for ( software_part *part = software_find_part( swinfo, NULL, NULL ); part != NULL; part = software_part_next( part ) ) + for ( const rom_entry *region = part->romdata; region != NULL; region = rom_next_region(region) ) { - for ( const rom_entry *region = part->romdata; region != NULL; region = rom_next_region(region) ) + for ( const rom_entry *rom = rom_first_file(region); rom != NULL; rom = rom_next_file(rom) ) { - for ( const rom_entry *rom = rom_first_file(region); rom != NULL; rom = rom_next_file(rom) ) + hash_collection romhashes(ROM_GETHASHDATA(rom)); + if ( hashes == romhashes ) { - hash_collection romhashes(ROM_GETHASHDATA(rom)); - if ( hashes == romhashes ) - { - bool baddump = romhashes.flag(hash_collection::FLAG_BAD_DUMP); + bool baddump = romhashes.flag(hash_collection::FLAG_BAD_DUMP); - /* output information about the match */ - if (*found != 0) - mame_printf_info(" "); - mame_printf_info("= %s%-20s %s:%s %s\n", baddump ? "(BAD) " : "", ROM_GETNAME(rom), swlist->list_name[i], swinfo->shortname, swinfo->longname); - (*found)++; - } + /* output information about the match */ + if (*found != 0) + mame_printf_info(" "); + mame_printf_info("= %s%-20s %s:%s %s\n", baddump ? "(BAD) " : "", ROM_GETNAME(rom), swlist->list_name[i], swinfo->shortname, swinfo->longname); + (*found)++; } } } } - - software_list_close( list ); } + + software_list_close( list ); } } } @@ -1507,8 +1501,7 @@ static void identify_data(emu_options &options, const char *name, const UINT8 *d status->matches++; /* free any temporary JED data */ - if (tempjed != NULL) - global_free(tempjed); + global_free(tempjed); } @@ -1518,19 +1511,15 @@ static void identify_data(emu_options &options, const char *name, const UINT8 *d static void match_roms(emu_options &options, const hash_collection &hashes, int length, int *found) { - int drvindex; - /* iterate over drivers */ - for (drvindex = 0; drivers[drvindex] != NULL; drvindex++) + for (int drvindex = 0; drivers[drvindex] != NULL; drvindex++) { machine_config config(*drivers[drvindex]); - const rom_entry *region, *rom; - const rom_source *source; /* iterate over sources, regions and files within the region */ - for (source = rom_first_source(config); source != NULL; source = rom_next_source(*source)) - for (region = rom_first_region(*source); region; region = rom_next_region(region)) - for (rom = rom_first_file(region); rom; rom = rom_next_file(rom)) + for (const rom_source *source = rom_first_source(config); source != NULL; source = rom_next_source(*source)) + for (const rom_entry *region = rom_first_region(*source); region; region = rom_next_region(region)) + for (const rom_entry *rom = rom_first_file(region); rom; rom = rom_next_file(rom)) { hash_collection romhashes(ROM_GETHASHDATA(rom)); if (!romhashes.flag(hash_collection::FLAG_NO_DUMP) && hashes == romhashes) @@ -1544,7 +1533,8 @@ static void match_roms(emu_options &options, const hash_collection &hashes, int (*found)++; } } - } - softlist_match_roms( options, hashes, length, found ); + // also check any softlists + softlist_match_roms( config, options, hashes, length, found ); + } } diff --git a/src/emu/emualloc.c b/src/emu/emualloc.c index c9734a36c9c..75b972e0eeb 100644 --- a/src/emu/emualloc.c +++ b/src/emu/emualloc.c @@ -41,6 +41,14 @@ #include "coreutil.h" +//************************************************************************** +// DEBUGGING +//************************************************************************** + +#define LOG_ALLOCS (0) + + + //************************************************************************** // CONSTANTS //************************************************************************** @@ -122,10 +130,10 @@ memory_entry *memory_entry::s_freehead = NULL; // GLOBAL HELPERS //************************************************************************** -/*------------------------------------------------- - malloc_file_line - allocate memory with file - and line number information --------------------------------------------------*/ +//------------------------------------------------- +// malloc_file_line - allocate memory with file +// and line number information +//------------------------------------------------- void *malloc_file_line(size_t size, const char *file, int line) { @@ -146,10 +154,10 @@ void *malloc_file_line(size_t size, const char *file, int line) } -/*------------------------------------------------- - free_file_line - free memory with file - and line number information --------------------------------------------------*/ +//------------------------------------------------- +// free_file_line - free memory with file +// and line number information +//------------------------------------------------- void free_file_line(void *memory, const char *file, int line) { @@ -167,21 +175,19 @@ void free_file_line(void *memory, const char *file, int line) #ifdef MAME_DEBUG // clear memory to a bogus value memset(memory, 0xfc, entry->m_size); - - // free the entry and the memory - if (entry != NULL) - memory_entry::release(entry); #endif + // free the entry and the memory + memory_entry::release(entry); osd_free(memory); } -/*------------------------------------------------- - dump_unfreed_mem - called from the exit path - of any code that wants to check for unfreed - memory --------------------------------------------------*/ +//------------------------------------------------- +// dump_unfreed_mem - called from the exit path +// of any code that wants to check for unfreed +// memory +//------------------------------------------------- void dump_unfreed_mem(void) { @@ -196,10 +202,10 @@ void dump_unfreed_mem(void) // RESOURCE POOL //************************************************************************** -/*------------------------------------------------- - resource_pool - constructor for a new resource - pool --------------------------------------------------*/ +//------------------------------------------------- +// resource_pool - constructor for a new resource +// pool +//------------------------------------------------- resource_pool::resource_pool() : m_listlock(osd_lock_alloc()), @@ -210,11 +216,11 @@ resource_pool::resource_pool() } -/*------------------------------------------------- - ~resource_pool - destructor for a resource - pool; make sure all tracked objects are - deleted --------------------------------------------------*/ +//------------------------------------------------- +// ~resource_pool - destructor for a resource +// pool; make sure all tracked objects are +// deleted +//------------------------------------------------- resource_pool::~resource_pool() { @@ -224,9 +230,9 @@ resource_pool::~resource_pool() } -/*------------------------------------------------- - add - add a new item to the resource pool --------------------------------------------------*/ +//------------------------------------------------- +// add - add a new item to the resource pool +//------------------------------------------------- void resource_pool::add(resource_pool_item &item) { @@ -244,6 +250,8 @@ void resource_pool::add(resource_pool_item &item) entry = memory_entry::find(reinterpret_cast(item.m_ptr) - sizeof(size_t)); assert(entry != NULL); item.m_id = entry->m_id; + if (LOG_ALLOCS) + fprintf(stderr, "#%06d, add %d bytes (%s:%d)\n", (UINT32)entry->m_id, static_cast(entry->m_size), entry->m_file, (int)entry->m_line); // find the entry to insert after resource_pool_item *insert_after; @@ -277,10 +285,10 @@ void resource_pool::add(resource_pool_item &item) } -/*------------------------------------------------- - remove - remove a specific item from the - resource pool --------------------------------------------------*/ +//------------------------------------------------- +// remove - remove a specific item from the +// resource pool +//------------------------------------------------- void resource_pool::remove(void *ptr) { @@ -312,6 +320,8 @@ void resource_pool::remove(void *ptr) m_ordered_tail = deleteme->m_ordered_prev; // delete the object and break + if (LOG_ALLOCS) + fprintf(stderr, "#%06d, delete %d bytes\n", (UINT32)deleteme->m_id, static_cast(deleteme->m_size)); delete deleteme; break; } @@ -320,10 +330,10 @@ void resource_pool::remove(void *ptr) } -/*------------------------------------------------- - find - find a specific item in the resource - pool --------------------------------------------------*/ +//------------------------------------------------- +// find - find a specific item in the resource +// pool +//------------------------------------------------- resource_pool_item *resource_pool::find(void *ptr) { @@ -342,10 +352,10 @@ resource_pool_item *resource_pool::find(void *ptr) } -/*------------------------------------------------- - contains - return true if given ptr is - contained by one of the objects in the pool --------------------------------------------------*/ +//------------------------------------------------- +// contains - return true if given ptr is +// contained by one of the objects in the pool +//------------------------------------------------- bool resource_pool::contains(void *_ptrstart, void *_ptrend) { @@ -371,9 +381,9 @@ found: } -/*------------------------------------------------- - clear - remove all items from a resource pool --------------------------------------------------*/ +//------------------------------------------------- +// clear - remove all items from a resource pool +//------------------------------------------------- void resource_pool::clear() { @@ -393,10 +403,10 @@ void resource_pool::clear() // MEMORY ENTRY //************************************************************************** -/*------------------------------------------------- - acquire_lock - acquire the memory entry lock, - creating a new one if needed --------------------------------------------------*/ +//------------------------------------------------- +// acquire_lock - acquire the memory entry lock, +// creating a new one if needed +//------------------------------------------------- void memory_entry::acquire_lock() { @@ -414,9 +424,9 @@ void memory_entry::acquire_lock() } -/*------------------------------------------------- - release_lock - release the memory entry lock --------------------------------------------------*/ +//------------------------------------------------- +// release_lock - release the memory entry lock +//------------------------------------------------- void memory_entry::release_lock() { @@ -424,9 +434,9 @@ void memory_entry::release_lock() } -/*------------------------------------------------- - allocate - allocate a new memory entry --------------------------------------------------*/ +//------------------------------------------------- +// allocate - allocate a new memory entry +//------------------------------------------------- memory_entry *memory_entry::allocate(size_t size, void *base, const char *file, int line) { @@ -461,6 +471,8 @@ memory_entry *memory_entry::allocate(size_t size, void *base, const char *file, entry->m_file = file; entry->m_line = line; entry->m_id = s_curid++; + if (LOG_ALLOCS) + fprintf(stderr, "#%06d, alloc %d bytes (%s:%d)\n", (UINT32)entry->m_id, static_cast(entry->m_size), entry->m_file, (int)entry->m_line); // add it to the alloc list int hashval = reinterpret_cast(base) % k_hash_prime; @@ -475,9 +487,9 @@ memory_entry *memory_entry::allocate(size_t size, void *base, const char *file, } -/*------------------------------------------------- - find - find a memory entry --------------------------------------------------*/ +//------------------------------------------------- +// find - find a memory entry +//------------------------------------------------- memory_entry *memory_entry::find(void *ptr) { @@ -499,9 +511,9 @@ memory_entry *memory_entry::find(void *ptr) } -/*------------------------------------------------- - release - release a memory entry --------------------------------------------------*/ +//------------------------------------------------- +// release - release a memory entry +//------------------------------------------------- void memory_entry::release(memory_entry *entry) { @@ -524,10 +536,10 @@ void memory_entry::release(memory_entry *entry) } -/*------------------------------------------------- - report_unfreed - print a list of unfreed - memory to the target file --------------------------------------------------*/ +//------------------------------------------------- +// report_unfreed - print a list of unfreed +// memory to the target file +//------------------------------------------------- void memory_entry::report_unfreed() { @@ -543,7 +555,7 @@ void memory_entry::report_unfreed() if (total == 0) fprintf(stderr, "--- memory leak warning ---\n"); total += entry->m_size; - fprintf(stderr, "allocation #%06d, %d bytes (%s:%d)\n", (UINT32)entry->m_id, static_cast(entry->m_size), entry->m_file, (int)entry->m_line); + fprintf(stderr, "#%06d, nofree %d bytes (%s:%d)\n", (UINT32)entry->m_id, static_cast(entry->m_size), entry->m_file, (int)entry->m_line); } release_lock(); diff --git a/src/emu/emualloc.h b/src/emu/emualloc.h index 10aa43a04e6..0a26fcad3ec 100644 --- a/src/emu/emualloc.h +++ b/src/emu/emualloc.h @@ -67,13 +67,125 @@ //************************************************************************** -// TYPE DEFINITIONS +// FUNCTION PROTOTYPES +//************************************************************************** + +// allocate memory with file and line number information +void *malloc_file_line(size_t size, const char *file, int line); + +// free memory with file and line number information +void free_file_line(void *memory, const char *file, int line); + +// called from the exit path of any code that wants to check for unfreed memory +void dump_unfreed_mem(); + + + +//************************************************************************** +// INLINE FUNCTIONS //************************************************************************** // zeromem_t is a dummy class used to tell new to zero memory after allocation class zeromem_t { }; +// standard new/delete operators (try to avoid using) +ATTR_FORCE_INLINE inline void *operator new(std::size_t size) throw (std::bad_alloc) +{ + void *result = malloc_file_line(size, NULL, 0); + if (result == NULL) + throw std::bad_alloc(); + return result; +} + +ATTR_FORCE_INLINE inline void *operator new[](std::size_t size) throw (std::bad_alloc) +{ + void *result = malloc_file_line(size, NULL, 0); + if (result == NULL) + throw std::bad_alloc(); + return result; +} + +ATTR_FORCE_INLINE inline void operator delete(void *ptr) throw() +{ + if (ptr != NULL) + free_file_line(ptr, NULL, 0); +} + +ATTR_FORCE_INLINE inline void operator delete[](void *ptr) throw() +{ + if (ptr != NULL) + free_file_line(ptr, NULL, 0); +} + + +// file/line new/delete operators +ATTR_FORCE_INLINE inline void *operator new(std::size_t size, const char *file, int line) throw (std::bad_alloc) +{ + void *result = malloc_file_line(size, file, line); + if (result == NULL) + throw std::bad_alloc(); + return result; +} + +ATTR_FORCE_INLINE inline void *operator new[](std::size_t size, const char *file, int line) throw (std::bad_alloc) +{ + void *result = malloc_file_line(size, file, line); + if (result == NULL) + throw std::bad_alloc(); + return result; +} + +ATTR_FORCE_INLINE inline void operator delete(void *ptr, const char *file, int line) +{ + if (ptr != NULL) + free_file_line(ptr, file, line); +} + +ATTR_FORCE_INLINE inline void operator delete[](void *ptr, const char *file, int line) +{ + if (ptr != NULL) + free_file_line(ptr, file, line); +} + + +// file/line new/delete operators with zeroing +ATTR_FORCE_INLINE inline void *operator new(std::size_t size, const char *file, int line, const zeromem_t &) throw (std::bad_alloc) +{ + void *result = malloc_file_line(size, file, line); + if (result == NULL) + throw std::bad_alloc(); + memset(result, 0, size); + return result; +} + +ATTR_FORCE_INLINE inline void *operator new[](std::size_t size, const char *file, int line, const zeromem_t &) throw (std::bad_alloc) +{ + void *result = malloc_file_line(size, file, line); + if (result == NULL) + throw std::bad_alloc(); + memset(result, 0, size); + return result; +} + +ATTR_FORCE_INLINE inline void operator delete(void *ptr, const char *file, int line, const zeromem_t &) +{ + if (ptr != NULL) + free_file_line(ptr, file, line); +} + +ATTR_FORCE_INLINE inline void operator delete[](void *ptr, const char *file, int line, const zeromem_t &) +{ + if (ptr != NULL) + free_file_line(ptr, file, line); +} + + + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + // resource_pool_item is a base class for items that are tracked by a resource pool class resource_pool_item { @@ -184,118 +296,6 @@ extern const zeromem_t zeromem; -//************************************************************************** -// FUNCTION PROTOTYPES -//************************************************************************** - -// allocate memory with file and line number information -void *malloc_file_line(size_t size, const char *file, int line); - -// free memory with file and line number information -void free_file_line(void *memory, const char *file, int line); - -// called from the exit path of any code that wants to check for unfreed memory -void dump_unfreed_mem(); - - - -//************************************************************************** -// INLINE FUNCTIONS -//************************************************************************** - -// standard new/delete operators (try to avoid using) -ATTR_FORCE_INLINE inline void *operator new(std::size_t size) throw (std::bad_alloc) -{ - void *result = malloc_file_line(size, NULL, 0); - if (result == NULL) - throw std::bad_alloc(); - return result; -} - -ATTR_FORCE_INLINE inline void *operator new[](std::size_t size) throw (std::bad_alloc) -{ - void *result = malloc_file_line(size, NULL, 0); - if (result == NULL) - throw std::bad_alloc(); - return result; -} - -ATTR_FORCE_INLINE inline void operator delete(void *ptr) throw() -{ - if (ptr != NULL) - free_file_line(ptr, NULL, 0); -} - -ATTR_FORCE_INLINE inline void operator delete[](void *ptr) throw() -{ - if (ptr != NULL) - free_file_line(ptr, NULL, 0); -} - - -// file/line new/delete operators -ATTR_FORCE_INLINE inline void *operator new(std::size_t size, const char *file, int line) throw (std::bad_alloc) -{ - void *result = malloc_file_line(size, file, line); - if (result == NULL) - throw std::bad_alloc(); - return result; -} - -ATTR_FORCE_INLINE inline void *operator new[](std::size_t size, const char *file, int line) throw (std::bad_alloc) -{ - void *result = malloc_file_line(size, file, line); - if (result == NULL) - throw std::bad_alloc(); - return result; -} - -ATTR_FORCE_INLINE inline void operator delete(void *ptr, const char *file, int line) -{ - if (ptr != NULL) - free_file_line(ptr, file, line); -} - -ATTR_FORCE_INLINE inline void operator delete[](void *ptr, const char *file, int line) -{ - if (ptr != NULL) - free_file_line(ptr, file, line); -} - - -// file/line new/delete operators with zeroing -ATTR_FORCE_INLINE inline void *operator new(std::size_t size, const char *file, int line, const zeromem_t &) throw (std::bad_alloc) -{ - void *result = malloc_file_line(size, file, line); - if (result == NULL) - throw std::bad_alloc(); - memset(result, 0, size); - return result; -} - -ATTR_FORCE_INLINE inline void *operator new[](std::size_t size, const char *file, int line, const zeromem_t &) throw (std::bad_alloc) -{ - void *result = malloc_file_line(size, file, line); - if (result == NULL) - throw std::bad_alloc(); - memset(result, 0, size); - return result; -} - -ATTR_FORCE_INLINE inline void operator delete(void *ptr, const char *file, int line, const zeromem_t &) -{ - if (ptr != NULL) - free_file_line(ptr, file, line); -} - -ATTR_FORCE_INLINE inline void operator delete[](void *ptr, const char *file, int line, const zeromem_t &) -{ - if (ptr != NULL) - free_file_line(ptr, file, line); -} - - - //************************************************************************** // ADDDITIONAL MACROS //**************************************************************************