21 *
22 */
23
24 #include "precompiled.hpp"
25 #include "gc/shared/barrierSet.hpp"
26 #include "gc/shenandoah/shenandoahForwarding.hpp"
27 #include "gc/shenandoah/shenandoahHeap.hpp"
28 #include "gc/shenandoah/shenandoahHeuristics.hpp"
29 #include "gc/shenandoah/shenandoahRuntime.hpp"
30 #include "gc/shenandoah/shenandoahThreadLocalData.hpp"
31 #include "gc/shenandoah/c2/shenandoahBarrierSetC2.hpp"
32 #include "gc/shenandoah/c2/shenandoahSupport.hpp"
33 #include "opto/arraycopynode.hpp"
34 #include "opto/escape.hpp"
35 #include "opto/graphKit.hpp"
36 #include "opto/idealKit.hpp"
37 #include "opto/macro.hpp"
38 #include "opto/movenode.hpp"
39 #include "opto/narrowptrnode.hpp"
40 #include "opto/rootnode.hpp"
41
42 ShenandoahBarrierSetC2* ShenandoahBarrierSetC2::bsc2() {
43 return reinterpret_cast<ShenandoahBarrierSetC2*>(BarrierSet::barrier_set()->barrier_set_c2());
44 }
45
46 ShenandoahBarrierSetC2State::ShenandoahBarrierSetC2State(Arena* comp_arena)
47 : _enqueue_barriers(new (comp_arena) GrowableArray<ShenandoahEnqueueBarrierNode*>(comp_arena, 8, 0, NULL)),
48 _load_reference_barriers(new (comp_arena) GrowableArray<ShenandoahLoadReferenceBarrierNode*>(comp_arena, 8, 0, NULL)) {
49 }
50
51 int ShenandoahBarrierSetC2State::enqueue_barriers_count() const {
52 return _enqueue_barriers->length();
53 }
54
55 ShenandoahEnqueueBarrierNode* ShenandoahBarrierSetC2State::enqueue_barrier(int idx) const {
56 return _enqueue_barriers->at(idx);
57 }
58
59 void ShenandoahBarrierSetC2State::add_enqueue_barrier(ShenandoahEnqueueBarrierNode * n) {
60 assert(!_enqueue_barriers->contains(n), "duplicate entry in barrier list");
760 if ((src_type->klass_is_exact() || (!ik->is_interface() && !ik->has_subklass())) && !ik->has_injected_fields()) {
761 if (ik->has_object_fields()) {
762 return true;
763 } else {
764 if (!src_type->klass_is_exact()) {
765 igvn.C->dependencies()->assert_leaf_type(ik);
766 }
767 }
768 } else {
769 return true;
770 }
771 } else if (src_type->isa_aryptr()) {
772 BasicType src_elem = src_type->klass()->as_array_klass()->element_type()->basic_type();
773 if (src_elem == T_OBJECT || src_elem == T_ARRAY) {
774 return true;
775 }
776 } else {
777 return true;
778 }
779 return false;
780 }
781
782 // Support for macro expanded GC barriers
783 void ShenandoahBarrierSetC2::register_potential_barrier_node(Node* node) const {
784 if (node->Opcode() == Op_ShenandoahEnqueueBarrier) {
785 state()->add_enqueue_barrier((ShenandoahEnqueueBarrierNode*) node);
786 }
787 if (node->Opcode() == Op_ShenandoahLoadReferenceBarrier) {
788 state()->add_load_reference_barrier((ShenandoahLoadReferenceBarrierNode*) node);
789 }
790 }
791
792 void ShenandoahBarrierSetC2::unregister_potential_barrier_node(Node* node) const {
793 if (node->Opcode() == Op_ShenandoahEnqueueBarrier) {
794 state()->remove_enqueue_barrier((ShenandoahEnqueueBarrierNode*) node);
795 }
796 if (node->Opcode() == Op_ShenandoahLoadReferenceBarrier) {
797 state()->remove_load_reference_barrier((ShenandoahLoadReferenceBarrierNode*) node);
798 }
799 }
|
21 *
22 */
23
24 #include "precompiled.hpp"
25 #include "gc/shared/barrierSet.hpp"
26 #include "gc/shenandoah/shenandoahForwarding.hpp"
27 #include "gc/shenandoah/shenandoahHeap.hpp"
28 #include "gc/shenandoah/shenandoahHeuristics.hpp"
29 #include "gc/shenandoah/shenandoahRuntime.hpp"
30 #include "gc/shenandoah/shenandoahThreadLocalData.hpp"
31 #include "gc/shenandoah/c2/shenandoahBarrierSetC2.hpp"
32 #include "gc/shenandoah/c2/shenandoahSupport.hpp"
33 #include "opto/arraycopynode.hpp"
34 #include "opto/escape.hpp"
35 #include "opto/graphKit.hpp"
36 #include "opto/idealKit.hpp"
37 #include "opto/macro.hpp"
38 #include "opto/movenode.hpp"
39 #include "opto/narrowptrnode.hpp"
40 #include "opto/rootnode.hpp"
41 #include "opto/runtime.hpp"
42
43 ShenandoahBarrierSetC2* ShenandoahBarrierSetC2::bsc2() {
44 return reinterpret_cast<ShenandoahBarrierSetC2*>(BarrierSet::barrier_set()->barrier_set_c2());
45 }
46
47 ShenandoahBarrierSetC2State::ShenandoahBarrierSetC2State(Arena* comp_arena)
48 : _enqueue_barriers(new (comp_arena) GrowableArray<ShenandoahEnqueueBarrierNode*>(comp_arena, 8, 0, NULL)),
49 _load_reference_barriers(new (comp_arena) GrowableArray<ShenandoahLoadReferenceBarrierNode*>(comp_arena, 8, 0, NULL)) {
50 }
51
52 int ShenandoahBarrierSetC2State::enqueue_barriers_count() const {
53 return _enqueue_barriers->length();
54 }
55
56 ShenandoahEnqueueBarrierNode* ShenandoahBarrierSetC2State::enqueue_barrier(int idx) const {
57 return _enqueue_barriers->at(idx);
58 }
59
60 void ShenandoahBarrierSetC2State::add_enqueue_barrier(ShenandoahEnqueueBarrierNode * n) {
61 assert(!_enqueue_barriers->contains(n), "duplicate entry in barrier list");
761 if ((src_type->klass_is_exact() || (!ik->is_interface() && !ik->has_subklass())) && !ik->has_injected_fields()) {
762 if (ik->has_object_fields()) {
763 return true;
764 } else {
765 if (!src_type->klass_is_exact()) {
766 igvn.C->dependencies()->assert_leaf_type(ik);
767 }
768 }
769 } else {
770 return true;
771 }
772 } else if (src_type->isa_aryptr()) {
773 BasicType src_elem = src_type->klass()->as_array_klass()->element_type()->basic_type();
774 if (src_elem == T_OBJECT || src_elem == T_ARRAY) {
775 return true;
776 }
777 } else {
778 return true;
779 }
780 return false;
781 }
782
783 static Node* shenandoah_call_clone_barrier(PhaseMacroExpand* phase, Node* call, Node* dest) {
784 assert (UseShenandoahGC && ShenandoahCloneBarrier, "Should be enabled");
785 const TypePtr* raw_adr_type = TypeRawPtr::BOTTOM;
786 Node* c = new ProjNode(call,TypeFunc::Control);
787 phase->transform_later(c);
788 Node* m = new ProjNode(call, TypeFunc::Memory);
789 phase->transform_later(m);
790 assert(dest->is_AddP(), "bad input");
791 call = phase->make_leaf_call(c, m, ShenandoahBarrierSetC2::shenandoah_clone_barrier_Type(),
792 CAST_FROM_FN_PTR(address, ShenandoahRuntime::shenandoah_clone_barrier),
793 "shenandoah_clone_barrier", raw_adr_type, dest->in(AddPNode::Base));
794 phase->transform_later(call);
795 return call;
796 }
797
798 #define XTOP LP64_ONLY(COMMA phase->top())
799
800 void ShenandoahBarrierSetC2::clone_at_expansion(PhaseMacroExpand* phase, ArrayCopyNode* ac) const {
801 Node* ctrl = ac->in(TypeFunc::Control);
802 Node* mem = ac->in(TypeFunc::Memory);
803 Node* src = ac->in(ArrayCopyNode::Src);
804 Node* src_offset = ac->in(ArrayCopyNode::SrcPos);
805 Node* dest = ac->in(ArrayCopyNode::Dest);
806 Node* dest_offset = ac->in(ArrayCopyNode::DestPos);
807 Node* length = ac->in(ArrayCopyNode::Length);
808
809 assert (src_offset == NULL && dest_offset == NULL, "for clone offsets should be null");
810 const char* copyfunc_name = "arraycopy";
811 address copyfunc_addr =
812 phase->basictype2arraycopy(T_LONG, NULL, NULL,
813 true, copyfunc_name, true);
814
815 const TypePtr* raw_adr_type = TypeRawPtr::BOTTOM;
816 const TypeFunc* call_type = OptoRuntime::fast_arraycopy_Type();
817
818 Node* call = phase->make_leaf_call(ctrl, mem, call_type, copyfunc_addr, copyfunc_name, raw_adr_type, src, dest, length XTOP);
819 phase->transform_later(call);
820
821 if (ShenandoahCloneBarrier) {
822 const TypeOopPtr* src_type = phase->igvn().type(src)->is_oopptr();
823 if (src_type->isa_instptr() != NULL) {
824 ciInstanceKlass* ik = src_type->klass()->as_instance_klass();
825 if ((src_type->klass_is_exact() || (!ik->is_interface() && !ik->has_subklass())) && !ik->has_injected_fields()) {
826 if (ik->has_object_fields()) {
827 call = shenandoah_call_clone_barrier(phase, call, dest);
828 } else {
829 if (!src_type->klass_is_exact()) {
830 phase->C->dependencies()->assert_leaf_type(ik);
831 }
832 }
833 } else {
834 call = shenandoah_call_clone_barrier(phase, call, dest);
835 }
836 } else if (src_type->isa_aryptr()) {
837 BasicType src_elem = src_type->klass()->as_array_klass()->element_type()->basic_type();
838 if (src_elem == T_OBJECT || src_elem == T_ARRAY) {
839 call = shenandoah_call_clone_barrier(phase, call, dest);
840 }
841 } else {
842 call = shenandoah_call_clone_barrier(phase, call, dest);
843 }
844 }
845
846 phase->igvn().replace_node(ac, call);
847 }
848
849 // Support for macro expanded GC barriers
850 void ShenandoahBarrierSetC2::register_potential_barrier_node(Node* node) const {
851 if (node->Opcode() == Op_ShenandoahEnqueueBarrier) {
852 state()->add_enqueue_barrier((ShenandoahEnqueueBarrierNode*) node);
853 }
854 if (node->Opcode() == Op_ShenandoahLoadReferenceBarrier) {
855 state()->add_load_reference_barrier((ShenandoahLoadReferenceBarrierNode*) node);
856 }
857 }
858
859 void ShenandoahBarrierSetC2::unregister_potential_barrier_node(Node* node) const {
860 if (node->Opcode() == Op_ShenandoahEnqueueBarrier) {
861 state()->remove_enqueue_barrier((ShenandoahEnqueueBarrierNode*) node);
862 }
863 if (node->Opcode() == Op_ShenandoahLoadReferenceBarrier) {
864 state()->remove_load_reference_barrier((ShenandoahLoadReferenceBarrierNode*) node);
865 }
866 }
|