Demand paging on Windows
This commit is contained in:
@@ -7,3 +7,10 @@
|
|||||||
#define CONFIG_CMPXCHG128 1
|
#define CONFIG_CMPXCHG128 1
|
||||||
// #define CONFIG_ATOMIC64 1
|
// #define CONFIG_ATOMIC64 1
|
||||||
#define CONFIG_PLUGIN 1
|
#define CONFIG_PLUGIN 1
|
||||||
|
|
||||||
|
// QEMU by default allocates (and commits) 1GB memory on Windows, and multiple Unicorn instances will result in OOM error easily.
|
||||||
|
// Unfortunately, Windows doesn't have a similar demand paging feature like mmap(), therefore a workaround is to use tcg regions mechanism.
|
||||||
|
// Note most Unicorn hacks (and even QEMU!) relies on the assumption that the translation memory won't run out and thus it might result
|
||||||
|
// in some unexpected errors. If that is case, define to align with QEMU and Unicorn <= 2.0.1 behavior.
|
||||||
|
//
|
||||||
|
// #define USE_STATIC_CODE_GEN_BUFFER
|
||||||
@@ -869,6 +869,7 @@ static inline void *alloc_code_gen_buffer(struct uc_struct *uc)
|
|||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
#elif defined(_WIN32)
|
#elif defined(_WIN32)
|
||||||
|
#ifdef USE_STATIC_CODE_GEN_BUFFER
|
||||||
static inline void *alloc_code_gen_buffer(struct uc_struct *uc)
|
static inline void *alloc_code_gen_buffer(struct uc_struct *uc)
|
||||||
{
|
{
|
||||||
TCGContext *tcg_ctx = uc->tcg_ctx;
|
TCGContext *tcg_ctx = uc->tcg_ctx;
|
||||||
@@ -876,6 +877,23 @@ static inline void *alloc_code_gen_buffer(struct uc_struct *uc)
|
|||||||
return VirtualAlloc(NULL, size, MEM_RESERVE | MEM_COMMIT,
|
return VirtualAlloc(NULL, size, MEM_RESERVE | MEM_COMMIT,
|
||||||
PAGE_EXECUTE_READWRITE);
|
PAGE_EXECUTE_READWRITE);
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
static inline void *alloc_code_gen_buffer(struct uc_struct *uc)
|
||||||
|
{
|
||||||
|
TCGContext *tcg_ctx = uc->tcg_ctx;
|
||||||
|
size_t size = tcg_ctx->code_gen_buffer_size;
|
||||||
|
|
||||||
|
void* ptr = VirtualAlloc(NULL, size, MEM_RESERVE,
|
||||||
|
PAGE_EXECUTE_READWRITE);
|
||||||
|
|
||||||
|
// for prolog init
|
||||||
|
VirtualAlloc(ptr,
|
||||||
|
uc->qemu_real_host_page_size * UC_TCG_REGION_PAGES_COUNT,
|
||||||
|
MEM_COMMIT,
|
||||||
|
PAGE_EXECUTE_READWRITE);
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
void free_code_gen_buffer(struct uc_struct *uc)
|
void free_code_gen_buffer(struct uc_struct *uc)
|
||||||
{
|
{
|
||||||
TCGContext *tcg_ctx = uc->tcg_ctx;
|
TCGContext *tcg_ctx = uc->tcg_ctx;
|
||||||
|
|||||||
@@ -20,6 +20,7 @@
|
|||||||
#ifndef QEMU_CPU_H
|
#ifndef QEMU_CPU_H
|
||||||
#define QEMU_CPU_H
|
#define QEMU_CPU_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
#include "exec/hwaddr.h"
|
#include "exec/hwaddr.h"
|
||||||
#include "exec/memattrs.h"
|
#include "exec/memattrs.h"
|
||||||
#include "qemu/bitmap.h"
|
#include "qemu/bitmap.h"
|
||||||
|
|||||||
@@ -35,6 +35,11 @@
|
|||||||
#include "tcg-apple-jit.h"
|
#include "tcg-apple-jit.h"
|
||||||
#include "qemu/int128.h"
|
#include "qemu/int128.h"
|
||||||
|
|
||||||
|
// Unicorn: Default region size for win32
|
||||||
|
#if defined(_WIN32) && !defined(USE_STATIC_CODE_GEN_BUFFER)
|
||||||
|
#define UC_TCG_REGION_PAGES_COUNT (128)
|
||||||
|
#endif
|
||||||
|
|
||||||
/* XXX: make safe guess about sizes */
|
/* XXX: make safe guess about sizes */
|
||||||
#define MAX_OP_PER_INSTR 266
|
#define MAX_OP_PER_INSTR 266
|
||||||
|
|
||||||
|
|||||||
@@ -23,6 +23,8 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/* define it to use liveness analysis (better code) */
|
/* define it to use liveness analysis (better code) */
|
||||||
|
#include "tcg/tcg.h"
|
||||||
|
#include <stdio.h>
|
||||||
#define USE_TCG_OPTIMIZATIONS
|
#define USE_TCG_OPTIMIZATIONS
|
||||||
|
|
||||||
#include "qemu/osdep.h"
|
#include "qemu/osdep.h"
|
||||||
@@ -406,6 +408,13 @@ static void tcg_region_assign(TCGContext *s, size_t curr_region)
|
|||||||
s->code_gen_buffer = start;
|
s->code_gen_buffer = start;
|
||||||
s->code_gen_ptr = start;
|
s->code_gen_ptr = start;
|
||||||
s->code_gen_buffer_size = (char *)end - (char *)start;
|
s->code_gen_buffer_size = (char *)end - (char *)start;
|
||||||
|
#if defined(WIN32) && !defined(USE_STATIC_CODE_GEN_BUFFER)
|
||||||
|
VirtualAlloc(
|
||||||
|
s->code_gen_buffer,
|
||||||
|
ROUND_UP(s->code_gen_buffer_size, s->uc->qemu_real_host_page_size),
|
||||||
|
MEM_COMMIT,
|
||||||
|
PAGE_EXECUTE_READWRITE);
|
||||||
|
#endif
|
||||||
memset(s->code_gen_buffer, 0x00, s->code_gen_buffer_size);
|
memset(s->code_gen_buffer, 0x00, s->code_gen_buffer_size);
|
||||||
s->code_gen_highwater = (char *)end - TCG_HIGHWATER;
|
s->code_gen_highwater = (char *)end - TCG_HIGHWATER;
|
||||||
}
|
}
|
||||||
@@ -500,7 +509,11 @@ void tcg_region_init(TCGContext *tcg_ctx)
|
|||||||
size_t n_regions;
|
size_t n_regions;
|
||||||
size_t i;
|
size_t i;
|
||||||
|
|
||||||
|
#if defined(WIN32) && !defined(USE_STATIC_CODE_GEN_BUFFER)
|
||||||
|
n_regions = size / (tcg_ctx->uc->qemu_real_host_page_size * UC_TCG_REGION_PAGES_COUNT);
|
||||||
|
#else
|
||||||
n_regions = 1;
|
n_regions = 1;
|
||||||
|
#endif
|
||||||
|
|
||||||
/* The first region will be 'aligned - buf' bytes larger than the others */
|
/* The first region will be 'aligned - buf' bytes larger than the others */
|
||||||
aligned = (void *)QEMU_ALIGN_PTR_UP(buf, page_size);
|
aligned = (void *)QEMU_ALIGN_PTR_UP(buf, page_size);
|
||||||
@@ -537,6 +550,11 @@ void tcg_region_init(TCGContext *tcg_ctx)
|
|||||||
}
|
}
|
||||||
|
|
||||||
tcg_ctx->tree = g_tree_new(tb_tc_cmp);
|
tcg_ctx->tree = g_tree_new(tb_tc_cmp);
|
||||||
|
|
||||||
|
#if defined(WIN32) && !defined(USE_STATIC_CODE_GEN_BUFFER)
|
||||||
|
// Allocate a region immediately, or the highwater is not set correctly.
|
||||||
|
tcg_region_alloc(tcg_ctx);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
Reference in New Issue
Block a user