1 / 32

Thin Slice のサイズに関する統計的評価

Thin Slice のサイズに関する統計的評価. ○ 秦野 智臣,鹿島 悠,石尾 隆,井上 克郎 大阪大学大学院情報科学研究科. 概要. Thin Slicing [1] が抽 出するプログラムスライスの大きさを 計測 し,統計的評価を行う Thin Slicing :プログラムスライシングの一種 Thin Slice : Thin Slicing が抽 出するスライス 7 つ の Java プログラムを対象とした実験で, Thin Slice のサイズが十分小さくなることを確認した.

ruana
Download Presentation

Thin Slice のサイズに関する統計的評価

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Thin Slice のサイズに関する統計的評価 ○ 秦野 智臣,鹿島 悠,石尾 隆,井上 克郎 大阪大学大学院情報科学研究科

  2. 概要 • Thin Slicing [1] が抽出するプログラムスライスの大きさを計測し,統計的評価を行う • Thin Slicing:プログラムスライシングの一種 • Thin Slice:Thin Slicing が抽出するスライス • 7つのJavaプログラムを対象とした実験で,Thin Sliceのサイズが十分小さくなることを確認した [1] Sridharan, M., Fink, S. J. and Bodik, R.: Thin slicing, Proc. of PLDI2007, pp. 112–122 (2007).

  3. 発表内容 • 背景 2. プログラムスライシング 3. Thin Slicing 4. 実験 5. Thin Slicing の実装 6. 計測指標 7. 計測結果

  4. 背景 • 開発者はプログラムの保守作業に多くの時間を費やしている • プログラムの保守作業において,データ依存関係を探索する必要があり,この作業に多くの時間がかかる [2] [2] LaToza, T. D. and Myers, B. A.: Developers ask reachability questions, Proc. of ICSE, pp. 185–194 (2010).

  5. プログラムスライシング • プログラム内のある文の変数を基準として,その変数の値に影響を与える可能性のあるすべての文を抽出する ソースコード 1 void main() { 2 int sum = 0; 3 inti= 1; 4 while (i <= 10) { 5 sum = sum + i; 6 i = i + 1; 7 } 8 print(i); 9 print(sum); 10 } スライス 1 void main() { 3 inti= 1; 4 while (i <= 10) { 6i = i + 1; 7 } 8 print(i); 10 } プログラム スライシング スライシング基準

  6. スライスのサイズ • スライスサイズの平均値は,プログラム全体の約30%である [3] • 100万行のプログラムの場合,平均で約30万行のスライスが抽出される • 大規模プログラムではスライスサイズが大きくなってしまう 開発者がスライスを閲覧する用途において プログラムスライシングの利用は困難 [3] Binkley, D., Gold, N. and Harman, M.: An empirical study of static program slice size, ACM TOSEM, Vol. 16, No. 2, pp. 1–32 (2007).

  7. Thin Slicing[1] • 制御フローを無視して,限定したデータフローのみに着目する • スライスサイズが小さくなる • データの生成元が特定できる • プログラムの保守にかかる時間が減少する • プログラム理解の時間が減少した22個の例 [1]

  8. Thin Slicing の定義 • 基準となる文がデータ依存する文を抽出する • 手続き内のデータ依存関係 • ポインタ変数のデータ依存関係は無視する • 文 y = p.fにおいて,変数 p のデータ依存関係は無視 • 手続き間のデータ依存関係 • 仮パラメータが実パラメータにデータ依存する • 呼び出し元が呼び出し先の返り値にデータ依存する • ヒープ領域のデータ依存関係 • 同一のフィールドまたは配列の内容を代入,参照する可能性のある文の組について,所属する手続きに関係なく,参照する文が代入する文にデータ依存する

  9. Thin Slicing の例 ソースコード 1 void main() { 2 A x, z, w; 3 inta, b; 4 a = 1; 5 x = new A(); 6 z = x; 7 b = inc(a); 8 w = x; 9 w.f = b; 10 if (w == z) { 11 intv = z.f; 12 } 13 } 14 intinc(int x) { 15 return x + 1; 16 } 17 class A { int f; } ソースコード 1 void main() { 2 A x, z, w; 3 inta, b; 4 a = 1; 5 x = new A(); 6 z = x; 7 b = inc(a); 8 w = x; 9 w.f = b; 10 if (w == z) { 11 int v = z.f; 12 } 13 } 14 intinc(int x) { 15 return x + 1; 16 } 17 class A { int f; } ソースコード 1 void main() { 2 A x, z, w; 3 inta, b; 4 a = 1; 5 x = new A(); 6 z = x; 7 b = inc(a); 8 w = x; 9 w.f = b; 10 if (w == z) { 11 intv = z.f; 12 } 13 } 14 intinc(int x) { 15 return x + 1; 16 } 17 class A { int f; } Thin Slice 4 a = 1; 7 b = inc(a); 9 w.f = b; 11 int v = z.f; 14 intinc(int x) { 15 return x + 1; 16 } 変数vがデータ依存する 文が抽出されている Thin Slicing 変数zがデータ依存する 文は抽出されていない スライシング基準

  10. 調査すべきこと • Thin Slicing が一般的に有効かどうかは明らかではない • 平均的に Thin Slice のサイズは小さくなるのか • Thin Slicing が有効な場面は多いのか

  11. Thin Slicing が有効であると考えられる例 1 package sample; 7 id = 1; 9 id = 0; 10 a.addData(id); 16 void addData(int id) { 17 b.addData(id); } 20 class B { 21 intmax = 4; 22 X x = new X(); 23 void addData(int id) { 24 if (id >= 0 && id <= max) 25 x.addData(id); 26 } 27 } 28 class X { 29 int[] idList = new int[16]; 30 intcount = 0; 31 void addData(int id) { 32 System.out.println(id); 33 idList[count] = id; 34 count = count + 1; 35 } 36 intgetData(int index) { 37 return idList[index]; 38 } 39 } 1 package sample; 2 public class Main { public static void main(String[] args) { 4 A a = new A(); 5 intid; 6 if (args.length > 0) 7 id = 1; 8 else 9 id = 0; 10 a.addData(id); 11 System.out.println(a); 12 } 13 } 14 class A { 15 B b = new B(); 16 void addData(int id) { 17 b.addData(id); 18 } 19 } 23 void addData(int id) { 25 x.addData(id); 26 } 31 void addData(int id) { 32 System.out.println(id); 35 } Thin Slice が複数のメソッド にまたがっている データの生成元 開発者がメソッドをたどって データ依存関係を探索する 作業をThin Slicingによって 置き換える

  12. Thin Slicing が有効でないと考えられる例 20 class B { 21 intmax = 4; 22 X x = new X(); 23 void addData(int id) { 24 if (id >= 0 && id <= max) 25 x.addData(id); 26 } 27 } 28 class X { 29 int[] idList = new int[16]; 30 intcount = 0; 31 void addData(int id) { 32 System.out.println(id); 33 idList[count] = id; 34 count = count + 1; 35 } 36 intgetData(int index) { 37 return idList[index]; 38 } 39 } 1 package sample; 2 public class Main { public static void main(String[] args) { 4 A a = new A(); 5 intid; 6 if (args.length > 0) 7 id = 1; 8 else 9 id = 0; 10 a.addData(id); 11 System.out.println(a); 12 } 13 } 14 class A { 15 B b = new B(); 16 void addData(int id) { 17 b.addData(id); 18 } 19 } Thin Slice が1つのメソッドで 閉じている ソースコードを見るだけで すぐにデータの生成元が 特定できる

  13. Thin Slicing が有効でないと考えられる例 20 class B { 21 intmax = 4; 22 X x = new X(); 23 void addData(int id) { 24 if (id >= 0 && id <= max) 25 x.addData(id); 26 } 27 } 28 class X { 29 int[] idList = new int[16]; 30 intcount = 0; 31 void addData(int id) { 32 System.out.println(id); 33 idList[count] = id; 34 count = count + 1; 35 } 36 intgetData(int index) { 37 return idList[index]; 38 } 39 } 1 package sample; 2 public class Main { public static void main(String[] args) { 4 A a = new A(); 5 intid; 6 if (args.length > 0) 7 id = 1; 8 else 9 id = 0; 10 a.addData(id); 11 System.out.println(a); 12 } 13 } 14 class A { 15 B b = new B(); 16 void addData(int id) { 17 b.addData(id); 18 } 19 } Thin Slice が1つのメソッドで 閉じている どちらのケースが多いかはわかっていない ソースコードを見るだけで すぐにデータの生成元が 特定できる

  14. リサーチクエスチョン • Thin Slicing が一般的に有効であるか • RQ1:Thin Slice のサイズは,平均的に十分小さいものであるか • スライスサイズの平均値を計測して,その有効性を評価する研究が行われている [3,4] • RQ2:データ依存関係の調査において有効であると考えられるThin Sliceはどの程度存在するか • プログラムの保守作業において,データ依存関係を探索する必要があることが知られている [2] [4] Jasz, J., Arpad Beszedes, Gyimothy, T. and Rajlich, V.: Static Execute After/Before as a Replacement of Traditional Software Dependencies, Proc. of ICSM,pp. 137–146 (2008).

  15. Thin Slicing の実装 • Java のバイトコードを解析する • グラフを作成し,探索する • 頂点:バイトコードの1命令 • 辺:命令間のデータ依存関係

  16. Java のバイトコード ソースコード 1 package example; 2 public class Sample { 3 public static void main(String[] args) { 4 A x, z, w; 5 inta, b; 6 a = 1; 7 x = new A(); 8 z = x; 9 b = inc(a); 10 w = x; 11 w.f= b; 12 if (w == z) { 13 intv = z.f; 14 System.out.println(v); 15 } 16 } 17 static intinc(int x) { 18 return x + 1; 19 } 20 } 21 class A { int f; } 16: ALOAD 3 (w) 17: ALOAD 2 (z) 18: IF_ACMPNE 19: ALOAD 2 (z) 20: GETFIELD example/A#f: int 21: ISTORE 6 (v) 22: GETSTATIC java/lang/System#out: java/io/PrintStream 23: ILOAD 6 (v) 24: INVOKEVIRTUAL java/io/PrintStream#println(I)V 25: RETURN example/Sample#inc 0: ILOAD 0 (x) 1: ICONST_1 2: IADD 3: IRETURN example/Sample#main 0: ICONST_1 1: ISTORE 4 (a) 2: NEW 3: DUP 4: INVOKESPECIAL example/A#<init>()V 5: ASTORE 1 (x) 6: ALOAD 1 (x) 7: ASTORE 2 (z) 8: ILOAD 4 (a) 9: INVOKESTATIC example/Sample#inc(I)I 10: ISTORE 5 (b) 11: ALOAD 1 (x) 12: ASTORE 3 (w) 13: ALOAD 3 (w) 14: ILOAD 5 (b) 15: PUTFIELD example/A#f: int 定数の生成 書き込み 引数xの読み込み 定数の生成 加算命令 値を返す

  17. グラフの作成 16: ALOAD 3 (w) 17: ALOAD 2 (z) 18: IF_ACMPNE 19: ALOAD 2 (z) 20: GETFIELD example/A#f: int 21: ISTORE 6 (v) 22: GETSTATIC java/lang/System#out: java/io/PrintStream 23: ILOAD 6 (v) 24: INVOKEVIRTUAL java/io/PrintStream#println(I)V 25: RETURN example/Sample#inc 0: ILOAD 0 (x) 1: ICONST_1 2: IADD 3: IRETURN example/Sample#main 0: ICONST_1 1: ISTORE 4 (a) 2: NEW 3: DUP 4: INVOKESPECIAL example/A#<init>()V 5: ASTORE 1 (x) 6: ALOAD 1 (x) 7: ASTORE 2 (z) 8: ILOAD 4 (a) 9: INVOKESTATIC example/Sample#inc(I)I 10: ISTORE 5 (b) 11: ALOAD 1 (x) 12: ASTORE 3 (w) 13: ALOAD 3 (w) 14: ILOAD 5 (b) 15: PUTFIELD example/A#f: int

  18. main 0: ICONST_1 15: PUTFIELD 20: GETFIELD 2: NEW 11: ALOAD 1 21: ISTORE 6 1: ISTORE 4 3: DUP 14: ILOAD 5 12: ASTORE 3 23: ILOAD 6 8: ILOAD 4 10: ISTORE 5 4: INVOKESPECIAL 13: ALOAD 3 呼び出し元 実パラメータ actual 24 actual 9 result 9 5: ASTORE 1 16: ALOAD 3 9: INVOKESTATIC 17: ALOAD 2 6: ALOAD 1 24: INVOKEVIRTUAL 19: ALOAD 2 22: GETSTATIC 7: ASTORE 2 inc formal return 18: IF_ACMPNE 仮パラメータ 返り値 0: ILOAD 0 3: IRETURN 手続き内のデータ依存辺 手続き間のデータ依存辺 1: ICONST_1 2: IADD ヒープ領域のデータ依存辺 25: RETURN

  19. main 0: ICONST_1 15: PUTFIELD 20: GETFIELD 0: ICONST_1 15: PUTFIELD 20: GETFIELD 2: NEW 11: ALOAD 1 21: ISTORE 6 21: ISTORE 6 1: ISTORE 4 14: ILOAD 5 1: ISTORE 4 3: DUP 14: ILOAD 5 12: ASTORE 3 23: ILOAD 6 23: ILOAD 6 8: ILOAD 4 10: ISTORE 5 8: ILOAD 4 10: ISTORE 5 4: INVOKESPECIAL 13: ALOAD 3 actual 24 actual 24 actual 9 result 9 actual 9 result 9 5: ASTORE 1 16: ALOAD 3 9: INVOKESTATIC 9: INVOKESTATIC 17: ALOAD 2 6: ALOAD 1 24: INVOKEVIRTUAL 19: ALOAD 2 22: GETSTATIC 7: ASTORE 2 inc inc formal return formal return 25: RETURN 18: IF_ACMPNE 0: ILOAD 0 3: IRETURN 0: ILOAD 0 3: IRETURN スライシング基準:actual 24の後ろ向き Thin Slice 1: ICONST_1 2: IADD 1: ICONST_1 2: IADD 赤色の頂点の集合

  20. スライシング基準の決定 • スライシング基準を決定するために,バイトコード命令を分類する • source:データを生成する • 定数の生成(ICONST_1),オブジェクトの生成(NEW),メソッドの返り値 • sink:データを使用する • 比較演算(IFEQ),メソッドの実引数 • transfer:データを伝播する • 変数の代入(ISTORE),参照(ILOAD) • (前向き Thin Slice) • (後ろ向き Thin Slice)

  21. 計測する指標 • あるsink に対する後ろ向き Thin Slice • に含まれる source 頂点の集合 • ある source に対する前向き Thin Slice • に含まれる sink 頂点の集合 • Thin Slice Stsの頂点が所属するメソッドの集合 sink に関する指標 source に関する指標 sinkとsource に関する指標 以上の指標をプログラム中のすべての sink,source に対して計測する

  22. 例:指標の計測方法 16: ALOAD 3 (w) 17: ALOAD 2 (z) 18: IF_ACMPNE 19: ALOAD 2 (z) 20: GETFIELD example/A#f: int 21: ISTORE 6 (v) 22: GETSTATIC java/lang/System#out: java/io/PrintStream 23: ILOAD 6 (v) 24: INVOKEVIRTUAL java/io/PrintStream#println(I)V 25: RETURN example/Sample#inc 0: ILOAD 0 (x) 1: ICONST_1 2: IADD 3: IRETURN example/Sample#main 0: ICONST_1 1: ISTORE 4 (a) 2: NEW 3: DUP 4: INVOKESPECIAL example/A#<init>()V 5: ASTORE 1 (x) 6: ALOAD 1 (x) 7: ASTORE 2 (z) 8: ILOAD 4 (a) 9: INVOKESTATIC example/Sample#inc(I)I 10: ISTORE 5 (b) 11: ALOAD 1 (x) 12: ASTORE 3 (w) 13: ALOAD 3 (w) 14: ILOAD 5 (b) 15: PUTFIELD example/A#f: int

  23. main 0: ICONST_1 15: PUTFIELD 20: GETFIELD 0: ICONST_1 15: PUTFIELD 20: GETFIELD 2: NEW 11: ALOAD 1 0: ICONST_1 21: ISTORE 6 21: ISTORE 6 1: ISTORE 4 14: ILOAD 5 1: ISTORE 4 3: DUP 14: ILOAD 5 12: ASTORE 3 23: ILOAD 6 23: ILOAD 6 8: ILOAD 4 10: ISTORE 5 8: ILOAD 4 10: ISTORE 5 4: INVOKESPECIAL 13: ALOAD 3 actual 24 actual 24 actual 9 result 9 actual 9 result 9 5: ASTORE 1 16: ALOAD 3 9: INVOKESTATIC 9: INVOKESTATIC 17: ALOAD 2 6: ALOAD 1 24: INVOKEVIRTUAL 19: ALOAD 2 22: GETSTATIC 7: ASTORE 2 inc inc formal return formal return 25: RETURN 18: IF_ACMPNE スライシング基準:sink actual 24の後ろ向き Thin Slice 0: ILOAD 0 3: IRETURN 0: ILOAD 0 3: IRETURN 赤色の頂点の集合 ⇒ 中の source 命令 = { 0: ICONST_1, 1: ICONST_1, 2: IADD } ⇒ 1: ICONST_1 2: IADD 1: ICONST_1 1: ICONST_1 2: IADD 2: IADD

  24. main 0: ICONST_1 15: PUTFIELD 20: GETFIELD 0: ICONST_1 15: PUTFIELD 20: GETFIELD 2: NEW 11: ALOAD 1 21: ISTORE 6 21: ISTORE 6 1: ISTORE 4 14: ILOAD 5 1: ISTORE 4 3: DUP 14: ILOAD 5 12: ASTORE 3 23: ILOAD 6 23: ILOAD 6 8: ILOAD 4 10: ISTORE 5 8: ILOAD 4 10: ISTORE 5 4: INVOKESPECIAL 13: ALOAD 3 actual 24 actual 24 actual 9 result 9 actual 9 result 9 5: ASTORE 1 16: ALOAD 3 9: INVOKESTATIC 9: INVOKESTATIC 17: ALOAD 2 6: ALOAD 1 24: INVOKEVIRTUAL 19: ALOAD 2 22: GETSTATIC 7: ASTORE 2 inc inc formal return formal return 25: RETURN 18: IF_ACMPNE スライシング基準:sink actual 24の後ろ向き Thin Slice 0: ILOAD 0 3: IRETURN 0: ILOAD 0 3: IRETURN 赤色の頂点の集合 ⇒ = { main, inc } 1: ICONST_1 2: IADD 1: ICONST_1 2: IADD

  25. main 0: ICONST_1 15: PUTFIELD 20: GETFIELD 2: NEW 11: ALOAD 1 2: NEW 11: ALOAD 1 21: ISTORE 6 1: ISTORE 4 3: DUP 14: ILOAD 5 12: ASTORE 3 12: ASTORE 3 23: ILOAD 6 8: ILOAD 4 10: ISTORE 5 4: INVOKESPECIAL 13: ALOAD 3 13: ALOAD 3 actual 24 actual 9 result 9 5: ASTORE 1 16: ALOAD 3 16: ALOAD 3 5: ASTORE 1 9: INVOKESTATIC 17: ALOAD 2 6: ALOAD 1 6: ALOAD 1 17: ALOAD 2 24: INVOKEVIRTUAL 7: ASTORE 2 19: ALOAD 2 19: ALOAD 2 22: GETSTATIC 7: ASTORE 2 inc formal return 25: RETURN 18: IF_ACMPNE 18: IF_ACMPNE 18: IF_ACMPNE スライシング基準:source 2: NEW の前向き Thin Slice 0: ILOAD 0 3: IRETURN 赤色の頂点の集合 ⇒ 1: ICONST_1 2: IADD 中の sink 命令 = { 18: IF_ACMPNE } ⇒

  26. 実験対象 • DaCapo benchmark (バージョン 9.12) • 7つのJava プログラム

  27. RQ1:実験結果(1/3) • RQ1:Thin Slice のサイズは,平均的に十分小さいものであるか

  28. RQ1:実験結果(2/3) • 7つのプログラムでの平均 • |𝐵𝑎𝑐𝑘𝑤𝑎𝑟𝑑(𝑣)|の平均:2.5% • |𝐹𝑜𝑟𝑤𝑎𝑟𝑑(𝑤)|の平均:1.9% • |𝐵𝑎𝑐𝑘𝑤𝑎𝑟𝑑(𝑣)|と|𝐹𝑜𝑟𝑤𝑎𝑟𝑑(𝑤)|の平均:2.2% Thin Slice のサイズは平均で約2.2% 従来のスライスサイズは約30%

  29. RQ1:実験結果(3/3) • 60から80%の Thin Slice は,そのサイズが0.1%以下である • 残りの20から40%のThin Slice は,最大値付近に分布している 0.1% 10% 18%

  30. RQ2:実験結果 • RQ2:データ依存関係の調査において有効であると考えられるThin Sliceはどの程度存在するか • 2 である後ろ向きThin Slice の割合:全スライス中の60% • 約60%の後ろ向きThin Slice は複数のメソッドにまたがっている • 3 かつ 2 であるThin Sliceの割合:全スライス中の10% • 約10%の後ろ向き Thin Slice が表すデータフローは複数のメソッドにまたがっており,データの生成元の数が3以下である

  31. 考察 • RQ1:Thin Slice のサイズについて • Thin Slice のサイズは平均的に十分小さい • 分布は非常に小さいものと大きいものの2つに分かれている • RQ2:Thin Slicing の有効性について • 複数のメソッドにまたがるものが約60% • 複数のメソッドにまたがり,データの生成元が少ないものが約10% • データフローを複数のメソッドに渡って追跡する作業をThin Slicing によって置き換えられる

  32. まとめと今後の課題 • Thin Slice のサイズを計測し,統計的な評価を行った • サイズが平均して小さくなることを確認した • サイズが大きいものが20から40%存在する • Thin Slice のサイズが大きくなる原因を調査する • サイズが大きいスライスはどのようなデータフローであるか

More Related