hotspot/src/share/vm/prims/jvmtiEventController.cpp
void VM_EnterInterpOnlyMode::doit() {
{- -------------------------------------------
(1) JvmtiThreadState::invalidate_cur_stack_depth() を呼び出し,
JvmtiThreadState::_cur_stack_depth フィールドの値をリセットしておく.
(これは FramePop イベントのための処理. (See: [here](no2935pZs.html) for details))
---------------------------------------- -}
// Set up the current stack depth for later tracking
_state->invalidate_cur_stack_depth();
{- -------------------------------------------
(1) JvmtiThreadState::enter_interp_only_mode() を呼んで
対象の JavaThread 内の _interp_only_mode フィールドの値を increment しておく.
---------------------------------------- -}
_state->enter_interp_only_mode();
{- -------------------------------------------
(1) 対象のスレッドのスタック内に compiled フレームが有れば deopt する.
(スタック内にある(ネイティブメソッドではない)メソッドのフレームを全てたどる.
その中に JIT 生成されたメソッドのフレーム(= can_be_deoptimized() が true になるフレーム) があれば
対応する nmethod に CodeCache::mark_for_deoptimization() で印を付け,
num_marked 変数もインクリメントしておく.
スタックを辿り終わった後で num_marked が 0 以上であれば, VM_Deoptimize::doit() を呼び出す)
(なお, VM_Deoptimize::doit() は
CodeCache::mark_for_deoptimization() で印を付けられたフレームを全て deopt する関数 (See: VM_Deoptimize))
---------------------------------------- -}
JavaThread *thread = _state->get_thread();
if (thread->has_last_Java_frame()) {
// If running in fullspeed mode, single stepping is implemented
// as follows: first, the interpreter does not dispatch to
// compiled code for threads that have single stepping enabled;
// second, we deoptimize all methods on the thread's stack when
// interpreted-only mode is enabled the first time for a given
// thread (nothing to do if no Java frames yet).
int num_marked = 0;
ResourceMark resMark;
RegisterMap rm(thread, false);
for (vframe* vf = thread->last_java_vframe(&rm); vf; vf = vf->sender()) {
if (can_be_deoptimized(vf)) {
((compiledVFrame*) vf)->code()->mark_for_deoptimization();
++num_marked;
}
}
if (num_marked > 0) {
VM_Deoptimize op;
VMThread::execute(&op);
}
}
}
This document is available under the GNU GENERAL PUBLIC LICENSE Version 2.