|
1 | 1 | /*
|
2 |
| - * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved. |
| 2 | + * Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved. |
3 | 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
4 | 4 | *
|
5 | 5 | * This code is free software; you can redistribute it and/or modify it
|
|
33 | 33 | #include "prims/jvmtiImpl.hpp"
|
34 | 34 | #include "prims/jvmtiThreadState.inline.hpp"
|
35 | 35 | #include "runtime/deoptimization.hpp"
|
36 |
| -#include "runtime/frame.hpp" |
| 36 | +#include "runtime/frame.inline.hpp" |
37 | 37 | #include "runtime/thread.inline.hpp"
|
38 | 38 | #include "runtime/threadSMR.hpp"
|
39 | 39 | #include "runtime/vframe.hpp"
|
@@ -190,60 +190,38 @@ JvmtiEnvEventEnable::~JvmtiEnvEventEnable() {
|
190 | 190 |
|
191 | 191 | ///////////////////////////////////////////////////////////////
|
192 | 192 | //
|
193 |
| -// VM_EnterInterpOnlyMode |
| 193 | +// EnterInterpOnlyModeClosure |
194 | 194 | //
|
195 | 195 |
|
196 |
| -class VM_EnterInterpOnlyMode : public VM_Operation { |
197 |
| -private: |
198 |
| - JvmtiThreadState *_state; |
| 196 | +class EnterInterpOnlyModeClosure : public HandshakeClosure { |
199 | 197 |
|
200 | 198 | public:
|
201 |
| - VM_EnterInterpOnlyMode(JvmtiThreadState *state); |
202 |
| - |
203 |
| - bool allow_nested_vm_operations() const { return true; } |
204 |
| - VMOp_Type type() const { return VMOp_EnterInterpOnlyMode; } |
205 |
| - void doit(); |
206 |
| - |
207 |
| - // to do: this same function is in jvmtiImpl - should be in one place |
208 |
| - bool can_be_deoptimized(vframe* vf) { |
209 |
| - return (vf->is_compiled_frame() && vf->fr().can_be_deoptimized()); |
210 |
| - } |
211 |
| -}; |
212 |
| - |
213 |
| -VM_EnterInterpOnlyMode::VM_EnterInterpOnlyMode(JvmtiThreadState *state) |
214 |
| - : _state(state) |
215 |
| -{ |
216 |
| -} |
217 |
| - |
218 |
| - |
219 |
| -void VM_EnterInterpOnlyMode::doit() { |
220 |
| - // Set up the current stack depth for later tracking |
221 |
| - _state->invalidate_cur_stack_depth(); |
222 |
| - |
223 |
| - _state->enter_interp_only_mode(); |
224 |
| - |
225 |
| - JavaThread *thread = _state->get_thread(); |
226 |
| - if (thread->has_last_Java_frame()) { |
227 |
| - // If running in fullspeed mode, single stepping is implemented |
228 |
| - // as follows: first, the interpreter does not dispatch to |
229 |
| - // compiled code for threads that have single stepping enabled; |
230 |
| - // second, we deoptimize all methods on the thread's stack when |
231 |
| - // interpreted-only mode is enabled the first time for a given |
232 |
| - // thread (nothing to do if no Java frames yet). |
233 |
| - int num_marked = 0; |
234 |
| - ResourceMark resMark; |
235 |
| - RegisterMap rm(thread, false); |
236 |
| - for (vframe* vf = thread->last_java_vframe(&rm); vf; vf = vf->sender()) { |
237 |
| - if (can_be_deoptimized(vf)) { |
238 |
| - ((compiledVFrame*) vf)->code()->mark_for_deoptimization(); |
239 |
| - ++num_marked; |
| 199 | + EnterInterpOnlyModeClosure() : HandshakeClosure("EnterInterpOnlyMode") { } |
| 200 | + void do_thread(Thread* th) { |
| 201 | + JavaThread* jt = (JavaThread*) th; |
| 202 | + JvmtiThreadState* state = jt->jvmti_thread_state(); |
| 203 | + |
| 204 | + // Set up the current stack depth for later tracking |
| 205 | + state->invalidate_cur_stack_depth(); |
| 206 | + |
| 207 | + state->enter_interp_only_mode(); |
| 208 | + |
| 209 | + if (jt->has_last_Java_frame()) { |
| 210 | + // If running in fullspeed mode, single stepping is implemented |
| 211 | + // as follows: first, the interpreter does not dispatch to |
| 212 | + // compiled code for threads that have single stepping enabled; |
| 213 | + // second, we deoptimize all compiled java frames on the thread's stack when |
| 214 | + // interpreted-only mode is enabled the first time for a given |
| 215 | + // thread (nothing to do if no Java frames yet). |
| 216 | + ResourceMark resMark; |
| 217 | + for (StackFrameStream fst(jt, false); !fst.is_done(); fst.next()) { |
| 218 | + if (fst.current()->can_be_deoptimized()) { |
| 219 | + Deoptimization::deoptimize(jt, *fst.current()); |
| 220 | + } |
240 | 221 | }
|
241 | 222 | }
|
242 |
| - if (num_marked > 0) { |
243 |
| - Deoptimization::deoptimize_all_marked(); |
244 |
| - } |
245 | 223 | }
|
246 |
| -} |
| 224 | +}; |
247 | 225 |
|
248 | 226 |
|
249 | 227 | ///////////////////////////////////////////////////////////////
|
@@ -352,9 +330,12 @@ void VM_ChangeSingleStep::doit() {
|
352 | 330 | void JvmtiEventControllerPrivate::enter_interp_only_mode(JvmtiThreadState *state) {
|
353 | 331 | EC_TRACE(("[%s] # Entering interpreter only mode",
|
354 | 332 | JvmtiTrace::safe_get_thread_name(state->get_thread())));
|
355 |
| - |
356 |
| - VM_EnterInterpOnlyMode op(state); |
357 |
| - VMThread::execute(&op); |
| 333 | + EnterInterpOnlyModeClosure hs; |
| 334 | + if (SafepointSynchronize::is_at_safepoint()) { |
| 335 | + hs.do_thread(state->get_thread()); |
| 336 | + } else { |
| 337 | + Handshake::execute_direct(&hs, state->get_thread()); |
| 338 | + } |
358 | 339 | }
|
359 | 340 |
|
360 | 341 |
|
|
0 commit comments