summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDean Michael Berris <dberris@google.com>2017-10-27 23:59:41 +0000
committerDean Michael Berris <dberris@google.com>2017-10-27 23:59:41 +0000
commit35f3b0cf471b703311360e8357717653ec490ccb (patch)
tree8977164308090887abb3705a546087d38178b5f2
parent0c8987ad277c57f75859487ab81ca85b15db2380 (diff)
downloadcompiler-rt-35f3b0cf471b703311360e8357717653ec490ccb.tar.gz
[XRay][compiler-rt] Remove more STL dependenices from FDR mode
Summary: This change removes dependencies on STL types: - std::aligned_storage -- we're using manually-aligned character buffers instead for metadata and function records. - std::tuple -- use a plain old struct instead. This is an incremental step in removing all STL references from the compiler-rt implementation of XRay (llvm.org/PR32274). Reviewers: dblaikie, pelikan, kpw Subscribers: llvm-commits Differential Revision: https://reviews.llvm.org/D39277 git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@316816 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/xray/xray_fdr_logging.cc46
-rw-r--r--lib/xray/xray_fdr_logging_impl.h49
2 files changed, 42 insertions, 53 deletions
diff --git a/lib/xray/xray_fdr_logging.cc b/lib/xray/xray_fdr_logging.cc
index 90eb6c572..2ad68cbac 100644
--- a/lib/xray/xray_fdr_logging.cc
+++ b/lib/xray/xray_fdr_logging.cc
@@ -15,15 +15,10 @@
//
//===----------------------------------------------------------------------===//
#include "xray_fdr_logging.h"
-#include <algorithm>
-#include <bitset>
-#include <cerrno>
-#include <cstring>
#include <sys/syscall.h>
#include <sys/time.h>
#include <time.h>
#include <unistd.h>
-#include <unordered_map>
#include "sanitizer_common/sanitizer_atomic.h"
#include "sanitizer_common/sanitizer_common.h"
@@ -176,19 +171,22 @@ XRayLogInitStatus fdrLoggingReset() XRAY_NEVER_INSTRUMENT {
return XRayLogInitStatus::XRAY_LOG_UNINITIALIZED;
}
-static std::tuple<uint64_t, unsigned char>
-getTimestamp() XRAY_NEVER_INSTRUMENT {
+struct TSCAndCPU {
+ uint64_t TSC;
+ unsigned char CPU;
+};
+
+static TSCAndCPU getTimestamp() XRAY_NEVER_INSTRUMENT {
// We want to get the TSC as early as possible, so that we can check whether
// we've seen this CPU before. We also do it before we load anything else, to
// allow for forward progress with the scheduling.
- unsigned char CPU;
- uint64_t TSC;
+ TSCAndCPU Result;
// Test once for required CPU features
static bool TSCSupported = probeRequiredCPUFeatures();
if (TSCSupported) {
- TSC = __xray::readTSC(CPU);
+ Result.TSC = __xray::readTSC(Result.CPU);
} else {
// FIXME: This code needs refactoring as it appears in multiple locations
timespec TS;
@@ -197,34 +195,32 @@ getTimestamp() XRAY_NEVER_INSTRUMENT {
Report("clock_gettime(2) return %d, errno=%d", result, int(errno));
TS = {0, 0};
}
- CPU = 0;
- TSC = TS.tv_sec * __xray::NanosecondsPerSecond + TS.tv_nsec;
+ Result.CPU = 0;
+ Result.TSC = TS.tv_sec * __xray::NanosecondsPerSecond + TS.tv_nsec;
}
- return std::make_tuple(TSC, CPU);
+ return Result;
}
void fdrLoggingHandleArg0(int32_t FuncId,
XRayEntryType Entry) XRAY_NEVER_INSTRUMENT {
- auto TSC_CPU = getTimestamp();
- __xray_fdr_internal::processFunctionHook(FuncId, Entry, std::get<0>(TSC_CPU),
- std::get<1>(TSC_CPU), 0,
- clock_gettime, *BQ);
+ auto TC = getTimestamp();
+ __xray_fdr_internal::processFunctionHook(FuncId, Entry, TC.TSC,
+ TC.CPU, 0, clock_gettime, *BQ);
}
void fdrLoggingHandleArg1(int32_t FuncId, XRayEntryType Entry,
uint64_t Arg) XRAY_NEVER_INSTRUMENT {
- auto TSC_CPU = getTimestamp();
- __xray_fdr_internal::processFunctionHook(FuncId, Entry, std::get<0>(TSC_CPU),
- std::get<1>(TSC_CPU), Arg,
- clock_gettime, *BQ);
+ auto TC = getTimestamp();
+ __xray_fdr_internal::processFunctionHook(
+ FuncId, Entry, TC.TSC, TC.CPU, Arg, clock_gettime, *BQ);
}
void fdrLoggingHandleCustomEvent(void *Event,
std::size_t EventSize) XRAY_NEVER_INSTRUMENT {
using namespace __xray_fdr_internal;
- auto TSC_CPU = getTimestamp();
- auto &TSC = std::get<0>(TSC_CPU);
- auto &CPU = std::get<1>(TSC_CPU);
+ auto TC = getTimestamp();
+ auto &TSC = TC.TSC;
+ auto &CPU = TC.CPU;
RecursionGuard Guard{Running};
if (!Guard) {
assert(Running && "RecursionGuard is buggy!");
@@ -261,7 +257,7 @@ void fdrLoggingHandleCustomEvent(void *Event,
CustomEvent.Type = uint8_t(RecordType::Metadata);
CustomEvent.RecordKind =
uint8_t(MetadataRecord::RecordKinds::CustomEventMarker);
- constexpr auto TSCSize = sizeof(std::get<0>(TSC_CPU));
+ constexpr auto TSCSize = sizeof(TC.TSC);
std::memcpy(&CustomEvent.Data, &ReducedEventSize, sizeof(int32_t));
std::memcpy(&CustomEvent.Data[sizeof(int32_t)], &TSC, TSCSize);
std::memcpy(TLD.RecordPtr, &CustomEvent, sizeof(CustomEvent));
diff --git a/lib/xray/xray_fdr_logging_impl.h b/lib/xray/xray_fdr_logging_impl.h
index f7c77c6c2..c109d1384 100644
--- a/lib/xray/xray_fdr_logging_impl.h
+++ b/lib/xray/xray_fdr_logging_impl.h
@@ -18,16 +18,17 @@
#define XRAY_XRAY_FDR_LOGGING_IMPL_H
#include <cassert>
-#include <cstdint>
+#include <cstddef>
#include <cstring>
#include <limits>
-#include <memory>
#include <pthread.h>
-#include <string>
#include <sys/syscall.h>
#include <time.h>
#include <unistd.h>
+// FIXME: Implement analogues to std::shared_ptr and std::weak_ptr
+#include <memory>
+
#include "sanitizer_common/sanitizer_common.h"
#include "xray/xray_log_interface.h"
#include "xray_buffer_queue.h"
@@ -96,7 +97,7 @@ static void writeTSCWrapMetadata(uint64_t TSC);
// call so that it can be initialized on first use instead of as a global. We
// force the alignment to 64-bytes for x86 cache line alignment, as this
// structure is used in the hot path of implementation.
-struct ALIGNED(64) ThreadLocalData {
+struct alignas(64) ThreadLocalData {
BufferQueue::Buffer Buffer;
char *RecordPtr = nullptr;
// The number of FunctionEntry records immediately preceding RecordPtr.
@@ -176,8 +177,8 @@ static ThreadLocalData &getThreadLocalData() {
// We need aligned, uninitialized storage for the TLS object which is
// trivially destructible. We're going to use this as raw storage and
// placement-new the ThreadLocalData object into it later.
- thread_local std::aligned_storage<sizeof(ThreadLocalData),
- alignof(ThreadLocalData)>::type TLSBuffer;
+ alignas(alignof(ThreadLocalData)) thread_local unsigned char
+ TLSBuffer[sizeof(ThreadLocalData)];
// Ensure that we only actually ever do the pthread initialization once.
thread_local bool UNUSED Unused = [] {
@@ -215,7 +216,7 @@ static ThreadLocalData &getThreadLocalData() {
return true;
}();
- return *reinterpret_cast<ThreadLocalData *>(&TLSBuffer);
+ return *reinterpret_cast<ThreadLocalData *>(TLSBuffer);
}
//-----------------------------------------------------------------------------|
@@ -255,14 +256,15 @@ public:
inline void writeNewBufferPreamble(pid_t Tid, timespec TS,
char *&MemPtr) XRAY_NEVER_INSTRUMENT {
static constexpr int InitRecordsCount = 2;
- std::aligned_storage<sizeof(MetadataRecord)>::type Records[InitRecordsCount];
+ alignas(alignof(MetadataRecord)) unsigned char
+ Records[InitRecordsCount * MetadataRecSize];
{
// Write out a MetadataRecord to signify that this is the start of a new
// buffer, associated with a particular thread, with a new CPU. For the
// data, we have 15 bytes to squeeze as much information as we can. At this
// point we only write down the following bytes:
// - Thread ID (pid_t, 4 bytes)
- auto &NewBuffer = *reinterpret_cast<MetadataRecord *>(&Records[0]);
+ auto &NewBuffer = *reinterpret_cast<MetadataRecord *>(Records);
NewBuffer.Type = uint8_t(RecordType::Metadata);
NewBuffer.RecordKind = uint8_t(MetadataRecord::RecordKinds::NewBuffer);
std::memcpy(&NewBuffer.Data, &Tid, sizeof(pid_t));
@@ -270,7 +272,8 @@ inline void writeNewBufferPreamble(pid_t Tid, timespec TS,
// Also write the WalltimeMarker record.
{
static_assert(sizeof(time_t) <= 8, "time_t needs to be at most 8 bytes");
- auto &WalltimeMarker = *reinterpret_cast<MetadataRecord *>(&Records[1]);
+ auto &WalltimeMarker =
+ *reinterpret_cast<MetadataRecord *>(Records + MetadataRecSize);
WalltimeMarker.Type = uint8_t(RecordType::Metadata);
WalltimeMarker.RecordKind =
uint8_t(MetadataRecord::RecordKinds::WalltimeMarker);
@@ -382,10 +385,7 @@ static inline void writeCallArgumentMetadata(uint64_t A) XRAY_NEVER_INSTRUMENT {
static inline void writeFunctionRecord(int FuncId, uint32_t TSCDelta,
XRayEntryType EntryType,
char *&MemPtr) XRAY_NEVER_INSTRUMENT {
- std::aligned_storage<sizeof(FunctionRecord), alignof(FunctionRecord)>::type
- AlignedFuncRecordBuffer;
- auto &FuncRecord =
- *reinterpret_cast<FunctionRecord *>(&AlignedFuncRecordBuffer);
+ FunctionRecord FuncRecord;
FuncRecord.Type = uint8_t(RecordType::Function);
// Only take 28 bits of the function id.
FuncRecord.FuncId = FuncId & ~(0x0F << 28);
@@ -439,7 +439,7 @@ static inline void writeFunctionRecord(int FuncId, uint32_t TSCDelta,
}
}
- std::memcpy(MemPtr, &AlignedFuncRecordBuffer, sizeof(FunctionRecord));
+ std::memcpy(MemPtr, &FuncRecord, sizeof(FunctionRecord));
MemPtr += sizeof(FunctionRecord);
}
@@ -456,14 +456,10 @@ static uint64_t thresholdTicks() {
// "Function Entry" record and any "Tail Call Exit" records after that.
static void rewindRecentCall(uint64_t TSC, uint64_t &LastTSC,
uint64_t &LastFunctionEntryTSC, int32_t FuncId) {
- using AlignedFuncStorage =
- std::aligned_storage<sizeof(FunctionRecord),
- alignof(FunctionRecord)>::type;
auto &TLD = getThreadLocalData();
TLD.RecordPtr -= FunctionRecSize;
- AlignedFuncStorage AlignedFuncRecordBuffer;
- const auto &FuncRecord = *reinterpret_cast<FunctionRecord *>(
- std::memcpy(&AlignedFuncRecordBuffer, TLD.RecordPtr, FunctionRecSize));
+ FunctionRecord FuncRecord;
+ std::memcpy(&FuncRecord, TLD.RecordPtr, FunctionRecSize);
assert(FuncRecord.RecordKind ==
uint8_t(FunctionRecord::RecordKinds::FunctionEnter) &&
"Expected to find function entry recording when rewinding.");
@@ -485,20 +481,17 @@ static void rewindRecentCall(uint64_t TSC, uint64_t &LastTSC,
auto RewindingTSC = LastTSC;
auto RewindingRecordPtr = TLD.RecordPtr - FunctionRecSize;
while (TLD.NumTailCalls > 0) {
- AlignedFuncStorage TailExitRecordBuffer;
// Rewind the TSC back over the TAIL EXIT record.
- const auto &ExpectedTailExit =
- *reinterpret_cast<FunctionRecord *>(std::memcpy(
- &TailExitRecordBuffer, RewindingRecordPtr, FunctionRecSize));
+ FunctionRecord ExpectedTailExit;
+ std::memcpy(&ExpectedTailExit, RewindingRecordPtr, FunctionRecSize);
assert(ExpectedTailExit.RecordKind ==
uint8_t(FunctionRecord::RecordKinds::FunctionTailExit) &&
"Expected to find tail exit when rewinding.");
RewindingRecordPtr -= FunctionRecSize;
RewindingTSC -= ExpectedTailExit.TSCDelta;
- AlignedFuncStorage FunctionEntryBuffer;
- const auto &ExpectedFunctionEntry = *reinterpret_cast<FunctionRecord *>(
- std::memcpy(&FunctionEntryBuffer, RewindingRecordPtr, FunctionRecSize));
+ FunctionRecord ExpectedFunctionEntry;
+ std::memcpy(&ExpectedFunctionEntry, RewindingRecordPtr, FunctionRecSize);
assert(ExpectedFunctionEntry.RecordKind ==
uint8_t(FunctionRecord::RecordKinds::FunctionEnter) &&
"Expected to find function entry when rewinding tail call.");