From ee69b268853dbd822e36512fce0e6294d35b9216 Mon Sep 17 00:00:00 2001
Date: Sat, 16 May 2026 11:40:30 +0800
Subject: Prefetch for LSE

---
 src/hotspot/cpu/aarch64/globals_aarch64.hpp        | 2 ++
 src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp | 9 +++++++++
 src/hotspot/cpu/aarch64/stubGenerator_aarch64.cpp  | 3 +++
 3 files changed, 14 insertions(+)

diff --git a/src/hotspot/cpu/aarch64/globals_aarch64.hpp b/src/hotspot/cpu/aarch64/globals_aarch64.hpp
index 6ea0c9834..ef9833629 100644
--- a/src/hotspot/cpu/aarch64/globals_aarch64.hpp
+++ b/src/hotspot/cpu/aarch64/globals_aarch64.hpp
@@ -104,6 +104,8 @@ define_pd_global(intx, InlineSmallCode,          1000);
           "Avoid generating unaligned memory accesses")                 \
   product(bool, UseLSE, false,                                          \
           "Use LSE instructions")                                       \
+  product(bool, UseLSEPrefetch, false,                                  \
+          "Prefetch before lock-related LSE instructions (CAS)")        \
   product(uint, UseSVE, 0,                                              \
           "Highest supported SVE instruction set version")              \
           range(0, 2)                                                   \
diff --git a/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp b/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp
index fb43d1ea8..a77723306 100644
--- a/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp
+++ b/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp
@@ -2999,6 +2999,9 @@ void MacroAssembler::cmpxchgptr(Register oldv, Register newv, Register addr, Reg
   // newv holds value to write in exchange
   // addr identifies memory word to compare against/update
   if (UseLSE) {
+    if (UseLSEPrefetch) {
+      prfm(Address(addr), PSTL1STRM);
+    }
     mov(tmp, oldv);
     casal(Assembler::xword, oldv, newv, addr);
     cmp(tmp, oldv);
@@ -3041,6 +3044,9 @@ void MacroAssembler::cmpxchgw(Register oldv, Register newv, Register addr, Regis
   // addr identifies memory word to compare against/update
   // tmp returns 0/1 for success/failure
   if (UseLSE) {
+    if (UseLSEPrefetch) {
+      prfm(Address(addr), PSTL1STRM);
+    }
     mov(tmp, oldv);
     casal(Assembler::word, oldv, newv, addr);
     cmp(tmp, oldv);
@@ -3084,6 +3090,9 @@ void MacroAssembler::cmpxchg(Register addr, Register expected,
   if (result == noreg)  result = rscratch1;
   BLOCK_COMMENT("cmpxchg {");
   if (UseLSE) {
+    if (UseLSEPrefetch) {
+      prfm(Address(addr), PSTL1STRM);
+    }
     mov(result, expected);
     lse_cas(result, new_val, addr, size, acquire, release, /*not_pair*/ true);
     compare_eq(result, expected, size);
diff --git a/src/hotspot/cpu/aarch64/stubGenerator_aarch64.cpp b/src/hotspot/cpu/aarch64/stubGenerator_aarch64.cpp
index b304104d2..cf8166f9a 100644
--- a/src/hotspot/cpu/aarch64/stubGenerator_aarch64.cpp
+++ b/src/hotspot/cpu/aarch64/stubGenerator_aarch64.cpp
@@ -7801,6 +7801,9 @@ class StubGenerator: public StubCodeGenerator {
         release = true;
         break;
     }
+    if (UseLSEPrefetch) {
+      __ prfm(Address(ptr), PSTL1STRM);
+    }
     __ mov(prev, compare_val);
     __ lse_cas(prev, exchange_val, ptr, size, acquire, release, /*not_pair*/true);
     if (order == memory_order_conservative) {
-- 
2.17.1