211 // VM thread sees a Java thread in native, it does |
211 // VM thread sees a Java thread in native, it does |
212 // not wait for this thread to block. The order of the memory |
212 // not wait for this thread to block. The order of the memory |
213 // writes and reads of both the safepoint state and the Java |
213 // writes and reads of both the safepoint state and the Java |
214 // threads state is critical. In order to guarantee that the |
214 // threads state is critical. In order to guarantee that the |
215 // memory writes are serialized with respect to each other, |
215 // memory writes are serialized with respect to each other, |
216 // the VM thread issues a memory barrier instruction |
216 // the VM thread issues a memory barrier instruction. |
217 // (on MP systems). In order to avoid the overhead of issuing |
|
218 // a memory barrier for each Java thread making native calls, each Java |
|
219 // thread performs a write to a single memory page after changing |
|
220 // the thread state. The VM thread performs a sequence of |
|
221 // mprotect OS calls which forces all previous writes from all |
|
222 // Java threads to be serialized. This is done in the |
|
223 // os::serialize_thread_states() call. This has proven to be |
|
224 // much more efficient than executing a membar instruction |
|
225 // on every call to native code. |
|
226 // 3. Running compiled Code |
217 // 3. Running compiled Code |
227 // Compiled code reads a global (Safepoint Polling) page that |
218 // Compiled code reads a global (Safepoint Polling) page that |
228 // is set to fault if we are trying to get to a safepoint. |
219 // is set to fault if we are trying to get to a safepoint. |
229 // 4. Blocked |
220 // 4. Blocked |
230 // A thread which is blocked will not be allowed to return from the |
221 // A thread which is blocked will not be allowed to return from the |
248 // Make sure the threads start polling, it is time to yield. |
239 // Make sure the threads start polling, it is time to yield. |
249 SafepointMechanism::arm_local_poll(cur); |
240 SafepointMechanism::arm_local_poll(cur); |
250 } |
241 } |
251 } |
242 } |
252 OrderAccess::fence(); // storestore|storeload, global state -> local state |
243 OrderAccess::fence(); // storestore|storeload, global state -> local state |
253 |
|
254 // Flush all thread states to memory |
|
255 if (!UseMembar) { |
|
256 os::serialize_thread_states(); |
|
257 } |
|
258 |
244 |
259 if (SafepointMechanism::uses_global_page_poll()) { |
245 if (SafepointMechanism::uses_global_page_poll()) { |
260 // Make interpreter safepoint aware |
246 // Make interpreter safepoint aware |
261 Interpreter::notice_safepoints(); |
247 Interpreter::notice_safepoints(); |
262 |
248 |