From 3956f39e58f0d29487057b523cd68bbd24efc844 Mon Sep 17 00:00:00 2001
From: Aurelien Larcher <aurelien.larcher@gmail.com>
Date: Thu, 11 Jun 2020 13:24:30 +0200
Subject: [PATCH 18/25] 18-obmalloc-adi.patch

---
 Objects/obmalloc.c | 35 ++++++++++++++++++++++++++++++++++-
 1 file changed, 34 insertions(+), 1 deletion(-)

diff --git a/Objects/obmalloc.c b/Objects/obmalloc.c
index 9408855383..225052df17 100644
--- a/Objects/obmalloc.c
+++ b/Objects/obmalloc.c
@@ -1350,6 +1350,39 @@ obmalloc controls.  Since this test is needed at every entry point, it's
 extremely desirable that it be this fast.
 */
 
+#ifdef __sparcv9
+/*
+ * Py_ADDRESS_IN_RANGE needs to access memory that might be arbitrarily
+ * tagged by an ADI aware allocator. The use of a nonfaulting load
+ * guarantees that the read will succeed.
+ */
+#ifdef __SUNPRO_C
+
+/* Studio can use built-in nonfaulting load instruction for vis.h */ 
+#include <vis.h>
+#define POOL_INDEX(x)   __vis_ldswa_ASI_PNF((void*)x)
+
+#else  /* __SUNPRO_C */
+/* 
+ * GCC doesn't have similar instruction built-in, but it can use
+ * following assembly code to do the same.
+ */
+
+static inline int vis_ldswa_ASI_PNF(void *arg);
+
+int vis_ldswa_ASI_PNF(void *arg) {
+  int res;
+  __asm__ ("ldswa  [%1]0x82,%0" : "=r" (res) : "r" (arg));
+  return res;
+}
+#define POOL_INDEX(x)   vis_ldswa_ASI_PNF((void*)x)
+
+#endif  /* __SUNPRO_C */
+#else   /* __sparcv9 */
+#define POOL_INDEX(x)   (*(x))
+#endif  /* __sparcv9 */
+
+
 static bool _Py_NO_SANITIZE_ADDRESS
             _Py_NO_SANITIZE_THREAD
             _Py_NO_SANITIZE_MEMORY
@@ -1360,7 +1393,7 @@ address_in_range(void *p, poolp pool)
     // another thread may be concurrently modifying the value without holding
     // the GIL. The following dance forces the compiler to read pool->arenaindex
     // only once.
-    uint arenaindex = *((volatile uint *)&pool->arenaindex);
+    uint arenaindex = (uint)POOL_INDEX((volatile uint *)&pool->arenaindex);
     return arenaindex < maxarenas &&
         (uintptr_t)p - arenas[arenaindex].address < ARENA_SIZE &&
         arenas[arenaindex].address != 0;
-- 
2.25.4