[compiler-rt] r340814 - [XRay][compiler-rt] Remove uses of internal allocator in profiling mode

Dean Michael Berris via llvm-commits llvm-commits at lists.llvm.org
Tue Aug 28 03:41:10 PDT 2018


Author: dberris
Date: Tue Aug 28 03:41:10 2018
New Revision: 340814

URL: http://llvm.org/viewvc/llvm-project?rev=340814&view=rev
Log:
[XRay][compiler-rt] Remove uses of internal allocator in profiling mode

Summary:
This change removes further cases where the profiling mode
implementation relied on dynamic memory allocation. We're using
thread-local aligned (uninitialized) memory instead, which we initialize
appropriately with placement new.

Addresses llvm.org/PR38577.

Reviewers: eizan, kpw

Subscribers: jfb, llvm-commits

Differential Revision: https://reviews.llvm.org/D51278

Modified:
    compiler-rt/trunk/lib/xray/xray_profiling.cc

Modified: compiler-rt/trunk/lib/xray/xray_profiling.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/xray/xray_profiling.cc?rev=340814&r1=340813&r2=340814&view=diff
==============================================================================
--- compiler-rt/trunk/lib/xray/xray_profiling.cc (original)
+++ compiler-rt/trunk/lib/xray/xray_profiling.cc Tue Aug 28 03:41:10 2018
@@ -40,42 +40,49 @@ atomic_sint32_t ProfilerLogStatus = {XRa
 SpinMutex ProfilerOptionsMutex;
 
 struct alignas(64) ProfilingData {
-  FunctionCallTrie::Allocators *Allocators = nullptr;
-  FunctionCallTrie *FCT = nullptr;
+  FunctionCallTrie::Allocators *Allocators;
+  FunctionCallTrie *FCT;
 };
 
 static pthread_key_t ProfilingKey;
 
+thread_local std::aligned_storage<sizeof(FunctionCallTrie::Allocators)>::type
+    AllocatorsStorage;
+thread_local std::aligned_storage<sizeof(FunctionCallTrie)>::type
+    FunctionCallTrieStorage;
 thread_local std::aligned_storage<sizeof(ProfilingData)>::type ThreadStorage{};
+
 static ProfilingData &getThreadLocalData() XRAY_NEVER_INSTRUMENT {
   thread_local auto ThreadOnce = [] {
     new (&ThreadStorage) ProfilingData{};
+    auto *Allocators =
+        reinterpret_cast<FunctionCallTrie::Allocators *>(&AllocatorsStorage);
+    new (Allocators) FunctionCallTrie::Allocators();
+    *Allocators = FunctionCallTrie::InitAllocators();
+    auto *FCT = reinterpret_cast<FunctionCallTrie *>(&FunctionCallTrieStorage);
+    new (FCT) FunctionCallTrie(*Allocators);
+    auto &TLD = *reinterpret_cast<ProfilingData *>(&ThreadStorage);
+    TLD.Allocators = Allocators;
+    TLD.FCT = FCT;
     pthread_setspecific(ProfilingKey, &ThreadStorage);
     return false;
   }();
   (void)ThreadOnce;
 
-  auto &TLD = *reinterpret_cast<ProfilingData *>(&ThreadStorage);
+  auto &TLD = *reinterpret_cast<ProfilingData*>(&ThreadStorage);
 
-  // We need to check whether the global flag to finalizing/finalized has been
-  // switched. If it is, then we ought to not actually initialise the data.
-  auto Status = atomic_load(&ProfilerLogStatus, memory_order_acquire);
-  if (Status == XRayLogInitStatus::XRAY_LOG_FINALIZING ||
-      Status == XRayLogInitStatus::XRAY_LOG_FINALIZED)
-    return TLD;
-
-  // If we're live, then we re-initialize TLD if the pointers are not null.
-  if (UNLIKELY(TLD.Allocators == nullptr && TLD.FCT == nullptr)) {
-    TLD.Allocators = reinterpret_cast<FunctionCallTrie::Allocators *>(
-        InternalAlloc(sizeof(FunctionCallTrie::Allocators)));
-    new (TLD.Allocators) FunctionCallTrie::Allocators();
-    *TLD.Allocators = FunctionCallTrie::InitAllocators();
-    TLD.FCT = reinterpret_cast<FunctionCallTrie *>(
-        InternalAlloc(sizeof(FunctionCallTrie)));
-    new (TLD.FCT) FunctionCallTrie(*TLD.Allocators);
+  if (UNLIKELY(TLD.Allocators == nullptr || TLD.FCT == nullptr)) {
+    auto *Allocators =
+        reinterpret_cast<FunctionCallTrie::Allocators *>(&AllocatorsStorage);
+    new (Allocators) FunctionCallTrie::Allocators();
+    *Allocators = FunctionCallTrie::InitAllocators();
+    auto *FCT = reinterpret_cast<FunctionCallTrie *>(&FunctionCallTrieStorage);
+    new (FCT) FunctionCallTrie(*Allocators);
+    TLD.Allocators = Allocators;
+    TLD.FCT = FCT;
   }
 
-  return TLD;
+  return *reinterpret_cast<ProfilingData *>(&ThreadStorage);
 }
 
 static void cleanupTLD() XRAY_NEVER_INSTRUMENT {
@@ -83,8 +90,6 @@ static void cleanupTLD() XRAY_NEVER_INST
   if (TLD.Allocators != nullptr && TLD.FCT != nullptr) {
     TLD.FCT->~FunctionCallTrie();
     TLD.Allocators->~Allocators();
-    InternalFree(TLD.FCT);
-    InternalFree(TLD.Allocators);
     TLD.FCT = nullptr;
     TLD.Allocators = nullptr;
   }
@@ -181,13 +186,14 @@ void profilingHandleArg0(int32_t FuncId,
     return;
 
   auto Status = atomic_load(&ProfilerLogStatus, memory_order_acquire);
-  auto &TLD = getThreadLocalData();
   if (UNLIKELY(Status == XRayLogInitStatus::XRAY_LOG_FINALIZED ||
                Status == XRayLogInitStatus::XRAY_LOG_FINALIZING)) {
+    auto &TLD = getThreadLocalData();
     postCurrentThreadFCT(TLD);
     return;
   }
 
+  auto &TLD = getThreadLocalData();
   switch (Entry) {
   case XRayEntryType::ENTRY:
   case XRayEntryType::LOG_ARGS_ENTRY:




More information about the llvm-commits mailing list