アスペクト指向プログラミングの 動的プログラムスライスへの応用

Slides:



Advertisements
Similar presentations
Web アプリをユーザー毎に カスタマイズ可能にする AOP フレームワーク
Advertisements

シーケンス図の生成のための実行履歴圧縮手法
背景 ソフトウェアの大規模化・複雑化 生産性と品質の向上 ↓ オブジェクト指向分析設計の適用 開発ツールの投入.
XHTML構文検証手法における スクリプト要素の静的解析アルゴリズム
プログラムの動作を理解するための技術として
F11: Analysis III (このセッションは論文2本です)
リファクタリングのための 変更波及解析を利用した テスト支援ツールの提案
動的スライスを用いたバグ修正前後の実行系列の差分検出手法の提案
プログラム静的解析手法の効率化と 解析フレームワークの構築に関する研究
アスペクト指向プログラムに対する プログラムスライシング
型付きアセンブリ言語を用いた安全なカーネル拡張
静的情報と動的情報を用いた プログラムスライス計算法
細かい粒度でコードの再利用を可能とするメソッド内メソッドのJava言語への導入
プログラム依存グラフを利用した 情報漏洩解析手法の提案と実現
コードクローンに含まれるメソッド呼び出しの 変更度合の分析
コードクローンに含まれるメソッド呼び出しの 変更度合の調査
プログラムスライスを用いた アスペクト指向プログラムのデバッグ支援環境
細かい粒度で コードの再利用を可能とする メソッド内メソッドと その効率の良い実装方法の提案
動的スライスを用いた バグ修正前後の実行系列の比較
暗黙的に型付けされる構造体の Java言語への導入
動的依存グラフの3-gramを用いた 実行トレースの比較手法
オブジェクト指向プログラムにおける エイリアス解析手法の提案と実現
オブジェクト指向プログラムにおける エイリアス解析について
シーケンス図を用いて実行履歴を可視化するデバッグ環境の試作
動的スライスを用いたバグ修正前後の実行系列の差分検出手法
利用関係に基づく類似度を用いたJavaコンポーネント分類ツールの作成
プログラムスライスを用いた アスペクト指向プログラムのデバッグ支援環境
Javaプログラムの変更を支援する 影響波及解析システム
コードクローン検出ツールを用いた ソースコード分析システムの試作と プログラミング演習への適用
動的データ依存関係解析を用いた Javaプログラムスライス手法
オープンソース開発支援のための ソースコード及びメールの履歴対応表示システム
ソースコードの特徴量を用いた機械学習による メソッド抽出リファクタリング推薦手法
コードクローンの動作を比較するためのコードクローン周辺コードの解析
Javaバイトコードの 動的依存解析情報を用いた スライシングシステムの実現
コードクローン検出に基づくデザイン パターン適用支援手法の提案と実現
アスペクト指向言語のための 独立性の高いパッケージシステム
プログラム理解におけるThin sliceの 統計的調査による有用性評価
バイトコードを単位とするJavaスライスシステムの試作
ソフトウェア保守のための コードクローン情報検索ツール
Java における 先進的リフレクション技術
コードクローンの理解支援を目的としたコードクローン周辺コードの解析
コードクローン分類の詳細化に基づく 集約パターンの提案と評価
Javaバーチャルマシンを利用した 動的依存関係解析手法の提案
プログラムの織り込み関係を可視化するアウトラインビューの提案と実装
コーディングパターンの あいまい検索の提案と実装
JAVAバイトコードにおける データ依存解析手法の提案と実装
JavaScriptを含んだHTML文書に対する データフロー解析を用いた構文検証手法の提案
オブジェクトの協調動作を用いた オブジェクト指向プログラム実行履歴分割手法
静的情報と動的情報を用いた Javaプログラムスライス計算法
Josh : バイトコードレベルでのJava用 Aspect Weaver
プログラムスライスを用いた凝集度メトリクスに基づく 類似メソッド集約候補の順位付け手法
依存関係の局所性を利用した プログラム依存グラフの 効率的な構築法
保守請負時を対象とした 労力見積のためのメトリクスの提案
アスペクト指向言語のための視点に応じた編集を可能にするツール
プログラムの差分記述を 容易に行うための レイヤー機構付きIDEの提案
クローン検出ツールを用いた ソフトウェアシステムの類似度調査
メソッドの同時更新履歴を用いたクラスの機能別分類法
開発作業の形式化に基づく プロセス評価 松下誠 大阪大学.
欠陥検出を目的とした類似コード検索法 吉田則裕,石尾隆,松下誠,井上克郎 大阪大学 大学院情報科学研究科
エイリアス関係を考慮した Javaプログラム用静的スライシングツール
プログラムの一時停止時に 将来の実行情報を提供するデバッガ
動的スライスを用いたバグ修正前後の実行系列の差分検出手法の提案
動的スライスを用いたバグ修正前後の実行系列の差分検出手法の提案
コードクローン解析に基づく デザインパターン適用候補の検出手法
回帰テストにおける実行系列の差分の効率的な検出手法
オブジェクト指向言語における セキュリティ解析アルゴリズムの提案と実現
識別子の読解を目的とした名詞辞書の作成方法の一試案
オブジェクト指向メトリクスを用いた 開発支援に関する研究 --- VC++とMFCを用いた開発を対象として ---
Josh : バイトコードレベルでのJava用 Aspect Weaver
Presentation transcript:

アスペクト指向プログラミングの 動的プログラムスライスへの応用 石尾 隆, 楠本 真二, 井上 克郎 大阪大学大学院基礎工学研究科

研究の背景 ソフトウェアの大規模化 フォールト特定、修正のコスト増大 実際に動くコードは、全体のごく一部 テストケースからのフォールト特定 扱うコード量が多いと効率が悪くなる 実際に動くコードは、全体のごく一部 まず研究の背景について説明します。近年、ソフトウェアの大規模化に伴い、コード中からフォールトを特定し、修正するという作業のコストが大きくなってきました。基本的にはテストケースから、そのフォールトを特定するという作業が行われていますが、複雑な挙動をするコードも多いため、フォールトを特定することが難しくなってきています。 しかし、あるテストケースに対して実際に動いたコードというのは、全体のうち、ごく一部に限られていることから、無関係なコードを自動的に除外して、フォールト位置の特定を迅速に行うことが求められるようになってきました。 関係のないコードを自動的に除外して 迅速なフォールト特定を行いたい

プログラムスライス プログラム中のある文sのある変数v (スライス基点)の値に影響を与えうる文の集合 デバッグ対象が限定され、フォールト位置特定を効率よく行うことができる 1: a = 5; 2: b = a + a; 3: if (b > 0) { 4: c = a; 5: } 6: d = b; 1: a = 5; 2: b = a + a; 3: if (b > 0) { 4: c = a; 5: } 6: d = b; スライス基点(6, b)に対するスライス そのための技術のひとつとして、プログラムスライスが提案されています。これは、プログラム中のある文 sのある変数 v 、これをスライス基点と呼びますが、これに影響を与える文の集合を抽出するというものです。例で示すと、このようなプログラムに対して、スライス基点として 6行目の変数 b を選ぶと、このようなコードを得ることができます。 このようにして扱うコード量を減らすことで、フォールト位置特定を効率よく行うことができます。 以後、プログラムスライスを単にスライスと呼ぶことにします。

DC(Dependence Cache)スライス 12: b = a; a データ依存関係 1.依存関係解析 動的データ依存関係 静的制御依存関係 2.プログラム依存グラフ(PDG)構築 節点:各プログラム文 有向辺:文間の依存関係 3.グラフ探索 スライス基点に対応する節点から 有向辺を逆向きに探索 20: if (a < 1) { 21: b = a; 22: } 制御依存関係 プログラム依存グラフ (PDG) スライス計算には方法がいくつかありますが、その中で、コストと得られるスライスのバランスが取れているDC(Dependence Cache)スライスについて説明します。 スライス計算は、プログラム中の依存関係を解析し、プログラム文を節点、依存関係を辺とするプログラム依存グラフを作成することで、グラフ探索問題に置き換えられます。 依存関係の解析ですが、DCスライスではデータ依存関係を動的に、制御依存関係を静的に行います。データ依存関係というのは変数の値の定義と参照に対応する関係のことです。例で示すとこのように、10行目で定義した変数から12行目での参照へ、依存関係があるということになります。プログラムを実行して、このデータ依存関係を収集していきます。制御依存関係は、いわゆる条件文などの実行制御文において、条件節がそのブロックの実行を制御することから、この例のように条件節から実行文へ、依存関係が生じるものとします。こちらは、ソースコードを静的に解析することによって得ることができます。 このような解析結果からプログラム依存グラフを構築し、スライス基点に対応する頂点を選び、そこからグラフを逆向きに探索することで、対応するスライスを得ることができます。 † Y.Ashida, F.Ohata and K.Inoue: “Slicing Methods Using Static and Dynamic Information”, Proceedings of the 6th Asia Pacific Software Engineering Conference , pp.344-350, Takamatsu, Japan, December (1999).

既存の手法 Java Virtual Machine (JVM)の改造† → ソースコード側に依存関係解析処理を追加する 細粒度でのスライスが可能 特定のJVMの実装、バージョンに依存する プログラムがそのバージョンのJVMで動くかどうかの検証は困難 コンパイラによる最適化を抑止する必要あり → ソースコード側に依存関係解析処理を追加する DCスライスの計算では動的なデータ依存関係の解析が重要となります。 現在、オブジェクト指向言語として一般に用いられている Java を対象とした場合、実行環境である Java Virtual Machine, JVM にその機能を付加する方法で実現されています。 JVM の改造という方法では、バイトコードレベルでのデータ依存関係を取得することができるため、細粒度でのスライスが可能になり、スレッド管理をはじめとする多くの実行環境情報を活用することができます。そのかわり、元になった JVM の実装に依存してしまうため、本体のバージョンアップへの追随などの作業が必要になります。また、プログラムがそのバージョンの JVM で動作するかどうかを確認するのは一般に困難ですし、加えて、コンパイラによるバイトコード最適化によって正しい結果が得られなくなることがあるため、最適化を抑制する必要があり、その結果実行時にパフォーマンス上のオーバーヘッドを生じることになります。 JVMのバージョン依存性を受けないためには、JVMの改造ではなくソースコード側にデータ依存関係解析処理を追加したいということになりますが、この場合のようなシステムのクラス群全体に埋め込むようなコードの扱いを容易にするためのパラダイムとして、アスペクト指向プログラミングというものを紹介します。 † 誉田謙二, 大畑文明, 井上克郎: Javaバーチャルマシンを利用した動的依存関係解析手法の提案, SIGSS-2002 Jan

アスペクト指向プログラミング 複数のクラスを横断する要素をモジュール「アスペクト」として記述するプログラミング手法 ある特定の目的に関する処理が、複数のクラスに分散することを避ける ソースコード上では、ひとつの単位にまとめて記述 コンパイル時、実行時にクラスに結合する AspectJ: Java 用アスペクト記述・処理系 http://aspectj.org/ アスペクト指向プログラミングとは何か、ということについて簡単に説明します。オブジェクト指向プログラミングではオブジェクトというカプセル化単位を用いていましたが、複数のクラスを横断するような、カプセル化できない要素を新しいモジュール単位、アスペクトとして記述しようというものです。これは、ある特定の処理に関する記述が複数のクラスに分散することを避けることを目的としています。ソースコード上ではまとまった単位として記述しておき、処理系にもよりますがコンパイル時あるいは実行時に、通常のプログラムに変換してやろうというものです。Java 用の処理系としては、AspectJ などがあります。

Session Managing Aspect アスペクトの例 HTTP Request HTTP Session HTTP Response クラスによる実現 Session Managing Code Session Managing Code Session Managing Code アスペクトをクラスに結合する (Aspect Weaving) AspectJ HTTP Request HTTP Session HTTP Response クラスによる実現と、アスペクトによる実現との比較を、図で説明します。これは HTTP でのセッション管理の例で、上側がクラスのみによる実現、下側がアスペクトを利用した実現です。 ここではセッション管理のコードが Session, Request, Response の三つのクラスに分散しており、相互に依存した構造になっています。これらのクラスに対するテスト、変更、再利用は、このクラス群をまとめて扱わなければなりません。 その分散するはずのコードをアスペクトとして、クラス本体から切り離し、クラス間の依存性を簡略化することができ、また1モジュール内に簡潔に処理を記述できるようになります。実際にコードを実行するときは、これをAspectJのような処理系でクラスだけの実現に変換してやることで、標準の JVM でプログラムを実行することができます。 データ依存関係解析の処理も、このようなコードと同様に各クラスに分散する処理ですので、アスペクトを用いることで簡潔なモジュールとして記述できる、と考えられます。 アスペクトによる実現 Session Managing Aspect

アスペクトの記述 アスペクト = 結合の基準 + 結合するコード 動的データ依存関係解析アスペクト 主要な結合の基準 結合するコードの特徴 メソッド呼び出し、メソッド実行 フィールド代入、参照 メソッド、フィールドの属するクラスに関する条件 結合するコードの特徴 通常の Java で記述される 実際の結合位置に関する情報へアクセスできる 動的データ依存関係解析アスペクト フィールドへの代入: 代入のソースコード内での位置を記録 フィールドの参照: そのフィールドへの最後の代入位置を取得し、動的依存関係を記録 アスペクトは、基本的には処理の中心となるプログラムコードと、それをクラスのどこに結合するかという結合の基準のセットによって記述されます。AspectJ では、結合の基準として、メソッド呼び出しの直前、直後、メソッド本体の先頭と最後、フィールドの代入、参照、そしてメソッドやフィールドの属するクラスに関する条件などが利用できます。 実際にそこに結合されるコードは、通常のJavaで記述されますが、AspectJ では、プログラム内からこの結合位置に関する情報へアクセスできます。 そこで、動的データ依存関係解析のアスペクトは、その要点だけ説明すると、フィールドへの代入というところに、そのソースコード位置を記録する処理を結合し、フィールドの参照というところに、そのフィールドへの最後の代入位置を取得し、動的依存関係を記録するという処理を結合する、ということで実現できます。

アスペクトによる実現の特徴 利点 AspectJ における制限 高い抽象度で、結合ルールを明快に記述できる データ依存関係解析処理をカプセル化できる 特定のJavaのバージョンに依存しない コンパイラによる最適化の影響を受けない AspectJ における制限 ローカル変数に対してはアスペクトを結合できない →静的解析で補う必要がある アスペクトによる実現の利点をまとめます。 アスペクトでは高い抽象度でコードの結合ルールを記述でき、また、解析処理をカプセル化できるためコードの保守が容易になります。また、 JVMの特定のバージョンに依存せず、コンパイラによる最適化の影響を受けない、ということにもなります。 今回はツールとして AspectJ を用いましたが、その実装上の制限として、ローカル変数にはアスペクトを結合することができない、というものがありましたので、これは静的な解析で補うということにしました。

アスペクトによる依存関係解析 スライスツールの実装(Java) AspectJ によるデータ依存関係解析 約 16,000 行(コメント含む) AspectJ によるデータ依存関係解析 依存関係解析アスペクト+クラス: 300行 JVM改造アプローチでは、16,000 行程度の追加コードが必要(全体で約 580,000 行) 実際に、その差がどのようなものとなるのかを確認するために、スライスツールを Java で実装しました。コードサイズはコメントを含めて約16000行、先ほど述べたようなデータ依存関係解析モジュールは、約 300 行となりました。JVM改造のアプローチではJavaのコンパイラとVMで50万行をこえるコードに16000行ほどのコードを追加するのに比べて、はるかに小さなコード量で済ませることができました。

ツールの動作 スライス 計算 スライス結果 依存関係解析 アスペクト スライス対象 ソースコード AspectJ アスペクト結合済み クラスファイル 通常の JVM 依存関係情報 通常の実行結果 ツールの動作について説明します。 最初にスライスをとりたいプログラムのソースコードと、依存関係解析のアスペクトを一緒に AspectJ でコンパイルし、アスペクトを結合したクラスファイルを生成します。この結合結果は通常の Java のプログラムとなっているので、普通の JVM 上で実行することができ、それによって通常の実行結果とあわせて、依存関係情報をファイルに出力します。この情報から得られた動的依存関係と、ソースコードを解析して得られた静的依存関係から、最終的にスライスを計算・出力します。

評価: スライスのサイズ JVM 改造による実現との比較 適用対象 P1: 簡易データベースプログラム (4クラス、262行) ローカル変数の扱いの差 による影響はほとんど見られない 短いメソッドが多いため 単位: 行 このツールを用いて、JVM改造によるアプローチとの比較実験を行いました。 テストケースとして、簡易データベースプログラム、ソーティングプログラム、スライス計算プログラムを与え、スライスを計算してみました。得られた結果を右下の表に示してあります。これは基本的に行数による比較を行っていますが、アスペクトと JVM ではほとんど差はありませんでした。アスペクト側のほうが、ローカル変数に関して静的な解析で補うという都合上、スライスに余計な文も加わる、つまりスライスサイズが大きくなる、という予想がありましたが、実際にはアスペクトのほうが小さくなる、という結果になりました。実際に得られたスライスを確認したところ、ここで生まれた差の原因ですが、行の数え方、たとえば2行に分かれた式をアスペクトは1行として数えており、JVMでは2行として数える、といった差が、ローカル変数の扱いの差よりも大きく効いてきたことにありました。プログラムには短いメソッドが多く、ほとんどローカル変数が使われていなかったこともその原因と考えられます。 アスペクト JVM P1 33 30 P2 25 28 P3 226 240

評価: 実行コスト 同じ入力を与えて実行時間を比較 適用対象はスライスサイズの場合と同様 コンパイラの最適化による影響 JVMは、すべてのクラスに対し、解析コストを支払う ライブラリが多いプログラムほど、JVM のアプローチは不利 通常実行 アスペクト JVM P1 240 ms 343ms(x1.4) 1829 ms(x7.6) P2 242 ms 416ms(x1.7) 2846 ms(x11.8) P3 0.7 sec 9.0 sec(x12.9) 79.3 sec(x113.3) 次に、実行コストに関して比較を行いました。 先ほどと同様、三つのプログラムに対して、アスペクトとJVMで同じ入力を与えて実行し、その実行時間を計測しました。結果は表の通りです。 表はプログラムを通常実行した場合と、アスペクトを結合して実行した場合、改造JVMで実行した場合の3通りでの実行時間です。括弧内の値は、それが通常実行に対して何倍になるか、という値です。 一般に、アスペクトのほうが JVM 側に比べて高いパフォーマンスを発揮しました。この原因としては、まずコンパイラの最適化の影響が考えられます。また、JVMのアプローチが、ライブラリなどを含むすべての実行に対して、データ依存関係の解決のオーバーヘッドを支払っていることから、規模が大きくなり、ライブラリを多く使うプログラムほど、JVM側のアプローチは実行コスト上不利になったと考えられます。

まとめと今後の課題 アスペクトを用いた動的データ依存解析 課題 アスペクト指向プログラミングによって、動的情報取得モジュールの取り扱いが容易になる JVM 改造アプローチに比べ、わずかなスライスサイズの変化で、高速化できる 課題 大規模プログラムへの適用 手法のスケーラビリティ 最後にまとめと今後の課題について述べます。 アスペクトを用いた動的データ依存関係解析では、アスペクト指向プログラミングによってデータ依存解析モジュールの取り扱いが容易になり、また、JVMアプローチでは犠牲になったバージョン独立性や移植性の確保を行うことができました。 また、JVM改造アプローチに比べ、わずかなスライスサイズの変化で、大幅なパフォーマンス改善を実現することができました。 今後の課題ですが、今回の実験では、まだ小規模から中規模程度のプログラムしか対象としていないため、大規模プログラムに対してこれらの手法を適用し、スケーラビリティについて確認する、ということが挙げられます。 以上で、発表を終わります。