hotspot/src/share/vm/interpreter/interpreter.cpp
void AbstractInterpreterGenerator::bang_stack_shadow_pages(bool native_call) {
{- -------------------------------------------
(1) (この関数では, quick & dirty なスタックオーバーフロー検査を行う.
スタックをたたいてみて, メモリアクセス違反が出たらシグナルハンドラで捕まえる.
なお, この処理はフレームのセットアップが終わってからにすること.
例外ハンドラは, きちんとしたフレームが出来ていると想定している.
また, synchronized メソッドについては既にロックを確保済みだとも想定しているので,
あまり早くこの処理を呼び出すとおかしなことになる.)
<= と書いてあるが, synchronized については
do_not_unlock_if_synchronized ビットで対処しているような...#TODO
---------------------------------------- -}
// Quick & dirty stack overflow checking: bang the stack & handle trap.
// Note that we do the banging after the frame is setup, since the exception
// handling code expects to find a valid interpreter frame on the stack.
// Doing the banging earlier fails if the caller frame is not an interpreter
// frame.
// (Also, the exception throwing code expects to unlock any synchronized
// method receiever, so do the banging after locking the receiver.)
{- -------------------------------------------
(1) コード生成: (ただし, UseStackBanging オプションが指定されていなければ, 不要なので生成しない)
以下のコードを, banging 対象のページ数分だけ生成する (pages 変数の値を変えて生成).
「MacroAssembler::bang_stack_with_offset() が生成するコードにより,
現在の SP から pages ページ分だけ離れたアドレスに書き込みを行う.」
(なお, 非ネイティブメソッドの場合はこれまでにどの程度 banging されてきたかが分からないので
shadow page 全域を bang するとのこと.
逆にネイティブメソッドの場合は, 今回追加された 1枚分だけを banging する.)
---------------------------------------- -}
// Bang each page in the shadow zone. We can't assume it's been done for
// an interpreter frame with greater than a page of locals, so each page
// needs to be checked. Only true for non-native.
if (UseStackBanging) {
const int start_page = native_call ? StackShadowPages : 1;
const int page_size = os::vm_page_size();
for (int pages = start_page; pages <= StackShadowPages ; pages++) {
__ bang_stack_with_offset(pages*page_size);
}
}
}
This document is available under the GNU GENERAL PUBLIC LICENSE Version 2.