summaryrefslogtreecommitdiffstatshomepage
path: root/src
diff options
context:
space:
mode:
author Olivier Galibert <galibert@pobox.com>2011-06-01 13:00:12 +0000
committer Olivier Galibert <galibert@pobox.com>2011-06-01 13:00:12 +0000
commitb0a4945735307355809ec15e344952e914251bdd (patch)
treef78a17c87c7e07f1d1b3f6565fa7ffb2d9c19b81 /src
parentf90cbff557a35389b702ba03383db39e6468a613 (diff)
Revert "memory: Change the gc into a refcounter, for speed reasons. [O. Galibert]"
This reverts commit 5deef5b2c6fabdea8cd45ccf71c99f56940e88a2. Broken, sorry.
Diffstat (limited to 'src')
-rw-r--r--src/emu/memory.c120
1 files changed, 52 insertions, 68 deletions
diff --git a/src/emu/memory.c b/src/emu/memory.c
index 98789c5e5e9..041a2fd45e2 100644
--- a/src/emu/memory.c
+++ b/src/emu/memory.c
@@ -837,6 +837,7 @@ protected:
// table population/depopulation
void populate_range_mirrored(offs_t bytestart, offs_t byteend, offs_t bytemirror, UINT8 handler);
void populate_range(offs_t bytestart, offs_t byteend, UINT8 handler);
+ void depopulate_unused();
// subtable management
UINT8 subtable_alloc();
@@ -873,29 +874,7 @@ protected:
static UINT8 s_watchpoint_table[1 << LEVEL1_BITS];
private:
- int handler_refcount[SUBTABLE_BASE-STATIC_COUNT];
- UINT8 handler_next_free[SUBTABLE_BASE-STATIC_COUNT];
- UINT8 handler_free;
UINT8 get_free_handler();
-
- void handler_ref(UINT8 entry, int count)
- {
- assert(entry < SUBTABLE_BASE);
- if (entry >= STATIC_COUNT)
- handler_refcount[entry - STATIC_COUNT] += count;
- }
-
- void handler_unref(UINT8 entry)
- {
- assert(entry < SUBTABLE_BASE);
- if (entry >= STATIC_COUNT)
- if (! --handler_refcount[entry - STATIC_COUNT])
- {
- handler(entry).deconfigure();
- handler_next_free[entry - STATIC_COUNT] = handler_free;
- handler_free = entry;
- }
- }
};
@@ -3228,15 +3207,6 @@ address_table::address_table(address_space &space, bool large)
// initialize everything to unmapped
memset(m_table, STATIC_UNMAP, 1 << LEVEL1_BITS);
-
- // initialize the handlers freelist
- for (int i=0; i != SUBTABLE_BASE-STATIC_COUNT-1; i++)
- handler_next_free[i] = i+STATIC_COUNT+1;
- handler_next_free[SUBTABLE_BASE-STATIC_COUNT-1] = STATIC_INVALID;
- handler_free = STATIC_COUNT;
-
- // initialize the handlers refcounts
- memset(handler_refcount, 0, sizeof(handler_refcount));
}
@@ -3284,12 +3254,18 @@ void address_table::map_range(offs_t addrstart, offs_t addrend, offs_t addrmask,
UINT8 address_table::get_free_handler()
{
- if (handler_free == STATIC_INVALID)
- throw emu_fatalerror("Out of handler entries in address table");
+ // scan all possible assigned entries for something unpopulated
+ for (UINT8 scanentry = STATIC_COUNT; scanentry < SUBTABLE_BASE; scanentry++)
+ if (!handler(scanentry).populated())
+ return scanentry;
+
+ // if we didn't find anything, find something to depopulate and try again
+ depopulate_unused();
+ for (UINT8 scanentry = STATIC_COUNT; scanentry < SUBTABLE_BASE; scanentry++)
+ if (!handler(scanentry).populated())
+ return scanentry;
- UINT8 handler = handler_free;
- handler_free = handler_next_free[handler - STATIC_COUNT];
- return handler;
+ throw emu_fatalerror("Out of handler entries in address table");
}
@@ -3443,24 +3419,13 @@ void address_table::populate_range(offs_t bytestart, offs_t byteend, UINT8 handl
// if the start and stop end within the same block, handle that
if (l1start == l1stop)
{
- for (int i = l2start; i <= l2stop; i++)
- {
- handler_unref(subtable[i]);
- subtable[i] = handlerindex;
- }
- handler_ref(handlerindex, l2stop-l2start+1);
+ memset(&subtable[l2start], handlerindex, l2stop - l2start + 1);
subtable_close(l1start);
return;
}
// otherwise, fill until the end
- int max = 1 << level2_bits();
- for (int i = l2start; i < max; i++)
- {
- handler_unref(subtable[i]);
- subtable[i] = handlerindex;
- }
- handler_ref(handlerindex, max - l2start);
+ memset(&subtable[l2start], handlerindex, (1 << level2_bits()) - l2start);
subtable_close(l1start);
if (l1start != (offs_t)~0)
l1start++;
@@ -3472,12 +3437,7 @@ void address_table::populate_range(offs_t bytestart, offs_t byteend, UINT8 handl
UINT8 *subtable = subtable_open(l1stop);
// fill from the beginning
- for (int i = 0; i <= l2stop; i++)
- {
- handler_unref(subtable[i]);
- subtable[i] = handlerindex;
- }
- handler_ref(handlerindex, l2stop+1);
+ memset(&subtable[0], handlerindex, l2stop + 1);
subtable_close(l1stop);
// if the start and stop end within the same block, handle that
@@ -3490,22 +3450,11 @@ void address_table::populate_range(offs_t bytestart, offs_t byteend, UINT8 handl
// now fill in the middle tables
for (offs_t l1index = l1start; l1index <= l1stop; l1index++)
{
- UINT8 subindex = m_table[l1index];
-
// if we have a subtable here, release it
- if (m_table[l1index] >= SUBTABLE_BASE) {
- UINT8 *subtable = subtable_open(subindex);
- int max = 1 << level2_bits();
- for (int i = l2start; i < max; i++)
- handler_unref(subtable[i]);
- subtable_close(subindex);
- subtable_release(subindex);
- } else
- handler_unref(subindex);
-
+ if (m_table[l1index] >= SUBTABLE_BASE)
+ subtable_release(m_table[l1index]);
m_table[l1index] = handlerindex;
}
- handler_ref(handlerindex, l1stop - l1start + 1);
}
@@ -3595,6 +3544,41 @@ void address_table::populate_range_mirrored(offs_t bytestart, offs_t byteend, of
//-------------------------------------------------
+// depopulate_unused - scan the table and
+// eliminate entries that are no longer used
+//-------------------------------------------------
+
+void address_table::depopulate_unused()
+{
+ bool used[SUBTABLE_BASE - STATIC_COUNT];
+ memset(used, 0, sizeof(used));
+
+ for (int level1 = 0; level1 != 1 << LEVEL1_BITS; level1++)
+ {
+ UINT8 l1_entry = m_table[level1];
+ if (l1_entry >= SUBTABLE_BASE)
+ {
+ assert(m_large);
+ const UINT8 *subtable = subtable_ptr(l1_entry);
+ for (int level2 = 0; level2 != 1 << LEVEL2_BITS; level2++)
+ {
+ UINT8 l2_entry = subtable[level2];
+ assert(l2_entry < SUBTABLE_BASE);
+ if (l2_entry >= STATIC_COUNT)
+ used[l2_entry - STATIC_COUNT] = true;
+ }
+ }
+ else if (l1_entry >= STATIC_COUNT)
+ used[l1_entry - STATIC_COUNT] = true;
+ }
+
+ for (int slot=0; slot != SUBTABLE_BASE - STATIC_COUNT; slot++)
+ if (!used[slot])
+ handler(slot + STATIC_COUNT).deconfigure();
+}
+
+
+//-------------------------------------------------
// derive_range - look up the entry for a memory
// range, and then compute the extent of that
// range based on the lookup tables