スライド 1

理学部 情報科学科
06_19780 早船 総一郎
指導教員 千葉 滋 教授
1
動いているプログラムを修正する
 実行を止めることなく機能を追加するのは大変
 いろいろ制限がある
 静的と同じ自由度
にしたい
©森田 悟史
2
既存の around advice
 様々システムが存在
 未実装や不可能な部分も存在
 特に around advice
around は不完全
around advice
利用可能
execution remote
pointcut pointcut
+ HW
+ HW
分散DAOP
remote
pointcut
Hot weaving
(HW)
before after
advice
PROSE
×
○
○
?
?
×
JAC
×
○
○
○
○
×
DJAsCo
○
○
○
○
○
△
CaesarJ
×
×
○
○
×
×
ReflexD
○
○
○
○
?
?
DandyJ
○
○
○
○
△
△
3
なぜ実装が難しいか
 特に around advice
 実装には新規メソッドの追加が必要
 標準 JVM の Hotswap は追加をサポートしない

Inlining などの最適化技法を難しくする
class {
void run(){
…
}
…
置き換え
code
追加
method
追加
}
field
4
提案: around advice に対応した
分散 DAOP の実装方法
 標準 JVM の利用
 around advice
 execution pointcut, proceed, remote pointcut に対応
 実装技術
 ロード時の method wrap

proceed + execution pointcut を実現
 遠隔 proceed 呼び出しの拡張



実行コンテキストを含むように改造
proceed + remote pointcut を実現
二重の around advice を実現 (今回の発表では省略)
5
around advice とはadvice
 メソッドの上書き
 proceed: 元のメソッド
を呼び出す
 メソッドボディの退避
が必要

これができないのが
問題だった
Aspect
around :
execution (foo()) {
// 追加機能
proceed(); // 元の処理
}
pointcut
Target App
void foo () {
// 処理
}
織り込み前
織り込み後
Aspect
around :
execution (foo()) {
// 追加機能
proceed(); // 元の処理
}
退避
Target App
void foo () {
hook
}
void foo’ () {
// 処理
}
6
提案手法1:
ロード時の method wrap
 あらかじめ退避しておく
 ロード時はメソッド追加可能
 上書きしても O.K.
Aspect
around : exec(foo()) {
// 追加機能
proceed(); // 元の処理
}
ロード前
ロード後
Aspect
around : exec(foo()) {
// 追加機能
proceed(); // 元の処理
}
Target App
void foo () {
// 処理
}
around : exec(foo()) {
// 追加機能
proceed(); // 元の処理
}
Target App
void foo () {
foo’();
}
void foo’ () {
// 処理
}
織り込み前
織り込み後
本システム
Target App
void foo () {
foo’();
}
void foo’ () {
// 処理
}
ロード後
Aspect
退避
Aspect
around : exec(foo()) {
// 追加機能
proceed(); // 元の処理
}
Target App
void foo () {
hook
}
void foo’ () {
// 処理
}
7
提案手法2:
遠隔 proceed 呼び出しの拡張
 実行コンテキストを含むように拡張
 分散では元の処理を直接呼び出せない
 本システムがディスパッチを行う
Target App
分散
Aspect
context
around : exec (foo()) {
// 追加機能
proceed(); // 元の処理
}
args
args
直接は呼び出せない
context
args
void foo () {
hook
}
void foo’() {
// 処理
}
本システム
context
実行コンテキストを
利用して dispatch
8
実装・実験

 実装
 行数:約2600 行
 Instrument API

バイトコードの置き換え
 Javassist
 バイトコードの変換
unweave
weave
300
250
時間 (ミリ秒)
 実験
 remote pointcut で
メッセージ通信 App
に機能追加
 改良の余地あり
実験環境
 InTrigger の chiba, mirai, hongo を利用
 OS:Debian
 chiba, hongo
 CPU: Core2Duo 2.13GHz
 メモリ: 4GB
 mirai
 CPU: XeonE5410 2.33GHz
 メモリ: 16GB
200
150
100
50
0
1
101
201
301
回数
401
9
関連研究
 DJcutter [Nishizawaら '04]
 分散対応のポイントカット (Remote Pointcut)
 動的な織り込みができない
 HotWave [Villazonら '09]
 アドバイス間のデータ伝達 (inter-advice communication)
 アラウンドアドバイスをエミュレート
 完璧なエミュレートでない
 Envelope-Based Weaving [Bockischら '06]
 コンパイル時のラップを行う
 VMレベルでの織り込み
 分散ではない
10
まとめと今後の課題
 まとめ
 分散動的アスペクト指向言語の around advice の
実装方法を提案


ロード時の method wrap
遠隔 proceed 呼び出しの拡張
 今後の課題
 method wrap の方法などを変え、オーバーヘッドの軽減
 他の方法での around advice の実装を提案


動的プロキシを利用
呼び出し側の変換
 各実装での比較実験
11
リモート呼び出しが実行コンテ
キストを含むように改造
 proceed がリモート呼び出しになる
 メソッドディスパッチを行う
 proceed に情報を付けて呼び出すことで行う
App Host
Aspect Host
Aspect
around():
execution(foo())
&& host(App){
// advice
proceed();
// advice
}
本システム
proceed
呼び出し
登録
index
App
foo(){
Hook
アドバイスの
foo$w();
呼び出し
}
元の処理を
呼び出し
foo$w(){
// code
}
12
同じジョインポイントに対して織
り込みが行われる場合
 proceed がアドバイスを呼び出す
 proceed の情報にアドバイスを呼び出すことを加える
App Host
Aspect Host
本システム
Aspect A
App
proceed();
Hook
Aspect B
proceed();
advice を
呼び出し
元の処理
元の処理を
呼び出し
13
13
14
実験の詳細
mirai
 mirai と chiba で通信
 hongo から mirai のジョインポイントを
指定する
 mirai -> hongo -> mirai -> chiba の
順
App
chiba
hongo
織り込み命令
Aspect
App
15
本システムのオーバーヘッド
 本システムを用いた場合のオーバーヘッド
 約3 %のエージェントによるオーバーヘッド
 これに加えて、ロード時に行うオーバーヘッド
50
50
エージェントなし
45
45
40
40
エージェントあり
3%
35
35
30
30
25
1
101
201
301
401
25
1
101
201
301
401
16
300
時間 (ミリ秒)
250
200
150
100
50
50
45
0
1
101
201
301
401
40
時間 (ミリ秒)
回数
時間 (ミリ秒)
70
35
30
25
20
15
60
10
50
5
0
40
1
101
201
301
401
回数
30
20
10
0
1
101
201
301
401
回数
17