13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25 #ifndef SHARE_VM_RUNTIME_INTERFACESUPPORT_HPP
26 #define SHARE_VM_RUNTIME_INTERFACESUPPORT_HPP
27
28 #include "gc/shared/gcLocker.hpp"
29 #include "runtime/handles.inline.hpp"
30 #include "runtime/mutexLocker.hpp"
31 #include "runtime/orderAccess.hpp"
32 #include "runtime/os.hpp"
33 #include "runtime/safepoint.hpp"
34 #include "runtime/thread.inline.hpp"
35 #include "runtime/vmThread.hpp"
36 #include "utilities/globalDefinitions.hpp"
37 #include "utilities/macros.hpp"
38 #include "utilities/preserveException.hpp"
39
40 // Wrapper for all entry points to the virtual machine.
41 // The HandleMarkCleaner is a faster version of HandleMark.
42 // It relies on the fact that there is a HandleMark further
43 // down the stack (in JavaCalls::call_helper), and just resets
44 // to the saved values in that HandleMark.
45
46 class HandleMarkCleaner: public StackObj {
47 private:
48 Thread* _thread;
49 public:
50 HandleMarkCleaner(Thread* thread) {
51 _thread = thread;
52 _thread->last_handle_mark()->push();
53 }
125 protected:
126 JavaThread* _thread;
127 public:
128 ThreadStateTransition(JavaThread *thread) {
129 _thread = thread;
130 assert(thread != NULL && thread->is_Java_thread(), "must be Java thread");
131 }
132
133 // Change threadstate in a manner, so safepoint can detect changes.
134 // Time-critical: called on exit from every runtime routine
135 static inline void transition(JavaThread *thread, JavaThreadState from, JavaThreadState to) {
136 assert(from != _thread_in_Java, "use transition_from_java");
137 assert(from != _thread_in_native, "use transition_from_native");
138 assert((from & 1) == 0 && (to & 1) == 0, "odd numbers are transitions states");
139 assert(thread->thread_state() == from, "coming from wrong thread state");
140 // Change to transition state
141 thread->set_thread_state((JavaThreadState)(from + 1));
142
143 InterfaceSupport::serialize_thread_state(thread);
144
145 if (SafepointSynchronize::do_call_back()) {
146 SafepointSynchronize::block(thread);
147 }
148 thread->set_thread_state(to);
149
150 CHECK_UNHANDLED_OOPS_ONLY(thread->clear_unhandled_oops();)
151 }
152
153 // transition_and_fence must be used on any thread state transition
154 // where there might not be a Java call stub on the stack, in
155 // particular on Windows where the Structured Exception Handler is
156 // set up in the call stub. os::write_memory_serialize_page() can
157 // fault and we can't recover from it on Windows without a SEH in
158 // place.
159 static inline void transition_and_fence(JavaThread *thread, JavaThreadState from, JavaThreadState to) {
160 assert(thread->thread_state() == from, "coming from wrong thread state");
161 assert((from & 1) == 0 && (to & 1) == 0, "odd numbers are transitions states");
162 // Change to transition state
163 thread->set_thread_state((JavaThreadState)(from + 1));
164
165 InterfaceSupport::serialize_thread_state_with_handler(thread);
166
167 if (SafepointSynchronize::do_call_back()) {
168 SafepointSynchronize::block(thread);
169 }
170 thread->set_thread_state(to);
171
172 CHECK_UNHANDLED_OOPS_ONLY(thread->clear_unhandled_oops();)
173 }
174
175 // Same as above, but assumes from = _thread_in_Java. This is simpler, since we
176 // never block on entry to the VM. This will break the code, since e.g. preserve arguments
177 // have not been setup.
178 static inline void transition_from_java(JavaThread *thread, JavaThreadState to) {
179 assert(thread->thread_state() == _thread_in_Java, "coming from wrong thread state");
180 thread->set_thread_state(to);
181 }
182
183 static inline void transition_from_native(JavaThread *thread, JavaThreadState to) {
184 assert((to & 1) == 0, "odd numbers are transitions states");
185 assert(thread->thread_state() == _thread_in_native, "coming from wrong thread state");
186 // Change to transition state
187 thread->set_thread_state(_thread_in_native_trans);
188
189 InterfaceSupport::serialize_thread_state_with_handler(thread);
190
191 // We never install asynchronous exceptions when coming (back) in
192 // to the runtime from native code because the runtime is not set
193 // up to handle exceptions floating around at arbitrary points.
194 if (SafepointSynchronize::do_call_back() || thread->is_suspend_after_native()) {
195 JavaThread::check_safepoint_and_suspend_for_native_trans(thread);
196
197 // Clear unhandled oops anywhere where we could block, even if we don't.
198 CHECK_UNHANDLED_OOPS_ONLY(thread->clear_unhandled_oops();)
199 }
200
201 thread->set_thread_state(to);
202 }
203 protected:
204 void trans(JavaThreadState from, JavaThreadState to) { transition(_thread, from, to); }
205 void trans_from_java(JavaThreadState to) { transition_from_java(_thread, to); }
206 void trans_from_native(JavaThreadState to) { transition_from_native(_thread, to); }
207 void trans_and_fence(JavaThreadState from, JavaThreadState to) { transition_and_fence(_thread, from, to); }
208 };
209
210
211 class ThreadInVMfromJava : public ThreadStateTransition {
212 public:
213 ThreadInVMfromJava(JavaThread* thread) : ThreadStateTransition(thread) {
214 trans_from_java(_thread_in_vm);
215 }
216 ~ThreadInVMfromJava() {
217 if (_thread->stack_yellow_reserved_zone_disabled()) {
218 _thread->enable_stack_yellow_reserved_zone();
219 }
220 trans(_thread_in_vm, _thread_in_Java);
221 // Check for pending. async. exceptions or suspends.
222 if (_thread->has_special_runtime_exit_condition()) _thread->handle_special_runtime_exit_condition();
223 }
224 };
225
226
227 class ThreadInVMfromUnknown {
228 private:
229 JavaThread* _thread;
|
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25 #ifndef SHARE_VM_RUNTIME_INTERFACESUPPORT_HPP
26 #define SHARE_VM_RUNTIME_INTERFACESUPPORT_HPP
27
28 #include "gc/shared/gcLocker.hpp"
29 #include "runtime/handles.inline.hpp"
30 #include "runtime/mutexLocker.hpp"
31 #include "runtime/orderAccess.hpp"
32 #include "runtime/os.hpp"
33 #include "runtime/safepointMechanism.inline.hpp"
34 #include "runtime/thread.inline.hpp"
35 #include "runtime/vmThread.hpp"
36 #include "utilities/globalDefinitions.hpp"
37 #include "utilities/macros.hpp"
38 #include "utilities/preserveException.hpp"
39
40 // Wrapper for all entry points to the virtual machine.
41 // The HandleMarkCleaner is a faster version of HandleMark.
42 // It relies on the fact that there is a HandleMark further
43 // down the stack (in JavaCalls::call_helper), and just resets
44 // to the saved values in that HandleMark.
45
46 class HandleMarkCleaner: public StackObj {
47 private:
48 Thread* _thread;
49 public:
50 HandleMarkCleaner(Thread* thread) {
51 _thread = thread;
52 _thread->last_handle_mark()->push();
53 }
125 protected:
126 JavaThread* _thread;
127 public:
128 ThreadStateTransition(JavaThread *thread) {
129 _thread = thread;
130 assert(thread != NULL && thread->is_Java_thread(), "must be Java thread");
131 }
132
133 // Change threadstate in a manner, so safepoint can detect changes.
134 // Time-critical: called on exit from every runtime routine
135 static inline void transition(JavaThread *thread, JavaThreadState from, JavaThreadState to) {
136 assert(from != _thread_in_Java, "use transition_from_java");
137 assert(from != _thread_in_native, "use transition_from_native");
138 assert((from & 1) == 0 && (to & 1) == 0, "odd numbers are transitions states");
139 assert(thread->thread_state() == from, "coming from wrong thread state");
140 // Change to transition state
141 thread->set_thread_state((JavaThreadState)(from + 1));
142
143 InterfaceSupport::serialize_thread_state(thread);
144
145 SafepointMechanism::block_if_requested(thread);
146 thread->set_thread_state(to);
147
148 CHECK_UNHANDLED_OOPS_ONLY(thread->clear_unhandled_oops();)
149 }
150
151 // transition_and_fence must be used on any thread state transition
152 // where there might not be a Java call stub on the stack, in
153 // particular on Windows where the Structured Exception Handler is
154 // set up in the call stub. os::write_memory_serialize_page() can
155 // fault and we can't recover from it on Windows without a SEH in
156 // place.
157 static inline void transition_and_fence(JavaThread *thread, JavaThreadState from, JavaThreadState to) {
158 assert(thread->thread_state() == from, "coming from wrong thread state");
159 assert((from & 1) == 0 && (to & 1) == 0, "odd numbers are transitions states");
160 // Change to transition state
161 thread->set_thread_state((JavaThreadState)(from + 1));
162
163 InterfaceSupport::serialize_thread_state_with_handler(thread);
164
165 SafepointMechanism::block_if_requested(thread);
166 thread->set_thread_state(to);
167
168 CHECK_UNHANDLED_OOPS_ONLY(thread->clear_unhandled_oops();)
169 }
170
171 // Same as above, but assumes from = _thread_in_Java. This is simpler, since we
172 // never block on entry to the VM. This will break the code, since e.g. preserve arguments
173 // have not been setup.
174 static inline void transition_from_java(JavaThread *thread, JavaThreadState to) {
175 assert(thread->thread_state() == _thread_in_Java, "coming from wrong thread state");
176 thread->set_thread_state(to);
177 }
178
179 static inline void transition_from_native(JavaThread *thread, JavaThreadState to) {
180 assert((to & 1) == 0, "odd numbers are transitions states");
181 assert(thread->thread_state() == _thread_in_native, "coming from wrong thread state");
182 // Change to transition state
183 thread->set_thread_state(_thread_in_native_trans);
184
185 InterfaceSupport::serialize_thread_state_with_handler(thread);
186
187 // We never install asynchronous exceptions when coming (back) in
188 // to the runtime from native code because the runtime is not set
189 // up to handle exceptions floating around at arbitrary points.
190 if (SafepointMechanism::poll(thread) || thread->is_suspend_after_native()) {
191 JavaThread::check_safepoint_and_suspend_for_native_trans(thread);
192
193 // Clear unhandled oops anywhere where we could block, even if we don't.
194 CHECK_UNHANDLED_OOPS_ONLY(thread->clear_unhandled_oops();)
195 }
196
197 thread->set_thread_state(to);
198 }
199 protected:
200 void trans(JavaThreadState from, JavaThreadState to) { transition(_thread, from, to); }
201 void trans_from_java(JavaThreadState to) { transition_from_java(_thread, to); }
202 void trans_from_native(JavaThreadState to) { transition_from_native(_thread, to); }
203 void trans_and_fence(JavaThreadState from, JavaThreadState to) { transition_and_fence(_thread, from, to); }
204 };
205
206 class ThreadInVMForHandshake : public ThreadStateTransition {
207 const JavaThreadState _original_state;
208
209 void transition_back() {
210 // This can be invoked from transition states and must return to the original state properly
211 assert(_thread->thread_state() == _thread_in_vm, "should only call when leaving VM after handshake");
212 _thread->set_thread_state(_thread_in_vm_trans);
213
214 InterfaceSupport::serialize_thread_state(_thread);
215
216 SafepointMechanism::block_if_requested(_thread);
217
218 _thread->set_thread_state(_original_state);
219 }
220
221 public:
222
223 ThreadInVMForHandshake(JavaThread* thread) : ThreadStateTransition(thread),
224 _original_state(thread->thread_state()) {
225
226 if (thread->has_last_Java_frame()) {
227 thread->frame_anchor()->make_walkable(thread);
228 }
229
230 thread->set_thread_state(_thread_in_vm);
231 }
232
233 ~ThreadInVMForHandshake() {
234 transition_back();
235 }
236
237 };
238
239 class ThreadInVMfromJava : public ThreadStateTransition {
240 public:
241 ThreadInVMfromJava(JavaThread* thread) : ThreadStateTransition(thread) {
242 trans_from_java(_thread_in_vm);
243 }
244 ~ThreadInVMfromJava() {
245 if (_thread->stack_yellow_reserved_zone_disabled()) {
246 _thread->enable_stack_yellow_reserved_zone();
247 }
248 trans(_thread_in_vm, _thread_in_Java);
249 // Check for pending. async. exceptions or suspends.
250 if (_thread->has_special_runtime_exit_condition()) _thread->handle_special_runtime_exit_condition();
251 }
252 };
253
254
255 class ThreadInVMfromUnknown {
256 private:
257 JavaThread* _thread;
|