Template Interpreter の場合, do_oop_store() 関数によって Write Barrier 処理を行うコードが生成される.
なお, do_oop_store() は現在は以下のパスで(のみ)呼び出されている.
TemplateTable::putfield_or_static() -> do_oop_store()
TemplateTable::fast_storefield() -> do_oop_store()
TemplateTable::aastore() -> do_oop_store()
なお G1GC の場合は, java.lang.ref.Reference.get() の処理 (= InterpreterGenerator::generate_Reference_get_entry() が生成するコード)においても, MacroAssembler::g1_write_barrier_pre() が生成したコードによる処理が行われる (See: here for details).
-> do_oop_store() が生成するコード
-> 使用する GC アルゴリズムが G1GC かどうかに応じて 2通りの処理が存在
* G1GC 以外の場合:
-> (1) 対象のポインタ値の書き換えを行う
-> MacroAssembler::store_heap_oop() が生成するコード or
MacroAssembler::store_heap_oop_null()
(2) 書き換え箇所に対応する Barrier Set 中の値を dirty にする
-> MacroAssembler::store_check() が生成するコード
-> MacroAssembler::card_table_write() が生成するコード
* G1GC の場合:
-> (1) SATB 用の Write Barrier 処理を (その必要があれば) 実行する
-> MacroAssembler::g1_write_barrier_pre() が生成するコード
-> * ConcurrentMarkThread が作業をしていない場合: (See: here for details)
何もしない
* 現在の値(= 書き換え前の値)が NULL の場合:
何もしない
* それ以外の場合:
-> generate_satb_log_enqueue_if_necessary() が生成するコード
-> generate_satb_log_enqueue() が生成するコード
-> SATBMarkQueueSet::handle_zero_index_for_thread() (<= もうバッファに空きがない場合には呼び出す)
-> PtrQueue::handle_zero_index()
-> ObjPtrQueue::should_enqueue_buffer()
-> * ロックと関連づけられているバッファの場合:
-> PtrQueue::locking_enqueue_completed_buffer()
-> PtrQueueSet::enqueue_complete_buffer()
-> Monitor::notify()
* ロックと関連づけられていないバッファの場合:
-> PtrQueueSet::process_or_enqueue_complete_buffer()
-> * 自分で処理してしまう場合:
-> DirtyCardQueueSet::mut_process_buffer()
* それ以外の場合:
-> PtrQueueSet::enqueue_complete_buffer()
-> (同上)
-> PtrQueueSet::allocate_buffer()
(2) 対象のポインタ値の書き換えを行う
-> MacroAssembler::store_heap_oop() が生成するコード
(3) 書き換え箇所に対応する Barrier Set 中の値を dirty にする
-> MacroAssembler::g1_write_barrier_post() が生成するコード
-> * 同一 HeapRegion 内を指している場合:
何もしない
* それ以外の場合:
-> generate_dirty_card_log_enqueue_if_necessary() が生成するコード
-> generate_dirty_card_log_enqueue() が生成するコード
-> DirtyCardQueueSet::handle_zero_index_for_thread() (<= もうバッファに空きがない場合には呼び出す)
-> PtrQueue::handle_zero_index()
-> (略) (同上)
(ただし, ObjPtrQueue::should_enqueue_buffer() ではなく PtrQueue::should_enqueue_buffer() が呼び出される)
-> PtrQueueSet::enqueue_complete_buffer()
-> Monitor::notify() (<= DirtyCardQ_CBL_mon に対して. これは ConcurrentG1RefineThread を起床させる処理 (See: here for details))
-> do_oop_store() が生成するコード
-> 使用する GC アルゴリズムが G1GC かどうかに応じて 2通りの処理が存在
* G1GC 以外の場合:
-> (1) 対象のポインタ値の書き換えを行う
-> MacroAssembler::store_heap_oop() が生成するコード
(2) 書き換え箇所に対応する Barrier Set 中の値を dirty にする
-> MacroAssembler::store_check()
-> MacroAssembler::store_check_part_1() が生成するコード
-> MacroAssembler::store_check_part_2() が生成するコード
* G1GC の場合:
-> (1) SATB 用の Write Barrier 処理を (その必要があれば) 実行する
-> MacroAssembler::g1_write_barrier_pre()
-> * ConcurrentMarkThread が作業をしていない場合: (See: here for details)
何もしない
* 現在の値(= 書き換え前の値)が NULL の場合:
何もしない
* それ以外の場合:
-> SharedRuntime::g1_wb_pre() (← もうバッファに空きがない場合には呼び出す)
-> PtrQueue::enqueue() (← thread->satb_mark_queue() に対して呼び出す)
-> PtrQueue::enqueue_known_active()
-> PtrQueue::handle_zero_index()
-> (同上)
(2) 対象のポインタ値の書き換えを行う
-> MacroAssembler::store_heap_oop() が生成するコード, または
MacroAssembler::store_heap_oop_null() が生成するコード
(2) 書き換え箇所に対応する Barrier Set 中の値を dirty にする
-> MacroAssembler::g1_write_barrier_post() が生成するコード
-> SharedRuntime::g1_wb_post() (← もうバッファに空きがない場合には呼び出す)
-> PtrQueue::enqueue() (← thread->dirty_card_queue() に対して呼び出す)
-> (同上)
See: here for details
See: here for details
See: here for details
See: here for details
See: here for details
See: here for details
See: here for details
See: here for details
See: here for details
See: here for details
See: here for details
See: here for details
See: here for details
See: here for details
See: here for details
See: here for details
See: here for details
See: here for details
See: here for details
See: here for details
See: here for details
See: here for details
See: here for details
See: here for details
See: here for details
See: here for details
See: here for details
See: here for details
See: here for details
This document is available under the GNU GENERAL PUBLIC LICENSE Version 2.