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.
This commit is contained in:
Aaron Giles 2011-03-10 07:06:21 +00:00
parent d49ead22c9
commit 46550a475b
3 changed files with 219 additions and 217 deletions

View File

@ -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<const legacy_device_config_base *>(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<const legacy_device_config_base *>(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 );
}
}

View File

@ -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<UINT8 *>(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<UINT32>(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<UINT32>(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<UINT32>(entry->m_size), entry->m_file, (int)entry->m_line);
// add it to the alloc list
int hashval = reinterpret_cast<FPTR>(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<UINT32>(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<UINT32>(entry->m_size), entry->m_file, (int)entry->m_line);
}
release_lock();

View File

@ -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
//**************************************************************************