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,6 +767,7 @@ int page_get_flags(target_ulong address);
767 void page_set_flags(target_ulong start, target_ulong end, int flags); 767 void page_set_flags(target_ulong start, target_ulong end, int flags);
768 int page_check_range(target_ulong start, target_ulong len, int flags); 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 CPUState *cpu_copy(CPUState *env); 771 CPUState *cpu_copy(CPUState *env);
771 772
772 void cpu_dump_state(CPUState *env, FILE *f, 773 void cpu_dump_state(CPUState *env, FILE *f,
darwin-user/main.c
@@ -873,6 +873,7 @@ int main(int argc, char **argv) @@ -873,6 +873,7 @@ int main(int argc, char **argv)
873 #endif 873 #endif
874 } 874 }
875 875
  876 + cpu_exec_init_all(0);
876 /* NOTE: we need to init the CPU at this stage to get 877 /* NOTE: we need to init the CPU at this stage to get
877 qemu_host_page_size */ 878 qemu_host_page_size */
878 env = cpu_init(cpu_model); 879 env = cpu_init(cpu_model);
exec-all.h
@@ -56,12 +56,6 @@ typedef void (GenOpFunc1)(long); @@ -56,12 +56,6 @@ typedef void (GenOpFunc1)(long);
56 typedef void (GenOpFunc2)(long, long); 56 typedef void (GenOpFunc2)(long, long);
57 typedef void (GenOpFunc3)(long, long, long); 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 extern FILE *logfile; 59 extern FILE *logfile;
66 extern int loglevel; 60 extern int loglevel;
67 61
@@ -105,31 +99,7 @@ static inline int tlb_set_page(CPUState *env1, target_ulong vaddr, @@ -105,31 +99,7 @@ static inline int tlb_set_page(CPUState *env1, target_ulong vaddr,
105 #define CODE_GEN_PHYS_HASH_BITS 15 99 #define CODE_GEN_PHYS_HASH_BITS 15
106 #define CODE_GEN_PHYS_HASH_SIZE (1 << CODE_GEN_PHYS_HASH_BITS) 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 /* estimated block size for TB allocation */ 104 /* estimated block size for TB allocation */
135 /* XXX: use a per code average code fragment size and modulate it 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,8 +110,6 @@ static inline int tlb_set_page(CPUState *env1, target_ulong vaddr,
140 #define CODE_GEN_AVG_BLOCK_SIZE 64 110 #define CODE_GEN_AVG_BLOCK_SIZE 64
141 #endif 111 #endif
142 112
143 -#define CODE_GEN_MAX_BLOCKS (CODE_GEN_BUFFER_SIZE / CODE_GEN_AVG_BLOCK_SIZE)  
144 -  
145 #if defined(__powerpc__) || defined(__x86_64__) || defined(__arm__) 113 #if defined(__powerpc__) || defined(__x86_64__) || defined(__arm__)
146 #define USE_DIRECT_JUMP 114 #define USE_DIRECT_JUMP
147 #endif 115 #endif
@@ -210,9 +178,8 @@ void tb_link_phys(TranslationBlock *tb, @@ -210,9 +178,8 @@ void tb_link_phys(TranslationBlock *tb,
210 target_ulong phys_pc, target_ulong phys_page2); 178 target_ulong phys_pc, target_ulong phys_page2);
211 179
212 extern TranslationBlock *tb_phys_hash[CODE_GEN_PHYS_HASH_SIZE]; 180 extern TranslationBlock *tb_phys_hash[CODE_GEN_PHYS_HASH_SIZE];
213 -  
214 -extern uint8_t code_gen_buffer[CODE_GEN_BUFFER_SIZE];  
215 extern uint8_t *code_gen_ptr; 181 extern uint8_t *code_gen_ptr;
  182 +extern int code_gen_max_blocks;
216 183
217 #if defined(USE_DIRECT_JUMP) 184 #if defined(USE_DIRECT_JUMP)
218 185
@@ -58,9 +58,6 @@ @@ -58,9 +58,6 @@
58 #undef DEBUG_TB_CHECK 58 #undef DEBUG_TB_CHECK
59 #endif 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 #define SMC_BITMAP_USE_THRESHOLD 10 61 #define SMC_BITMAP_USE_THRESHOLD 10
65 62
66 #define MMAP_AREA_START 0x00000000 63 #define MMAP_AREA_START 0x00000000
@@ -85,13 +82,17 @@ @@ -85,13 +82,17 @@
85 #endif 82 #endif
86 83
87 TranslationBlock *tbs; 84 TranslationBlock *tbs;
  85 +int code_gen_max_blocks;
88 TranslationBlock *tb_phys_hash[CODE_GEN_PHYS_HASH_SIZE]; 86 TranslationBlock *tb_phys_hash[CODE_GEN_PHYS_HASH_SIZE];
89 int nb_tbs; 87 int nb_tbs;
90 /* any access to the tbs or the page table must use this lock */ 88 /* any access to the tbs or the page table must use this lock */
91 spinlock_t tb_lock = SPIN_LOCK_UNLOCKED; 89 spinlock_t tb_lock = SPIN_LOCK_UNLOCKED;
92 90
93 uint8_t code_gen_prologue[1024] __attribute__((aligned (32))); 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 uint8_t *code_gen_ptr; 96 uint8_t *code_gen_ptr;
96 97
97 ram_addr_t phys_ram_size; 98 ram_addr_t phys_ram_size;
@@ -215,9 +216,6 @@ static void page_init(void) @@ -215,9 +216,6 @@ static void page_init(void)
215 #else 216 #else
216 qemu_real_host_page_size = getpagesize(); 217 qemu_real_host_page_size = getpagesize();
217 #endif 218 #endif
218 - map_exec(code_gen_buffer, sizeof(code_gen_buffer));  
219 - map_exec(code_gen_prologue, sizeof(code_gen_prologue));  
220 -  
221 if (qemu_host_page_size == 0) 219 if (qemu_host_page_size == 0)
222 qemu_host_page_size = qemu_real_host_page_size; 220 qemu_host_page_size = qemu_real_host_page_size;
223 if (qemu_host_page_size < TARGET_PAGE_SIZE) 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,18 +326,67 @@ static void tlb_unprotect_code_phys(CPUState *env, ram_addr_t ram_addr,
328 target_ulong vaddr); 326 target_ulong vaddr);
329 #endif 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 void cpu_exec_init(CPUState *env) 385 void cpu_exec_init(CPUState *env)
332 { 386 {
333 CPUState **penv; 387 CPUState **penv;
334 int cpu_index; 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 env->next_cpu = NULL; 390 env->next_cpu = NULL;
344 penv = &first_cpu; 391 penv = &first_cpu;
345 cpu_index = 0; 392 cpu_index = 0;
@@ -390,7 +437,7 @@ void tb_flush(CPUState *env1) @@ -390,7 +437,7 @@ void tb_flush(CPUState *env1)
390 nb_tbs, nb_tbs > 0 ? 437 nb_tbs, nb_tbs > 0 ?
391 ((unsigned long)(code_gen_ptr - code_gen_buffer)) / nb_tbs : 0); 438 ((unsigned long)(code_gen_ptr - code_gen_buffer)) / nb_tbs : 0);
392 #endif 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 cpu_abort(env1, "Internal error: code buffer overflow\n"); 441 cpu_abort(env1, "Internal error: code buffer overflow\n");
395 442
396 nb_tbs = 0; 443 nb_tbs = 0;
@@ -960,8 +1007,8 @@ TranslationBlock *tb_alloc(target_ulong pc) @@ -960,8 +1007,8 @@ TranslationBlock *tb_alloc(target_ulong pc)
960 { 1007 {
961 TranslationBlock *tb; 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 return NULL; 1012 return NULL;
966 tb = &tbs[nb_tbs++]; 1013 tb = &tbs[nb_tbs++];
967 tb->pc = pc; 1014 tb->pc = pc;
@@ -2990,7 +3037,10 @@ void dump_exec_info(FILE *f, @@ -2990,7 +3037,10 @@ void dump_exec_info(FILE *f,
2990 } 3037 }
2991 /* XXX: avoid using doubles ? */ 3038 /* XXX: avoid using doubles ? */
2992 cpu_fprintf(f, "Translation buffer state:\n"); 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 cpu_fprintf(f, "TB avg target size %d max=%d bytes\n", 3044 cpu_fprintf(f, "TB avg target size %d max=%d bytes\n",
2995 nb_tbs ? target_code_size / nb_tbs : 0, 3045 nb_tbs ? target_code_size / nb_tbs : 0,
2996 max_target_code_size); 3046 max_target_code_size);
linux-user/main.c
@@ -2115,6 +2115,7 @@ int main(int argc, char **argv) @@ -2115,6 +2115,7 @@ int main(int argc, char **argv)
2115 cpu_model = "any"; 2115 cpu_model = "any";
2116 #endif 2116 #endif
2117 } 2117 }
  2118 + cpu_exec_init_all(0);
2118 /* NOTE: we need to init the CPU at this stage to get 2119 /* NOTE: we need to init the CPU at this stage to get
2119 qemu_host_page_size */ 2120 qemu_host_page_size */
2120 env = cpu_init(cpu_model); 2121 env = cpu_init(cpu_model);
target-i386/cpu.h
@@ -723,6 +723,8 @@ static inline int cpu_mmu_index (CPUState *env) @@ -723,6 +723,8 @@ static inline int cpu_mmu_index (CPUState *env)
723 return (env->hflags & HF_CPL_MASK) == 3 ? 1 : 0; 723 return (env->hflags & HF_CPL_MASK) == 3 ? 1 : 0;
724 } 724 }
725 725
  726 +void optimize_flags_init(void);
  727 +
726 typedef struct CCTable { 728 typedef struct CCTable {
727 int (*compute_all)(void); /* return all the flags */ 729 int (*compute_all)(void); /* return all the flags */
728 int (*compute_c)(void); /* return the C flag */ 730 int (*compute_c)(void); /* return the C flag */
@@ -7378,6 +7378,7 @@ enum { @@ -7378,6 +7378,7 @@ enum {
7378 QEMU_OPTION_old_param, 7378 QEMU_OPTION_old_param,
7379 QEMU_OPTION_clock, 7379 QEMU_OPTION_clock,
7380 QEMU_OPTION_startdate, 7380 QEMU_OPTION_startdate,
  7381 + QEMU_OPTION_tb_size,
7381 }; 7382 };
7382 7383
7383 typedef struct QEMUOption { 7384 typedef struct QEMUOption {
@@ -7489,6 +7490,7 @@ const QEMUOption qemu_options[] = { @@ -7489,6 +7490,7 @@ const QEMUOption qemu_options[] = {
7489 #endif 7490 #endif
7490 { "clock", HAS_ARG, QEMU_OPTION_clock }, 7491 { "clock", HAS_ARG, QEMU_OPTION_clock },
7491 { "startdate", HAS_ARG, QEMU_OPTION_startdate }, 7492 { "startdate", HAS_ARG, QEMU_OPTION_startdate },
  7493 + { "tb-size", HAS_ARG, QEMU_OPTION_tb_size },
7492 { NULL }, 7494 { NULL },
7493 }; 7495 };
7494 7496
@@ -7697,6 +7699,7 @@ int main(int argc, char **argv) @@ -7697,6 +7699,7 @@ int main(int argc, char **argv)
7697 const char *usb_devices[MAX_USB_CMDLINE]; 7699 const char *usb_devices[MAX_USB_CMDLINE];
7698 int usb_devices_index; 7700 int usb_devices_index;
7699 int fds[2]; 7701 int fds[2];
  7702 + int tb_size;
7700 const char *pid_file = NULL; 7703 const char *pid_file = NULL;
7701 VLANState *vlan; 7704 VLANState *vlan;
7702 7705
@@ -7768,8 +7771,9 @@ int main(int argc, char **argv) @@ -7768,8 +7771,9 @@ int main(int argc, char **argv)
7768 hda_index = -1; 7771 hda_index = -1;
7769 7772
7770 nb_nics = 0; 7773 nb_nics = 0;
7771 - /* default mac address of the first network interface */  
7772 7774
  7775 + tb_size = 0;
  7776 +
7773 optind = 1; 7777 optind = 1;
7774 for(;;) { 7778 for(;;) {
7775 if (optind >= argc) 7779 if (optind >= argc)
@@ -8296,6 +8300,11 @@ int main(int argc, char **argv) @@ -8296,6 +8300,11 @@ int main(int argc, char **argv)
8296 } 8300 }
8297 } 8301 }
8298 break; 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,6 +8476,9 @@ int main(int argc, char **argv)
8467 exit(1); 8476 exit(1);
8468 } 8477 }
8469 8478
  8479 + /* init the dynamic translator */
  8480 + cpu_exec_init_all(tb_size * 1024 * 1024);
  8481 +
8470 bdrv_init(); 8482 bdrv_init();
8471 8483
8472 /* we always create the cdrom drive, even if no disk is there */ 8484 /* we always create the cdrom drive, even if no disk is there */