diff --git a/src/iss/plugin/pctrace.cpp b/src/iss/plugin/pctrace.cpp index 7f25652..fdda44d 100644 --- a/src/iss/plugin/pctrace.cpp +++ b/src/iss/plugin/pctrace.cpp @@ -1,5 +1,5 @@ #include -#include "pctrace.h" +#include #include #include #include @@ -157,8 +157,9 @@ void cov::callback(instr_info_t iinfo, const exec_info& einfo) { size_t id = iinfo.instr_id; auto entry = delays[id]; auto instr = instr_if->get_instr_word(); - auto call = (id==2 || id==3) && bit_sub<7,5>(instr)!=0; + auto call = id==65 || id ==86 || ((id==2 || id==3) && bit_sub<7,5>(instr)!=0) ;//not taking care of tail calls (jalr with loading x6) bool taken = einfo.branch_taken; + bool compressed = (instr&0x3)!=0x3; if (einfo.branch_taken) { delay = entry.taken; if(entry.taken > 1) @@ -169,10 +170,10 @@ void cov::callback(instr_info_t iinfo, const exec_info& einfo) { instr_if->set_curr_instr_cycles(entry.not_taken); } #ifndef WITH_LZ4 - output<get_pc() <<"," << delay <<"," << call<< "\n"; + output<get_pc() <<"," << delay <<"," << call<<","<<(compressed?2:4) <<"\n"; #else auto rdbuf=ostr.rdbuf(); - ostr<get_pc() <<"," << delay <<"," << call<< "\n"; + ostr<get_pc() <<"," << delay <<"," << call<<","<<(compressed?2:4) <<"\n"; #endif } } diff --git a/src/plugin/pctrace.cpp b/src/plugin/pctrace.cpp deleted file mode 100644 index 0d93801..0000000 --- a/src/plugin/pctrace.cpp +++ /dev/null @@ -1,180 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include "rapidjson/writer.h" -#include "rapidjson/stringbuffer.h" -#include -#include -#include -#include -#ifdef WITH_LZ4 -#include -#endif - -namespace iss { -namespace plugin { - -using namespace rapidjson; -using namespace std; - -#ifdef WITH_LZ4 -class lz4compress_steambuf: public std::streambuf { -public: - lz4compress_steambuf(const lz4compress_steambuf&) = delete; - lz4compress_steambuf& operator=(const lz4compress_steambuf&) = delete; - lz4compress_steambuf(std::ostream &sink, size_t buf_size) - : sink(sink) - , src_buf(buf_size) - , dest_buf(LZ4F_compressBound(buf_size, nullptr)) - { - auto errCode = LZ4F_createCompressionContext(&ctx, LZ4F_VERSION); - if (LZ4F_isError(errCode) != 0) - throw std::runtime_error(std::string("Failed to create LZ4 context: ") + LZ4F_getErrorName(errCode)); - size_t ret = LZ4F_compressBegin(ctx, &dest_buf.front(), dest_buf.capacity(), nullptr); - if (LZ4F_isError(ret) != 0) - throw std::runtime_error(std::string("Failed to start LZ4 compression: ") + LZ4F_getErrorName(ret)); - setp(src_buf.data(), src_buf.data() + src_buf.size() - 1); - sink.write(dest_buf.data(), ret); - } - - ~lz4compress_steambuf() { - close(); - } - - void close() { - if (closed) - return; - sync(); - auto ret = LZ4F_compressEnd(ctx, dest_buf.data(), dest_buf.capacity(), nullptr); - if (LZ4F_isError(ret) != 0) - throw std::runtime_error(std::string("Failed to finish LZ4 compression: ") + LZ4F_getErrorName(ret)); - sink.write(dest_buf.data(), ret); - LZ4F_freeCompressionContext(ctx); - closed = true; - } - -private: - int_type overflow(int_type ch) override { - compress_and_write(); - *pptr() = static_cast(ch); - pbump(1); - return ch; - } - - int_type sync() override { - compress_and_write(); - return 0; - } - - void compress_and_write() { - if (closed) - throw std::runtime_error("Cannot write to closed stream"); - if(auto orig_size = pptr() - pbase()){ - auto ret = LZ4F_compressUpdate(ctx, dest_buf.data(), dest_buf.capacity(), pbase(), orig_size, nullptr); - if (LZ4F_isError(ret) != 0) - throw std::runtime_error(std::string("LZ4 compression failed: ") + LZ4F_getErrorName(ret)); - if(ret) sink.write(dest_buf.data(), ret); - pbump(-orig_size); - } - } - - std::ostream &sink; - std::vector src_buf; - std::vector dest_buf; - LZ4F_compressionContext_t ctx{ nullptr }; - bool closed{ false }; -}; -#endif - -cov::cov(std::string const &filename) -: instr_if(nullptr) -, filename(filename) -, output("output.trc") -#ifdef WITH_LZ4 -, strbuf(new lz4compress_steambuf(output, 4096)) -, ostr(strbuf.get()) -#endif -{ } - -cov::~cov() { } - -bool cov::registration(const char *const version, vm_if& vm) { - instr_if = vm.get_arch()->get_instrumentation_if(); - if(!instr_if) return false; - const string core_name = instr_if->core_type_name(); - if (filename.length() > 0) { - ifstream is(filename); - if (is.is_open()) { - try { - IStreamWrapper isw(is); - Document d; - ParseResult ok = d.ParseStream(isw); - if(ok) { - Value& val = d[core_name.c_str()]; - if(val.IsArray()){ - delays.reserve(val.Size()); - for (auto it = val.Begin(); it != val.End(); ++it) { - auto& name = (*it)["name"]; - auto& size = (*it)["size"]; - auto& delay = (*it)["delay"]; - auto& branch = (*it)["branch"]; - if(delay.IsArray()) { - auto dt = delay[0].Get(); - auto dnt = delay[1].Get(); - delays.push_back(instr_desc{size.Get(), dt, dnt, branch.Get()}); - } else if(delay.Is()) { - auto d = delay.Get(); - delays.push_back(instr_desc{size.Get(), d, d, branch.Get()}); - } else - throw runtime_error("JSON parse error"); - - } - } else { - LOG(ERR)<<"plugin cycle_estimate: could not find an entry for "<get_instr_word(); - auto call = id==65 || id ==86 || ((id==2 || id==3) && bit_sub<7,5>(instr)!=0) ;//not taking care of tail calls (jalr with loading x6) - bool taken = einfo.branch_taken; - bool compressed = (instr&0x3)!=0x3; - if (einfo.branch_taken) { - delay = entry.taken; - if(entry.taken > 1) - instr_if->set_curr_instr_cycles(entry.taken); - } else { - delay = entry.not_taken; - if (entry.not_taken > 1) - instr_if->set_curr_instr_cycles(entry.not_taken); - } -#ifndef WITH_LZ4 - output<get_pc() <<"," << delay <<"," << call<<","<<(compressed?2:4) <<"\n"; -#else - auto rdbuf=ostr.rdbuf(); - ostr<get_pc() <<"," << delay <<"," << call<<","<<(compressed?2:4) <<"\n"; -#endif -} -} -}