From 2705ed0a71e606a517518569d60051c85ad3c516 Mon Sep 17 00:00:00 2001
From: Axel Boldt-Christmas <aboldtch@openjdk.org>
Date: Fri, 16 Feb 2024 08:34:58 +0000
Subject: [PATCH] 8325074: ZGC fails assert(index == 0 || is_power_of_2(index))
 failed: Incorrect load shift: 11

Reviewed-by: eosterlund, stefank, rcastanedalo
---
 src/hotspot/share/gc/z/zBarrierSet.cpp        | 5 +++--
 src/hotspot/share/gc/z/zBarrierSet.hpp        | 2 +-
 src/hotspot/share/gc/z/zBarrierSet.inline.hpp | 2 +-
 3 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/src/hotspot/share/gc/z/zBarrierSet.cpp b/src/hotspot/share/gc/z/zBarrierSet.cpp
index a82cc67754b..48228a3e1ab 100644
--- a/src/hotspot/share/gc/z/zBarrierSet.cpp
+++ b/src/hotspot/share/gc/z/zBarrierSet.cpp
@@ -152,11 +152,12 @@ void ZBarrierSet::on_slowpath_allocation_exit(JavaThread* thread, oop new_obj) {
   deoptimize_allocation(thread);
 }
 
-void ZBarrierSet::clone_obj_array(objArrayOop src_obj, objArrayOop dst_obj, size_t size) {
+void ZBarrierSet::clone_obj_array(objArrayOop src_obj, objArrayOop dst_obj) {
   volatile zpointer* src = (volatile zpointer*)src_obj->base();
   volatile zpointer* dst = (volatile zpointer*)dst_obj->base();
+  const int length = src_obj->length();
 
-  for (const zpointer* const end = cast_from_oop<const zpointer*>(src_obj) + size; src < end; src++, dst++) {
+  for (const volatile zpointer* const end = src + length; src < end; src++, dst++) {
     zaddress elem = ZBarrier::load_barrier_on_oop_field(src);
     // We avoid healing here because the store below colors the pointer store good,
     // hence avoiding the cost of a CAS.
diff --git a/src/hotspot/share/gc/z/zBarrierSet.hpp b/src/hotspot/share/gc/z/zBarrierSet.hpp
index adba5ee15c1..bf233df683a 100644
--- a/src/hotspot/share/gc/z/zBarrierSet.hpp
+++ b/src/hotspot/share/gc/z/zBarrierSet.hpp
@@ -39,7 +39,7 @@ public:
   static ZBarrierSetAssembler* assembler();
   static bool barrier_needed(DecoratorSet decorators, BasicType type);
 
-  static void clone_obj_array(objArrayOop src, objArrayOop dst, size_t size);
+  static void clone_obj_array(objArrayOop src, objArrayOop dst);
 
   virtual void on_thread_create(Thread* thread);
   virtual void on_thread_destroy(Thread* thread);
diff --git a/src/hotspot/share/gc/z/zBarrierSet.inline.hpp b/src/hotspot/share/gc/z/zBarrierSet.inline.hpp
index 997e5bae58d..d53b69345dd 100644
--- a/src/hotspot/share/gc/z/zBarrierSet.inline.hpp
+++ b/src/hotspot/share/gc/z/zBarrierSet.inline.hpp
@@ -439,7 +439,7 @@ inline void ZBarrierSet::AccessBarrier<decorators, BarrierSetT>::clone_in_heap(o
     // for cloning arrays transform the clone to an optimized allocation
     // and arraycopy sequence, so the performance of this runtime call
     // does not matter for object arrays.
-    clone_obj_array(objArrayOop(src), objArrayOop(dst), size);
+    clone_obj_array(objArrayOop(src), objArrayOop(dst));
     return;
   }