[TSan] Refactor ExternalAccess() to avoid unnecessary pop/push tag [NFC]
authorJulian Lettner <julian.lettner@apple.com>
Wed, 22 Mar 2023 22:07:37 +0000 (15:07 -0700)
committerJulian Lettner <julian.lettner@apple.com>
Fri, 24 Mar 2023 18:17:40 +0000 (11:17 -0700)
* Avoid unnecessary frame & tag push/pops if memory access is ignored
* Rename function and add comment to make it clearer what the code does
* Make helper functions static and move inside `#if !SANITIZER_GO`

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

compiler-rt/lib/tsan/rtl/tsan_external.cpp

index 463f32d7fdc31fade7e5919dae4d260f2536f1a4..98abff54e2b2817b37824323d3fe598ec5e85109 100644 (file)
@@ -46,10 +46,6 @@ const char *GetReportHeaderFromTag(uptr tag) {
   return tag_data ? tag_data->header : nullptr;
 }
 
-void InsertShadowStackFrameForTag(ThreadState *thr, uptr tag) {
-  FuncEntry(thr, (uptr)&registered_tags[tag]);
-}
-
 uptr TagFromShadowStackFrame(uptr pc) {
   uptr tag_count = atomic_load(&used_tags, memory_order_relaxed);
   void *pc_ptr = (void *)pc;
@@ -60,16 +56,26 @@ uptr TagFromShadowStackFrame(uptr pc) {
 
 #if !SANITIZER_GO
 
-void ExternalAccess(void *addr, uptr caller_pc, uptr tsan_caller_pc, void *tag,
-                    AccessType typ) {
+// We need to track tags for individual memory accesses, but there is no space
+// in the shadow cells for them.  Instead we push/pop them onto the thread
+// traces and ignore the extra tag frames when printing reports.
+static void PushTag(ThreadState *thr, uptr tag) {
+  FuncEntry(thr, (uptr)&registered_tags[tag]);
+}
+static void PopTag(ThreadState *thr) { FuncExit(thr); }
+
+static void ExternalAccess(void *addr, uptr caller_pc, uptr tsan_caller_pc,
+                           void *tag, AccessType typ) {
   CHECK_LT(tag, atomic_load(&used_tags, memory_order_relaxed));
+  bool in_ignored_lib;
+  if (caller_pc && libignore()->IsIgnored(caller_pc, &in_ignored_lib))
+    return;
+
   ThreadState *thr = cur_thread();
   if (caller_pc) FuncEntry(thr, caller_pc);
-  InsertShadowStackFrameForTag(thr, (uptr)tag);
-  bool in_ignored_lib;
-  if (!caller_pc || !libignore()->IsIgnored(caller_pc, &in_ignored_lib))
-    MemoryAccess(thr, tsan_caller_pc, (uptr)addr, 1, typ);
-  FuncExit(thr);
+  PushTag(thr, (uptr)tag);
+  MemoryAccess(thr, tsan_caller_pc, (uptr)addr, 1, typ);
+  PopTag(thr);
   if (caller_pc) FuncExit(thr);
 }