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