From owner-svn-src-projects@freebsd.org Thu Aug 2 18:07:24 2018 Return-Path: Delivered-To: svn-src-projects@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 9960C106E60D for ; Thu, 2 Aug 2018 18:07:24 +0000 (UTC) (envelope-from dim@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 3BD447466F; Thu, 2 Aug 2018 18:07:24 +0000 (UTC) (envelope-from dim@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 1871615281; Thu, 2 Aug 2018 18:07:24 +0000 (UTC) (envelope-from dim@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id w72I7Nrv045591; Thu, 2 Aug 2018 18:07:23 GMT (envelope-from dim@FreeBSD.org) Received: (from dim@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id w72I7LEf045578; Thu, 2 Aug 2018 18:07:21 GMT (envelope-from dim@FreeBSD.org) Message-Id: <201808021807.w72I7LEf045578@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: dim set sender to dim@FreeBSD.org using -f From: Dimitry Andric Date: Thu, 2 Aug 2018 18:07:21 +0000 (UTC) To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r337154 - in projects/clang700-import/contrib/compiler-rt/lib: asan profile sanitizer_common ubsan ubsan_minimal xray X-SVN-Group: projects X-SVN-Commit-Author: dim X-SVN-Commit-Paths: in projects/clang700-import/contrib/compiler-rt/lib: asan profile sanitizer_common ubsan ubsan_minimal xray X-SVN-Commit-Revision: 337154 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-projects@freebsd.org X-Mailman-Version: 2.1.27 Precedence: list List-Id: "SVN commit messages for the src " projects" tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 02 Aug 2018 18:07:24 -0000 Author: dim Date: Thu Aug 2 18:07:21 2018 New Revision: 337154 URL: https://svnweb.freebsd.org/changeset/base/337154 Log: Merge compiler-rt trunk r338150 (just before the 7.0.0 branch point), and resolve conflicts. Modified: projects/clang700-import/contrib/compiler-rt/lib/asan/asan_mapping.h projects/clang700-import/contrib/compiler-rt/lib/profile/InstrProfilingUtil.c projects/clang700-import/contrib/compiler-rt/lib/profile/InstrProfilingUtil.h projects/clang700-import/contrib/compiler-rt/lib/sanitizer_common/sanitizer_mutex.h projects/clang700-import/contrib/compiler-rt/lib/sanitizer_common/sanitizer_win.cc projects/clang700-import/contrib/compiler-rt/lib/ubsan/ubsan_checks.inc projects/clang700-import/contrib/compiler-rt/lib/ubsan/ubsan_diag.h projects/clang700-import/contrib/compiler-rt/lib/ubsan/ubsan_handlers.cc projects/clang700-import/contrib/compiler-rt/lib/ubsan/ubsan_handlers.h projects/clang700-import/contrib/compiler-rt/lib/ubsan/ubsan_interface.inc projects/clang700-import/contrib/compiler-rt/lib/ubsan_minimal/ubsan_minimal_handlers.cc projects/clang700-import/contrib/compiler-rt/lib/xray/xray_buffer_queue.cc projects/clang700-import/contrib/compiler-rt/lib/xray/xray_profile_collector.cc projects/clang700-import/contrib/compiler-rt/lib/xray/xray_profiling.cc Directory Properties: projects/clang700-import/contrib/compiler-rt/ (props changed) Modified: projects/clang700-import/contrib/compiler-rt/lib/asan/asan_mapping.h ============================================================================== --- projects/clang700-import/contrib/compiler-rt/lib/asan/asan_mapping.h Thu Aug 2 18:04:37 2018 (r337153) +++ projects/clang700-import/contrib/compiler-rt/lib/asan/asan_mapping.h Thu Aug 2 18:07:21 2018 (r337154) @@ -122,7 +122,7 @@ // || `[0x400000000000, 0x47ffffffffff]` || LowShadow || // || `[0x000000000000, 0x3fffffffffff]` || LowMem || // -// Shadow mapping on NerBSD/i386 with SHADOW_OFFSET == 0x40000000: +// Shadow mapping on NetBSD/i386 with SHADOW_OFFSET == 0x40000000: // || `[0x60000000, 0xfffff000]` || HighMem || // || `[0x4c000000, 0x5fffffff]` || HighShadow || // || `[0x48000000, 0x4bffffff]` || ShadowGap || Modified: projects/clang700-import/contrib/compiler-rt/lib/profile/InstrProfilingUtil.c ============================================================================== --- projects/clang700-import/contrib/compiler-rt/lib/profile/InstrProfilingUtil.c Thu Aug 2 18:04:37 2018 (r337153) +++ projects/clang700-import/contrib/compiler-rt/lib/profile/InstrProfilingUtil.c Thu Aug 2 18:07:21 2018 (r337154) @@ -35,6 +35,8 @@ #include "InstrProfiling.h" #include "InstrProfilingUtil.h" +COMPILER_RT_WEAK unsigned lprofDirMode = 0755; + COMPILER_RT_VISIBILITY void __llvm_profile_recursive_mkdir(char *path) { int i; @@ -47,11 +49,18 @@ void __llvm_profile_recursive_mkdir(char *path) { #ifdef _WIN32 _mkdir(path); #else - mkdir(path, 0755); /* Some of these will fail, ignore it. */ + /* Some of these will fail, ignore it. */ + mkdir(path, __llvm_profile_get_dir_mode()); #endif path[i] = save; } } + +COMPILER_RT_VISIBILITY +void __llvm_profile_set_dir_mode(unsigned Mode) { lprofDirMode = Mode; } + +COMPILER_RT_VISIBILITY +unsigned __llvm_profile_get_dir_mode(void) { return lprofDirMode; } #if COMPILER_RT_HAS_ATOMICS != 1 COMPILER_RT_VISIBILITY Modified: projects/clang700-import/contrib/compiler-rt/lib/profile/InstrProfilingUtil.h ============================================================================== --- projects/clang700-import/contrib/compiler-rt/lib/profile/InstrProfilingUtil.h Thu Aug 2 18:04:37 2018 (r337153) +++ projects/clang700-import/contrib/compiler-rt/lib/profile/InstrProfilingUtil.h Thu Aug 2 18:07:21 2018 (r337154) @@ -16,6 +16,12 @@ /*! \brief Create a directory tree. */ void __llvm_profile_recursive_mkdir(char *Pathname); +/*! Set the mode used when creating profile directories. */ +void __llvm_profile_set_dir_mode(unsigned Mode); + +/*! Return the directory creation mode. */ +unsigned __llvm_profile_get_dir_mode(void); + int lprofLockFd(int fd); int lprofUnlockFd(int fd); Modified: projects/clang700-import/contrib/compiler-rt/lib/sanitizer_common/sanitizer_mutex.h ============================================================================== --- projects/clang700-import/contrib/compiler-rt/lib/sanitizer_common/sanitizer_mutex.h Thu Aug 2 18:04:37 2018 (r337153) +++ projects/clang700-import/contrib/compiler-rt/lib/sanitizer_common/sanitizer_mutex.h Thu Aug 2 18:07:21 2018 (r337154) @@ -73,13 +73,8 @@ class SpinMutex : public StaticSpinMutex { class BlockingMutex { public: -#if SANITIZER_WINDOWS - // Windows does not currently support LinkerInitialized - explicit BlockingMutex(LinkerInitialized); -#else explicit constexpr BlockingMutex(LinkerInitialized) - : opaque_storage_ {0, }, owner_(0) {} -#endif + : opaque_storage_ {0, }, owner_ {0} {} BlockingMutex(); void Lock(); void Unlock(); Modified: projects/clang700-import/contrib/compiler-rt/lib/sanitizer_common/sanitizer_win.cc ============================================================================== --- projects/clang700-import/contrib/compiler-rt/lib/sanitizer_common/sanitizer_win.cc Thu Aug 2 18:04:37 2018 (r337153) +++ projects/clang700-import/contrib/compiler-rt/lib/sanitizer_common/sanitizer_win.cc Thu Aug 2 18:07:21 2018 (r337154) @@ -767,43 +767,22 @@ void *internal_start_thread(void (*func)(void *arg), v void internal_join_thread(void *th) { } // ---------------------- BlockingMutex ---------------- {{{1 -const uptr LOCK_UNINITIALIZED = 0; -const uptr LOCK_READY = (uptr)-1; -BlockingMutex::BlockingMutex(LinkerInitialized li) { - // FIXME: see comments in BlockingMutex::Lock() for the details. - CHECK(li == LINKER_INITIALIZED || owner_ == LOCK_UNINITIALIZED); - - CHECK(sizeof(CRITICAL_SECTION) <= sizeof(opaque_storage_)); - InitializeCriticalSection((LPCRITICAL_SECTION)opaque_storage_); - owner_ = LOCK_READY; -} - BlockingMutex::BlockingMutex() { - CHECK(sizeof(CRITICAL_SECTION) <= sizeof(opaque_storage_)); - InitializeCriticalSection((LPCRITICAL_SECTION)opaque_storage_); - owner_ = LOCK_READY; + CHECK(sizeof(SRWLOCK) <= sizeof(opaque_storage_)); + internal_memset(this, 0, sizeof(*this)); } void BlockingMutex::Lock() { - if (owner_ == LOCK_UNINITIALIZED) { - // FIXME: hm, global BlockingMutex objects are not initialized?!? - // This might be a side effect of the clang+cl+link Frankenbuild... - new(this) BlockingMutex((LinkerInitialized)(LINKER_INITIALIZED + 1)); - - // FIXME: If it turns out the linker doesn't invoke our - // constructors, we should probably manually Lock/Unlock all the global - // locks while we're starting in one thread to avoid double-init races. - } - EnterCriticalSection((LPCRITICAL_SECTION)opaque_storage_); - CHECK_EQ(owner_, LOCK_READY); + AcquireSRWLockExclusive((PSRWLOCK)opaque_storage_); + CHECK_EQ(owner_, 0); owner_ = GetThreadSelf(); } void BlockingMutex::Unlock() { - CHECK_EQ(owner_, GetThreadSelf()); - owner_ = LOCK_READY; - LeaveCriticalSection((LPCRITICAL_SECTION)opaque_storage_); + CheckLocked(); + owner_ = 0; + ReleaseSRWLockExclusive((PSRWLOCK)opaque_storage_); } void BlockingMutex::CheckLocked() { Modified: projects/clang700-import/contrib/compiler-rt/lib/ubsan/ubsan_checks.inc ============================================================================== --- projects/clang700-import/contrib/compiler-rt/lib/ubsan/ubsan_checks.inc Thu Aug 2 18:04:37 2018 (r337153) +++ projects/clang700-import/contrib/compiler-rt/lib/ubsan/ubsan_checks.inc Thu Aug 2 18:07:21 2018 (r337154) @@ -30,6 +30,8 @@ UBSAN_CHECK(IntegerDivideByZero, "integer-divide-by-ze "integer-divide-by-zero") UBSAN_CHECK(FloatDivideByZero, "float-divide-by-zero", "float-divide-by-zero") UBSAN_CHECK(InvalidBuiltin, "invalid-builtin-use", "invalid-builtin-use") +UBSAN_CHECK(ImplicitIntegerTruncation, "implicit-integer-truncation", + "implicit-integer-truncation") UBSAN_CHECK(InvalidShiftBase, "invalid-shift-base", "shift-base") UBSAN_CHECK(InvalidShiftExponent, "invalid-shift-exponent", "shift-exponent") UBSAN_CHECK(OutOfBoundsIndex, "out-of-bounds-index", "bounds") Modified: projects/clang700-import/contrib/compiler-rt/lib/ubsan/ubsan_diag.h ============================================================================== --- projects/clang700-import/contrib/compiler-rt/lib/ubsan/ubsan_diag.h Thu Aug 2 18:04:37 2018 (r337153) +++ projects/clang700-import/contrib/compiler-rt/lib/ubsan/ubsan_diag.h Thu Aug 2 18:07:21 2018 (r337154) @@ -178,7 +178,7 @@ class Diag { (public) }; private: - static const unsigned MaxArgs = 5; + static const unsigned MaxArgs = 8; static const unsigned MaxRanges = 1; /// The arguments which have been added to this diagnostic so far. Modified: projects/clang700-import/contrib/compiler-rt/lib/ubsan/ubsan_handlers.cc ============================================================================== --- projects/clang700-import/contrib/compiler-rt/lib/ubsan/ubsan_handlers.cc Thu Aug 2 18:04:37 2018 (r337153) +++ projects/clang700-import/contrib/compiler-rt/lib/ubsan/ubsan_handlers.cc Thu Aug 2 18:07:21 2018 (r337154) @@ -451,6 +451,49 @@ void __ubsan::__ubsan_handle_load_invalid_value_abort( Die(); } +static void handleImplicitConversion(ImplicitConversionData *Data, + ReportOptions Opts, ValueHandle Src, + ValueHandle Dst) { + SourceLocation Loc = Data->Loc.acquire(); + ErrorType ET = ErrorType::GenericUB; + + switch (Data->Kind) { + case ICCK_IntegerTruncation: + ET = ErrorType::ImplicitIntegerTruncation; + break; + } + + if (ignoreReport(Loc, Opts, ET)) + return; + + const TypeDescriptor &SrcTy = Data->FromType; + const TypeDescriptor &DstTy = Data->ToType; + + ScopedReport R(Opts, Loc, ET); + + // FIXME: is it possible to dump the values as hex with fixed width? + + Diag(Loc, DL_Error, ET, + "implicit conversion from type %0 of value %1 (%2-bit, %3signed) to " + "type %4 changed the value to %5 (%6-bit, %7signed)") + << SrcTy << Value(SrcTy, Src) << SrcTy.getIntegerBitWidth() + << (SrcTy.isSignedIntegerTy() ? "" : "un") << DstTy << Value(DstTy, Dst) + << DstTy.getIntegerBitWidth() << (DstTy.isSignedIntegerTy() ? "" : "un"); +} + +void __ubsan::__ubsan_handle_implicit_conversion(ImplicitConversionData *Data, + ValueHandle Src, + ValueHandle Dst) { + GET_REPORT_OPTIONS(false); + handleImplicitConversion(Data, Opts, Src, Dst); +} +void __ubsan::__ubsan_handle_implicit_conversion_abort( + ImplicitConversionData *Data, ValueHandle Src, ValueHandle Dst) { + GET_REPORT_OPTIONS(true); + handleImplicitConversion(Data, Opts, Src, Dst); + Die(); +} + static void handleInvalidBuiltin(InvalidBuiltinData *Data, ReportOptions Opts) { SourceLocation Loc = Data->Loc.acquire(); ErrorType ET = ErrorType::InvalidBuiltin; Modified: projects/clang700-import/contrib/compiler-rt/lib/ubsan/ubsan_handlers.h ============================================================================== --- projects/clang700-import/contrib/compiler-rt/lib/ubsan/ubsan_handlers.h Thu Aug 2 18:04:37 2018 (r337153) +++ projects/clang700-import/contrib/compiler-rt/lib/ubsan/ubsan_handlers.h Thu Aug 2 18:07:21 2018 (r337154) @@ -122,6 +122,23 @@ struct InvalidValueData { /// \brief Handle a load of an invalid value for the type. RECOVERABLE(load_invalid_value, InvalidValueData *Data, ValueHandle Val) +/// Known implicit conversion check kinds. +/// Keep in sync with the enum of the same name in CGExprScalar.cpp +enum ImplicitConversionCheckKind : unsigned char { + ICCK_IntegerTruncation = 0, +}; + +struct ImplicitConversionData { + SourceLocation Loc; + const TypeDescriptor &FromType; + const TypeDescriptor &ToType; + /* ImplicitConversionCheckKind */ unsigned char Kind; +}; + +/// \brief Implict conversion that changed the value. +RECOVERABLE(implicit_conversion, ImplicitConversionData *Data, ValueHandle Src, + ValueHandle Dst) + /// Known builtin check kinds. /// Keep in sync with the enum of the same name in CodeGenFunction.h enum BuiltinCheckKind : unsigned char { Modified: projects/clang700-import/contrib/compiler-rt/lib/ubsan/ubsan_interface.inc ============================================================================== --- projects/clang700-import/contrib/compiler-rt/lib/ubsan/ubsan_interface.inc Thu Aug 2 18:04:37 2018 (r337153) +++ projects/clang700-import/contrib/compiler-rt/lib/ubsan/ubsan_interface.inc Thu Aug 2 18:07:21 2018 (r337154) @@ -22,6 +22,8 @@ INTERFACE_FUNCTION(__ubsan_handle_float_cast_overflow) INTERFACE_FUNCTION(__ubsan_handle_float_cast_overflow_abort) INTERFACE_FUNCTION(__ubsan_handle_function_type_mismatch) INTERFACE_FUNCTION(__ubsan_handle_function_type_mismatch_abort) +INTERFACE_FUNCTION(__ubsan_handle_implicit_conversion) +INTERFACE_FUNCTION(__ubsan_handle_implicit_conversion_abort) INTERFACE_FUNCTION(__ubsan_handle_invalid_builtin) INTERFACE_FUNCTION(__ubsan_handle_invalid_builtin_abort) INTERFACE_FUNCTION(__ubsan_handle_load_invalid_value) Modified: projects/clang700-import/contrib/compiler-rt/lib/ubsan_minimal/ubsan_minimal_handlers.cc ============================================================================== --- projects/clang700-import/contrib/compiler-rt/lib/ubsan_minimal/ubsan_minimal_handlers.cc Thu Aug 2 18:04:37 2018 (r337153) +++ projects/clang700-import/contrib/compiler-rt/lib/ubsan_minimal/ubsan_minimal_handlers.cc Thu Aug 2 18:07:21 2018 (r337154) @@ -109,6 +109,7 @@ HANDLER(float_cast_overflow, "float-cast-overflow") HANDLER(load_invalid_value, "load-invalid-value") HANDLER(invalid_builtin, "invalid-builtin") HANDLER(function_type_mismatch, "function-type-mismatch") +HANDLER(implicit_conversion, "implicit-conversion") HANDLER(nonnull_arg, "nonnull-arg") HANDLER(nonnull_return, "nonnull-return") HANDLER(nullability_arg, "nullability-arg") Modified: projects/clang700-import/contrib/compiler-rt/lib/xray/xray_buffer_queue.cc ============================================================================== --- projects/clang700-import/contrib/compiler-rt/lib/xray/xray_buffer_queue.cc Thu Aug 2 18:04:37 2018 (r337153) +++ projects/clang700-import/contrib/compiler-rt/lib/xray/xray_buffer_queue.cc Thu Aug 2 18:07:21 2018 (r337154) @@ -13,17 +13,50 @@ // //===----------------------------------------------------------------------===// #include "xray_buffer_queue.h" -#include "sanitizer_common/sanitizer_allocator_internal.h" #include "sanitizer_common/sanitizer_common.h" #include "sanitizer_common/sanitizer_libc.h" +#include "sanitizer_common/sanitizer_posix.h" #include +#include +#ifndef MAP_NORESERVE +// no-op on NetBSD (at least), unsupported flag on FreeBSD +#define MAP_NORESERVE 0 +#endif + using namespace __xray; using namespace __sanitizer; +template static T *allocRaw(size_t N) { + // TODO: Report errors? + // We use MAP_NORESERVE on platforms where it's supported to ensure that the + // pages we're allocating for XRay never end up in pages that can be swapped + // in/out. We're doing this because for FDR mode, we want to ensure that + // writes to the buffers stay resident in memory to prevent XRay itself from + // causing swapping/thrashing. + // + // In the case when XRay pages cannot be swapped in/out or there's not enough + // RAM to back these pages, we're willing to cause a segmentation fault + // instead of introducing latency in the measurement. We assume here that + // there are enough pages that are swappable in/out outside of the buffers + // being used by FDR mode (which are bounded and configurable anyway) to allow + // us to keep using always-resident memory. + // + // TODO: Make this configurable? + void *A = reinterpret_cast( + internal_mmap(NULL, N * sizeof(T), PROT_WRITE | PROT_READ, + MAP_ANONYMOUS | MAP_PRIVATE | MAP_NORESERVE, -1, 0)); + return (A == MAP_FAILED) ? nullptr : reinterpret_cast(A); +} + +template static void deallocRaw(T *ptr, size_t N) { + // TODO: Report errors? + if (ptr != nullptr) + internal_munmap(ptr, N); +} + template static T *initArray(size_t N) { - auto A = reinterpret_cast( - InternalAlloc(N * sizeof(T), nullptr, kCacheLineSize)); + auto A = allocRaw(N); if (A != nullptr) while (N > 0) new (A + (--N)) T(); @@ -42,19 +75,19 @@ BufferQueue::BufferQueue(size_t B, size_t N, bool &Suc // Clean up the buffers we've already allocated. for (auto B = Buffers, E = Buffers + BufferCount; B != E; ++B) B->~BufferRep(); - InternalFree(Buffers); + deallocRaw(Buffers, N); Success = false; return; }; for (size_t i = 0; i < N; ++i) { auto &T = Buffers[i]; - void *Tmp = InternalAlloc(BufferSize, nullptr, 64); + void *Tmp = allocRaw(BufferSize); if (Tmp == nullptr) { Success = false; return; } - void *Extents = InternalAlloc(sizeof(BufferExtents), nullptr, 64); + auto *Extents = allocRaw(1); if (Extents == nullptr) { Success = false; return; @@ -62,7 +95,7 @@ BufferQueue::BufferQueue(size_t B, size_t N, bool &Suc auto &Buf = T.Buff; Buf.Data = Tmp; Buf.Size = B; - Buf.Extents = reinterpret_cast(Extents); + Buf.Extents = Extents; OwnedBuffers[i] = Tmp; } Success = true; @@ -128,11 +161,11 @@ BufferQueue::~BufferQueue() { for (auto I = Buffers, E = Buffers + BufferCount; I != E; ++I) { auto &T = *I; auto &Buf = T.Buff; - InternalFree(Buf.Data); - InternalFree(Buf.Extents); + deallocRaw(Buf.Data, Buf.Size); + deallocRaw(Buf.Extents, 1); } for (auto B = Buffers, E = Buffers + BufferCount; B != E; ++B) B->~BufferRep(); - InternalFree(Buffers); - InternalFree(OwnedBuffers); + deallocRaw(Buffers, BufferCount); + deallocRaw(OwnedBuffers, BufferCount); } Modified: projects/clang700-import/contrib/compiler-rt/lib/xray/xray_profile_collector.cc ============================================================================== --- projects/clang700-import/contrib/compiler-rt/lib/xray/xray_profile_collector.cc Thu Aug 2 18:04:37 2018 (r337153) +++ projects/clang700-import/contrib/compiler-rt/lib/xray/xray_profile_collector.cc Thu Aug 2 18:07:21 2018 (r337154) @@ -37,6 +37,19 @@ struct ProfileBuffer { size_t Size; }; +// Current version of the profile format. +constexpr u64 XRayProfilingVersion = 0x20180424; + +// Identifier for XRay profiling files 'xrayprof' in hex. +constexpr u64 XRayMagicBytes = 0x7872617970726f66; + +struct XRayProfilingFileHeader { + const u64 MagicBytes = XRayMagicBytes; + const u64 Version = XRayProfilingVersion; + u64 Timestamp = 0; // System time in nanoseconds. + u64 PID = 0; // Process ID. +}; + struct BlockHeader { u32 BlockSize; u32 BlockNum; @@ -302,7 +315,22 @@ XRayBuffer nextBuffer(XRayBuffer B) { if (ProfileBuffers == nullptr || ProfileBuffers->Size() == 0) return {nullptr, 0}; - if (B.Data == nullptr) + static pthread_once_t Once = PTHREAD_ONCE_INIT; + static typename std::aligned_storage::type + FileHeaderStorage; + pthread_once(&Once, + +[] { new (&FileHeaderStorage) XRayProfilingFileHeader{}; }); + + if (UNLIKELY(B.Data == nullptr)) { + // The first buffer should always contain the file header information. + auto &FileHeader = + *reinterpret_cast(&FileHeaderStorage); + FileHeader.Timestamp = NanoTime(); + FileHeader.PID = internal_getpid(); + return {&FileHeaderStorage, sizeof(XRayProfilingFileHeader)}; + } + + if (UNLIKELY(B.Data == &FileHeaderStorage)) return {(*ProfileBuffers)[0].Data, (*ProfileBuffers)[0].Size}; BlockHeader Header; Modified: projects/clang700-import/contrib/compiler-rt/lib/xray/xray_profiling.cc ============================================================================== --- projects/clang700-import/contrib/compiler-rt/lib/xray/xray_profiling.cc Thu Aug 2 18:04:37 2018 (r337153) +++ projects/clang700-import/contrib/compiler-rt/lib/xray/xray_profiling.cc Thu Aug 2 18:07:21 2018 (r337154) @@ -32,16 +32,6 @@ namespace __xray { namespace { -constexpr uptr XRayProfilingVersion = 0x20180424; - -struct XRayProfilingFileHeader { - const u64 MagicBytes = 0x7872617970726f66; // Identifier for XRay profiling - // files 'xrayprof' in hex. - const uptr Version = XRayProfilingVersion; - uptr Timestamp = 0; // System time in nanoseconds. - uptr PID = 0; // Process ID. -}; - atomic_sint32_t ProfilerLogFlushStatus = { XRayLogFlushStatus::XRAY_LOG_NOT_FLUSHING}; @@ -144,14 +134,7 @@ XRayLogFlushStatus profilingFlush() XRAY_NEVER_INSTRUM if (Verbosity()) Report("profiling: Failed to flush to file, dropping data.\n"); } else { - XRayProfilingFileHeader Header; - Header.Timestamp = NanoTime(); - Header.PID = internal_getpid(); - retryingWriteAll(Fd, reinterpret_cast(&Header), - reinterpret_cast(&Header) + - sizeof(Header)); - - // Now for each of the threads, write out the profile data as we would + // Now for each of the buffers, write out the profile data as we would // see it in memory, verbatim. while (B.Data != nullptr && B.Size != 0) { retryingWriteAll(Fd, reinterpret_cast(B.Data),