< prev index next >

src/hotspot/cpu/aarch64/gc/shared/barrierSetNMethod_aarch64.cpp

Print this page

146     ResourceMark mark;
147     log_trace(nmethod, barrier)("deoptimize(nmethod: %s(%p), return_addr: %p, osr: %d, thread: %p(%s), making rsp: %p) -> %p",
148                                 nm->method()->name_and_sig_as_C_string(),
149                                 nm, *(address *) return_address_ptr, nm->is_osr_method(), thread,
150                                 thread->name(), frame.sp(), nm->verified_entry_point());
151   }
152 
153   new_frame->sp = frame.sp();
154   new_frame->fp = frame.fp();
155   new_frame->lr = frame.pc();
156   new_frame->pc = SharedRuntime::get_handle_wrong_method_stub();
157 }
158 
159 static NativeNMethodBarrier* native_nmethod_barrier(nmethod* nm) {
160   address barrier_address = nm->code_begin() + nm->frame_complete_offset() + entry_barrier_offset(nm);
161   NativeNMethodBarrier* barrier = reinterpret_cast<NativeNMethodBarrier*>(barrier_address);
162   debug_only(barrier->verify());
163   return barrier;
164 }
165 

























166 void BarrierSetNMethod::disarm(nmethod* nm) {
167   if (!supports_entry_barrier(nm)) {
168     return;
169   }
170 
171   // The patching epoch is incremented before the nmethod is disarmed. Disarming
172   // is performed with a release store. In the nmethod entry barrier, the values
173   // are read in the opposite order, such that the load of the nmethod guard
174   // acquires the patching epoch. This way, the guard is guaranteed to block
175   // entries to the nmethod, until it has safely published the requirement for
176   // further fencing by mutators, before they are allowed to enter.
177   BarrierSetAssembler* bs_asm = BarrierSet::barrier_set()->barrier_set_assembler();
178   bs_asm->increment_patching_epoch();
179 
180   // Disarms the nmethod guard emitted by BarrierSetAssembler::nmethod_entry_barrier.
181   // Symmetric "LDR; DMB ISHLD" is in the nmethod barrier.
182   NativeNMethodBarrier* barrier = native_nmethod_barrier(nm);
183   barrier->set_value(nm, disarmed_value());
184 }
185 
186 void BarrierSetNMethod::arm(nmethod* nm, int arm_value) {
187   if (!supports_entry_barrier(nm)) {
188     return;
189   }
190 
191   if (arm_value == disarmed_value()) {
192     // The patching epoch is incremented before the nmethod is disarmed. Disarming
193     // is performed with a release store. In the nmethod entry barrier, the values
194     // are read in the opposite order, such that the load of the nmethod guard
195     // acquires the patching epoch. This way, the guard is guaranteed to block
196     // entries to the nmethod, until it has safely published the requirement for
197     // further fencing by mutators, before they are allowed to enter.
198     BarrierSetAssembler* bs_asm = BarrierSet::barrier_set()->barrier_set_assembler();
199     bs_asm->increment_patching_epoch();
200   }
201 
202   NativeNMethodBarrier* barrier = native_nmethod_barrier(nm);
203   barrier->set_value(nm, arm_value);
204 }
205 
206 bool BarrierSetNMethod::is_armed(nmethod* nm) {
207   if (!supports_entry_barrier(nm)) {
208     return false;
209   }
210 
211   NativeNMethodBarrier* barrier = native_nmethod_barrier(nm);
212   return barrier->get_value(nm) != disarmed_value();
213 }

146     ResourceMark mark;
147     log_trace(nmethod, barrier)("deoptimize(nmethod: %s(%p), return_addr: %p, osr: %d, thread: %p(%s), making rsp: %p) -> %p",
148                                 nm->method()->name_and_sig_as_C_string(),
149                                 nm, *(address *) return_address_ptr, nm->is_osr_method(), thread,
150                                 thread->name(), frame.sp(), nm->verified_entry_point());
151   }
152 
153   new_frame->sp = frame.sp();
154   new_frame->fp = frame.fp();
155   new_frame->lr = frame.pc();
156   new_frame->pc = SharedRuntime::get_handle_wrong_method_stub();
157 }
158 
159 static NativeNMethodBarrier* native_nmethod_barrier(nmethod* nm) {
160   address barrier_address = nm->code_begin() + nm->frame_complete_offset() + entry_barrier_offset(nm);
161   NativeNMethodBarrier* barrier = reinterpret_cast<NativeNMethodBarrier*>(barrier_address);
162   debug_only(barrier->verify());
163   return barrier;
164 }
165 
166 static void set_value(nmethod* nm, jint val) {
167   NativeNMethodBarrier* cmp1 = native_nmethod_barrier(nm);
168   cmp1->set_value(nm, val);
169 
170   if (!nm->is_osr_method() && nm->method()->has_scalarized_args()) {
171     // nmethods with scalarized arguments have multiple entry points that each have an own nmethod entry barrier
172     assert(nm->verified_entry_point() != nm->verified_inline_entry_point(), "scalarized entry point not found");
173     address method_body = nm->is_compiled_by_c1() ? nm->verified_inline_entry_point() : nm->verified_entry_point();
174     address entry_point2 = nm->is_compiled_by_c1() ? nm->verified_entry_point() : nm->verified_inline_entry_point();
175 
176     int barrier_offset = reinterpret_cast<address>(cmp1) - method_body;
177     NativeNMethodBarrier* cmp2 = reinterpret_cast<NativeNMethodBarrier*>(entry_point2 + barrier_offset);
178     assert(cmp1 != cmp2, "sanity");
179     debug_only(cmp2->verify());
180     cmp2->set_value(nm, val);
181 
182     if (method_body != nm->verified_inline_ro_entry_point() && entry_point2 != nm->verified_inline_ro_entry_point()) {
183       NativeNMethodBarrier* cmp3 = reinterpret_cast<NativeNMethodBarrier*>(nm->verified_inline_ro_entry_point() + barrier_offset);
184       assert(cmp1 != cmp3 && cmp2 != cmp3, "sanity");
185       debug_only(cmp3->verify());
186       cmp3->set_value(nm, val);
187     }
188   }
189 }
190 
191 void BarrierSetNMethod::disarm(nmethod* nm) {
192   if (!supports_entry_barrier(nm)) {
193     return;
194   }
195 
196   // The patching epoch is incremented before the nmethod is disarmed. Disarming
197   // is performed with a release store. In the nmethod entry barrier, the values
198   // are read in the opposite order, such that the load of the nmethod guard
199   // acquires the patching epoch. This way, the guard is guaranteed to block
200   // entries to the nmethod, until it has safely published the requirement for
201   // further fencing by mutators, before they are allowed to enter.
202   BarrierSetAssembler* bs_asm = BarrierSet::barrier_set()->barrier_set_assembler();
203   bs_asm->increment_patching_epoch();
204 
205   // Disarms the nmethod guard emitted by BarrierSetAssembler::nmethod_entry_barrier.
206   // Symmetric "LDR; DMB ISHLD" is in the nmethod barrier.
207   set_value(nm, disarmed_value());

208 }
209 
210 void BarrierSetNMethod::arm(nmethod* nm, int arm_value) {
211   if (!supports_entry_barrier(nm)) {
212     return;
213   }
214 
215   if (arm_value == disarmed_value()) {
216     // The patching epoch is incremented before the nmethod is disarmed. Disarming
217     // is performed with a release store. In the nmethod entry barrier, the values
218     // are read in the opposite order, such that the load of the nmethod guard
219     // acquires the patching epoch. This way, the guard is guaranteed to block
220     // entries to the nmethod, until it has safely published the requirement for
221     // further fencing by mutators, before they are allowed to enter.
222     BarrierSetAssembler* bs_asm = BarrierSet::barrier_set()->barrier_set_assembler();
223     bs_asm->increment_patching_epoch();
224   }
225 
226   set_value(nm, arm_value);

227 }
228 
229 bool BarrierSetNMethod::is_armed(nmethod* nm) {
230   if (!supports_entry_barrier(nm)) {
231     return false;
232   }
233 
234   NativeNMethodBarrier* barrier = native_nmethod_barrier(nm);
235   return barrier->get_value(nm) != disarmed_value();
236 }
< prev index next >