< prev index next >

src/hotspot/share/gc/shared/barrierSetNMethod.cpp

Print this page

169   // Enable WXWrite: the function is called directly from nmethod_entry_barrier
170   // stub.
171   MACOS_AARCH64_ONLY(ThreadWXEnable wx(WXWrite, Thread::current()));
172 
173   address return_address = *return_address_ptr;
174   AARCH64_PORT_ONLY(return_address = pauth_strip_pointer(return_address));
175   CodeBlob* cb = CodeCache::find_blob(return_address);
176   assert(cb != nullptr, "invariant");
177 
178   nmethod* nm = cb->as_nmethod();
179   BarrierSetNMethod* bs_nm = BarrierSet::barrier_set()->barrier_set_nmethod();
180 
181   // Check for disarmed method here to avoid going into DeoptimizeNMethodBarriersALot code
182   // too often. nmethod_entry_barrier checks for disarmed status itself,
183   // but we have no visibility into whether the barrier acted or not.
184   if (!bs_nm->is_armed(nm)) {
185     return 0;
186   }
187 
188   assert(!nm->is_osr_method(), "Should not reach here");

189   // Called upon first entry after being armed
190   bool may_enter = bs_nm->nmethod_entry_barrier(nm);
191 
192   // In case a concurrent thread disarmed the nmethod, we need to ensure the new instructions
193   // are made visible, by using a cross modify fence. Note that this is synchronous cross modifying
194   // code, where the existence of new instructions is communicated via data (the guard value).
195   // This cross modify fence is only needed when the nmethod entry barrier modifies the
196   // instructions. Not all platforms currently do that, so if this check becomes expensive,
197   // it can be made conditional on the nmethod_patching_type.
198   OrderAccess::cross_modify_fence();
199 
200   // Diagnostic option to force deoptimization 1 in 3 times. It is otherwise
201   // a very rare event.
202   if (DeoptimizeNMethodBarriersALot) {
203     static volatile uint32_t counter=0;
204     if (Atomic::add(&counter, 1u) % 3 == 0) {
205       may_enter = false;
206     }
207   }
208 
209   if (!may_enter) {


210     log_trace(nmethod, barrier)("Deoptimizing nmethod: " PTR_FORMAT, p2i(nm));
211     bs_nm->deoptimize(nm, return_address_ptr);
212   }
213   return may_enter ? 0 : 1;
214 }
215 
216 bool BarrierSetNMethod::nmethod_osr_entry_barrier(nmethod* nm) {
217   // This check depends on the invariant that all nmethods that are deoptimized / made not entrant
218   // are NOT disarmed.
219   // This invariant is important because a method can be deoptimized after the method have been
220   // resolved / looked up by OSR by another thread. By not deoptimizing them we guarantee that
221   // a deoptimized method will always hit the barrier and come to the same conclusion - deoptimize
222   if (!is_armed(nm)) {
223     return true;
224   }
225 
226   assert(nm->is_osr_method(), "Should not reach here");
227   log_trace(nmethod, barrier)("Running osr nmethod entry barrier: " PTR_FORMAT, p2i(nm));
228   bool result = nmethod_entry_barrier(nm);



229   OrderAccess::cross_modify_fence();
230   return result;
231 }

169   // Enable WXWrite: the function is called directly from nmethod_entry_barrier
170   // stub.
171   MACOS_AARCH64_ONLY(ThreadWXEnable wx(WXWrite, Thread::current()));
172 
173   address return_address = *return_address_ptr;
174   AARCH64_PORT_ONLY(return_address = pauth_strip_pointer(return_address));
175   CodeBlob* cb = CodeCache::find_blob(return_address);
176   assert(cb != nullptr, "invariant");
177 
178   nmethod* nm = cb->as_nmethod();
179   BarrierSetNMethod* bs_nm = BarrierSet::barrier_set()->barrier_set_nmethod();
180 
181   // Check for disarmed method here to avoid going into DeoptimizeNMethodBarriersALot code
182   // too often. nmethod_entry_barrier checks for disarmed status itself,
183   // but we have no visibility into whether the barrier acted or not.
184   if (!bs_nm->is_armed(nm)) {
185     return 0;
186   }
187 
188   assert(!nm->is_osr_method(), "Should not reach here");
189   log_trace(nmethod, barrier)("Running nmethod entry barrier: %d " PTR_FORMAT, nm->compile_id(), p2i(nm));
190   // Called upon first entry after being armed
191   bool may_enter = bs_nm->nmethod_entry_barrier(nm);
192 
193   // In case a concurrent thread disarmed the nmethod, we need to ensure the new instructions
194   // are made visible, by using a cross modify fence. Note that this is synchronous cross modifying
195   // code, where the existence of new instructions is communicated via data (the guard value).
196   // This cross modify fence is only needed when the nmethod entry barrier modifies the
197   // instructions. Not all platforms currently do that, so if this check becomes expensive,
198   // it can be made conditional on the nmethod_patching_type.
199   OrderAccess::cross_modify_fence();
200 
201   // Diagnostic option to force deoptimization 1 in 3 times. It is otherwise
202   // a very rare event.
203   if (DeoptimizeNMethodBarriersALot) {
204     static volatile uint32_t counter=0;
205     if (Atomic::add(&counter, 1u) % 3 == 0) {
206       may_enter = false;
207     }
208   }
209 
210   if (may_enter) {
211     nm->set_used();
212   } else {
213     log_trace(nmethod, barrier)("Deoptimizing nmethod: " PTR_FORMAT, p2i(nm));
214     bs_nm->deoptimize(nm, return_address_ptr);
215   }
216   return may_enter ? 0 : 1;
217 }
218 
219 bool BarrierSetNMethod::nmethod_osr_entry_barrier(nmethod* nm) {
220   // This check depends on the invariant that all nmethods that are deoptimized / made not entrant
221   // are NOT disarmed.
222   // This invariant is important because a method can be deoptimized after the method have been
223   // resolved / looked up by OSR by another thread. By not deoptimizing them we guarantee that
224   // a deoptimized method will always hit the barrier and come to the same conclusion - deoptimize
225   if (!is_armed(nm)) {
226     return true;
227   }
228 
229   assert(nm->is_osr_method(), "Should not reach here");
230   log_trace(nmethod, barrier)("Running osr nmethod entry barrier: %d " PTR_FORMAT, nm->compile_id(), p2i(nm));
231   bool result = nmethod_entry_barrier(nm);
232   if (result) {
233     nm->set_used();
234   }
235   OrderAccess::cross_modify_fence();
236   return result;
237 }
< prev index next >