C2: Understanding LoadNode::find_previous_arraycopy()
Reingruber, Richard
richard.reingruber at sap.com
Wed Mar 17 11:12:54 UTC 2021
Hi,
I'd need a little help please understanding the implementation of the following method.
Specifically, L556 is the only location where mem is changed. NULL will be returned if we reach there.
memnode.cpp:
531 // Find an arraycopy that must have set (can_see_stored_value=true) or
532 // could have set (can_see_stored_value=false) the value for this load
533 Node* LoadNode::find_previous_arraycopy(PhaseTransform* phase, Node* ld_alloc, Node*& mem, bool can_see_stored_value) const {
534 ArrayCopyNode* ac = find_array_copy_clone(phase, ld_alloc, mem);
535 if (ac != NULL) {
536 return ac;
537 } else if (mem->is_Proj() && mem->in(0) != NULL && mem->in(0)->is_ArrayCopy()) {
538 ArrayCopyNode* ac = mem->in(0)->as_ArrayCopy();
539
540 if (ac->is_arraycopy_validated() ||
541 ac->is_copyof_validated() ||
542 ac->is_copyofrange_validated()) {
543 Node* ld_addp = in(MemNode::Address);
544 if (ld_addp->is_AddP()) {
545 Node* ld_base = ld_addp->in(AddPNode::Address);
546 Node* ld_offs = ld_addp->in(AddPNode::Offset);
547
548 Node* dest = ac->in(ArrayCopyNode::Dest);
549
550 if (dest == ld_base) {
551 const TypeX *ld_offs_t = phase->type(ld_offs)->isa_intptr_t();
552 if (ac->modifies(ld_offs_t->_lo, ld_offs_t->_hi, phase, can_see_stored_value)) {
553 return ac;
554 }
555 if (!can_see_stored_value) {
556 mem = ac->in(TypeFunc::Memory);
557 }
558 }
559 }
560 }
561 }
562 return NULL;
563 }
The only call that can reach L556 is in MemNode::find_previous_store() L709:
709 } else if (find_previous_arraycopy(phase, alloc, mem, false) != NULL) {
710 if (prev != mem) {
711 // Found an arraycopy but it doesn't affect that load
712 continue;
713 }
714 // Found an arraycopy that may affect that load
715 return mem;
Observation: 712 is dead code.
Is this a bug? I'd think so. I'd expect find_previous_arraycopy() to change mem
if it can prove that current mem is produced by an arraycopy that does not
affect self and in that case L712 should be reached.
Should we return ac when executing L556?
Background: I'm currently working on JDK-8262295 [1] and my fix [2] changes
find_previous_arraycopy() and I'm trying to understand what needs to be returned
in that context if can_see_stored_value == true.
Thanks, Richard.
[1] JDK-8262295: C2: Out-of-Bounds Array Load from Clone Source
https://bugs.openjdk.java.net/browse/JDK-8262295
[2] PR for JDK-8262295 [1]
https://github.com/openjdk/jdk/pull/2708
More information about the hotspot-compiler-dev
mailing list