< prev index next >

src/hotspot/share/gc/shenandoah/shenandoahStackWatermark.cpp

Print this page

 47 ThreadLocalAllocStats& ShenandoahStackWatermark::stats() {
 48   return _stats;
 49 }
 50 
 51 uint32_t ShenandoahStackWatermark::epoch_id() const {
 52   return _epoch_id;
 53 }
 54 
 55 void ShenandoahStackWatermark::change_epoch_id() {
 56   shenandoah_assert_safepoint();
 57   _epoch_id++;
 58   if (_epoch_id > MAX_EPOCH_ID) {
 59     _epoch_id = MIN_EPOCH_ID;
 60   }
 61 }
 62 
 63 ShenandoahStackWatermark::ShenandoahStackWatermark(JavaThread* jt) :
 64   StackWatermark(jt, StackWatermarkKind::gc, _epoch_id),
 65   _heap(ShenandoahHeap::heap()),
 66   _stats(),

 67   _keep_alive_cl(),
 68   _evac_update_oop_cl(),
 69   _nm_cl() {
 70   assert(StackWatermarkState::epoch(_state) == _epoch_id,
 71     "Should be the same: %u != %u", StackWatermarkState::epoch(_state), _epoch_id);
 72 }
 73 
 74 OopClosure* ShenandoahStackWatermark::closure_from_context(void* context) {
 75   if (context != nullptr) {
 76     assert((_heap->is_concurrent_weak_root_in_progress() && _heap->is_evacuation_in_progress()) ||
 77            _heap->is_concurrent_mark_in_progress(),
 78            "Only these two phases");
 79     assert(Thread::current()->is_Worker_thread(), "Unexpected thread passing in context: " PTR_FORMAT, p2i(context));
 80     return reinterpret_cast<OopClosure*>(context);
 81   } else {
 82     if (_heap->is_concurrent_weak_root_in_progress() && _heap->is_evacuation_in_progress()) {
 83       return &_evac_update_oop_cl;
 84     } else if (_heap->is_concurrent_mark_in_progress()) {
 85       return &_keep_alive_cl;
 86     } else {
 87       ShouldNotReachHere();
 88       return nullptr;
 89     }
 90   }
 91 }
 92 
 93 void ShenandoahStackWatermark::start_processing_impl(void* context) {
 94   NoSafepointVerifier nsv;
 95 
 96   // Process the non-frame part of the thread
 97   if (_heap->is_concurrent_weak_root_in_progress() && _heap->is_evacuation_in_progress()) {
 98     // Retire the TLABs, which will force threads to reacquire their TLABs.
 99     // This is needed for two reasons. Strong one: new allocations would be with new freeset,
100     // which would be outside the collection set, so no cset writes would happen there.
101     // Weaker one: new allocations would happen past update watermark, and so less work would
102     // be needed for reference updates (would update the large filler instead).
103     retire_tlab();
104 
105     _jt->oops_do_no_frames(closure_from_context(context), &_nm_cl);
106   } else if (_heap->is_concurrent_mark_in_progress()) {
107     // We need to reset all TLABs because they might be below the TAMS, and we need to mark
108     // the objects in them. Do not let mutators allocate any new objects in their current TLABs.
109     // It is also a good place to resize the TLAB sizes for future allocations.
110     retire_tlab();
111 
112     _jt->oops_do_no_frames(closure_from_context(context), &_nm_cl);
113   } else {
114     ShouldNotReachHere();
115   }
116 



117   // Publishes the processing start to concurrent threads
118   StackWatermark::start_processing_impl(context);
119 }
120 
121 void ShenandoahStackWatermark::retire_tlab() {
122   // Retire TLAB
123   if (UseTLAB) {
124     _stats.reset();
125     _jt->retire_tlab(&_stats);
126     if (ResizeTLAB) {
127       _jt->tlab().resize();
128     }
129   }
130 }
131 
132 void ShenandoahStackWatermark::process(const frame& fr, RegisterMap& register_map, void* context) {
133   OopClosure* oops = closure_from_context(context);
134   assert(oops != nullptr, "Should not get to here");
135   assert((_heap->is_concurrent_weak_root_in_progress() && _heap->is_evacuation_in_progress()) ||
136          _heap->is_concurrent_mark_in_progress(),
137          "Only these two phases");
138   fr.oops_do(oops, &_nm_cl, &register_map, DerivedPointerIterationMode::_directly);
139 }

 47 ThreadLocalAllocStats& ShenandoahStackWatermark::stats() {
 48   return _stats;
 49 }
 50 
 51 uint32_t ShenandoahStackWatermark::epoch_id() const {
 52   return _epoch_id;
 53 }
 54 
 55 void ShenandoahStackWatermark::change_epoch_id() {
 56   shenandoah_assert_safepoint();
 57   _epoch_id++;
 58   if (_epoch_id > MAX_EPOCH_ID) {
 59     _epoch_id = MIN_EPOCH_ID;
 60   }
 61 }
 62 
 63 ShenandoahStackWatermark::ShenandoahStackWatermark(JavaThread* jt) :
 64   StackWatermark(jt, StackWatermarkKind::gc, _epoch_id),
 65   _heap(ShenandoahHeap::heap()),
 66   _stats(),
 67   _no_op_cl(),
 68   _keep_alive_cl(),
 69   _evac_update_oop_cl(),
 70   _nm_cl() {
 71   assert(StackWatermarkState::epoch(_state) == _epoch_id,
 72     "Should be the same: %u != %u", StackWatermarkState::epoch(_state), _epoch_id);
 73 }
 74 
 75 OopClosure* ShenandoahStackWatermark::closure_from_context(void* context) {
 76   if (context != nullptr) {



 77     assert(Thread::current()->is_Worker_thread(), "Unexpected thread passing in context: " PTR_FORMAT, p2i(context));
 78     return reinterpret_cast<OopClosure*>(context);
 79   } else {
 80     if (_heap->is_concurrent_weak_root_in_progress() && _heap->is_evacuation_in_progress()) {
 81       return &_evac_update_oop_cl;
 82     } else if (_heap->is_concurrent_mark_in_progress()) {
 83       return &_keep_alive_cl;
 84     } else {
 85       return &_no_op_cl;

 86     }
 87   }
 88 }
 89 
 90 void ShenandoahStackWatermark::start_processing_impl(void* context) {
 91   NoSafepointVerifier nsv;
 92 

 93   if (_heap->is_concurrent_weak_root_in_progress() && _heap->is_evacuation_in_progress()) {

 94     // This is needed for two reasons. Strong one: new allocations would be with new freeset,
 95     // which would be outside the collection set, so no cset writes would happen there.
 96     // Weaker one: new allocations would happen past update watermark, and so less work would
 97     // be needed for reference updates (would update the large filler instead).
 98     retire_tlab();


 99   } else if (_heap->is_concurrent_mark_in_progress()) {
100     // We need to reset all TLABs because they might be below the TAMS, and we need to mark
101     // the objects in them. Do not let mutators allocate any new objects in their current TLABs.
102     // It is also a good place to resize the TLAB sizes for future allocations.
103     retire_tlab();




104   }
105 
106   // Process the non-frame part of the thread
107   _jt->oops_do_no_frames(closure_from_context(context), &_nm_cl);
108 
109   // Publishes the processing start to concurrent threads
110   StackWatermark::start_processing_impl(context);
111 }
112 
113 void ShenandoahStackWatermark::retire_tlab() {
114   // Retire TLAB
115   if (UseTLAB) {
116     _stats.reset();
117     _jt->retire_tlab(&_stats);
118     if (ResizeTLAB) {
119       _jt->tlab().resize();
120     }
121   }
122 }
123 
124 void ShenandoahStackWatermark::process(const frame& fr, RegisterMap& register_map, void* context) {
125   OopClosure* oops = closure_from_context(context);
126   assert(oops != nullptr, "Should not get to here");



127   fr.oops_do(oops, &_nm_cl, &register_map, DerivedPointerIterationMode::_directly);
128 }
< prev index next >