< prev index next >

src/hotspot/share/gc/shenandoah/c2/shenandoahBarrierSetC2.cpp

Print this page
rev 58687 : Shenandoah: New incremental-update mode


 757 
 758 bool ShenandoahBarrierSetC2::optimize_loops(PhaseIdealLoop* phase, LoopOptsMode mode, VectorSet& visited, Node_Stack& nstack, Node_List& worklist) const {
 759   if (mode == LoopOptsShenandoahExpand) {
 760     assert(UseShenandoahGC, "only for shenandoah");
 761     ShenandoahBarrierC2Support::pin_and_expand(phase);
 762     return true;
 763   } else if (mode == LoopOptsShenandoahPostExpand) {
 764     assert(UseShenandoahGC, "only for shenandoah");
 765     visited.clear();
 766     ShenandoahBarrierC2Support::optimize_after_expansion(visited, nstack, worklist, phase);
 767     return true;
 768   }
 769   return false;
 770 }
 771 
 772 bool ShenandoahBarrierSetC2::array_copy_requires_gc_barriers(bool tightly_coupled_alloc, BasicType type, bool is_clone, ArrayCopyPhase phase) const {
 773   bool is_oop = is_reference_type(type);
 774   if (!is_oop) {
 775     return false;
 776   }
 777   if (tightly_coupled_alloc) {
 778     if (phase == Optimization) {
 779       return false;
 780     }
 781     return !is_clone;
 782   }
 783   if (phase == Optimization) {
 784     return !ShenandoahStoreValEnqueueBarrier;
 785   }
 786   return true;
 787 }
 788 
 789 bool ShenandoahBarrierSetC2::clone_needs_barrier(Node* src, PhaseGVN& gvn) {
 790   const TypeOopPtr* src_type = gvn.type(src)->is_oopptr();
 791   if (src_type->isa_instptr() != NULL) {
 792     ciInstanceKlass* ik = src_type->klass()->as_instance_klass();
 793     if ((src_type->klass_is_exact() || (!ik->is_interface() && !ik->has_subklass())) && !ik->has_injected_fields()) {
 794       if (ik->has_object_fields()) {
 795         return true;
 796       } else {
 797         if (!src_type->klass_is_exact()) {


 824   Node* src = phase->basic_plus_adr(src_base, src_offset);
 825   Node* dest = phase->basic_plus_adr(dest_base, dest_offset);
 826 
 827   if (ShenandoahCloneBarrier && clone_needs_barrier(src, phase->igvn())) {
 828     // Check if heap is has forwarded objects. If it does, we need to call into the special
 829     // routine that would fix up source references before we can continue.
 830 
 831     enum { _heap_stable = 1, _heap_unstable, PATH_LIMIT };
 832     Node* region = new RegionNode(PATH_LIMIT);
 833     Node* mem_phi = new PhiNode(region, Type::MEMORY, TypeRawPtr::BOTTOM);
 834 
 835     Node* thread = phase->transform_later(new ThreadLocalNode());
 836     Node* offset = phase->igvn().MakeConX(in_bytes(ShenandoahThreadLocalData::gc_state_offset()));
 837     Node* gc_state_addr = phase->transform_later(new AddPNode(phase->C->top(), thread, offset));
 838 
 839     uint gc_state_idx = Compile::AliasIdxRaw;
 840     const TypePtr* gc_state_adr_type = NULL; // debug-mode-only argument
 841     debug_only(gc_state_adr_type = phase->C->get_adr_type(gc_state_idx));
 842 
 843     Node* gc_state    = phase->transform_later(new LoadBNode(ctrl, mem, gc_state_addr, gc_state_adr_type, TypeInt::BYTE, MemNode::unordered));
 844     Node* stable_and  = phase->transform_later(new AndINode(gc_state, phase->igvn().intcon(ShenandoahHeap::HAS_FORWARDED)));




 845     Node* stable_cmp  = phase->transform_later(new CmpINode(stable_and, phase->igvn().zerocon(T_INT)));
 846     Node* stable_test = phase->transform_later(new BoolNode(stable_cmp, BoolTest::ne));
 847 
 848     IfNode* stable_iff  = phase->transform_later(new IfNode(ctrl, stable_test, PROB_UNLIKELY(0.999), COUNT_UNKNOWN))->as_If();
 849     Node* stable_ctrl   = phase->transform_later(new IfFalseNode(stable_iff));
 850     Node* unstable_ctrl = phase->transform_later(new IfTrueNode(stable_iff));
 851 
 852     // Heap is stable, no need to do anything additional
 853     region->init_req(_heap_stable, stable_ctrl);
 854     mem_phi->init_req(_heap_stable, mem);
 855 
 856     // Heap is unstable, call into clone barrier stub
 857     Node* call = phase->make_leaf_call(unstable_ctrl, mem,
 858                     ShenandoahBarrierSetC2::shenandoah_clone_barrier_Type(),
 859                     CAST_FROM_FN_PTR(address, ShenandoahRuntime::shenandoah_clone_barrier),
 860                     "shenandoah_clone",
 861                     TypeRawPtr::BOTTOM,
 862                     src_base);
 863     call = phase->transform_later(call);
 864 




 757 
 758 bool ShenandoahBarrierSetC2::optimize_loops(PhaseIdealLoop* phase, LoopOptsMode mode, VectorSet& visited, Node_Stack& nstack, Node_List& worklist) const {
 759   if (mode == LoopOptsShenandoahExpand) {
 760     assert(UseShenandoahGC, "only for shenandoah");
 761     ShenandoahBarrierC2Support::pin_and_expand(phase);
 762     return true;
 763   } else if (mode == LoopOptsShenandoahPostExpand) {
 764     assert(UseShenandoahGC, "only for shenandoah");
 765     visited.clear();
 766     ShenandoahBarrierC2Support::optimize_after_expansion(visited, nstack, worklist, phase);
 767     return true;
 768   }
 769   return false;
 770 }
 771 
 772 bool ShenandoahBarrierSetC2::array_copy_requires_gc_barriers(bool tightly_coupled_alloc, BasicType type, bool is_clone, ArrayCopyPhase phase) const {
 773   bool is_oop = is_reference_type(type);
 774   if (!is_oop) {
 775     return false;
 776   }
 777   if (ShenandoahSATBBarrier && tightly_coupled_alloc) {
 778     if (phase == Optimization) {
 779       return false;
 780     }
 781     return !is_clone;
 782   }
 783   if (phase == Optimization) {
 784     return !ShenandoahStoreValEnqueueBarrier;
 785   }
 786   return true;
 787 }
 788 
 789 bool ShenandoahBarrierSetC2::clone_needs_barrier(Node* src, PhaseGVN& gvn) {
 790   const TypeOopPtr* src_type = gvn.type(src)->is_oopptr();
 791   if (src_type->isa_instptr() != NULL) {
 792     ciInstanceKlass* ik = src_type->klass()->as_instance_klass();
 793     if ((src_type->klass_is_exact() || (!ik->is_interface() && !ik->has_subklass())) && !ik->has_injected_fields()) {
 794       if (ik->has_object_fields()) {
 795         return true;
 796       } else {
 797         if (!src_type->klass_is_exact()) {


 824   Node* src = phase->basic_plus_adr(src_base, src_offset);
 825   Node* dest = phase->basic_plus_adr(dest_base, dest_offset);
 826 
 827   if (ShenandoahCloneBarrier && clone_needs_barrier(src, phase->igvn())) {
 828     // Check if heap is has forwarded objects. If it does, we need to call into the special
 829     // routine that would fix up source references before we can continue.
 830 
 831     enum { _heap_stable = 1, _heap_unstable, PATH_LIMIT };
 832     Node* region = new RegionNode(PATH_LIMIT);
 833     Node* mem_phi = new PhiNode(region, Type::MEMORY, TypeRawPtr::BOTTOM);
 834 
 835     Node* thread = phase->transform_later(new ThreadLocalNode());
 836     Node* offset = phase->igvn().MakeConX(in_bytes(ShenandoahThreadLocalData::gc_state_offset()));
 837     Node* gc_state_addr = phase->transform_later(new AddPNode(phase->C->top(), thread, offset));
 838 
 839     uint gc_state_idx = Compile::AliasIdxRaw;
 840     const TypePtr* gc_state_adr_type = NULL; // debug-mode-only argument
 841     debug_only(gc_state_adr_type = phase->C->get_adr_type(gc_state_idx));
 842 
 843     Node* gc_state    = phase->transform_later(new LoadBNode(ctrl, mem, gc_state_addr, gc_state_adr_type, TypeInt::BYTE, MemNode::unordered));
 844     int flags = ShenandoahHeap::HAS_FORWARDED;
 845     if (ShenandoahStoreValEnqueueBarrier) {
 846       flags |= ShenandoahHeap::MARKING;
 847     }
 848     Node* stable_and  = phase->transform_later(new AndINode(gc_state, phase->igvn().intcon(flags)));
 849     Node* stable_cmp  = phase->transform_later(new CmpINode(stable_and, phase->igvn().zerocon(T_INT)));
 850     Node* stable_test = phase->transform_later(new BoolNode(stable_cmp, BoolTest::ne));
 851 
 852     IfNode* stable_iff  = phase->transform_later(new IfNode(ctrl, stable_test, PROB_UNLIKELY(0.999), COUNT_UNKNOWN))->as_If();
 853     Node* stable_ctrl   = phase->transform_later(new IfFalseNode(stable_iff));
 854     Node* unstable_ctrl = phase->transform_later(new IfTrueNode(stable_iff));
 855 
 856     // Heap is stable, no need to do anything additional
 857     region->init_req(_heap_stable, stable_ctrl);
 858     mem_phi->init_req(_heap_stable, mem);
 859 
 860     // Heap is unstable, call into clone barrier stub
 861     Node* call = phase->make_leaf_call(unstable_ctrl, mem,
 862                     ShenandoahBarrierSetC2::shenandoah_clone_barrier_Type(),
 863                     CAST_FROM_FN_PTR(address, ShenandoahRuntime::shenandoah_clone_barrier),
 864                     "shenandoah_clone",
 865                     TypeRawPtr::BOTTOM,
 866                     src_base);
 867     call = phase->transform_later(call);
 868 


< prev index next >