Commit 26a5f13b8eb1281d0552fe323e869806f3cefbfb

Authored by bellard
1 parent bed5cc52

variable dynamic translation buffer size

git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4600 c046a42c-6fe2-441c-8c8c-71466251a162
cpu-all.h
... ... @@ -767,6 +767,7 @@ int page_get_flags(target_ulong address);
767 767 void page_set_flags(target_ulong start, target_ulong end, int flags);
768 768 int page_check_range(target_ulong start, target_ulong len, int flags);
769 769  
  770 +void cpu_exec_init_all(unsigned long tb_size);
770 771 CPUState *cpu_copy(CPUState *env);
771 772  
772 773 void cpu_dump_state(CPUState *env, FILE *f,
... ...
darwin-user/main.c
... ... @@ -873,6 +873,7 @@ int main(int argc, char **argv)
873 873 #endif
874 874 }
875 875  
  876 + cpu_exec_init_all(0);
876 877 /* NOTE: we need to init the CPU at this stage to get
877 878 qemu_host_page_size */
878 879 env = cpu_init(cpu_model);
... ...
exec-all.h
... ... @@ -56,12 +56,6 @@ typedef void (GenOpFunc1)(long);
56 56 typedef void (GenOpFunc2)(long, long);
57 57 typedef void (GenOpFunc3)(long, long, long);
58 58  
59   -#if defined(TARGET_I386)
60   -
61   -void optimize_flags_init(void);
62   -
63   -#endif
64   -
65 59 extern FILE *logfile;
66 60 extern int loglevel;
67 61  
... ... @@ -105,31 +99,7 @@ static inline int tlb_set_page(CPUState *env1, target_ulong vaddr,
105 99 #define CODE_GEN_PHYS_HASH_BITS 15
106 100 #define CODE_GEN_PHYS_HASH_SIZE (1 << CODE_GEN_PHYS_HASH_BITS)
107 101  
108   -/* maximum total translate dcode allocated */
109   -
110   -/* NOTE: the translated code area cannot be too big because on some
111   - archs the range of "fast" function calls is limited. Here is a
112   - summary of the ranges:
113   -
114   - i386 : signed 32 bits
115   - arm : signed 26 bits
116   - ppc : signed 24 bits
117   - sparc : signed 32 bits
118   - alpha : signed 23 bits
119   -*/
120   -
121   -#if defined(__alpha__)
122   -#define CODE_GEN_BUFFER_SIZE (2 * 1024 * 1024)
123   -#elif defined(__ia64)
124   -#define CODE_GEN_BUFFER_SIZE (4 * 1024 * 1024) /* range of addl */
125   -#elif defined(__powerpc__)
126   -#define CODE_GEN_BUFFER_SIZE (6 * 1024 * 1024)
127   -#else
128   -/* XXX: make it dynamic on x86 */
129   -#define CODE_GEN_BUFFER_SIZE (64 * 1024 * 1024)
130   -#endif
131   -
132   -//#define CODE_GEN_BUFFER_SIZE (128 * 1024)
  102 +#define MIN_CODE_GEN_BUFFER_SIZE (1024 * 1024)
133 103  
134 104 /* estimated block size for TB allocation */
135 105 /* XXX: use a per code average code fragment size and modulate it
... ... @@ -140,8 +110,6 @@ static inline int tlb_set_page(CPUState *env1, target_ulong vaddr,
140 110 #define CODE_GEN_AVG_BLOCK_SIZE 64
141 111 #endif
142 112  
143   -#define CODE_GEN_MAX_BLOCKS (CODE_GEN_BUFFER_SIZE / CODE_GEN_AVG_BLOCK_SIZE)
144   -
145 113 #if defined(__powerpc__) || defined(__x86_64__) || defined(__arm__)
146 114 #define USE_DIRECT_JUMP
147 115 #endif
... ... @@ -210,9 +178,8 @@ void tb_link_phys(TranslationBlock *tb,
210 178 target_ulong phys_pc, target_ulong phys_page2);
211 179  
212 180 extern TranslationBlock *tb_phys_hash[CODE_GEN_PHYS_HASH_SIZE];
213   -
214   -extern uint8_t code_gen_buffer[CODE_GEN_BUFFER_SIZE];
215 181 extern uint8_t *code_gen_ptr;
  182 +extern int code_gen_max_blocks;
216 183  
217 184 #if defined(USE_DIRECT_JUMP)
218 185  
... ...
... ... @@ -58,9 +58,6 @@
58 58 #undef DEBUG_TB_CHECK
59 59 #endif
60 60  
61   -/* threshold to flush the translated code buffer */
62   -#define CODE_GEN_BUFFER_MAX_SIZE (CODE_GEN_BUFFER_SIZE - code_gen_max_block_size())
63   -
64 61 #define SMC_BITMAP_USE_THRESHOLD 10
65 62  
66 63 #define MMAP_AREA_START 0x00000000
... ... @@ -85,13 +82,17 @@
85 82 #endif
86 83  
87 84 TranslationBlock *tbs;
  85 +int code_gen_max_blocks;
88 86 TranslationBlock *tb_phys_hash[CODE_GEN_PHYS_HASH_SIZE];
89 87 int nb_tbs;
90 88 /* any access to the tbs or the page table must use this lock */
91 89 spinlock_t tb_lock = SPIN_LOCK_UNLOCKED;
92 90  
93 91 uint8_t code_gen_prologue[1024] __attribute__((aligned (32)));
94   -uint8_t code_gen_buffer[CODE_GEN_BUFFER_SIZE] __attribute__((aligned (32)));
  92 +uint8_t *code_gen_buffer;
  93 +unsigned long code_gen_buffer_size;
  94 +/* threshold to flush the translated code buffer */
  95 +unsigned long code_gen_buffer_max_size;
95 96 uint8_t *code_gen_ptr;
96 97  
97 98 ram_addr_t phys_ram_size;
... ... @@ -215,9 +216,6 @@ static void page_init(void)
215 216 #else
216 217 qemu_real_host_page_size = getpagesize();
217 218 #endif
218   - map_exec(code_gen_buffer, sizeof(code_gen_buffer));
219   - map_exec(code_gen_prologue, sizeof(code_gen_prologue));
220   -
221 219 if (qemu_host_page_size == 0)
222 220 qemu_host_page_size = qemu_real_host_page_size;
223 221 if (qemu_host_page_size < TARGET_PAGE_SIZE)
... ... @@ -328,18 +326,67 @@ static void tlb_unprotect_code_phys(CPUState *env, ram_addr_t ram_addr,
328 326 target_ulong vaddr);
329 327 #endif
330 328  
  329 +void code_gen_alloc(unsigned long tb_size)
  330 +{
  331 + code_gen_buffer_size = tb_size;
  332 + if (code_gen_buffer_size == 0) {
  333 + /* XXX: needs ajustments */
  334 + code_gen_buffer_size = (int)(phys_ram_size / 4);
  335 + }
  336 + if (code_gen_buffer_size < MIN_CODE_GEN_BUFFER_SIZE)
  337 + code_gen_buffer_size = MIN_CODE_GEN_BUFFER_SIZE;
  338 + /* The code gen buffer location may have constraints depending on
  339 + the host cpu and OS */
  340 +#if defined(__linux__)
  341 + {
  342 + int flags;
  343 + flags = MAP_PRIVATE | MAP_ANONYMOUS;
  344 +#if defined(__x86_64__)
  345 + flags |= MAP_32BIT;
  346 + /* Cannot map more than that */
  347 + if (code_gen_buffer_size > (800 * 1024 * 1024))
  348 + code_gen_buffer_size = (800 * 1024 * 1024);
  349 +#endif
  350 + code_gen_buffer = mmap(NULL, code_gen_buffer_size,
  351 + PROT_WRITE | PROT_READ | PROT_EXEC,
  352 + flags, -1, 0);
  353 + if (code_gen_buffer == MAP_FAILED) {
  354 + fprintf(stderr, "Could not allocate dynamic translator buffer\n");
  355 + exit(1);
  356 + }
  357 + }
  358 +#else
  359 + code_gen_buffer = qemu_malloc(code_gen_buffer_size);
  360 + if (!code_gen_buffer) {
  361 + fprintf(stderr, "Could not allocate dynamic translator buffer\n");
  362 + exit(1);
  363 + }
  364 + map_exec(code_gen_buffer, code_gen_buffer_size);
  365 +#endif
  366 + map_exec(code_gen_prologue, sizeof(code_gen_prologue));
  367 + code_gen_buffer_max_size = code_gen_buffer_size -
  368 + code_gen_max_block_size();
  369 + code_gen_max_blocks = code_gen_buffer_size / CODE_GEN_AVG_BLOCK_SIZE;
  370 + tbs = qemu_malloc(code_gen_max_blocks * sizeof(TranslationBlock));
  371 +}
  372 +
  373 +/* Must be called before using the QEMU cpus. 'tb_size' is the size
  374 + (in bytes) allocated to the translation buffer. Zero means default
  375 + size. */
  376 +void cpu_exec_init_all(unsigned long tb_size)
  377 +{
  378 + page_init();
  379 + cpu_gen_init();
  380 + code_gen_alloc(tb_size);
  381 + code_gen_ptr = code_gen_buffer;
  382 + io_mem_init();
  383 +}
  384 +
331 385 void cpu_exec_init(CPUState *env)
332 386 {
333 387 CPUState **penv;
334 388 int cpu_index;
335 389  
336   - if (!code_gen_ptr) {
337   - cpu_gen_init();
338   - tbs = qemu_malloc(CODE_GEN_MAX_BLOCKS * sizeof(TranslationBlock));
339   - code_gen_ptr = code_gen_buffer;
340   - page_init();
341   - io_mem_init();
342   - }
343 390 env->next_cpu = NULL;
344 391 penv = &first_cpu;
345 392 cpu_index = 0;
... ... @@ -390,7 +437,7 @@ void tb_flush(CPUState *env1)
390 437 nb_tbs, nb_tbs > 0 ?
391 438 ((unsigned long)(code_gen_ptr - code_gen_buffer)) / nb_tbs : 0);
392 439 #endif
393   - if ((unsigned long)(code_gen_ptr - code_gen_buffer) > CODE_GEN_BUFFER_SIZE)
  440 + if ((unsigned long)(code_gen_ptr - code_gen_buffer) > code_gen_buffer_size)
394 441 cpu_abort(env1, "Internal error: code buffer overflow\n");
395 442  
396 443 nb_tbs = 0;
... ... @@ -960,8 +1007,8 @@ TranslationBlock *tb_alloc(target_ulong pc)
960 1007 {
961 1008 TranslationBlock *tb;
962 1009  
963   - if (nb_tbs >= CODE_GEN_MAX_BLOCKS ||
964   - (code_gen_ptr - code_gen_buffer) >= CODE_GEN_BUFFER_MAX_SIZE)
  1010 + if (nb_tbs >= code_gen_max_blocks ||
  1011 + (code_gen_ptr - code_gen_buffer) >= code_gen_buffer_max_size)
965 1012 return NULL;
966 1013 tb = &tbs[nb_tbs++];
967 1014 tb->pc = pc;
... ... @@ -2990,7 +3037,10 @@ void dump_exec_info(FILE *f,
2990 3037 }
2991 3038 /* XXX: avoid using doubles ? */
2992 3039 cpu_fprintf(f, "Translation buffer state:\n");
2993   - cpu_fprintf(f, "TB count %d\n", nb_tbs);
  3040 + cpu_fprintf(f, "gen code size %ld/%ld\n",
  3041 + code_gen_ptr - code_gen_buffer, code_gen_buffer_max_size);
  3042 + cpu_fprintf(f, "TB count %d/%d\n",
  3043 + nb_tbs, code_gen_max_blocks);
2994 3044 cpu_fprintf(f, "TB avg target size %d max=%d bytes\n",
2995 3045 nb_tbs ? target_code_size / nb_tbs : 0,
2996 3046 max_target_code_size);
... ...
linux-user/main.c
... ... @@ -2115,6 +2115,7 @@ int main(int argc, char **argv)
2115 2115 cpu_model = "any";
2116 2116 #endif
2117 2117 }
  2118 + cpu_exec_init_all(0);
2118 2119 /* NOTE: we need to init the CPU at this stage to get
2119 2120 qemu_host_page_size */
2120 2121 env = cpu_init(cpu_model);
... ...
target-i386/cpu.h
... ... @@ -723,6 +723,8 @@ static inline int cpu_mmu_index (CPUState *env)
723 723 return (env->hflags & HF_CPL_MASK) == 3 ? 1 : 0;
724 724 }
725 725  
  726 +void optimize_flags_init(void);
  727 +
726 728 typedef struct CCTable {
727 729 int (*compute_all)(void); /* return all the flags */
728 730 int (*compute_c)(void); /* return the C flag */
... ...
... ... @@ -7378,6 +7378,7 @@ enum {
7378 7378 QEMU_OPTION_old_param,
7379 7379 QEMU_OPTION_clock,
7380 7380 QEMU_OPTION_startdate,
  7381 + QEMU_OPTION_tb_size,
7381 7382 };
7382 7383  
7383 7384 typedef struct QEMUOption {
... ... @@ -7489,6 +7490,7 @@ const QEMUOption qemu_options[] = {
7489 7490 #endif
7490 7491 { "clock", HAS_ARG, QEMU_OPTION_clock },
7491 7492 { "startdate", HAS_ARG, QEMU_OPTION_startdate },
  7493 + { "tb-size", HAS_ARG, QEMU_OPTION_tb_size },
7492 7494 { NULL },
7493 7495 };
7494 7496  
... ... @@ -7697,6 +7699,7 @@ int main(int argc, char **argv)
7697 7699 const char *usb_devices[MAX_USB_CMDLINE];
7698 7700 int usb_devices_index;
7699 7701 int fds[2];
  7702 + int tb_size;
7700 7703 const char *pid_file = NULL;
7701 7704 VLANState *vlan;
7702 7705  
... ... @@ -7768,8 +7771,9 @@ int main(int argc, char **argv)
7768 7771 hda_index = -1;
7769 7772  
7770 7773 nb_nics = 0;
7771   - /* default mac address of the first network interface */
7772 7774  
  7775 + tb_size = 0;
  7776 +
7773 7777 optind = 1;
7774 7778 for(;;) {
7775 7779 if (optind >= argc)
... ... @@ -8296,6 +8300,11 @@ int main(int argc, char **argv)
8296 8300 }
8297 8301 }
8298 8302 break;
  8303 + case QEMU_OPTION_tb_size:
  8304 + tb_size = strtol(optarg, NULL, 0);
  8305 + if (tb_size < 0)
  8306 + tb_size = 0;
  8307 + break;
8299 8308 }
8300 8309 }
8301 8310 }
... ... @@ -8467,6 +8476,9 @@ int main(int argc, char **argv)
8467 8476 exit(1);
8468 8477 }
8469 8478  
  8479 + /* init the dynamic translator */
  8480 + cpu_exec_init_all(tb_size * 1024 * 1024);
  8481 +
8470 8482 bdrv_init();
8471 8483  
8472 8484 /* we always create the cdrom drive, even if no disk is there */
... ...