@@ -814,8 +814,58 @@ Node* BarrierSetC2::obj_allocate(PhaseMacroExpand* macro, Node* mem, Node* toobi
814814 return old_tlab_top;
815815}
816816
817+ static const TypeFunc* clone_type () {
818+ // Create input type (domain)
819+ int argcnt = NOT_LP64 (3 ) LP64_ONLY (4 );
820+ const Type** const domain_fields = TypeTuple::fields (argcnt);
821+ int argp = TypeFunc::Parms;
822+ domain_fields[argp++] = TypeInstPtr::NOTNULL; // src
823+ domain_fields[argp++] = TypeInstPtr::NOTNULL; // dst
824+ domain_fields[argp++] = TypeX_X; // size lower
825+ LP64_ONLY (domain_fields[argp++] = Type::HALF); // size upper
826+ assert (argp == TypeFunc::Parms+argcnt, " correct decoding" );
827+ const TypeTuple* const domain = TypeTuple::make (TypeFunc::Parms + argcnt, domain_fields);
828+
829+ // Create result type (range)
830+ const Type** const range_fields = TypeTuple::fields (0 );
831+ const TypeTuple* const range = TypeTuple::make (TypeFunc::Parms + 0 , range_fields);
832+
833+ return TypeFunc::make (domain, range);
834+ }
835+
817836#define XTOP LP64_ONLY (COMMA phase->top ())
818837
838+ void BarrierSetC2::clone_in_runtime(PhaseMacroExpand* phase, ArrayCopyNode* ac,
839+ address clone_addr, const char * clone_name) const {
840+ Node* const ctrl = ac->in (TypeFunc::Control);
841+ Node* const mem = ac->in (TypeFunc::Memory);
842+ Node* const src = ac->in (ArrayCopyNode::Src);
843+ Node* const dst = ac->in (ArrayCopyNode::Dest);
844+ Node* const size = ac->in (ArrayCopyNode::Length);
845+
846+ assert (size->bottom_type ()->base () == Type_X,
847+ " Should be of object size type (int for 32 bits, long for 64 bits)" );
848+
849+ // The native clone we are calling here expects the object size in words.
850+ // Add header/offset size to payload size to get object size.
851+ Node* const base_offset = phase->MakeConX (arraycopy_payload_base_offset (ac->is_clone_array ()) >> LogBytesPerLong);
852+ Node* const full_size = phase->transform_later (new AddXNode (size, base_offset));
853+ // HeapAccess<>::clone expects size in heap words.
854+ // For 64-bits platforms, this is a no-operation.
855+ // For 32-bits platforms, we need to multiply full_size by HeapWordsPerLong (2).
856+ Node* const full_size_in_heap_words = phase->transform_later (new LShiftXNode (full_size, phase->intcon (LogHeapWordsPerLong)));
857+
858+ Node* const call = phase->make_leaf_call (ctrl,
859+ mem,
860+ clone_type (),
861+ clone_addr,
862+ clone_name,
863+ TypeRawPtr::BOTTOM,
864+ src, dst, full_size_in_heap_words XTOP);
865+ phase->transform_later (call);
866+ phase->igvn ().replace_node (ac, call);
867+ }
868+
819869void BarrierSetC2::clone_at_expansion (PhaseMacroExpand* phase, ArrayCopyNode* ac) const {
820870 Node* ctrl = ac->in (TypeFunc::Control);
821871 Node* mem = ac->in (TypeFunc::Memory);
0 commit comments