From 8552d95c52d46a6d7b65553df8e945e8fb999a7a Mon Sep 17 00:00:00 2001 From: "Emilio G. Cota" Date: Mon, 5 Mar 2018 02:57:19 -0500 Subject: [PATCH] exec-all: extract tb->tc_* into a separate struct tc_tb In preparation for adding tc.size to be able to keep track of TB's using the binary search tree implementation from glib. Backports commit e7e168f41364c6e83d0f75fc1b3ce7f9c41ccf76 from qemu --- qemu/cpu-exec.c | 14 +++++++------- qemu/include/exec/exec-all.h | 11 +++++++++-- qemu/tcg-runtime.c | 4 ++-- qemu/tcg/tcg.c | 4 ++-- qemu/translate-all.c | 28 ++++++++++++++-------------- 5 files changed, 34 insertions(+), 27 deletions(-) diff --git a/qemu/cpu-exec.c b/qemu/cpu-exec.c index 542b1e1b..187112d1 100644 --- a/qemu/cpu-exec.c +++ b/qemu/cpu-exec.c @@ -40,12 +40,12 @@ static inline tcg_target_ulong cpu_tb_exec(CPUState *cpu, TranslationBlock *itb) uintptr_t ret; TranslationBlock *last_tb; int tb_exit; - uint8_t *tb_ptr = itb->tc_ptr; + uint8_t *tb_ptr = itb->tc.ptr; // Unicorn: commented out //qemu_log_mask_and_addr(CPU_LOG_EXEC, itb->pc, // "Trace %p [" TARGET_FMT_lx "] %s\n", - // itb->tc_ptr, itb->pc, lookup_symbol(itb->pc)); + // itb->tc.ptr, itb->pc, lookup_symbol(itb->pc)); ret = tcg_qemu_tb_exec(env, tb_ptr); last_tb = (TranslationBlock *)(ret & ~TB_EXIT_MASK); tb_exit = ret & TB_EXIT_MASK; @@ -61,7 +61,7 @@ static inline tcg_target_ulong cpu_tb_exec(CPUState *cpu, TranslationBlock *itb) //qemu_log_mask_and_addr(CPU_LOG_EXEC, last_tb->pc, // "Stopped execution of TB chain before %p [" // TARGET_FMT_lx "] %s\n", - // last_tb->tc_ptr, last_tb->pc, + // last_tb->tc.ptr, last_tb->pc, // lookup_symbol(last_tb->pc)); if (cc->synchronize_from_tb) { // avoid sync twice when helper_uc_tracecode() already did this. @@ -168,7 +168,7 @@ void tb_set_jmp_target(TranslationBlock *tb, int n, uintptr_t addr) { if (TCG_TARGET_HAS_direct_jump) { uintptr_t offset = tb->jmp_target_arg[n]; - uintptr_t tc_ptr = (uintptr_t)tb->tc_ptr; + uintptr_t tc_ptr = (uintptr_t)tb->tc.ptr; tb_target_set_jmp_target(tc_ptr, tc_ptr + offset, addr); } else { tb->jmp_target_arg[n] = addr; @@ -188,11 +188,11 @@ static inline void tb_add_jump(TranslationBlock *tb, int n, qemu_log_mask_and_addr(CPU_LOG_EXEC, tb->pc, "Linking TBs %p [" TARGET_FMT_lx "] index %d -> %p [" TARGET_FMT_lx "]\n", - tb->tc_ptr, tb->pc, n, - tb_next->tc_ptr, tb_next->pc); + tb->tc.ptr, tb->pc, n, + tb_next->tc.ptr, tb_next->pc); /* patch the native jump address */ - tb_set_jmp_target(tb, n, (uintptr_t)tb_next->tc_ptr); + tb_set_jmp_target(tb, n, (uintptr_t)tb_next->tc.ptr); /* add in TB jmp circular list */ tb->jmp_list_next[n] = tb_next->jmp_list_first; diff --git a/qemu/include/exec/exec-all.h b/qemu/include/exec/exec-all.h index d363960e..d511f645 100644 --- a/qemu/include/exec/exec-all.h +++ b/qemu/include/exec/exec-all.h @@ -205,6 +205,14 @@ static inline void tb_invalidate_phys_addr(AddressSpace *as, hwaddr addr) #define CODE_GEN_AVG_BLOCK_SIZE 150 #endif +/* + * Translation Cache-related fields of a TB. + */ +struct tb_tc { + void *ptr; /* pointer to the translated code */ + uint8_t *search; /* pointer to search data */ +}; + struct TranslationBlock { target_ulong pc; /* simulated PC corresponding to this block (EIP + CS base) */ target_ulong cs_base; /* CS base for this block */ @@ -220,8 +228,7 @@ struct TranslationBlock { #define CF_IGNORE_ICOUNT 0x40000 /* Do not generate icount code */ #define CF_INVALID 0x80000 /* TB is stale. Setters must acquire tb_lock */ - void *tc_ptr; /* pointer to the translated code */ - uint8_t *tc_search; /* pointer to search data */ + struct tb_tc tc; /* next matching tb for physical address. */ struct TranslationBlock *phys_hash_next; /* original tb when cflags has CF_NOCACHE */ diff --git a/qemu/tcg-runtime.c b/qemu/tcg-runtime.c index 09c71532..4ca0f277 100644 --- a/qemu/tcg-runtime.c +++ b/qemu/tcg-runtime.c @@ -159,9 +159,9 @@ void *HELPER(lookup_tb_ptr)(CPUArchState *env) // Unicorn: commented out //qemu_log_mask_and_addr(CPU_LOG_EXEC, pc, // "Chain %p [%d: " TARGET_FMT_lx "] %s\n", - // tb->tc_ptr, cpu->cpu_index, pc, + // tb->tc.ptr, cpu->cpu_index, pc, // lookup_symbol(pc)); - return tb->tc_ptr; + return tb->tc.ptr; } void HELPER(exit_atomic)(CPUArchState *env) diff --git a/qemu/tcg/tcg.c b/qemu/tcg/tcg.c index 09d0841e..338cf5ef 100644 --- a/qemu/tcg/tcg.c +++ b/qemu/tcg/tcg.c @@ -2905,8 +2905,8 @@ int tcg_gen_code(TCGContext *s, TranslationBlock *tb) tcg_reg_alloc_start(s); - s->code_buf = tb->tc_ptr; - s->code_ptr = tb->tc_ptr; + s->code_buf = tb->tc.ptr; + s->code_ptr = tb->tc.ptr; #ifdef TCG_TARGET_NEED_LDST_LABELS s->ldst_labels = NULL; diff --git a/qemu/translate-all.c b/qemu/translate-all.c index eef1a2c5..262cdb2c 100644 --- a/qemu/translate-all.c +++ b/qemu/translate-all.c @@ -240,7 +240,7 @@ static target_long decode_sleb128(uint8_t **pp) which comes from the host pc of the end of the code implementing the insn. Each line of the table is encoded as sleb128 deltas from the previous - line. The seed for the first line is { tb->pc, 0..., tb->tc_ptr }. + line. The seed for the first line is { tb->pc, 0..., tb->tc.ptr }. That is, the first column is seeded with the guest pc, the last column with the host pc, and the middle columns with zeros. */ @@ -250,7 +250,7 @@ static int encode_search(TCGContext *tcg_ctx, TranslationBlock *tb, uint8_t *blo uint8_t *p = block; int i, j, n; - tb->tc_search = block; + tb->tc.search = block; for (i = 0, n = tb->icount; i < n; ++i) { target_ulong prev; @@ -285,9 +285,9 @@ static int cpu_restore_state_from_tb(CPUState *cpu, TranslationBlock *tb, uintptr_t searched_pc) { target_ulong data[TARGET_INSN_START_WORDS] = { tb->pc }; - uintptr_t host_pc = (uintptr_t)tb->tc_ptr; + uintptr_t host_pc = (uintptr_t)tb->tc.ptr; CPUArchState *env = cpu->env_ptr; - uint8_t *p = tb->tc_search; + uint8_t *p = tb->tc.search; int i, j, num_insns = tb->icount; #ifdef CONFIG_PROFILER int64_t ti = profile_getclock(); @@ -895,7 +895,7 @@ void tb_free(struct uc_struct *uc, TranslationBlock *tb) tb == tcg_ctx->tb_ctx.tbs[tcg_ctx->tb_ctx.nb_tbs - 1]) { size_t struct_size = ROUND_UP(sizeof(*tb), uc->qemu_icache_linesize); - tcg_ctx->code_gen_ptr = tb->tc_ptr - struct_size; + tcg_ctx->code_gen_ptr = tb->tc.ptr - struct_size; tcg_ctx->tb_ctx.nb_tbs--; } } @@ -1096,7 +1096,7 @@ static inline void tb_remove_from_jmp_list(TranslationBlock *tb, int n) another TB */ static inline void tb_reset_jump(TranslationBlock *tb, int n) { - uintptr_t addr = (uintptr_t)(tb->tc_ptr + tb->jmp_reset_offset[n]); + uintptr_t addr = (uintptr_t)(tb->tc.ptr + tb->jmp_reset_offset[n]); tb_set_jmp_target(tb, n, addr); } @@ -1343,7 +1343,7 @@ TranslationBlock *tb_gen_code(CPUState *cpu, assert(tb != NULL); } gen_code_buf = tcg_ctx->code_gen_ptr; - tb->tc_ptr = gen_code_buf; + tb->tc.ptr = gen_code_buf; tb->pc = pc; tb->cs_base = cs_base; tb->flags = flags; @@ -1370,7 +1370,7 @@ TranslationBlock *tb_gen_code(CPUState *cpu, } // UNICORN: Commented out - //trace_translate_block(tb, tb->pc, tb->tc_ptr); + //trace_translate_block(tb, tb->pc, tb->tc.ptr); /* generate machine code */ tb->jmp_reset_offset[0] = TB_JMP_RESET_OFFSET_INVALID; @@ -1418,11 +1418,11 @@ TranslationBlock *tb_gen_code(CPUState *cpu, qemu_log_in_addr_range(tb->pc)) { qemu_log("OUT: [size=%d]\n", gen_code_size); if (tcg_ctx->data_gen_ptr) { - size_t code_size = tcg_ctx->data_gen_ptr - tb->tc_ptr; + size_t code_size = tcg_ctx->data_gen_ptr - tb->tc.ptr; size_t data_size = gen_code_size - code_size; size_t i; - log_disas(tb->tc_ptr, code_size); + log_disas(tb->tc.ptr, code_size); for (i = 0; i < data_size; i += sizeof(tcg_target_ulong)) { if (sizeof(tcg_target_ulong) == 8) { @@ -1436,7 +1436,7 @@ TranslationBlock *tb_gen_code(CPUState *cpu, } } } else { - log_disas(tb->tc_ptr, gen_code_size); + log_disas(tb->tc.ptr, gen_code_size); } qemu_log("\n"); qemu_log_flush(); @@ -1738,8 +1738,8 @@ static bool tb_invalidate_phys_page(tb_page_addr_t addr, uintptr_t pc) } #endif -/* find the TB 'tb' such that tb[0].tc_ptr <= tc_ptr < - tb[1].tc_ptr. Return NULL if not found */ +/* find the TB 'tb' such that tb[0].tc.ptr <= tc_ptr < + tb[1].tc.ptr. Return NULL if not found */ static TranslationBlock *tb_find_pc(struct uc_struct *uc, uintptr_t tc_ptr) { TCGContext *tcg_ctx = uc->tcg_ctx; @@ -1760,7 +1760,7 @@ static TranslationBlock *tb_find_pc(struct uc_struct *uc, uintptr_t tc_ptr) while (m_min <= m_max) { m = (m_min + m_max) >> 1; tb = tcg_ctx->tb_ctx.tbs[m]; - v = (uintptr_t)tb->tc_ptr; + v = (uintptr_t)tb->tc.ptr; if (v == tc_ptr) { return tb; } else if (tc_ptr < v) {