Skip to content

Commit 5d87a21

Browse files
author
Nils Eliasson
committed
8263361: Incorrect arraycopy stub selected by C2 for SATB collectors
Reviewed-by: eosterlund, vlivanov
1 parent e152cc0 commit 5d87a21

File tree

3 files changed

+42
-33
lines changed

3 files changed

+42
-33
lines changed

src/hotspot/share/opto/library_call.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4143,8 +4143,8 @@ bool LibraryCallKit::inline_native_clone(bool is_virtual) {
41434143
PreserveJVMState pjvms2(this);
41444144
set_control(is_obja);
41454145
// Generate a direct call to the right arraycopy function(s).
4146-
Node* alloc = tightly_coupled_allocation(alloc_obj, NULL);
4147-
ArrayCopyNode* ac = ArrayCopyNode::make(this, true, obj, intcon(0), alloc_obj, intcon(0), obj_length, alloc != NULL, false);
4146+
// Clones are always tightly coupled.
4147+
ArrayCopyNode* ac = ArrayCopyNode::make(this, true, obj, intcon(0), alloc_obj, intcon(0), obj_length, true, false);
41484148
ac->set_clone_oop_array();
41494149
Node* n = _gvn.transform(ac);
41504150
assert(n == ac, "cannot disappear");

src/hotspot/share/opto/macroArrayCopy.cpp

Lines changed: 38 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -381,8 +381,9 @@ Node* PhaseMacroExpand::generate_arraycopy(ArrayCopyNode *ac, AllocateArrayNode*
381381
transform_later(slow_region);
382382
}
383383

384-
Node* original_dest = dest;
385-
bool dest_uninitialized = false;
384+
Node* original_dest = dest;
385+
bool dest_needs_zeroing = false;
386+
bool acopy_to_uninitialized = false;
386387

387388
// See if this is the initialization of a newly-allocated array.
388389
// If so, we will take responsibility here for initializing it to zero.
@@ -394,25 +395,34 @@ Node* PhaseMacroExpand::generate_arraycopy(ArrayCopyNode *ac, AllocateArrayNode*
394395
&& basic_elem_type != T_CONFLICT // avoid corner case
395396
&& !src->eqv_uncast(dest)
396397
&& alloc != NULL
397-
&& _igvn.find_int_con(alloc->in(AllocateNode::ALength), 1) > 0
398-
&& alloc->maybe_set_complete(&_igvn)) {
399-
// "You break it, you buy it."
400-
InitializeNode* init = alloc->initialization();
401-
assert(init->is_complete(), "we just did this");
402-
init->set_complete_with_arraycopy();
403-
assert(dest->is_CheckCastPP(), "sanity");
404-
assert(dest->in(0)->in(0) == init, "dest pinned");
405-
adr_type = TypeRawPtr::BOTTOM; // all initializations are into raw memory
406-
// From this point on, every exit path is responsible for
407-
// initializing any non-copied parts of the object to zero.
408-
// Also, if this flag is set we make sure that arraycopy interacts properly
409-
// with G1, eliding pre-barriers. See CR 6627983.
410-
dest_uninitialized = true;
398+
&& _igvn.find_int_con(alloc->in(AllocateNode::ALength), 1) > 0) {
399+
assert(ac->is_alloc_tightly_coupled(), "sanity");
400+
// acopy to uninitialized tightly coupled allocations
401+
// needs zeroing outside the copy range
402+
// and the acopy itself will be to uninitialized memory
403+
acopy_to_uninitialized = true;
404+
if (alloc->maybe_set_complete(&_igvn)) {
405+
// "You break it, you buy it."
406+
InitializeNode* init = alloc->initialization();
407+
assert(init->is_complete(), "we just did this");
408+
init->set_complete_with_arraycopy();
409+
assert(dest->is_CheckCastPP(), "sanity");
410+
assert(dest->in(0)->in(0) == init, "dest pinned");
411+
adr_type = TypeRawPtr::BOTTOM; // all initializations are into raw memory
412+
// From this point on, every exit path is responsible for
413+
// initializing any non-copied parts of the object to zero.
414+
// Also, if this flag is set we make sure that arraycopy interacts properly
415+
// with G1, eliding pre-barriers. See CR 6627983.
416+
dest_needs_zeroing = true;
417+
} else {
418+
// dest_need_zeroing = false;
419+
}
411420
} else {
412-
// No zeroing elimination here.
413-
alloc = NULL;
414-
//original_dest = dest;
415-
//dest_uninitialized = false;
421+
// No zeroing elimination needed here.
422+
alloc = NULL;
423+
acopy_to_uninitialized = false;
424+
//original_dest = dest;
425+
//dest_needs_zeroing = false;
416426
}
417427

418428
uint alias_idx = C->get_alias_index(adr_type);
@@ -446,11 +456,11 @@ Node* PhaseMacroExpand::generate_arraycopy(ArrayCopyNode *ac, AllocateArrayNode*
446456
Node* checked_value = NULL;
447457

448458
if (basic_elem_type == T_CONFLICT) {
449-
assert(!dest_uninitialized, "");
459+
assert(!dest_needs_zeroing, "");
450460
Node* cv = generate_generic_arraycopy(ctrl, &mem,
451461
adr_type,
452462
src, src_offset, dest, dest_offset,
453-
copy_length, dest_uninitialized);
463+
copy_length, acopy_to_uninitialized);
454464
if (cv == NULL) cv = intcon(-1); // failure (no stub available)
455465
checked_control = *ctrl;
456466
checked_i_o = *io;
@@ -471,7 +481,7 @@ Node* PhaseMacroExpand::generate_arraycopy(ArrayCopyNode *ac, AllocateArrayNode*
471481
}
472482

473483
// copy_length is 0.
474-
if (dest_uninitialized) {
484+
if (dest_needs_zeroing) {
475485
assert(!local_ctrl->is_top(), "no ctrl?");
476486
Node* dest_length = alloc->in(AllocateNode::ALength);
477487
if (copy_length->eqv_uncast(dest_length)
@@ -506,7 +516,7 @@ Node* PhaseMacroExpand::generate_arraycopy(ArrayCopyNode *ac, AllocateArrayNode*
506516
result_memory->init_req(zero_path, local_mem->memory_at(alias_idx));
507517
}
508518

509-
if (!(*ctrl)->is_top() && dest_uninitialized) {
519+
if (!(*ctrl)->is_top() && dest_needs_zeroing) {
510520
// We have to initialize the *uncopied* part of the array to zero.
511521
// The copy destination is the slice dest[off..off+len]. The other slices
512522
// are dest_head = dest[0..off] and dest_tail = dest[off+len..dest.length].
@@ -547,7 +557,7 @@ Node* PhaseMacroExpand::generate_arraycopy(ArrayCopyNode *ac, AllocateArrayNode*
547557
didit = generate_block_arraycopy(&local_ctrl, &local_mem, local_io,
548558
adr_type, basic_elem_type, alloc,
549559
src, src_offset, dest, dest_offset,
550-
dest_size, dest_uninitialized);
560+
dest_size, acopy_to_uninitialized);
551561
if (didit) {
552562
// Present the results of the block-copying fast call.
553563
result_region->init_req(bcopy_path, local_ctrl);
@@ -635,7 +645,7 @@ Node* PhaseMacroExpand::generate_arraycopy(ArrayCopyNode *ac, AllocateArrayNode*
635645
adr_type,
636646
dest_elem_klass,
637647
src, src_offset, dest, dest_offset,
638-
ConvI2X(copy_length), dest_uninitialized);
648+
ConvI2X(copy_length), acopy_to_uninitialized);
639649
if (cv == NULL) cv = intcon(-1); // failure (no stub available)
640650
checked_control = local_ctrl;
641651
checked_i_o = *io;
@@ -660,11 +670,10 @@ Node* PhaseMacroExpand::generate_arraycopy(ArrayCopyNode *ac, AllocateArrayNode*
660670
Node* local_ctrl = *ctrl;
661671
MergeMemNode* local_mem = MergeMemNode::make(mem);
662672
transform_later(local_mem);
663-
664673
is_partial_array_copy = generate_unchecked_arraycopy(&local_ctrl, &local_mem,
665674
adr_type, copy_type, disjoint_bases,
666675
src, src_offset, dest, dest_offset,
667-
ConvI2X(copy_length), dest_uninitialized);
676+
ConvI2X(copy_length), acopy_to_uninitialized);
668677

669678
// Present the results of the fast call.
670679
result_region->init_req(fast_path, local_ctrl);
@@ -753,7 +762,7 @@ Node* PhaseMacroExpand::generate_arraycopy(ArrayCopyNode *ac, AllocateArrayNode*
753762
// Generate the slow path, if needed.
754763
local_mem->set_memory_at(alias_idx, slow_mem);
755764

756-
if (dest_uninitialized) {
765+
if (dest_needs_zeroing) {
757766
generate_clear_array(local_ctrl, local_mem,
758767
adr_type, dest, basic_elem_type,
759768
intcon(0), NULL,

src/hotspot/share/runtime/stubRoutines.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -515,8 +515,8 @@ StubRoutines::select_arraycopy_function(BasicType t, bool aligned, bool disjoint
515515
name = #xxx_arraycopy; \
516516
return StubRoutines::xxx_arraycopy(); }
517517

518-
#define RETURN_STUB_PARM(xxx_arraycopy, parm) { \
519-
name = #xxx_arraycopy; \
518+
#define RETURN_STUB_PARM(xxx_arraycopy, parm) { \
519+
name = parm ? #xxx_arraycopy "_uninit": #xxx_arraycopy; \
520520
return StubRoutines::xxx_arraycopy(parm); }
521521

522522
switch (t) {

0 commit comments

Comments
 (0)