642 C2AccessFence fence(access); |
642 C2AccessFence fence(access); |
643 resolve_address(access); |
643 resolve_address(access); |
644 return atomic_add_at_resolved(access, new_val, value_type); |
644 return atomic_add_at_resolved(access, new_val, value_type); |
645 } |
645 } |
646 |
646 |
647 void BarrierSetC2::clone(GraphKit* kit, Node* src, Node* dst, Node* size, bool is_array) const { |
647 int BarrierSetC2::arraycopy_payload_base_offset(bool is_array) { |
648 // Exclude the header but include array length to copy by 8 bytes words. |
648 // Exclude the header but include array length to copy by 8 bytes words. |
649 // Can't use base_offset_in_bytes(bt) since basic type is unknown. |
649 // Can't use base_offset_in_bytes(bt) since basic type is unknown. |
650 int base_off = is_array ? arrayOopDesc::length_offset_in_bytes() : |
650 int base_off = is_array ? arrayOopDesc::length_offset_in_bytes() : |
651 instanceOopDesc::base_offset_in_bytes(); |
651 instanceOopDesc::base_offset_in_bytes(); |
652 // base_off: |
652 // base_off: |
653 // 8 - 32-bit VM |
653 // 8 - 32-bit VM |
654 // 12 - 64-bit VM, compressed klass |
654 // 12 - 64-bit VM, compressed klass |
655 // 16 - 64-bit VM, normal klass |
655 // 16 - 64-bit VM, normal klass |
656 if (base_off % BytesPerLong != 0) { |
656 if (base_off % BytesPerLong != 0) { |
662 // Include klass to copy by 8 bytes words. |
662 // Include klass to copy by 8 bytes words. |
663 base_off = instanceOopDesc::klass_offset_in_bytes(); |
663 base_off = instanceOopDesc::klass_offset_in_bytes(); |
664 } |
664 } |
665 assert(base_off % BytesPerLong == 0, "expect 8 bytes alignment"); |
665 assert(base_off % BytesPerLong == 0, "expect 8 bytes alignment"); |
666 } |
666 } |
667 Node* src_base = kit->basic_plus_adr(src, base_off); |
667 return base_off; |
668 Node* dst_base = kit->basic_plus_adr(dst, base_off); |
668 } |
|
669 |
|
670 void BarrierSetC2::clone(GraphKit* kit, Node* src_base, Node* dst_base, Node* size, bool is_array) const { |
|
671 int base_off = arraycopy_payload_base_offset(is_array); |
|
672 Node* payload_src = kit->basic_plus_adr(src_base, base_off); |
|
673 Node* payload_dst = kit->basic_plus_adr(dst_base, base_off); |
669 |
674 |
670 // Compute the length also, if needed: |
675 // Compute the length also, if needed: |
671 Node* countx = size; |
676 Node* payload_size = size; |
672 countx = kit->gvn().transform(new SubXNode(countx, kit->MakeConX(base_off))); |
677 payload_size = kit->gvn().transform(new SubXNode(payload_size, kit->MakeConX(base_off))); |
673 countx = kit->gvn().transform(new URShiftXNode(countx, kit->intcon(LogBytesPerLong) )); |
678 payload_size = kit->gvn().transform(new URShiftXNode(payload_size, kit->intcon(LogBytesPerLong) )); |
674 |
679 |
675 const TypePtr* raw_adr_type = TypeRawPtr::BOTTOM; |
680 const TypePtr* raw_adr_type = TypeRawPtr::BOTTOM; |
676 |
681 |
677 ArrayCopyNode* ac = ArrayCopyNode::make(kit, false, src_base, NULL, dst_base, NULL, countx, true, false); |
682 ArrayCopyNode* ac = ArrayCopyNode::make(kit, false, payload_src, NULL, payload_dst, NULL, payload_size, true, false); |
678 ac->set_clonebasic(); |
683 if (is_array) { |
|
684 ac->set_clone_array(); |
|
685 } else { |
|
686 ac->set_clone_inst(); |
|
687 } |
679 Node* n = kit->gvn().transform(ac); |
688 Node* n = kit->gvn().transform(ac); |
680 if (n == ac) { |
689 if (n == ac) { |
681 ac->_adr_type = TypeRawPtr::BOTTOM; |
690 ac->_adr_type = TypeRawPtr::BOTTOM; |
682 kit->set_predefined_output_for_runtime_call(ac, ac->in(TypeFunc::Memory), raw_adr_type); |
691 kit->set_predefined_output_for_runtime_call(ac, ac->in(TypeFunc::Memory), raw_adr_type); |
683 } else { |
692 } else { |