diff options
-rw-r--r-- | Makefile.target | 1 | ||||
-rw-r--r-- | dcache.c | 334 | ||||
-rw-r--r-- | dcache.h | 31 | ||||
-rw-r--r-- | target-arm/translate.c | 2 | ||||
-rw-r--r-- | trace.c | 101 | ||||
-rw-r--r-- | trace.h | 97 | ||||
-rw-r--r-- | vl-android.c | 8 |
7 files changed, 103 insertions, 471 deletions
diff --git a/Makefile.target b/Makefile.target index 6cf2283..aa3824b 100644 --- a/Makefile.target +++ b/Makefile.target @@ -137,7 +137,6 @@ LOCAL_SRC_FILES += \ translate-all.c \ trace.c \ varint.c \ - dcache.c \ softmmu_outside_jit.c \ ############################################################################## diff --git a/dcache.c b/dcache.c deleted file mode 100644 index 7cce505..0000000 --- a/dcache.c +++ /dev/null @@ -1,334 +0,0 @@ -/* Copyright (C) 2007-2008 The Android Open Source Project -** -** This software is licensed under the terms of the GNU General Public -** License version 2, as published by the Free Software Foundation, and -** may be copied, distributed, and modified under those terms. -** -** This program is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -** GNU General Public License for more details. -*/ -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include "dcache.h" -#include "cpu.h" -#include "exec-all.h" -#include "trace.h" -#include "varint.h" - -extern FILE *ftrace_debug; - -int dcache_size = 16 * 1024; -int dcache_ways = 4; -int dcache_line_size = 32; -int dcache_replace_policy = kPolicyRandom; -int dcache_load_miss_penalty = 30; -int dcache_store_miss_penalty = 5; - -typedef struct Dcache { - int size; - int ways; - int line_size; - int log_line_size; - int rows; - uint32_t addr_mask; - int replace_policy; - int next_way; - int extra_increment_counter; - int *replace; - uint32_t **table; - int load_miss_penalty; - int store_miss_penalty; - uint64_t load_hits; - uint64_t load_misses; - uint64_t store_hits; - uint64_t store_misses; -} Dcache; - -Dcache dcache; - -void dcache_cleanup(); - -// Returns the log2 of "num" rounded up to the nearest integer. -int log2_roundup(int num) -{ - int power2; - int exp; - - for (exp = 0, power2 = 1; power2 < num; power2 <<= 1) { - exp += 1; - } - return exp; -} - -void dcache_init(int size, int ways, int line_size, int replace_policy, - int load_miss_penalty, int store_miss_penalty) -{ - int ii; - - // Compute the logs of the params, rounded up - int log_size = log2_roundup(size); - int log_ways = log2_roundup(ways); - int log_line_size = log2_roundup(line_size); - - // The number of rows in the table = size / (line_size * ways) - int log_rows = log_size - log_line_size - log_ways; - - dcache.size = 1 << log_size; - dcache.ways = 1 << log_ways; - dcache.line_size = 1 << log_line_size; - dcache.log_line_size = log_line_size; - dcache.rows = 1 << log_rows; - dcache.addr_mask = (1 << log_rows) - 1; - - // Allocate an array of pointers, one for each row - uint32_t **table = malloc(sizeof(uint32_t *) << log_rows); - - // Allocate the data for the whole cache in one call to malloc() - int data_size = sizeof(uint32_t) << (log_rows + log_ways); - uint32_t *data = malloc(data_size); - - // Fill the cache with invalid addresses - memset(data, ~0, data_size); - - // Assign the pointers into the data array - int rows = dcache.rows; - for (ii = 0; ii < rows; ++ii) { - table[ii] = &data[ii << log_ways]; - } - dcache.table = table; - dcache.replace_policy = replace_policy; - dcache.next_way = 0; - dcache.extra_increment_counter = 0; - - dcache.replace = NULL; - if (replace_policy == kPolicyRoundRobin) { - dcache.replace = malloc(sizeof(int) << log_rows); - memset(dcache.replace, 0, sizeof(int) << log_rows); - } - dcache.load_miss_penalty = load_miss_penalty; - dcache.store_miss_penalty = store_miss_penalty; - dcache.load_hits = 0; - dcache.load_misses = 0; - dcache.store_hits = 0; - dcache.store_misses = 0; - - atexit(dcache_cleanup); -} - -void dcache_stats() -{ - uint64_t hits = dcache.load_hits + dcache.store_hits; - uint64_t misses = dcache.load_misses + dcache.store_misses; - uint64_t total = hits + misses; - double hit_per = 0; - double miss_per = 0; - if (total) { - hit_per = 100.0 * hits / total; - miss_per = 100.0 * misses / total; - } - printf("\n"); - printf("Dcache hits %10llu %6.2f%%\n", hits, hit_per); - printf("Dcache misses %10llu %6.2f%%\n", misses, miss_per); - printf("Dcache total %10llu\n", hits + misses); -} - -void dcache_free() -{ - free(dcache.table[0]); - free(dcache.table); - free(dcache.replace); - dcache.table = NULL; -} - -void dcache_cleanup() -{ - dcache_stats(); - dcache_free(); -} - -void compress_trace_addresses(TraceAddr *trace_addr) -{ - AddrRec *ptr; - char *comp_ptr = trace_addr->compressed_ptr; - uint32_t prev_addr = trace_addr->prev_addr; - uint64_t prev_time = trace_addr->prev_time; - AddrRec *last = &trace_addr->buffer[kMaxNumAddrs]; - for (ptr = trace_addr->buffer; ptr != last; ++ptr) { - if (comp_ptr >= trace_addr->high_water_ptr) { - uint32_t size = comp_ptr - trace_addr->compressed; - fwrite(trace_addr->compressed, sizeof(char), size, trace_addr->fstream); - comp_ptr = trace_addr->compressed; - } - - int addr_diff = ptr->addr - prev_addr; - uint64_t time_diff = ptr->time - prev_time; - prev_addr = ptr->addr; - prev_time = ptr->time; - - comp_ptr = varint_encode_signed(addr_diff, comp_ptr); - comp_ptr = varint_encode(time_diff, comp_ptr); - } - trace_addr->compressed_ptr = comp_ptr; - trace_addr->prev_addr = prev_addr; - trace_addr->prev_time = prev_time; -} - -// This function is called by the generated code to simulate -// a dcache load access. -void dcache_load(uint32_t addr) -{ - int ii; - int ways = dcache.ways; - uint32_t cache_addr = addr >> dcache.log_line_size; - int row = cache_addr & dcache.addr_mask; - //printf("ld %lld 0x%x\n", sim_time, addr); - for (ii = 0; ii < ways; ++ii) { - if (cache_addr == dcache.table[row][ii]) { - dcache.load_hits += 1; -#if 0 - printf("dcache load hit addr: 0x%x cache_addr: 0x%x row %d way %d\n", - addr, cache_addr, row, ii); -#endif - // If we are tracing all addresses, then include this in the trace. - if (trace_all_addr) { - AddrRec *next = trace_load.next; - next->addr = addr; - next->time = sim_time; - next += 1; - if (next == &trace_load.buffer[kMaxNumAddrs]) { - // Compress the trace - compress_trace_addresses(&trace_load); - next = &trace_load.buffer[0]; - } - trace_load.next = next; - } - return; - } - } - // This is a cache miss - -#if 0 - if (ftrace_debug) - fprintf(ftrace_debug, "t%lld %08x\n", sim_time, addr); -#endif - if (trace_load.fstream) { - AddrRec *next = trace_load.next; - next->addr = addr; - next->time = sim_time; - next += 1; - if (next == &trace_load.buffer[kMaxNumAddrs]) { - // Compress the trace - compress_trace_addresses(&trace_load); - next = &trace_load.buffer[0]; - } - trace_load.next = next; - } - - dcache.load_misses += 1; - sim_time += dcache.load_miss_penalty; - - // Pick a way to replace - int way; - if (dcache.replace_policy == kPolicyRoundRobin) { - // Round robin replacement policy - way = dcache.replace[row]; - int next_way = way + 1; - if (next_way == dcache.ways) - next_way = 0; - dcache.replace[row] = next_way; - } else { - // Random replacement policy - way = dcache.next_way; - dcache.next_way += 1; - if (dcache.next_way >= dcache.ways) - dcache.next_way = 0; - - // Every 13 replacements, add an extra increment to the next way - dcache.extra_increment_counter += 1; - if (dcache.extra_increment_counter == 13) { - dcache.extra_increment_counter = 0; - dcache.next_way += 1; - if (dcache.next_way >= dcache.ways) - dcache.next_way = 0; - } - } -#if 0 - printf("dcache load miss addr: 0x%x cache_addr: 0x%x row %d replacing way %d\n", - addr, cache_addr, row, way); -#endif - dcache.table[row][way] = cache_addr; -} - -// This function is called by the generated code to simulate -// a dcache store access. -void dcache_store(uint32_t addr, uint32_t val) -{ - //printf("st %lld 0x%08x val 0x%x\n", sim_time, addr, val); - - int ii; - int ways = dcache.ways; - uint32_t cache_addr = addr >> dcache.log_line_size; - int row = cache_addr & dcache.addr_mask; - for (ii = 0; ii < ways; ++ii) { - if (cache_addr == dcache.table[row][ii]) { - dcache.store_hits += 1; -#if 0 - printf("dcache store hit addr: 0x%x cache_addr: 0x%x row %d way %d\n", - addr, cache_addr, row, ii); -#endif - // If we are tracing all addresses, then include this in the trace. - if (trace_all_addr) { - AddrRec *next = trace_store.next; - next->addr = addr; - next->time = sim_time; - next += 1; - if (next == &trace_store.buffer[kMaxNumAddrs]) { - // Compress the trace - compress_trace_addresses(&trace_store); - next = &trace_store.buffer[0]; - } - trace_store.next = next; - } - return; - } - } - // This is a cache miss -#if 0 - printf("dcache store miss addr: 0x%x cache_addr: 0x%x row %d\n", - addr, cache_addr, row); -#endif - -#if 0 - if (ftrace_debug) - fprintf(ftrace_debug, "t%lld %08x\n", sim_time, addr); -#endif - - if (trace_store.fstream) { - AddrRec *next = trace_store.next; - next->addr = addr; - next->time = sim_time; - next += 1; - if (next == &trace_store.buffer[kMaxNumAddrs]) { - // Compress the trace - compress_trace_addresses(&trace_store); - next = &trace_store.buffer[0]; - } - trace_store.next = next; - } - - dcache.store_misses += 1; - sim_time += dcache.store_miss_penalty; - - // Assume no write-allocate for now -} - -// This function is called by the generated code to simulate -// a dcache load and store (swp) access. -void dcache_swp(uint32_t addr) -{ - dcache_load(addr); - dcache_store(addr, 0); -} diff --git a/dcache.h b/dcache.h deleted file mode 100644 index 8857600..0000000 --- a/dcache.h +++ /dev/null @@ -1,31 +0,0 @@ -/* Copyright (C) 2007-2008 The Android Open Source Project -** -** This software is licensed under the terms of the GNU General Public -** License version 2, as published by the Free Software Foundation, and -** may be copied, distributed, and modified under those terms. -** -** This program is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -** GNU General Public License for more details. -*/ -#ifndef DCACHE_H -#define DCACHE_H - -#include <inttypes.h> - -// Define constants for the replacement policies -#define kPolicyRoundRobin 1 -#define kPolicyRandom 2 - -extern int dcache_size; -extern int dcache_ways; -extern int dcache_line_size; -extern int dcache_replace_policy; -extern int dcache_load_miss_penalty; -extern int dcache_store_miss_penalty; - -extern void dcache_init(int size, int ways, int line_size, int replace_policy, - int load_miss_penalty, int store_miss_penalty); - -#endif /* DCACHE_H */ diff --git a/target-arm/translate.c b/target-arm/translate.c index f93a0cd..93ff4ea 100644 --- a/target-arm/translate.c +++ b/target-arm/translate.c @@ -8909,7 +8909,7 @@ static inline void gen_intermediate_code_internal(CPUState *env, gen_icount_start(); #ifdef CONFIG_TRACE if (tracing) { - gen_traceBB(trace_static.bb_num, tb); + gen_traceBB(trace_static_bb_num(), tb); trace_bb_start(dc->pc); } #endif @@ -26,6 +26,102 @@ #include "varint.h" #include "android/utils/path.h" +// For tracing dynamic execution of basic blocks +typedef struct TraceBB { + char *filename; + FILE *fstream; + BBRec buffer[kMaxNumBasicBlocks]; + BBRec *next; // points to next record in buffer + uint64_t flush_time; // time of last buffer flush + char compressed[kCompressedSize]; + char *compressed_ptr; + char *high_water_ptr; + int64_t prev_bb_num; + uint64_t prev_bb_time; + uint64_t current_bb_num; + uint64_t current_bb_start_time; + uint64_t recnum; // counts number of trace records + uint32_t current_bb_addr; + int num_insns; +} TraceBB; + +// For tracing simuation start times of instructions +typedef struct TraceInsn { + char *filename; + FILE *fstream; + InsnRec dummy; // this is here so we can use buffer[-1] + InsnRec buffer[kInsnBufferSize]; + InsnRec *current; + uint64_t prev_time; // time of last instruction start + char compressed[kCompressedSize]; + char *compressed_ptr; + char *high_water_ptr; +} TraceInsn; + +// For tracing the static information about a basic block +typedef struct TraceStatic { + char *filename; + FILE *fstream; + uint32_t insns[kMaxInsnPerBB]; + int next_insn; + uint64_t bb_num; + uint32_t bb_addr; + int is_thumb; +} TraceStatic; + +// For tracing load and store addresses +typedef struct TraceAddr { + char *filename; + FILE *fstream; + AddrRec buffer[kMaxNumAddrs]; + AddrRec *next; + char compressed[kCompressedSize]; + char *compressed_ptr; + char *high_water_ptr; + uint32_t prev_addr; + uint64_t prev_time; +} TraceAddr; + +// For tracing exceptions +typedef struct TraceExc { + char *filename; + FILE *fstream; + char compressed[kCompressedSize]; + char *compressed_ptr; + char *high_water_ptr; + uint64_t prev_time; + uint64_t prev_bb_recnum; +} TraceExc; + +// For tracing process id changes +typedef struct TracePid { + char *filename; + FILE *fstream; + char compressed[kCompressedSize]; + char *compressed_ptr; + uint64_t prev_time; +} TracePid; + +// For tracing Dalvik VM method enter and exit +typedef struct TraceMethod { + char *filename; + FILE *fstream; + char compressed[kCompressedSize]; + char *compressed_ptr; + uint64_t prev_time; + uint32_t prev_addr; + int32_t prev_pid; +} TraceMethod; + +extern TraceBB trace_bb; +extern TraceInsn trace_insn; +extern TraceStatic trace_static; +extern TraceAddr trace_load; +extern TraceAddr trace_store; +extern TraceExc trace_exc; +extern TracePid trace_pid; +extern TraceMethod trace_method; + TraceBB trace_bb; TraceInsn trace_insn; TraceStatic trace_static; @@ -1878,3 +1974,8 @@ void trace_interpreted_method(uint32_t addr, int call_type) comp_ptr = varint_encode(call_type, comp_ptr); trace_method.compressed_ptr = comp_ptr; } + +uint64_t trace_static_bb_num(void) +{ + return trace_static.bb_num; +} @@ -22,104 +22,9 @@ extern uint64_t Now(); struct TranslationBlock; -// For tracing dynamic execution of basic blocks -typedef struct TraceBB { - char *filename; - FILE *fstream; - BBRec buffer[kMaxNumBasicBlocks]; - BBRec *next; // points to next record in buffer - uint64_t flush_time; // time of last buffer flush - char compressed[kCompressedSize]; - char *compressed_ptr; - char *high_water_ptr; - int64_t prev_bb_num; - uint64_t prev_bb_time; - uint64_t current_bb_num; - uint64_t current_bb_start_time; - uint64_t recnum; // counts number of trace records - uint32_t current_bb_addr; - int num_insns; -} TraceBB; - -// For tracing simuation start times of instructions -typedef struct TraceInsn { - char *filename; - FILE *fstream; - InsnRec dummy; // this is here so we can use buffer[-1] - InsnRec buffer[kInsnBufferSize]; - InsnRec *current; - uint64_t prev_time; // time of last instruction start - char compressed[kCompressedSize]; - char *compressed_ptr; - char *high_water_ptr; -} TraceInsn; - -// For tracing the static information about a basic block -typedef struct TraceStatic { - char *filename; - FILE *fstream; - uint32_t insns[kMaxInsnPerBB]; - int next_insn; - uint64_t bb_num; - uint32_t bb_addr; - int is_thumb; -} TraceStatic; - -// For tracing load and store addresses -typedef struct TraceAddr { - char *filename; - FILE *fstream; - AddrRec buffer[kMaxNumAddrs]; - AddrRec *next; - char compressed[kCompressedSize]; - char *compressed_ptr; - char *high_water_ptr; - uint32_t prev_addr; - uint64_t prev_time; -} TraceAddr; - -// For tracing exceptions -typedef struct TraceExc { - char *filename; - FILE *fstream; - char compressed[kCompressedSize]; - char *compressed_ptr; - char *high_water_ptr; - uint64_t prev_time; - uint64_t prev_bb_recnum; -} TraceExc; - -// For tracing process id changes -typedef struct TracePid { - char *filename; - FILE *fstream; - char compressed[kCompressedSize]; - char *compressed_ptr; - uint64_t prev_time; -} TracePid; - -// For tracing Dalvik VM method enter and exit -typedef struct TraceMethod { - char *filename; - FILE *fstream; - char compressed[kCompressedSize]; - char *compressed_ptr; - uint64_t prev_time; - uint32_t prev_addr; - int32_t prev_pid; -} TraceMethod; - -extern TraceBB trace_bb; -extern TraceInsn trace_insn; -extern TraceStatic trace_static; -extern TraceAddr trace_load; -extern TraceAddr trace_store; -extern TraceExc trace_exc; -extern TracePid trace_pid; -extern TraceMethod trace_method; - // The simulated time, in clock ticks, starting with one. extern uint64_t sim_time; +extern uint64_t trace_static_bb_num(void);; // This variable == 1 if we are currently tracing, otherwise == 0. extern int tracing; diff --git a/vl-android.c b/vl-android.c index 08515cb..2c33092 100644 --- a/vl-android.c +++ b/vl-android.c @@ -226,7 +226,6 @@ extern void android_emulator_set_base_port(int port); #ifdef CONFIG_TRACE #include "trace.h" -#include "dcache.h" #endif #include "qemu_socket.h" @@ -5607,13 +5606,6 @@ int main(int argc, char **argv, char **envp) #ifdef CONFIG_TRACE if (trace_filename) { trace_init(trace_filename); -#if 0 - // We don't need the dcache code until we can get load and store tracing - // working again. - dcache_init(dcache_size, dcache_ways, dcache_line_size, - dcache_replace_policy, dcache_load_miss_penalty, - dcache_store_miss_penalty); -#endif fprintf(stderr, "-- When done tracing, exit the emulator. --\n"); } #endif |