better handling of static translation cache allocation, handle nested

execution paths from the cpu core, cleanups for KPX_MAX_CPUS == 1.
This commit is contained in:
gbeauche 2003-11-30 17:21:53 +00:00
parent c1dba58808
commit 4a3cd024ed
9 changed files with 62 additions and 59 deletions

View File

@ -118,9 +118,6 @@ public:
uint32 get_cr() const { return cr().get(); }
void set_cr(uint32 v) { cr().set(v); }
// Execution loop
void execute(uint32 entry, bool enable_cache = false);
// Execute 68k routine
void execute_68k(uint32 entry, M68kRegisters *r);
@ -244,12 +241,6 @@ void sheepshaver_cpu::execute_sheep(uint32 opcode)
}
}
// Execution loop
void sheepshaver_cpu::execute(uint32 entry, bool enable_cache)
{
powerpc_cpu::execute(entry, enable_cache);
}
// Handle MacOS interrupt
void sheepshaver_cpu::interrupt(uint32 entry)
{
@ -686,7 +677,7 @@ void emul_ppc(uint32 entry)
current_cpu->start_log();
#endif
// start emulation loop and enable code translation or caching
current_cpu->execute(entry, true);
current_cpu->execute(entry);
}
/*

View File

@ -28,8 +28,8 @@ int __op_jmp0, __op_jmp1;
#define DEFINE_GEN(NAME,ARGS) void basic_dyngen::NAME ARGS
#include "basic-dyngen-ops.hpp"
basic_dyngen::basic_dyngen(dyngen_cpu_base cpu)
: parent_cpu(cpu)
basic_dyngen::basic_dyngen(dyngen_cpu_base cpu, int cache_size)
: parent_cpu(cpu), basic_jit_cache(cache_size)
{
execute_func = gen_start();
gen_op_execute();

View File

@ -52,7 +52,7 @@ class basic_dyngen
public:
// Constructor, parent CPU required
basic_dyngen(dyngen_cpu_base cpu);
basic_dyngen(dyngen_cpu_base cpu, int cache_size = -1);
// Return CPU context associated to this code generator
dyngen_cpu_base cpu() const

View File

@ -30,10 +30,13 @@
#endif
#if STATIC_ICACHE_ALLOC
static uint8 g_translation_cache[basic_jit_cache::JIT_CACHE_SIZE];
const int G_TRANSLATION_CACHE_SIZE = 3 * 1024 * 1024; // 3 MB
static uint8 g_translation_cache[G_TRANSLATION_CACHE_SIZE];
static uint8 *g_translation_cache_p;
static uint8 *g_translation_cache_end_p;
#endif
basic_jit_cache::basic_jit_cache(uint32 init_cache_size)
basic_jit_cache::basic_jit_cache(int init_cache_size)
: tcode_start(NULL), code_start(NULL), code_p(NULL), code_end(NULL)
{
init_translation_cache(init_cache_size);
@ -45,16 +48,27 @@ basic_jit_cache::~basic_jit_cache()
}
bool
basic_jit_cache::init_translation_cache(uint32 size)
basic_jit_cache::init_translation_cache(int size)
{
// Round up translation cache size to next 16 KB boundaries
const uint32 roundup = 16 * 1024;
uint32 effective_cache_size = (size - JIT_CACHE_SIZE_GUARD) & -roundup;
cache_size = size & -roundup;
#if STATIC_ICACHE_ALLOC
if (g_translation_cache_p == 0) {
g_translation_cache_p = g_translation_cache;
g_translation_cache_end_p = g_translation_cache_p + G_TRANSLATION_CACHE_SIZE;
}
#endif
if (size == -1)
size = JIT_CACHE_SIZE;
// Round up translation cache size to next guard size boundaries boundaries
const uint32 roundup = JIT_CACHE_SIZE_GUARD;
cache_size = (size + roundup - 1) & -roundup;
assert(cache_size > 0);
#if STATIC_ICACHE_ALLOC
if (cache_size <= JIT_CACHE_SIZE) {
tcode_start = g_translation_cache;
if (cache_size <= (g_translation_cache_end_p - g_translation_cache_p)) {
tcode_start = g_translation_cache_p;
g_translation_cache_p += cache_size;
goto done;
}
#endif
@ -75,7 +89,7 @@ basic_jit_cache::init_translation_cache(uint32 size)
D(bug("basic_jit_cache: Translation cache: %d KB at %p\n", cache_size / 1024, tcode_start));
code_start = tcode_start;
code_p = code_start;
code_end = code_p + effective_cache_size;
code_end = code_p + size;
return true;
}
@ -84,8 +98,16 @@ basic_jit_cache::kill_translation_cache()
{
if (tcode_start) {
#if STATIC_ICACHE_ALLOC
if (cache_size > JIT_CACHE_SIZE)
if ((tcode_start - g_translation_cache) <= G_TRANSLATION_CACHE_SIZE) {
if (tcode_start == g_translation_cache_p - cache_size) {
D(bug("basic_jit_cache: Merge back free translation cache: %d KB at %p\n",
cache_size / 1024, tcode_start));
g_translation_cache_p -= cache_size;
}
return;
}
#endif
D(bug("basic_jit_cache: Release translation cache\n"));
vm_release(tcode_start, cache_size);
}
}

View File

@ -28,10 +28,8 @@
class basic_jit_cache
{
// Default cache size (2 MB)
public:
static const uint32 JIT_CACHE_SIZE = 2 * 1024 * 1024;
static const uint32 JIT_CACHE_SIZE_GUARD = 4096;
private:
uint32 cache_size;
// Translation cache (allocated base, current pointer, end pointer)
@ -43,7 +41,7 @@ private:
protected:
// Initialize translation cache
bool init_translation_cache(uint32 size);
bool init_translation_cache(int size);
void kill_translation_cache();
// Initialize user code start
@ -56,8 +54,8 @@ public:
public:
// Default constructor & destructor
basic_jit_cache(uint32 init_cache_size = JIT_CACHE_SIZE);
// Default constructor & destructor (use default JIT_CACHE_SIZE)
basic_jit_cache(int init_cache_size = -1);
~basic_jit_cache();
// Invalidate translation cache

View File

@ -37,20 +37,6 @@
#endif
/**
* PPC_NO_BASIC_CPU_BASE
*
* Define to not inherit from basic_cpu, thus removing two
* vtables. Otherwise, access to registers require an extra
* offset from "this" because vtables are stored before other
* regular members.
**/
#ifndef PPC_NO_BASIC_CPU_BASE
#undef PPC_NO_BASIC_CPU_BASE
#endif
/**
* PPC_NO_STATIC_II_INDEX_TABLE
*
@ -144,8 +130,7 @@
* Sanity checks and features enforcements
**/
#ifdef SHEEPSHAVER
#define PPC_NO_BASIC_CPU_BASE
#if KPX_MAX_CPUS == 1
#undef PPC_NO_STATIC_II_INDEX_TABLE
#endif

View File

@ -225,6 +225,7 @@ void powerpc_cpu::initialize()
init_decoder();
init_registers();
init_decode_cache();
execute_depth = 0;
// Init cache range invalidate recorder
cache_range.start = cache_range.end = 0;
@ -365,14 +366,16 @@ bool powerpc_cpu::check_spcflags()
return true;
}
void powerpc_cpu::execute(uint32 entry, bool enable_cache)
void powerpc_cpu::execute(uint32 entry)
{
pc() = entry;
#if PPC_EXECUTE_DUMP_STATE
const bool dump_state = true;
#endif
execute_depth++;
#if PPC_ENABLE_JIT
if (enable_cache) {
if (execute_depth == 1) {
for (;;) {
block_info *bi = compile_block(pc());
@ -382,7 +385,7 @@ void powerpc_cpu::execute(uint32 entry, bool enable_cache)
if (!spcflags().empty()) {
if (!check_spcflags())
return;
goto return_site;
// Force redecoding if cache was invalidated
if (spcflags().test(SPCFLAG_JIT_EXEC_RETURN)) {
@ -395,11 +398,11 @@ void powerpc_cpu::execute(uint32 entry, bool enable_cache)
break;
}
}
return;
goto return_site;
}
#endif
#if PPC_DECODE_CACHE
if (enable_cache) {
if (execute_depth == 1) {
for (;;) {
#if PPC_PROFILE_COMPILE_TIME
compile_count++;
@ -474,7 +477,7 @@ void powerpc_cpu::execute(uint32 entry, bool enable_cache)
if (!spcflags().empty()) {
if (!check_spcflags())
return;
goto return_site;
// Force redecoding if cache was invalidated
if (spcflags().test(SPCFLAG_JIT_EXEC_RETURN)) {
@ -487,7 +490,7 @@ void powerpc_cpu::execute(uint32 entry, bool enable_cache)
break;
}
}
return;
goto return_site;
}
#endif
for (;;) {
@ -508,8 +511,10 @@ void powerpc_cpu::execute(uint32 entry, bool enable_cache)
dump_registers();
#endif
if (!spcflags().empty() && !check_spcflags())
return;
goto return_site;
}
return_site:
--execute_depth;
}
void powerpc_cpu::execute()

View File

@ -33,7 +33,7 @@
#include <vector>
class powerpc_cpu
#ifndef PPC_NO_BASIC_CPU_BASE
#ifndef SHEEPSHAVER
: public basic_cpu
#endif
{
@ -200,10 +200,13 @@ private:
// Check special CPU flags
bool check_spcflags();
// Current execute() nested level
int execute_depth;
public:
// Initialization & finalization
#ifdef PPC_NO_BASIC_CPU_BASE
#ifdef SHEEPSHAVER
powerpc_cpu()
#if PPC_ENABLE_JIT
: codegen(this)
@ -238,7 +241,7 @@ public:
void fake_dump_registers(uint32);
// Start emulation loop
void execute(uint32 entry, bool enable_cache = true);
void execute(uint32 entry);
void execute();
// Interrupts handling
@ -311,7 +314,6 @@ private:
friend class powerpc_dyngen;
powerpc_dyngen codegen;
block_info *compile_block(uint32 entry);
powerpc_dyngen *codegen_ptr() { return &codegen; }
#endif
// Semantic action templates

View File

@ -73,8 +73,8 @@ public:
friend class powerpc_dyngen_helper;
// Default constructor
powerpc_dyngen(dyngen_cpu_base cpu)
: basic_dyngen(cpu)
powerpc_dyngen(dyngen_cpu_base cpu, int cache_size = -1)
: basic_dyngen(cpu, cache_size)
{ }
// Load/store registers