From: Diana Picus Date: Mon, 19 Dec 2016 12:43:08 +0000 (+0000) Subject: Revert "[XRay] [compiler-rt] Move machine-dependent code into machine-dependent files." X-Git-Tag: llvmorg-4.0.0-rc1~1707 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=c0eb9963180ef33debbd4f0a0e752eb8187a80c5;p=platform%2Fupstream%2Fllvm.git Revert "[XRay] [compiler-rt] Move machine-dependent code into machine-dependent files." This reverts commit r290077, 78, 79 and 83. llvm-svn: 290101 --- diff --git a/compiler-rt/lib/xray/xray_AArch64.cc b/compiler-rt/lib/xray/xray_AArch64.cc index 8f24610..c2d33a2 100644 --- a/compiler-rt/lib/xray/xray_AArch64.cc +++ b/compiler-rt/lib/xray/xray_AArch64.cc @@ -14,26 +14,12 @@ //===----------------------------------------------------------------------===// #include "sanitizer_common/sanitizer_common.h" #include "xray_defs.h" -#include "xray_emulate_tsc.h" #include "xray_interface_internal.h" #include #include namespace __xray { -uint64_t cycleFrequency() XRAY_NEVER_INSTRUMENT { - // There is no instruction like RDTSCP in user mode on ARM. ARM's CP15 does - // not have a constant frequency like TSC on x86[_64]; it may go faster or - // slower depending on CPU's turbo or power saving modes. Furthermore, to - // read from CP15 on ARM a kernel modification or a driver is needed. - // We can not require this from users of compiler-rt. - // So on ARM we use clock_gettime(2) which gives the result in nanoseconds. - // To get the measurements per second, we scale this by the number of - // nanoseconds per second, pretending that the TSC frequency is 1GHz and - // one TSC tick is 1 nanosecond. - return NanosecondsPerSecond; -} - // The machine codes for some instructions used in runtime patching. enum class PatchOpcodes : uint32_t { PO_StpX0X30SP_m16e = 0xA9BF7BE0, // STP X0, X30, [SP, #-16]! diff --git a/compiler-rt/lib/xray/xray_arm.cc b/compiler-rt/lib/xray/xray_arm.cc index d89322e..9ce8451 100644 --- a/compiler-rt/lib/xray/xray_arm.cc +++ b/compiler-rt/lib/xray/xray_arm.cc @@ -14,26 +14,12 @@ //===----------------------------------------------------------------------===// #include "sanitizer_common/sanitizer_common.h" #include "xray_defs.h" -#include "xray_emulate_tsc.h" #include "xray_interface_internal.h" #include #include namespace __xray { -uint64_t cycleFrequency() XRAY_NEVER_INSTRUMENT { - // There is no instruction like RDTSCP in user mode on ARM. ARM's CP15 does - // not have a constant frequency like TSC on x86[_64]; it may go faster or - // slower depending on CPU's turbo or power saving modes. Furthermore, to - // read from CP15 on ARM a kernel modification or a driver is needed. - // We can not require this from users of compiler-rt. - // So on ARM we use clock_gettime(2) which gives the result in nanoseconds. - // To get the measurements per second, we scale this by the number of - // nanoseconds per second, pretending that the TSC frequency is 1GHz and - // one TSC tick is 1 nanosecond. - return NanosecondsPerSecond; -} - // The machine codes for some instructions used in runtime patching. enum class PatchOpcodes : uint32_t { PO_PushR0Lr = 0xE92D4001, // PUSH {r0, lr} diff --git a/compiler-rt/lib/xray/xray_emulate_tsc.h b/compiler-rt/lib/xray/xray_emulate_tsc.h deleted file mode 100644 index dd8378c..0000000 --- a/compiler-rt/lib/xray/xray_emulate_tsc.h +++ /dev/null @@ -1,39 +0,0 @@ -//===-- xray_emulate_tsc.h --------------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file is a part of XRay, a dynamic runtime instrumentation system. -// -//===----------------------------------------------------------------------===// -#ifndef XRAY_EMULATE_TSC_H -#define XRAY_EMULATE_TSC_H - -#include "sanitizer_common/sanitizer_internal_defs.h" -#include "xray_defs.h" -#include -#include -#include - -namespace __xray { - -static constexpr uint64_t NanosecondsPerSecond = 1000ULL * 1000 * 1000; - -ALWAYS_INLINE uint64_t readTSC(uint8_t &CPU) XRAY_NEVER_INSTRUMENT { - timespec TS; - int result = clock_gettime(CLOCK_REALTIME, &TS); - if (result != 0) { - Report("clock_gettime(2) returned %d, errno=%d.", result, int(errno)); - TS.tv_sec = 0; - TS.tv_nsec = 0; - } - CPU = 0; - return TS.tv_sec * NanosecondsPerSecond + TS.tv_nsec; -} -} - -#endif // XRAY_EMULATE_TSC_H diff --git a/compiler-rt/lib/xray/xray_inmemory_log.cc b/compiler-rt/lib/xray/xray_inmemory_log.cc index 7ec56f4..a93972d 100644 --- a/compiler-rt/lib/xray/xray_inmemory_log.cc +++ b/compiler-rt/lib/xray/xray_inmemory_log.cc @@ -16,7 +16,6 @@ //===----------------------------------------------------------------------===// #include -#include #include #include #include @@ -27,12 +26,12 @@ #include #if defined(__x86_64__) -#include "xray_x86_64.h" +#include #elif defined(__arm__) || defined(__aarch64__) -#include "xray_emulate_tsc.h" +static const int64_t NanosecondsPerSecond = 1000LL * 1000 * 1000; #else #error "Unsupported CPU Architecture" -#endif /* Architecture-specific inline intrinsics */ +#endif /* CPU architecture */ #include "sanitizer_common/sanitizer_libc.h" #include "xray/xray_records.h" @@ -72,6 +71,52 @@ static void retryingWriteAll(int Fd, char *Begin, } } +#if defined(__x86_64__) +static std::pair +retryingReadSome(int Fd, char *Begin, char *End) XRAY_NEVER_INSTRUMENT { + auto BytesToRead = std::distance(Begin, End); + ssize_t BytesRead; + ssize_t TotalBytesRead = 0; + while (BytesToRead && (BytesRead = read(Fd, Begin, BytesToRead))) { + if (BytesRead == -1) { + if (errno == EINTR) + continue; + Report("Read error; errno = %d\n", errno); + return std::make_pair(TotalBytesRead, false); + } + + TotalBytesRead += BytesRead; + BytesToRead -= BytesRead; + Begin += BytesRead; + } + return std::make_pair(TotalBytesRead, true); +} + +static bool readValueFromFile(const char *Filename, + long long *Value) XRAY_NEVER_INSTRUMENT { + int Fd = open(Filename, O_RDONLY | O_CLOEXEC); + if (Fd == -1) + return false; + static constexpr size_t BufSize = 256; + char Line[BufSize] = {}; + ssize_t BytesRead; + bool Success; + std::tie(BytesRead, Success) = retryingReadSome(Fd, Line, Line + BufSize); + if (!Success) + return false; + close(Fd); + char *End = nullptr; + long long Tmp = internal_simple_strtoll(Line, &End, 10); + bool Result = false; + if (Line[0] != '\0' && (*End == '\n' || *End == '\0')) { + *Value = Tmp; + Result = true; + } + return Result; +} + +#endif /* CPU architecture */ + class ThreadExitFlusher { int Fd; XRayRecord *Start; @@ -106,46 +151,6 @@ void PrintToStdErr(const char *Buffer) XRAY_NEVER_INSTRUMENT { fprintf(stderr, "%s", Buffer); } -static int __xray_OpenLogFile() XRAY_NEVER_INSTRUMENT { - // FIXME: Figure out how to make this less stderr-dependent. - SetPrintfAndReportCallback(PrintToStdErr); - // Open a temporary file once for the log. - static char TmpFilename[256] = {}; - static char TmpWildcardPattern[] = "XXXXXX"; - auto E = internal_strncat(TmpFilename, flags()->xray_logfile_base, - sizeof(TmpFilename) - 10); - if (static_cast((E + 6) - TmpFilename) > (sizeof(TmpFilename) - 1)) { - Report("XRay log file base too long: %s\n", flags()->xray_logfile_base); - return -1; - } - internal_strncat(TmpFilename, TmpWildcardPattern, - sizeof(TmpWildcardPattern) - 1); - int Fd = mkstemp(TmpFilename); - if (Fd == -1) { - Report("XRay: Failed opening temporary file '%s'; not logging events.\n", - TmpFilename); - return -1; - } - if (Verbosity()) - fprintf(stderr, "XRay: Log file in '%s'\n", TmpFilename); - - // Since we're here, we get to write the header. We set it up so that the - // header will only be written once, at the start, and let the threads - // logging do writes which just append. - XRayFileHeader Header; - Header.Version = 1; - Header.Type = FileTypes::NAIVE_LOG; - Header.CycleFrequency = __xray::cycleFrequency(); - - // FIXME: Actually check whether we have 'constant_tsc' and 'nonstop_tsc' - // before setting the values in the header. - Header.ConstantTSC = 1; - Header.NonstopTSC = 1; - retryingWriteAll(Fd, reinterpret_cast(&Header), - reinterpret_cast(&Header) + sizeof(Header)); - return Fd; -} - void __xray_InMemoryRawLog(int32_t FuncId, XRayEntryType Type) XRAY_NEVER_INSTRUMENT { using Buffer = @@ -153,7 +158,75 @@ void __xray_InMemoryRawLog(int32_t FuncId, static constexpr size_t BuffLen = 1024; thread_local static Buffer InMemoryBuffer[BuffLen] = {}; thread_local static size_t Offset = 0; - static int Fd = __xray_OpenLogFile(); + static int Fd = [] { + // FIXME: Figure out how to make this less stderr-dependent. + SetPrintfAndReportCallback(PrintToStdErr); + // Open a temporary file once for the log. + static char TmpFilename[256] = {}; + static char TmpWildcardPattern[] = "XXXXXX"; + auto E = internal_strncat(TmpFilename, flags()->xray_logfile_base, + sizeof(TmpFilename) - 10); + if (static_cast((E + 6) - TmpFilename) > + (sizeof(TmpFilename) - 1)) { + Report("XRay log file base too long: %s\n", flags()->xray_logfile_base); + return -1; + } + internal_strncat(TmpFilename, TmpWildcardPattern, + sizeof(TmpWildcardPattern) - 1); + int Fd = mkstemp(TmpFilename); + if (Fd == -1) { + Report("XRay: Failed opening temporary file '%s'; not logging events.\n", + TmpFilename); + return -1; + } + if (Verbosity()) + fprintf(stderr, "XRay: Log file in '%s'\n", TmpFilename); + + // Get the cycle frequency from SysFS on Linux. + long long CPUFrequency = -1; +#if defined(__x86_64__) + if (readValueFromFile("/sys/devices/system/cpu/cpu0/tsc_freq_khz", + &CPUFrequency)) { + CPUFrequency *= 1000; + } else if (readValueFromFile( + "/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq", + &CPUFrequency)) { + CPUFrequency *= 1000; + } else { + Report("Unable to determine CPU frequency for TSC accounting.\n"); + } +#elif defined(__arm__) || defined(__aarch64__) + // There is no instruction like RDTSCP in user mode on ARM. ARM's CP15 does + // not have a constant frequency like TSC on x86(_64), it may go faster + // or slower depending on CPU turbo or power saving mode. Furthermore, + // to read from CP15 on ARM a kernel modification or a driver is needed. + // We can not require this from users of compiler-rt. + // So on ARM we use clock_gettime() which gives the result in nanoseconds. + // To get the measurements per second, we scale this by the number of + // nanoseconds per second, pretending that the TSC frequency is 1GHz and + // one TSC tick is 1 nanosecond. + CPUFrequency = NanosecondsPerSecond; +#else +#error "Unsupported CPU Architecture" +#endif /* CPU architecture */ + + // Since we're here, we get to write the header. We set it up so that the + // header will only be written once, at the start, and let the threads + // logging do writes which just append. + XRayFileHeader Header; + Header.Version = 1; + Header.Type = FileTypes::NAIVE_LOG; + Header.CycleFrequency = + CPUFrequency == -1 ? 0 : static_cast(CPUFrequency); + + // FIXME: Actually check whether we have 'constant_tsc' and 'nonstop_tsc' + // before setting the values in the header. + Header.ConstantTSC = 1; + Header.NonstopTSC = 1; + retryingWriteAll(Fd, reinterpret_cast(&Header), + reinterpret_cast(&Header) + sizeof(Header)); + return Fd; + }(); if (Fd == -1) return; thread_local __xray::ThreadExitFlusher Flusher( @@ -164,7 +237,27 @@ void __xray_InMemoryRawLog(int32_t FuncId, // through a pointer offset. auto &R = reinterpret_cast<__xray::XRayRecord *>(InMemoryBuffer)[Offset]; R.RecordType = RecordTypes::NORMAL; - R.TSC = __xray::readTSC(R.CPU); +#if defined(__x86_64__) + { + unsigned CPU; + R.TSC = __rdtscp(&CPU); + R.CPU = CPU; + } +#elif defined(__arm__) || defined(__aarch64__) + { + timespec TS; + int result = clock_gettime(CLOCK_REALTIME, &TS); + if (result != 0) { + Report("clock_gettime() returned %d, errno=%d.\n", result, int(errno)); + TS.tv_sec = 0; + TS.tv_nsec = 0; + } + R.TSC = TS.tv_sec * NanosecondsPerSecond + TS.tv_nsec; + R.CPU = 0; + } +#else +#error "Unsupported CPU Architecture" +#endif /* CPU architecture */ R.TId = TId; R.Type = Type; R.FuncId = FuncId; diff --git a/compiler-rt/lib/xray/xray_interface_internal.h b/compiler-rt/lib/xray/xray_interface_internal.h index a8434a6..c4f7243 100644 --- a/compiler-rt/lib/xray/xray_interface_internal.h +++ b/compiler-rt/lib/xray/xray_interface_internal.h @@ -48,8 +48,6 @@ struct XRaySledMap { size_t Entries; }; -uint64_t cycleFrequency(); - bool patchFunctionEntry(bool Enable, uint32_t FuncId, const XRaySledEntry &Sled); bool patchFunctionExit(bool Enable, uint32_t FuncId, const XRaySledEntry &Sled); diff --git a/compiler-rt/lib/xray/xray_x86_64.cc b/compiler-rt/lib/xray/xray_x86_64.cc index 74bd9cf..09ca34c 100644 --- a/compiler-rt/lib/xray/xray_x86_64.cc +++ b/compiler-rt/lib/xray/xray_x86_64.cc @@ -3,71 +3,10 @@ #include "xray_interface_internal.h" #include #include -#include #include -#include -#include namespace __xray { -static std::pair -retryingReadSome(int Fd, char *Begin, char *End) XRAY_NEVER_INSTRUMENT { - auto BytesToRead = std::distance(Begin, End); - ssize_t BytesRead; - ssize_t TotalBytesRead = 0; - while (BytesToRead && (BytesRead = read(Fd, Begin, BytesToRead))) { - if (BytesRead == -1) { - if (errno == EINTR) - continue; - Report("Read error; errno = %d\n", errno); - return std::make_pair(TotalBytesRead, false); - } - - TotalBytesRead += BytesRead; - BytesToRead -= BytesRead; - Begin += BytesRead; - } - return std::make_pair(TotalBytesRead, true); -} - -static bool readValueFromFile(const char *Filename, - long long *Value) XRAY_NEVER_INSTRUMENT { - int Fd = open(Filename, O_RDONLY | O_CLOEXEC); - if (Fd == -1) - return false; - static constexpr size_t BufSize = 256; - char Line[BufSize] = {}; - ssize_t BytesRead; - bool Success; - std::tie(BytesRead, Success) = retryingReadSome(Fd, Line, Line + BufSize); - if (!Success) - return false; - close(Fd); - char *End = nullptr; - long long Tmp = internal_simple_strtoll(Line, &End, 10); - bool Result = false; - if (Line[0] != '\0' && (*End == '\n' || *End == '\0')) { - *Value = Tmp; - Result = true; - } - return Result; -} - -uint64_t cycleFrequency() XRAY_NEVER_INSTRUMENT { - long long CPUFrequency = -1; - if (readValueFromFile("/sys/devices/system/cpu/cpu0/tsc_freq_khz", - &CPUFrequency)) { - CPUFrequency *= 1000; - } else if (readValueFromFile( - "/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq", - &CPUFrequency)) { - CPUFrequency *= 1000; - } else { - Report("Unable to determine CPU frequency for TSC accounting.\n"); - } - return CPUFrequency == -1 ? 0 : static_cast(CPUFrequency); -} - static constexpr uint8_t CallOpCode = 0xe8; static constexpr uint16_t MovR10Seq = 0xba41; static constexpr uint16_t Jmp9Seq = 0x09eb; diff --git a/compiler-rt/lib/xray/xray_x86_64.h b/compiler-rt/lib/xray/xray_x86_64.h deleted file mode 100644 index 52d2dea..0000000 --- a/compiler-rt/lib/xray/xray_x86_64.h +++ /dev/null @@ -1,32 +0,0 @@ -//===-- xray_x86_64.h -------------------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file is a part of XRay, a dynamic runtime instrumentation system. -// -//===----------------------------------------------------------------------===// -#ifndef XRAY_X86_64_H -#define XRAY_X86_64_H - -#include -#include - -#include "sanitizer_common/sanitizer_internal_defs.h" -#include "xray_defs.h" - -namespace __xray { - -ALWAYS_INLINE uint64_t readTSC(uint8_t &CPU) XRAY_NEVER_INSTRUMENT { - unsigned LongCPU; - uint64_t TSC = __rdtscp(&LongCPU); - CPU = LongCPU; - return TSC; -} -} - -#endif // XRAY_X86_64_H