Revision 0b0d3320 translate-all.c
b/translate-all.c | ||
---|---|---|
72 | 72 |
|
73 | 73 |
#define SMC_BITMAP_USE_THRESHOLD 10 |
74 | 74 |
|
75 |
/* Code generation and translation blocks */
|
|
75 |
/* Translation blocks */
|
|
76 | 76 |
static TranslationBlock *tbs; |
77 |
static int code_gen_max_blocks; |
|
78 | 77 |
TranslationBlock *tb_phys_hash[CODE_GEN_PHYS_HASH_SIZE]; |
79 | 78 |
static int nb_tbs; |
80 | 79 |
/* any access to the tbs or the page table must use this lock */ |
81 | 80 |
spinlock_t tb_lock = SPIN_LOCK_UNLOCKED; |
82 | 81 |
|
83 |
uint8_t *code_gen_prologue; |
|
84 |
static uint8_t *code_gen_buffer; |
|
85 |
static size_t code_gen_buffer_size; |
|
86 |
/* threshold to flush the translated code buffer */ |
|
87 |
static size_t code_gen_buffer_max_size; |
|
88 |
static uint8_t *code_gen_ptr; |
|
89 |
|
|
90 | 82 |
typedef struct PageDesc { |
91 | 83 |
/* list of TBs intersecting this ram page */ |
92 | 84 |
TranslationBlock *first_tb; |
... | ... | |
514 | 506 |
if (tb_size > MAX_CODE_GEN_BUFFER_SIZE) { |
515 | 507 |
tb_size = MAX_CODE_GEN_BUFFER_SIZE; |
516 | 508 |
} |
517 |
code_gen_buffer_size = tb_size; |
|
509 |
tcg_ctx.code_gen_buffer_size = tb_size;
|
|
518 | 510 |
return tb_size; |
519 | 511 |
} |
520 | 512 |
|
... | ... | |
524 | 516 |
|
525 | 517 |
static inline void *alloc_code_gen_buffer(void) |
526 | 518 |
{ |
527 |
map_exec(static_code_gen_buffer, code_gen_buffer_size); |
|
519 |
map_exec(static_code_gen_buffer, tcg_ctx.code_gen_buffer_size);
|
|
528 | 520 |
return static_code_gen_buffer; |
529 | 521 |
} |
530 | 522 |
#elif defined(USE_MMAP) |
... | ... | |
547 | 539 |
Leave the choice of exact location with the kernel. */ |
548 | 540 |
flags |= MAP_32BIT; |
549 | 541 |
/* Cannot expect to map more than 800MB in low memory. */ |
550 |
if (code_gen_buffer_size > 800u * 1024 * 1024) { |
|
551 |
code_gen_buffer_size = 800u * 1024 * 1024; |
|
542 |
if (tcg_ctx.code_gen_buffer_size > 800u * 1024 * 1024) {
|
|
543 |
tcg_ctx.code_gen_buffer_size = 800u * 1024 * 1024;
|
|
552 | 544 |
} |
553 | 545 |
# elif defined(__sparc__) |
554 | 546 |
start = 0x40000000ul; |
... | ... | |
556 | 548 |
start = 0x90000000ul; |
557 | 549 |
# endif |
558 | 550 |
|
559 |
buf = mmap((void *)start, code_gen_buffer_size, |
|
551 |
buf = mmap((void *)start, tcg_ctx.code_gen_buffer_size,
|
|
560 | 552 |
PROT_WRITE | PROT_READ | PROT_EXEC, flags, -1, 0); |
561 | 553 |
return buf == MAP_FAILED ? NULL : buf; |
562 | 554 |
} |
563 | 555 |
#else |
564 | 556 |
static inline void *alloc_code_gen_buffer(void) |
565 | 557 |
{ |
566 |
void *buf = g_malloc(code_gen_buffer_size); |
|
558 |
void *buf = g_malloc(tcg_ctx.code_gen_buffer_size);
|
|
567 | 559 |
|
568 | 560 |
if (buf) { |
569 |
map_exec(buf, code_gen_buffer_size); |
|
561 |
map_exec(buf, tcg_ctx.code_gen_buffer_size);
|
|
570 | 562 |
} |
571 | 563 |
return buf; |
572 | 564 |
} |
... | ... | |
574 | 566 |
|
575 | 567 |
static inline void code_gen_alloc(size_t tb_size) |
576 | 568 |
{ |
577 |
code_gen_buffer_size = size_code_gen_buffer(tb_size); |
|
578 |
code_gen_buffer = alloc_code_gen_buffer(); |
|
579 |
if (code_gen_buffer == NULL) { |
|
569 |
tcg_ctx.code_gen_buffer_size = size_code_gen_buffer(tb_size);
|
|
570 |
tcg_ctx.code_gen_buffer = alloc_code_gen_buffer();
|
|
571 |
if (tcg_ctx.code_gen_buffer == NULL) {
|
|
580 | 572 |
fprintf(stderr, "Could not allocate dynamic translator buffer\n"); |
581 | 573 |
exit(1); |
582 | 574 |
} |
583 | 575 |
|
584 |
qemu_madvise(code_gen_buffer, code_gen_buffer_size, QEMU_MADV_HUGEPAGE); |
|
576 |
qemu_madvise(tcg_ctx.code_gen_buffer, tcg_ctx.code_gen_buffer_size, |
|
577 |
QEMU_MADV_HUGEPAGE); |
|
585 | 578 |
|
586 | 579 |
/* Steal room for the prologue at the end of the buffer. This ensures |
587 | 580 |
(via the MAX_CODE_GEN_BUFFER_SIZE limits above) that direct branches |
588 | 581 |
from TB's to the prologue are going to be in range. It also means |
589 | 582 |
that we don't need to mark (additional) portions of the data segment |
590 | 583 |
as executable. */ |
591 |
code_gen_prologue = code_gen_buffer + code_gen_buffer_size - 1024; |
|
592 |
code_gen_buffer_size -= 1024; |
|
584 |
tcg_ctx.code_gen_prologue = tcg_ctx.code_gen_buffer + |
|
585 |
tcg_ctx.code_gen_buffer_size - 1024; |
|
586 |
tcg_ctx.code_gen_buffer_size -= 1024; |
|
593 | 587 |
|
594 |
code_gen_buffer_max_size = code_gen_buffer_size -
|
|
588 |
tcg_ctx.code_gen_buffer_max_size = tcg_ctx.code_gen_buffer_size -
|
|
595 | 589 |
(TCG_MAX_OP_SIZE * OPC_BUF_SIZE); |
596 |
code_gen_max_blocks = code_gen_buffer_size / CODE_GEN_AVG_BLOCK_SIZE; |
|
597 |
tbs = g_malloc(code_gen_max_blocks * sizeof(TranslationBlock)); |
|
590 |
tcg_ctx.code_gen_max_blocks = tcg_ctx.code_gen_buffer_size / |
|
591 |
CODE_GEN_AVG_BLOCK_SIZE; |
|
592 |
tbs = g_malloc(tcg_ctx.code_gen_max_blocks * sizeof(TranslationBlock)); |
|
598 | 593 |
} |
599 | 594 |
|
600 | 595 |
/* Must be called before using the QEMU cpus. 'tb_size' is the size |
... | ... | |
604 | 599 |
{ |
605 | 600 |
cpu_gen_init(); |
606 | 601 |
code_gen_alloc(tb_size); |
607 |
code_gen_ptr = code_gen_buffer;
|
|
608 |
tcg_register_jit(code_gen_buffer, code_gen_buffer_size);
|
|
602 |
tcg_ctx.code_gen_ptr = tcg_ctx.code_gen_buffer;
|
|
603 |
tcg_register_jit(tcg_ctx.code_gen_buffer, tcg_ctx.code_gen_buffer_size);
|
|
609 | 604 |
page_init(); |
610 | 605 |
#if !defined(CONFIG_USER_ONLY) || !defined(CONFIG_USE_GUEST_BASE) |
611 | 606 |
/* There's no guest base to take into account, so go ahead and |
... | ... | |
616 | 611 |
|
617 | 612 |
bool tcg_enabled(void) |
618 | 613 |
{ |
619 |
return code_gen_buffer != NULL; |
|
614 |
return tcg_ctx.code_gen_buffer != NULL;
|
|
620 | 615 |
} |
621 | 616 |
|
622 | 617 |
/* Allocate a new translation block. Flush the translation buffer if |
... | ... | |
625 | 620 |
{ |
626 | 621 |
TranslationBlock *tb; |
627 | 622 |
|
628 |
if (nb_tbs >= code_gen_max_blocks || |
|
629 |
(code_gen_ptr - code_gen_buffer) >= code_gen_buffer_max_size) { |
|
623 |
if (nb_tbs >= tcg_ctx.code_gen_max_blocks || |
|
624 |
(tcg_ctx.code_gen_ptr - tcg_ctx.code_gen_buffer) >= |
|
625 |
tcg_ctx.code_gen_buffer_max_size) { |
|
630 | 626 |
return NULL; |
631 | 627 |
} |
632 | 628 |
tb = &tbs[nb_tbs++]; |
... | ... | |
641 | 637 |
Ignore the hard cases and just back up if this TB happens to |
642 | 638 |
be the last one generated. */ |
643 | 639 |
if (nb_tbs > 0 && tb == &tbs[nb_tbs - 1]) { |
644 |
code_gen_ptr = tb->tc_ptr; |
|
640 |
tcg_ctx.code_gen_ptr = tb->tc_ptr;
|
|
645 | 641 |
nb_tbs--; |
646 | 642 |
} |
647 | 643 |
} |
... | ... | |
696 | 692 |
|
697 | 693 |
#if defined(DEBUG_FLUSH) |
698 | 694 |
printf("qemu: flush code_size=%ld nb_tbs=%d avg_tb_size=%ld\n", |
699 |
(unsigned long)(code_gen_ptr - code_gen_buffer),
|
|
695 |
(unsigned long)(tcg_ctx.code_gen_ptr - tcg_ctx.code_gen_buffer),
|
|
700 | 696 |
nb_tbs, nb_tbs > 0 ? |
701 |
((unsigned long)(code_gen_ptr - code_gen_buffer)) / nb_tbs : 0); |
|
697 |
((unsigned long)(tcg_ctx.code_gen_ptr - tcg_ctx.code_gen_buffer)) / |
|
698 |
nb_tbs : 0); |
|
702 | 699 |
#endif |
703 |
if ((unsigned long)(code_gen_ptr - code_gen_buffer)
|
|
704 |
> code_gen_buffer_size) { |
|
700 |
if ((unsigned long)(tcg_ctx.code_gen_ptr - tcg_ctx.code_gen_buffer)
|
|
701 |
> tcg_ctx.code_gen_buffer_size) {
|
|
705 | 702 |
cpu_abort(env1, "Internal error: code buffer overflow\n"); |
706 | 703 |
} |
707 | 704 |
nb_tbs = 0; |
... | ... | |
713 | 710 |
memset(tb_phys_hash, 0, CODE_GEN_PHYS_HASH_SIZE * sizeof(void *)); |
714 | 711 |
page_flush_tb(); |
715 | 712 |
|
716 |
code_gen_ptr = code_gen_buffer;
|
|
713 |
tcg_ctx.code_gen_ptr = tcg_ctx.code_gen_buffer;
|
|
717 | 714 |
/* XXX: flush processor icache at this point if cache flush is |
718 | 715 |
expensive */ |
719 | 716 |
tb_flush_count++; |
... | ... | |
960 | 957 |
/* Don't forget to invalidate previous TB info. */ |
961 | 958 |
tb_invalidated_flag = 1; |
962 | 959 |
} |
963 |
tc_ptr = code_gen_ptr; |
|
960 |
tc_ptr = tcg_ctx.code_gen_ptr;
|
|
964 | 961 |
tb->tc_ptr = tc_ptr; |
965 | 962 |
tb->cs_base = cs_base; |
966 | 963 |
tb->flags = flags; |
967 | 964 |
tb->cflags = cflags; |
968 | 965 |
cpu_gen_code(env, tb, &code_gen_size); |
969 |
code_gen_ptr = (void *)(((uintptr_t)code_gen_ptr + code_gen_size +
|
|
970 |
CODE_GEN_ALIGN - 1) & ~(CODE_GEN_ALIGN - 1));
|
|
966 |
tcg_ctx.code_gen_ptr = (void *)(((uintptr_t)tcg_ctx.code_gen_ptr +
|
|
967 |
code_gen_size + CODE_GEN_ALIGN - 1) & ~(CODE_GEN_ALIGN - 1));
|
|
971 | 968 |
|
972 | 969 |
/* check next page if needed */ |
973 | 970 |
virt_page2 = (pc + tb->size - 1) & TARGET_PAGE_MASK; |
... | ... | |
1312 | 1309 |
{ |
1313 | 1310 |
/* This can be called during code generation, code_gen_buffer_max_size |
1314 | 1311 |
is used instead of code_gen_ptr for upper boundary checking */ |
1315 |
return (tc_ptr >= (uintptr_t)code_gen_buffer && |
|
1316 |
tc_ptr < (uintptr_t)(code_gen_buffer + code_gen_buffer_max_size)); |
|
1312 |
return (tc_ptr >= (uintptr_t)tcg_ctx.code_gen_buffer && |
|
1313 |
tc_ptr < (uintptr_t)(tcg_ctx.code_gen_buffer + |
|
1314 |
tcg_ctx.code_gen_buffer_max_size)); |
|
1317 | 1315 |
} |
1318 | 1316 |
#endif |
1319 | 1317 |
|
... | ... | |
1328 | 1326 |
if (nb_tbs <= 0) { |
1329 | 1327 |
return NULL; |
1330 | 1328 |
} |
1331 |
if (tc_ptr < (uintptr_t)code_gen_buffer || |
|
1332 |
tc_ptr >= (uintptr_t)code_gen_ptr) { |
|
1329 |
if (tc_ptr < (uintptr_t)tcg_ctx.code_gen_buffer ||
|
|
1330 |
tc_ptr >= (uintptr_t)tcg_ctx.code_gen_ptr) {
|
|
1333 | 1331 |
return NULL; |
1334 | 1332 |
} |
1335 | 1333 |
/* binary search (cf Knuth) */ |
... | ... | |
1587 | 1585 |
/* XXX: avoid using doubles ? */ |
1588 | 1586 |
cpu_fprintf(f, "Translation buffer state:\n"); |
1589 | 1587 |
cpu_fprintf(f, "gen code size %td/%zd\n", |
1590 |
code_gen_ptr - code_gen_buffer, code_gen_buffer_max_size); |
|
1588 |
tcg_ctx.code_gen_ptr - tcg_ctx.code_gen_buffer, |
|
1589 |
tcg_ctx.code_gen_buffer_max_size); |
|
1591 | 1590 |
cpu_fprintf(f, "TB count %d/%d\n", |
1592 |
nb_tbs, code_gen_max_blocks); |
|
1591 |
nb_tbs, tcg_ctx.code_gen_max_blocks);
|
|
1593 | 1592 |
cpu_fprintf(f, "TB avg target size %d max=%d bytes\n", |
1594 | 1593 |
nb_tbs ? target_code_size / nb_tbs : 0, |
1595 | 1594 |
max_target_code_size); |
1596 | 1595 |
cpu_fprintf(f, "TB avg host size %td bytes (expansion ratio: %0.1f)\n", |
1597 |
nb_tbs ? (code_gen_ptr - code_gen_buffer) / nb_tbs : 0, |
|
1598 |
target_code_size ? (double) (code_gen_ptr - code_gen_buffer) |
|
1599 |
/ target_code_size : 0); |
|
1596 |
nb_tbs ? (tcg_ctx.code_gen_ptr - tcg_ctx.code_gen_buffer) / |
|
1597 |
nb_tbs : 0, |
|
1598 |
target_code_size ? |
|
1599 |
(double) (tcg_ctx.code_gen_ptr - tcg_ctx.code_gen_buffer) / |
|
1600 |
target_code_size : 0); |
|
1600 | 1601 |
cpu_fprintf(f, "cross page TB count %d (%d%%)\n", |
1601 | 1602 |
cross_page, |
1602 | 1603 |
nb_tbs ? (cross_page * 100) / nb_tbs : 0); |
Also available in: Unified diff