Files
fail/tools/import-trace/AdvancedMemoryImporter.hpp
Michael Lenz af92a751d9 import-trace: alias-based (importer) registry
This change implements a generic registry in order to clean up import-trace's
code - it's possible (and reasonable) to use the registry for pruners as well.
Importer now extends AliasedRegisterable; all importers have been adapted
to suit the interface/abstract methods.
Each AliasedRegisterable should have at least one alias (the class' name
is a sensible choice) but can have several. The first specified alias is
the class' prime alias which can be used e.g. to list all registered objects.

Change-Id: If6daa34edce35a3b0194e4ba67ed3b44b74a49b0
2014-04-25 08:34:01 +02:00

65 lines
2.4 KiB
C++

#ifndef __ADVANCED_MEMORY_IMPORTER_H__
#define __ADVANCED_MEMORY_IMPORTER_H__
#include <vector>
#include <deque>
#include "MemoryImporter.hpp"
#include "util/llvmdisassembler/LLVMDisassembler.hpp"
/**
* A MemoryImporter that additionally imports Relyzer-style conditional branch
* history, instruction opcodes, and a virtual duration = time2 - time1 + 1
* column (MariaDB 5.2+ only!) for fault-space pruning purposes.
*
* Initially this was implemented by directly passing through trace events to
* the MemoryImporter, keeping a record of conditional jumps and opcodes, and
* UPDATEing all inserted rows in a second pass when the MemoryImporter is
* finished.
*
* Unfortunately, UPDATE is very slow, and keeping all information in memory
* till the end doesn't scale indefinitely. Therefore the implementation now
* delays passing memory access events upwards to the MemoryImporter only until
* enough branch history is aggregated, and taps into Importer's database
* operations with a set of new virtual functions that are called downwards.
*/
class AdvancedMemoryImporter : public MemoryImporter {
llvm::OwningPtr<llvm::object::Binary> binary;
llvm::OwningPtr<fail::LLVMDisassembler> disas;
bool m_last_was_conditional_branch;
fail::guest_address_t m_ip_jump_not_taken;
std::vector<bool> branches_taken;
struct DelayedTraceEntry {
fail::simtime_t curtime;
instruction_count_t instr;
Trace_Event ev;
unsigned opcode;
unsigned branches_before;
};
std::deque<DelayedTraceEntry> delayed_entries;
static const unsigned BRANCH_WINDOW_SIZE = 16; //!< increasing this requires changing the underlying data types
unsigned m_cur_branchmask;
void insert_delayed_entries(bool finalizing);
public:
AdvancedMemoryImporter() : m_last_was_conditional_branch(false) {}
protected:
virtual std::string database_additional_columns();
virtual void database_insert_columns(std::string& sql, unsigned& num_columns);
virtual bool database_insert_data(Trace_Event &ev, std::stringstream& value_sql, unsigned num_columns, bool is_fake);
virtual bool handle_ip_event(fail::simtime_t curtime, instruction_count_t instr,
Trace_Event &ev);
virtual bool handle_mem_event(fail::simtime_t curtime, instruction_count_t instr,
Trace_Event &ev);
virtual bool trace_end_reached();
void getAliases(std::deque<std::string> *aliases) {
aliases->push_back("AdvancedMemoryImporter");
}
};
#endif