692 }
693
694 Node* BarrierSetC2::atomic_xchg_at(C2AtomicParseAccess& access, Node* new_val, const Type* value_type) const {
695 C2AccessFence fence(access);
696 resolve_address(access);
697 return atomic_xchg_at_resolved(access, new_val, value_type);
698 }
699
700 Node* BarrierSetC2::atomic_add_at(C2AtomicParseAccess& access, Node* new_val, const Type* value_type) const {
701 C2AccessFence fence(access);
702 resolve_address(access);
703 return atomic_add_at_resolved(access, new_val, value_type);
704 }
705
706 int BarrierSetC2::arraycopy_payload_base_offset(bool is_array) {
707 // Exclude the header but include array length to copy by 8 bytes words.
708 // Can't use base_offset_in_bytes(bt) since basic type is unknown.
709 int base_off = is_array ? arrayOopDesc::length_offset_in_bytes() :
710 instanceOopDesc::base_offset_in_bytes();
711 // base_off:
712 // 8 - 32-bit VM or 64-bit VM, compact headers
713 // 12 - 64-bit VM, compressed klass
714 // 16 - 64-bit VM, normal klass
715 if (base_off % BytesPerLong != 0) {
716 assert(UseCompressedClassPointers, "");
717 assert(!UseCompactObjectHeaders, "");
718 if (is_array) {
719 // Exclude length to copy by 8 bytes words.
720 base_off += sizeof(int);
721 } else {
722 // Include klass to copy by 8 bytes words.
723 base_off = instanceOopDesc::klass_offset_in_bytes();
724 }
725 assert(base_off % BytesPerLong == 0, "expect 8 bytes alignment");
726 }
727 return base_off;
728 }
729
730 void BarrierSetC2::clone(GraphKit* kit, Node* src_base, Node* dst_base, Node* size, bool is_array) const {
731 int base_off = arraycopy_payload_base_offset(is_array);
732 Node* payload_size = size;
733 Node* offset = kit->MakeConX(base_off);
734 payload_size = kit->gvn().transform(new SubXNode(payload_size, offset));
735 if (is_array) {
736 // Ensure the array payload size is rounded up to the next BytesPerLong
737 // multiple when converting to double-words. This is necessary because array
738 // size does not include object alignment padding, so it might not be a
739 // multiple of BytesPerLong for sub-long element types.
740 payload_size = kit->gvn().transform(new AddXNode(payload_size, kit->MakeConX(BytesPerLong - 1)));
741 }
742 payload_size = kit->gvn().transform(new URShiftXNode(payload_size, kit->intcon(LogBytesPerLong)));
743 ArrayCopyNode* ac = ArrayCopyNode::make(kit, false, src_base, offset, dst_base, offset, payload_size, true, false);
744 if (is_array) {
745 ac->set_clone_array();
|
692 }
693
694 Node* BarrierSetC2::atomic_xchg_at(C2AtomicParseAccess& access, Node* new_val, const Type* value_type) const {
695 C2AccessFence fence(access);
696 resolve_address(access);
697 return atomic_xchg_at_resolved(access, new_val, value_type);
698 }
699
700 Node* BarrierSetC2::atomic_add_at(C2AtomicParseAccess& access, Node* new_val, const Type* value_type) const {
701 C2AccessFence fence(access);
702 resolve_address(access);
703 return atomic_add_at_resolved(access, new_val, value_type);
704 }
705
706 int BarrierSetC2::arraycopy_payload_base_offset(bool is_array) {
707 // Exclude the header but include array length to copy by 8 bytes words.
708 // Can't use base_offset_in_bytes(bt) since basic type is unknown.
709 int base_off = is_array ? arrayOopDesc::length_offset_in_bytes() :
710 instanceOopDesc::base_offset_in_bytes();
711 // base_off:
712 // 4 - compact headers
713 // 8 - 32-bit VM
714 // 12 - 64-bit VM, compressed klass
715 // 16 - 64-bit VM, normal klass
716 if (base_off % BytesPerLong != 0) {
717 assert(UseCompressedClassPointers, "");
718 if (is_array) {
719 // Exclude length to copy by 8 bytes words.
720 base_off += sizeof(int);
721 } else {
722 if (UseCompactObjectHeaders) {
723 base_off = 0; /* FIXME */
724 } else {
725 // Include klass to copy by 8 bytes words.
726 base_off = instanceOopDesc::klass_offset_in_bytes();
727 }
728 }
729 assert(base_off % BytesPerLong == 0 || UseCompactObjectHeaders, "expect 8 bytes alignment");
730 }
731 return base_off;
732 }
733
734 void BarrierSetC2::clone(GraphKit* kit, Node* src_base, Node* dst_base, Node* size, bool is_array) const {
735 int base_off = arraycopy_payload_base_offset(is_array);
736 Node* payload_size = size;
737 Node* offset = kit->MakeConX(base_off);
738 payload_size = kit->gvn().transform(new SubXNode(payload_size, offset));
739 if (is_array) {
740 // Ensure the array payload size is rounded up to the next BytesPerLong
741 // multiple when converting to double-words. This is necessary because array
742 // size does not include object alignment padding, so it might not be a
743 // multiple of BytesPerLong for sub-long element types.
744 payload_size = kit->gvn().transform(new AddXNode(payload_size, kit->MakeConX(BytesPerLong - 1)));
745 }
746 payload_size = kit->gvn().transform(new URShiftXNode(payload_size, kit->intcon(LogBytesPerLong)));
747 ArrayCopyNode* ac = ArrayCopyNode::make(kit, false, src_base, offset, dst_base, offset, payload_size, true, false);
748 if (is_array) {
749 ac->set_clone_array();
|