From: YU Jincheng <[email protected]>

- For clang 9+, `asm volatile ("":::"memory")`
  does not ensure load after a const pointer
  assigned by trick on `ASSIGN_CONST_PTR`
- We found that using a dummy function can do
  this trick so this patch converts `barrier`
  to an invisible dummy function
- This dummy function `barrier` should be
  invisible from the caller to avoid inlining
  by the compiler
- This trick introduces one instruction size
  overhead which should only be 4-8 bytes and
  the runtime overhead is at most one cache
  miss (unconditional branch won't introduce
  branch misprediction penalty)

Signed-off-by: LoveSy <[email protected]>
---
 include/libbb.h    |  5 ++++-
 libbb/const_hack.c | 15 +++++++++++++++
 2 files changed, 19 insertions(+), 1 deletion(-)
 create mode 100644 libbb/const_hack.c

diff --git a/include/libbb.h b/include/libbb.h
index 02cc008f0..56b404b03 100644
--- a/include/libbb.h
+++ b/include/libbb.h
@@ -2284,7 +2284,6 @@ struct globals;
  * If you want to assign a value, use SET_PTR_TO_GLOBALS(x) */
 extern struct globals *const ptr_to_globals;
 
-#define barrier() asm volatile ("":::"memory")
 
 #if defined(__clang_major__) && __clang_major__ >= 9
 /* Clang/llvm drops assignment to "constant" storage. Silently.
@@ -2300,8 +2299,12 @@ static ALWAYS_INLINE void* not_const_pp(const void *p)
        );
        return pp;
 }
+/* Clang/llvm needs an invisible dummy function for barrier
+ */
+void barrier();
 #else
 static ALWAYS_INLINE void* not_const_pp(const void *p) { return (void*)p; }
+#define barrier() asm volatile ("":::"memory")
 #endif
 
 #define ASSIGN_CONST_PTR(p, v) do { \
diff --git a/libbb/const_hack.c b/libbb/const_hack.c
new file mode 100644
index 000000000..5450b82c6
--- /dev/null
+++ b/libbb/const_hack.c
@@ -0,0 +1,15 @@
+/* vi: set sw=4 ts=4: */
+/*
+ * Dummy function as barrier for const trick
+ *
+ * Copyright (C) 2021 by YU Jincheng <[email protected]>
+ *
+ * Licensed under GPLv2 or later, see file LICENSE in this source tree.
+ */
+
+#if defined(__clang_major__) && __clang_major__ >= 9
+void barrier() {
+       // dummy
+       // it should at most cost one instruction (4-8 bytes)
+}
+#endif
\ No newline at end of file
-- 
2.25.1

_______________________________________________
busybox mailing list
[email protected]
http://lists.busybox.net/mailman/listinfo/busybox

Reply via email to