Statically allocate the translation cache on PowerPC. This makes it possible

to generate direct bl instructions for function invokation.
This commit is contained in:
gbeauche 2003-11-27 00:26:35 +00:00
parent e30001bc00
commit 36ce9c07e6
3 changed files with 55 additions and 3 deletions

View File

@ -606,6 +606,34 @@ if [[ "x$EMULATED_PPC" = "xyes" ]]; then
fi
CPUSRCS="$CPUSRCS ../kpx_cpu/sheepshaver_glue.cpp"
fi
if [[ "x$ac_cv_use_dyngen" = "xyes" ]]; then
AC_CACHE_CHECK([whether static data regions are executable],
ac_cv_have_static_data_exec, [
AC_TRY_RUN([int main(void) {
#if defined(__powerpc__)
static unsigned int p[8] = {0x4e800020,};
asm volatile("dcbst 0,%0" : : "r" (p) : "memory");
asm volatile("sync" : : : "memory");
asm volatile("icbi 0,%0" : : "r" (p) : "memory");
asm volatile("sync" : : : "memory");
asm volatile("isync" : : : "memory");
((void (*)(void))p)();
return 0;
#endif
#if defined(__i386__)
static unsigned char p[] = {0xc3};
((void (*)(void))p)();
return 0;
#endif
return 1;
}], ac_cv_have_static_data_exec=yes, ac_cv_have_static_data_exec=no,
dnl When cross-compiling, do not assume anything.
ac_cv_have_static_data_exec=no
)
])
fi
AC_TRANSLATE_DEFINE(HAVE_STATIC_DATA_EXEC, "$ac_cv_have_static_data_exec",
[Define if your system marks static data pages as executable.])
dnl Generate Makefile.
AC_SUBST(DYNGENSRCS)

View File

@ -25,6 +25,16 @@
#define DEBUG 0
#include "debug.h"
// FIXME: Define this only for SheepShaver. Kheperix will need
// something like KPX_MAX_CPUS == 1.
#ifndef SHEEPSHAVER
#undef HAVE_STATIC_DATA_EXEC
#endif
#if HAVE_STATIC_DATA_EXEC
static uint8 g_translation_cache[basic_jit_cache::JIT_CACHE_SIZE];
#endif
basic_jit_cache::basic_jit_cache(uint32 init_cache_size)
: tcode_start(NULL), code_start(NULL), code_p(NULL), code_end(NULL)
{
@ -41,8 +51,15 @@ basic_jit_cache::init_translation_cache(uint32 size)
{
// Round up translation cache size to next 16 KB boundaries
const uint32 roundup = 16 * 1024;
cache_size = (size + JIT_CACHE_SIZE_GUARD + roundup - 1) & -roundup;
uint32 effective_cache_size = (size - JIT_CACHE_SIZE_GUARD) & -roundup;
cache_size = size & -roundup;
#if HAVE_STATIC_DATA_EXEC
if (cache_size <= JIT_CACHE_SIZE) {
tcode_start = g_translation_cache;
goto done;
}
#endif
tcode_start = (uint8 *)vm_acquire(cache_size, VM_MAP_PRIVATE | VM_MAP_32BIT);
if (tcode_start == VM_MAP_FAILED) {
tcode_start = NULL;
@ -56,16 +73,21 @@ basic_jit_cache::init_translation_cache(uint32 size)
return false;
}
done:
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 + cache_size;
code_end = code_p + effective_cache_size;
return true;
}
void
basic_jit_cache::kill_translation_cache()
{
if (tcode_start)
if (tcode_start) {
#if HAVE_STATIC_DATA_EXEC
if (cache_size > JIT_CACHE_SIZE)
#endif
vm_release(tcode_start, cache_size);
}
}

View File

@ -28,8 +28,10 @@
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)