SlideShare a Scribd company logo
1 of 32
Download to read offline
PLDIr#5 (PLDI2001)


2010-01-06 酒井 政裕
Citation Count: 43



Design and Implementation of
Generics for the .NET Common
     Language Runtime
   Andrew Kennedy (MSR),
       Don Syme (MSR)
背景


• JVMや当時のCLRは(パラメトリック)多相
  =Genericsをサポートしてない
• なので、多相をコンパイルしようとすると、
  ⾊々問題が……
 – プリミティブ型によるインスタンス化の禁⽌
   (GJ, NextGenのerasure変換)
 – “raw type” casting semantics (GJ)
 – 分割コンパイル出来ない (MLj)
 – 複雑なコンパイル⽅法 (NextGen)
 – プリミティブ型でインスタンス化したときのパ
   フォーマンスの問題 (PolyJ, Pizza)
• なので、ちゃんとCLRレベルで実装しましょう
Objectベースのスタック

class Stack {                            public object Pop() {
 private object[] store;                   return store[--size];
                                         }
 private int size;
  public Stack() {
    store = new object[10];           public static void Main() {
size=0;                                 Stack x = new Stack();
  }                                     x.Push(17); // boxing
                                        Console.WriteLine(x.Pop() ==
 void Push(object item) {            17)
   if (size >= store.Size) {          }
     object[] tmp = new
object[size*2];                      }
     Array.Copy(store, tmp, size);
     store = tmp;
   }
   store[size++] = x;
 }
Generic C# のスタック

class Stack<T> {                      public T Pop() {
 private T[] store;                     return store[--size];
                                      }
 private int size;
 public Stack() {
   store = new T[10]; size=0;      public static void Main() {
 }                                   Stack x = new Stack<int>();
                                     x.Push(17);
                                     Console.WriteLine(x.Pop() ==
  void Push(T item) {             17)
    if (size >= store.Size) {      }
      T[] tmp = new T[size*2];    }
      Array.Copy<T>(store, tmp,
size);
      store = tmp;
    }
    store[size++] = x;
  }
Design Choice


• クラス、インターフェース、構造体、メ
  ソッドはすべて型によるパラメータ化可
  能
• 厳密な実⾏時型:
  – e.g. List<string> と List<object> は区別
• インスタンス化は無制限にできる
  – e.g. List<int>, List<double>, …
• F-bounded polymorphism
Design Choice (2)


• インスタンス化されたクラスやインター
  フェースを継承可能
• 多相再帰(Polymorphic recursion)もOK
  – 多相的なクラスのメソッドは、異なる型でイ
    ンスタンス化された⾃分⾃⾝を呼び出せる
  – 多相的なメソッドも、異なる型でインスタン
    ス化された⾃分⾃⾝を呼び出せる
• 多相的な仮想関数もOK
Design Choice (3)


• 通常のクラスベースの⾔語はカバー
• それ以外の⾊々な⾔語では、サポートで
  きなかったものも……
  – Haskellの⾼階型と種 (e.g. List : *→*)
  – ML系⾔語のモジュールの、⾼階型を使ったエ
    ンコーディング
  – HaksellとMercuryの型クラス
  – Eiffelの、型構築⼦の型安全でない共変性
  – C++のtemplateも完全にはサポートしない
実装


• 伝統的なコンパイル・リンク・実⾏とい
  うモデルに囚われず、CLRの動的ローディ
  ングや実⾏時コード⽣成を活⽤
• ポイント
 – 実⾏時にコードを特化 (JIT type
   specialization)
 – コードと表現は可能な限り共有
 – ボックス化しない
 – 実⾏時型の効率的なサポート
ILの拡張
 オブジェクトベースのスタック                                多相的なスタック

.class Stack {                           .class Stack<T> {
  .field private class System.Object[]     .field private !0[] store
store
  .field private int32 size               .field private int32 size
  .method public void .ctor() {           .method public void .ctor() {
    ldarg.0                                 ldarg.0
    call void System.Object::.ctor()        call void System.Object::.ctor()
    ldarg.0                                 ldarg.0
    ldc.i4 10                               ldc.i4 10
    newarr System.Object                    newarr !0
    stfld class System.Object[]             stfld !0[] Stack<!0>::store
Stack::store
    ldarg.0                                   ldarg.0
    ldc.i4 0                                  ldc.i4 0
    stfld int32 Stack::size                   stfld int32 Stack<!0>::size
    ret                                       ret
  }                                       }
ILの拡張
 オブジェクトベースのスタック                                多相的なスタック

.class Stack {                           .class Stack<T> {
  .field private class System.Object[]     .field private !0[] store
store
  .field private int32 size               .field private int32 size
  .method public void .ctor() {           .method public void .ctor() {
    ldarg.0                                 ldarg.0
    call void System.Object::.ctor()        call void System.Object::.ctor()
    ldarg.0                                 ldarg.0
    ldc.i4 10                               ldc.i4 10
    newarr System.Object                    newarr !0
    stfld class System.Object[]             stfld !0[] Stack<!0>::store
Stack::store
    ldarg.0                                   ldarg.0
    ldc.i4 0                                  ldc.i4 0
    stfld 型パラメータ情報の追加
          int32 Stack::size                   stfld int32 Stack<!0>::size
    ret                                       ret
  }                                       }
       ldargなどの命令は、もともと複数の型に適用できる
       (JITが型を自動的に決定して型に応じたコード生成)
       ので、そのまま。
ILの拡張

.method public void Push(class               .method public void Push(!0 x) {
System.Object x) {
  .maxstack 4                                    .maxstack 4
  .locals (class System.Object[], int32)         .locals (!0[], int32)
  …                                              …
  ldarg.0                                        ldarg.0
  ldfld class System.Object[] Stack::store       ldfld !0[] Stack<!0>::store
  ldarg.0                                        ldarg.0
  dup                                            dup
  ldfld int32 Stack::size                        ldfld int32 Stack<!0>::size
  dup                                            dup
  stloc.1                                        stloc.1
  ldc.i4 1                                       ldc.i4 1
  add                                            add
  stfld int32 Stack::size                        stfld int32 Stack<!0>::size
  ldloc.1                                        ldloc.1
  ldarg.1                                        ldarg.1
  stelem.ref                                     stelem.any !0
  ret                                            ret
}                                            }



stelemは型に依存する命令なので、新たにstelem.anyを追加
ILの拡張

.method public static void Main() {           .method public static void Main() {
  .entrypoint                                  .entrypoint
  .maxstack 3                                  .maxstack 3
  .locals (class Stack)                        .locals (class Stack<int32>)
  newobj void Stack::.ctor()                   newobj void Stack<int32> ::.ctor()
  stloc.0                                      stloc.0
  ldloc.0                                      ldloc.0
  ldc.i4 17                                    ldc.i4 17
  box System.Int32
  call instance void Stack::Push(class            call instance void Stack<int32>::Push(!0)
System.Object)                                    ldloc.0
  ldloc.0                                         call instance !0 Stack<int32>::Pop()
  call instance class System.Object
Stack::Pop()
  unbox System.Int32
  ldind.i4                                        ldc.i4 17
  ldc.i4 17                                       ceq
  ceq                                             call void System.Console::WriteLine(bool)
  call void System.Console::WriteLine(bool)       ret
  ret                                         }
}


                           box/unboxが不要に
ILの拡張: 禁⽌されていること


• .class Foo<T> extends !0
• !0::.ctor()
• !0::.myMethod()
• クラスの型パラメータの静的変数での使
  ⽤
• パラメタ化されたインターフェースをイ
  ンスタンス化したものを、複数回実装す
  ること
ランタイム: データ表現とコード


• 伝統的には、データ表現とコードを、
 – 型パラメータ毎に特化、
 – もしくは共有
• CLRではこれらをミックス出来る
 – あるインスタンス化が必要になった時点で、互換性
   のあるインスタンス化がすでにされているか探す
 – なかったら新たに⽣成
 – ⽣成されたvtableのエントリは、呼ばれたときに実
   際にコード⽣成するスタブ
  • polymorphic recursionなどに対応するため: e.g.
    class C<T> { void m() { ... new C<C<T>>() ... } }
ランタイム: 型情報


• 厳密な型情報はvtable内に持つ
  (vtable を type handle として使う)
       Dict<int,object>   Dict<bool,string>
ランタイム: 型パラメタへのアクセス


class C { virtual void m(int) { ... } }
class D<T> : C {
  void p(Object x) { ... (Set<T[]>) x ... }
  override void m(int) { ... new List<T> ... }
}
class E<U> : D<Tree<U>> {
  // m inherited
  void q() { ... y is U[] ... }
}
                 毎回、型情報をlookupするのは大変
                なので、dictionaryをlazyに生成して……
ランタイム: Eのvtable内のdictionary

class C { virtual void       class E<U> :
   m(int) { ... } }             D<Tree<U>> {
class D<T> : C {               // m inherited
  void p(Object x) { ...       void q() { ... y is
   (Set<T[]>) x ... }           U[] ... }
  override void m(int)       }
   { ... new List<T> ... }
}
パフォーマンス


S := new stack
c := constant
for m ∈ 1…10000 do
  S.push(c) m times
  S.pop() m times
パフォーマンス2


• 実⾏時の型操作のオーバーヘッドを測定
• こんなやつ?
 – class C<T> {
     Main() {
       for … { new Dict<T[], List<T>>() }
     }}
Citation Count: 92



  Automatic Predicate
Abstraction of C Programs

        Thomas Ball (MSR),
 Rupak Majumdar (U.C.Berkeley),
Todd Millstein (Univ. of Washinton),
    Sriram K. Rajamani (MSR)
• ソフトウェアのモデル検査では抽象化が
  重要
 – 状態爆発を避けるため
 – そもそも無限状態の場合には、有限状態にす
   る必要がある
• この論⽂はSLAMが抽象化に使っている
  C2BPの詳しい話
 – CプログラムPと述語の集合Eから、
   述語抽象化した Boolean program B(P,E) を
   ⽣成
B(P, E)


• 変数はEの要素
• 元のプログラムの保守的な抽象化
  – 元のプログラムでfeasibleなパスは、抽象化
    後もfeasible
例: 元のCプログラム P

typedef struct cell {                      if (curr == *l) {
 int val;                                    *l = nextCurr;
 struct cell* next;                        }
} *list;                                   curr->next = newl;
                                     L: newl = curr;
list partition(list *l, int v) {         } else {
  list curr, prev, newl, nextCurr;         prev = curr;
  curr = *l;                             }
  prev = NULL;                           curr = nextCurr;
  newl = NULL;                         }
  while (curr != NULL) {               return newl;
    nextCurr = curr->next;           }
    if (curr->val > v) {
      if (prev != NULL) {
        prev->next = nextCurr;
      }
例: 述語の集合E


•   curr == NULL
•   prev == NULL
•   curr->val > v
•   prev->val > v
例: BP(P, E)

void partition() {                          if (*) {
 bool {curr==NULL}, {prev==NULL};             skip;
 bool {curr->val>v}, {prev->val>v};         }
 {curr==NULL} = unknown();                  skip;
 {curr->val>v} = unknown();           L: skip;
 {prev==NULL} = true;                     } else {
 {prev->val>v} = unknown();                 assume(!{curr->val>v});
 skip;                                      {prev==NULL} = {curr==NULL};
 while(*) {                                 {prev->val>v} = {curr->val>v};
  assume(!{curr==NULL});                  }
  skip;                                   {curr==NULL} = unknown();
  if (*) {                                {curr->val>v} = unknown();
    assume({curr->val>v});              }
    if (*) {                            assume({curr==NULL});
      assume(!{prev==NULL});          }
      skip;
    }
• ⾃明な話だと思ってたけど、⾊々⼯夫が
  必要
• 元のプログラムのコードに対応して、ど
  の述語の真偽がどう変化するかの判定
 – 最終的には定理証明器を駆動
  • 定理証明器は重いので、⼯夫して呼ぶ回数を削減
 – ポインタ解析による精度の改善
  • Our implementation uses Das's points-to
    algorithm [12] to obtain flow-insensitive,
    context-insensitive may-alias information.
Citation Count: 27




The Pointer Assertion Logic
          Engine
            Anders Møller
     & Michael I. Schwartzbach
  (University of Aarhus, Denmark)
概要


• ヒープの構造に関する性質を、Pointer
  Assertion Logic というロジックで、アノ
  テーション(事前条件・事後条件・不変条
  件)
• プログラムとアノテーションを、
  WS2S(weak monadic second-order
  theory of 2 successors)に変換して、
  MONAで検証する、
 – 条件を満たさない場合には、反例を出⼒
具体例

type List = {data next:List;}      proc reverse(data list:List):List
                                     set R:List;
pred roots(pointer x,y:List, set   [roots(list,null,R)]
   R:List)                         {
   = allpos p of List:               data res:List;
       p in R                        pointer temp:List;
       <=>                           res = null;
       x<next*>p | y<next*>p;        while [roots(list,res,R)] (list!=null)
                                     {
                                       temp = list.next;
                                       list.next = res;
                                       res = list;
                                       list = temp;
                                     }
                                     return res;
                                   }
                                   [roots(return,null,R)]
性能




     ※ GTA = Guided Tree Automata
• PAL(Pointer Assertion Logic)は、表現⼒
  と検証コストの良いバランス

• 主なターゲットはデータ構造
• アノテーションを書くのは⼤変だけど、
  データ構造の設計は元々invariantを注意
  深く考える必要があるから、それを考え
  れば⼤したことない

More Related Content

What's hot

[CB16] マイクロソフトウィンドウズカーネルのデスノート by Peter Hlavaty & Jin Long
[CB16] マイクロソフトウィンドウズカーネルのデスノート by Peter Hlavaty & Jin Long[CB16] マイクロソフトウィンドウズカーネルのデスノート by Peter Hlavaty & Jin Long
[CB16] マイクロソフトウィンドウズカーネルのデスノート by Peter Hlavaty & Jin Long
CODE BLUE
 
Javaセキュアコーディングセミナー東京第2回演習の解説
Javaセキュアコーディングセミナー東京第2回演習の解説Javaセキュアコーディングセミナー東京第2回演習の解説
Javaセキュアコーディングセミナー東京第2回演習の解説
JPCERT Coordination Center
 
Haskell超初心者勉強会14
Haskell超初心者勉強会14Haskell超初心者勉強会14
Haskell超初心者勉強会14
Takashi Kawachi
 
Sns suite presentation
Sns suite presentationSns suite presentation
Sns suite presentation
Jason Namkung
 

What's hot (20)

Objc lambda
Objc lambdaObjc lambda
Objc lambda
 
[CB16] マイクロソフトウィンドウズカーネルのデスノート by Peter Hlavaty & Jin Long
[CB16] マイクロソフトウィンドウズカーネルのデスノート by Peter Hlavaty & Jin Long[CB16] マイクロソフトウィンドウズカーネルのデスノート by Peter Hlavaty & Jin Long
[CB16] マイクロソフトウィンドウズカーネルのデスノート by Peter Hlavaty & Jin Long
 
LINQソースでGO!
LINQソースでGO!LINQソースでGO!
LINQソースでGO!
 
mruby搭載ボードGR-CITRUSのRubyファームVer2.35の説明
mruby搭載ボードGR-CITRUSのRubyファームVer2.35の説明mruby搭載ボードGR-CITRUSのRubyファームVer2.35の説明
mruby搭載ボードGR-CITRUSのRubyファームVer2.35の説明
 
Javaプログラミング入門【第2回】
Javaプログラミング入門【第2回】Javaプログラミング入門【第2回】
Javaプログラミング入門【第2回】
 
C# 式木 (Expression Tree) ~ LINQをより深く理解するために ~
C# 式木 (Expression Tree) ~ LINQをより深く理解するために ~C# 式木 (Expression Tree) ~ LINQをより深く理解するために ~
C# 式木 (Expression Tree) ~ LINQをより深く理解するために ~
 
Javaセキュアコーディングセミナー東京第2回演習の解説
Javaセキュアコーディングセミナー東京第2回演習の解説Javaセキュアコーディングセミナー東京第2回演習の解説
Javaセキュアコーディングセミナー東京第2回演習の解説
 
boost tour 1.48.0 all
boost tour 1.48.0 allboost tour 1.48.0 all
boost tour 1.48.0 all
 
Chapter 6: Computing on the language (R Language Definition)
Chapter 6: Computing on the language (R Language Definition)Chapter 6: Computing on the language (R Language Definition)
Chapter 6: Computing on the language (R Language Definition)
 
規格書で読むC++11のスレッド
規格書で読むC++11のスレッド規格書で読むC++11のスレッド
規格書で読むC++11のスレッド
 
【LT版】Elixir入門「第7回:Python/KerasをElixirから繋いでアレコレする」
【LT版】Elixir入門「第7回:Python/KerasをElixirから繋いでアレコレする」【LT版】Elixir入門「第7回:Python/KerasをElixirから繋いでアレコレする」
【LT版】Elixir入門「第7回:Python/KerasをElixirから繋いでアレコレする」
 
JEP280: Java 9 で文字列結合の処理が変わるぞ!準備はいいか!? #jjug_ccc
JEP280: Java 9 で文字列結合の処理が変わるぞ!準備はいいか!? #jjug_cccJEP280: Java 9 で文字列結合の処理が変わるぞ!準備はいいか!? #jjug_ccc
JEP280: Java 9 で文字列結合の処理が変わるぞ!準備はいいか!? #jjug_ccc
 
Haskell超初心者勉強会14
Haskell超初心者勉強会14Haskell超初心者勉強会14
Haskell超初心者勉強会14
 
Java x Groovy: improve your java development life
Java x Groovy: improve your java development lifeJava x Groovy: improve your java development life
Java x Groovy: improve your java development life
 
Project lambda
Project lambdaProject lambda
Project lambda
 
Javaプログラミング入門【第7回】
Javaプログラミング入門【第7回】Javaプログラミング入門【第7回】
Javaプログラミング入門【第7回】
 
Tensorflow dynamically loadable XLA plugin ソースコード解析
Tensorflow  dynamically loadable XLA plugin ソースコード解析Tensorflow  dynamically loadable XLA plugin ソースコード解析
Tensorflow dynamically loadable XLA plugin ソースコード解析
 
不遇の標準ライブラリ - valarray
不遇の標準ライブラリ - valarray不遇の標準ライブラリ - valarray
不遇の標準ライブラリ - valarray
 
非同期処理の基礎
非同期処理の基礎非同期処理の基礎
非同期処理の基礎
 
Sns suite presentation
Sns suite presentationSns suite presentation
Sns suite presentation
 

Viewers also liked

Viewers also liked (11)

“Adoption and Focus: Practical Linear Types for Imperative Programming”他の紹介@P...
“Adoption and Focus: Practical Linear Types for Imperative Programming”他の紹介@P...“Adoption and Focus: Practical Linear Types for Imperative Programming”他の紹介@P...
“Adoption and Focus: Practical Linear Types for Imperative Programming”他の紹介@P...
 
Omega test and beyond
Omega test and beyondOmega test and beyond
Omega test and beyond
 
Aluminum: Principled Scenario Exploration through Minimality
Aluminum: Principled Scenario Exploration through MinimalityAluminum: Principled Scenario Exploration through Minimality
Aluminum: Principled Scenario Exploration through Minimality
 
Introduction to Max-SAT and Max-SAT Evaluation
Introduction to Max-SAT and Max-SAT EvaluationIntroduction to Max-SAT and Max-SAT Evaluation
Introduction to Max-SAT and Max-SAT Evaluation
 
代数的実数とCADの実装紹介
代数的実数とCADの実装紹介代数的実数とCADの実装紹介
代数的実数とCADの実装紹介
 
自動定理証明の紹介
自動定理証明の紹介自動定理証明の紹介
自動定理証明の紹介
 
萩野服部研究室 スキー合宿 2012 自己紹介(酒井)
萩野服部研究室 スキー合宿 2012 自己紹介(酒井)萩野服部研究室 スキー合宿 2012 自己紹介(酒井)
萩野服部研究室 スキー合宿 2012 自己紹介(酒井)
 
ゼロピッチ: MOOC
ゼロピッチ: MOOCゼロピッチ: MOOC
ゼロピッチ: MOOC
 
SAT/SMT solving in Haskell
SAT/SMT solving in HaskellSAT/SMT solving in Haskell
SAT/SMT solving in Haskell
 
How a CDCL SAT solver works
How a CDCL SAT solver worksHow a CDCL SAT solver works
How a CDCL SAT solver works
 
SAT/SMTソルバの仕組み
SAT/SMTソルバの仕組みSAT/SMTソルバの仕組み
SAT/SMTソルバの仕組み
 

Similar to “Design and Implementation of Generics for the .NET Common Language Runtime”他の紹介@PLDIr#5

T69 c++cli ネイティブライブラリラッピング入門
T69 c++cli ネイティブライブラリラッピング入門T69 c++cli ネイティブライブラリラッピング入門
T69 c++cli ネイティブライブラリラッピング入門
伸男 伊藤
 
Lambda in template_final
Lambda in template_finalLambda in template_final
Lambda in template_final
Cryolite
 
オブジェクト指向できていますか?
オブジェクト指向できていますか?オブジェクト指向できていますか?
オブジェクト指向できていますか?
Moriharu Ohzu
 
Javaセキュアコーディングセミナー東京第3回演習の解説
Javaセキュアコーディングセミナー東京第3回演習の解説Javaセキュアコーディングセミナー東京第3回演習の解説
Javaセキュアコーディングセミナー東京第3回演習の解説
JPCERT Coordination Center
 
Or seminar2011final
Or seminar2011finalOr seminar2011final
Or seminar2011final
Mikio Kubo
 

Similar to “Design and Implementation of Generics for the .NET Common Language Runtime”他の紹介@PLDIr#5 (20)

Prosym2012
Prosym2012Prosym2012
Prosym2012
 
C++ マルチスレッドプログラミング
C++ マルチスレッドプログラミングC++ マルチスレッドプログラミング
C++ マルチスレッドプログラミング
 
Boost Tour 1.50.0 All
Boost Tour 1.50.0 AllBoost Tour 1.50.0 All
Boost Tour 1.50.0 All
 
What is template
What is templateWhat is template
What is template
 
中3女子が狂える本当に気持ちのいい constexpr
中3女子が狂える本当に気持ちのいい constexpr中3女子が狂える本当に気持ちのいい constexpr
中3女子が狂える本当に気持ちのいい constexpr
 
C#の新機能勉強会 ~ C#7、8の新機能を活用して速く安全なプログラムを書こう~
C#の新機能勉強会 ~ C#7、8の新機能を活用して速く安全なプログラムを書こう~C#の新機能勉強会 ~ C#7、8の新機能を活用して速く安全なプログラムを書こう~
C#の新機能勉強会 ~ C#7、8の新機能を活用して速く安全なプログラムを書こう~
 
Boost tour 1_40_0
Boost tour 1_40_0Boost tour 1_40_0
Boost tour 1_40_0
 
T69 c++cli ネイティブライブラリラッピング入門
T69 c++cli ネイティブライブラリラッピング入門T69 c++cli ネイティブライブラリラッピング入門
T69 c++cli ネイティブライブラリラッピング入門
 
中3女子でもわかる constexpr
中3女子でもわかる constexpr中3女子でもわかる constexpr
中3女子でもわかる constexpr
 
C++0x 言語の未来を語る
C++0x 言語の未来を語るC++0x 言語の未来を語る
C++0x 言語の未来を語る
 
Lambda in template_final
Lambda in template_finalLambda in template_final
Lambda in template_final
 
Introduction to cython
Introduction to cythonIntroduction to cython
Introduction to cython
 
思ったほど怖くない! Haskell on JVM 超入門 #jjug_ccc #ccc_l8
思ったほど怖くない! Haskell on JVM 超入門 #jjug_ccc #ccc_l8思ったほど怖くない! Haskell on JVM 超入門 #jjug_ccc #ccc_l8
思ったほど怖くない! Haskell on JVM 超入門 #jjug_ccc #ccc_l8
 
Introduction of Python
Introduction of PythonIntroduction of Python
Introduction of Python
 
つくってあそぼ ラムダ計算インタプリタ
つくってあそぼ ラムダ計算インタプリタつくってあそぼ ラムダ計算インタプリタ
つくってあそぼ ラムダ計算インタプリタ
 
オブジェクト指向できていますか?
オブジェクト指向できていますか?オブジェクト指向できていますか?
オブジェクト指向できていますか?
 
Clojure
ClojureClojure
Clojure
 
Javaセキュアコーディングセミナー東京第3回演習の解説
Javaセキュアコーディングセミナー東京第3回演習の解説Javaセキュアコーディングセミナー東京第3回演習の解説
Javaセキュアコーディングセミナー東京第3回演習の解説
 
Or seminar2011final
Or seminar2011finalOr seminar2011final
Or seminar2011final
 
C# LINQ入門
C# LINQ入門C# LINQ入門
C# LINQ入門
 

More from Masahiro Sakai

融合変換による最適化の理論的基盤と正当性 (2006-06-27)
融合変換による最適化の理論的基盤と正当性 (2006-06-27)融合変換による最適化の理論的基盤と正当性 (2006-06-27)
融合変換による最適化の理論的基盤と正当性 (2006-06-27)
Masahiro Sakai
 
融合変換による最適化の理論的基盤と正当性 (2006-06-20)
融合変換による最適化の理論的基盤と正当性 (2006-06-20)融合変換による最適化の理論的基盤と正当性 (2006-06-20)
融合変換による最適化の理論的基盤と正当性 (2006-06-20)
Masahiro Sakai
 
LLW2004 その場でどう書く - Haskell
LLW2004 その場でどう書く - HaskellLLW2004 その場でどう書く - Haskell
LLW2004 その場でどう書く - Haskell
Masahiro Sakai
 
非正格関数に対して適用可能な融合変換
非正格関数に対して適用可能な融合変換非正格関数に対して適用可能な融合変換
非正格関数に対して適用可能な融合変換
Masahiro Sakai
 

More from Masahiro Sakai (19)

DeepXplore: Automated Whitebox Testing of Deep Learning
DeepXplore: Automated Whitebox Testing of Deep LearningDeepXplore: Automated Whitebox Testing of Deep Learning
DeepXplore: Automated Whitebox Testing of Deep Learning
 
Towards formal verification of neural networks
Towards formal verification of neural networksTowards formal verification of neural networks
Towards formal verification of neural networks
 
関数プログラマから見たPythonと機械学習
関数プログラマから見たPythonと機械学習関数プログラマから見たPythonと機械学習
関数プログラマから見たPythonと機械学習
 
Writing a SAT solver as a hobby project
Writing a SAT solver as a hobby projectWriting a SAT solver as a hobby project
Writing a SAT solver as a hobby project
 
RClassify: Classifying Race Conditions in Web Applications via Deterministic ...
RClassify: Classifying Race Conditions in Web Applications via Deterministic ...RClassify: Classifying Race Conditions in Web Applications via Deterministic ...
RClassify: Classifying Race Conditions in Web Applications via Deterministic ...
 
Relaxed Dependency Analysis
Relaxed Dependency AnalysisRelaxed Dependency Analysis
Relaxed Dependency Analysis
 
“Symbolic bounds analysis of pointers, array indices, and accessed memory reg...
“Symbolic bounds analysis of pointers, array indices, and accessed memory reg...“Symbolic bounds analysis of pointers, array indices, and accessed memory reg...
“Symbolic bounds analysis of pointers, array indices, and accessed memory reg...
 
自然言語をラムダ式で解釈する体系PTQのHaskell実装
自然言語をラムダ式で解釈する体系PTQのHaskell実装自然言語をラムダ式で解釈する体系PTQのHaskell実装
自然言語をラムダ式で解釈する体系PTQのHaskell実装
 
Whole Program Paths 等の紹介@PLDIr#3
Whole Program Paths 等の紹介@PLDIr#3Whole Program Paths 等の紹介@PLDIr#3
Whole Program Paths 等の紹介@PLDIr#3
 
Run-time Code Generation and Modal-ML の紹介@PLDIr#2
Run-time Code Generation and Modal-ML の紹介@PLDIr#2Run-time Code Generation and Modal-ML の紹介@PLDIr#2
Run-time Code Generation and Modal-ML の紹介@PLDIr#2
 
Introduction to Categorical Programming (Revised)
Introduction to Categorical Programming (Revised)Introduction to Categorical Programming (Revised)
Introduction to Categorical Programming (Revised)
 
Introduction to Categorical Programming
Introduction to Categorical ProgrammingIntroduction to Categorical Programming
Introduction to Categorical Programming
 
融合変換による最適化の理論的基盤と正当性 (2006-06-27)
融合変換による最適化の理論的基盤と正当性 (2006-06-27)融合変換による最適化の理論的基盤と正当性 (2006-06-27)
融合変換による最適化の理論的基盤と正当性 (2006-06-27)
 
融合変換による最適化の理論的基盤と正当性 (2006-06-20)
融合変換による最適化の理論的基盤と正当性 (2006-06-20)融合変換による最適化の理論的基盤と正当性 (2006-06-20)
融合変換による最適化の理論的基盤と正当性 (2006-06-20)
 
Ruby-GNOME2におけるGC問題
Ruby-GNOME2におけるGC問題Ruby-GNOME2におけるGC問題
Ruby-GNOME2におけるGC問題
 
LLW2004 その場でどう書く - Haskell
LLW2004 その場でどう書く - HaskellLLW2004 その場でどう書く - Haskell
LLW2004 その場でどう書く - Haskell
 
非正格関数に対して適用可能な融合変換
非正格関数に対して適用可能な融合変換非正格関数に対して適用可能な融合変換
非正格関数に対して適用可能な融合変換
 
Haskell - LLRing2006 Language Update
Haskell  - LLRing2006 Language UpdateHaskell  - LLRing2006 Language Update
Haskell - LLRing2006 Language Update
 
LLDN / キミならどう書く Haskell 編 (自由演技)
LLDN / キミならどう書く Haskell 編 (自由演技)LLDN / キミならどう書く Haskell 編 (自由演技)
LLDN / キミならどう書く Haskell 編 (自由演技)
 

Recently uploaded

Recently uploaded (7)

Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。
 
LoRaWAN スマート距離検出デバイスDS20L日本語マニュアル
LoRaWAN スマート距離検出デバイスDS20L日本語マニュアルLoRaWAN スマート距離検出デバイスDS20L日本語マニュアル
LoRaWAN スマート距離検出デバイスDS20L日本語マニュアル
 
Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。
 
新人研修 後半 2024/04/26の勉強会で発表されたものです。
新人研修 後半        2024/04/26の勉強会で発表されたものです。新人研修 後半        2024/04/26の勉強会で発表されたものです。
新人研修 後半 2024/04/26の勉強会で発表されたものです。
 
NewSQLの可用性構成パターン(OCHaCafe Season 8 #4 発表資料)
NewSQLの可用性構成パターン(OCHaCafe Season 8 #4 発表資料)NewSQLの可用性構成パターン(OCHaCafe Season 8 #4 発表資料)
NewSQLの可用性構成パターン(OCHaCafe Season 8 #4 発表資料)
 
LoRaWANスマート距離検出センサー DS20L カタログ LiDARデバイス
LoRaWANスマート距離検出センサー  DS20L  カタログ  LiDARデバイスLoRaWANスマート距離検出センサー  DS20L  カタログ  LiDARデバイス
LoRaWANスマート距離検出センサー DS20L カタログ LiDARデバイス
 
業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)
業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)
業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)
 

“Design and Implementation of Generics for the .NET Common Language Runtime”他の紹介@PLDIr#5

  • 2. Citation Count: 43 Design and Implementation of Generics for the .NET Common Language Runtime Andrew Kennedy (MSR), Don Syme (MSR)
  • 3. 背景 • JVMや当時のCLRは(パラメトリック)多相 =Genericsをサポートしてない • なので、多相をコンパイルしようとすると、 ⾊々問題が…… – プリミティブ型によるインスタンス化の禁⽌ (GJ, NextGenのerasure変換) – “raw type” casting semantics (GJ) – 分割コンパイル出来ない (MLj) – 複雑なコンパイル⽅法 (NextGen) – プリミティブ型でインスタンス化したときのパ フォーマンスの問題 (PolyJ, Pizza) • なので、ちゃんとCLRレベルで実装しましょう
  • 4. Objectベースのスタック class Stack { public object Pop() { private object[] store; return store[--size]; } private int size; public Stack() { store = new object[10]; public static void Main() { size=0; Stack x = new Stack(); } x.Push(17); // boxing Console.WriteLine(x.Pop() == void Push(object item) { 17) if (size >= store.Size) { } object[] tmp = new object[size*2]; } Array.Copy(store, tmp, size); store = tmp; } store[size++] = x; }
  • 5. Generic C# のスタック class Stack<T> { public T Pop() { private T[] store; return store[--size]; } private int size; public Stack() { store = new T[10]; size=0; public static void Main() { } Stack x = new Stack<int>(); x.Push(17); Console.WriteLine(x.Pop() == void Push(T item) { 17) if (size >= store.Size) { } T[] tmp = new T[size*2]; } Array.Copy<T>(store, tmp, size); store = tmp; } store[size++] = x; }
  • 6. Design Choice • クラス、インターフェース、構造体、メ ソッドはすべて型によるパラメータ化可 能 • 厳密な実⾏時型: – e.g. List<string> と List<object> は区別 • インスタンス化は無制限にできる – e.g. List<int>, List<double>, … • F-bounded polymorphism
  • 7. Design Choice (2) • インスタンス化されたクラスやインター フェースを継承可能 • 多相再帰(Polymorphic recursion)もOK – 多相的なクラスのメソッドは、異なる型でイ ンスタンス化された⾃分⾃⾝を呼び出せる – 多相的なメソッドも、異なる型でインスタン ス化された⾃分⾃⾝を呼び出せる • 多相的な仮想関数もOK
  • 8. Design Choice (3) • 通常のクラスベースの⾔語はカバー • それ以外の⾊々な⾔語では、サポートで きなかったものも…… – Haskellの⾼階型と種 (e.g. List : *→*) – ML系⾔語のモジュールの、⾼階型を使ったエ ンコーディング – HaksellとMercuryの型クラス – Eiffelの、型構築⼦の型安全でない共変性 – C++のtemplateも完全にはサポートしない
  • 9. 実装 • 伝統的なコンパイル・リンク・実⾏とい うモデルに囚われず、CLRの動的ローディ ングや実⾏時コード⽣成を活⽤ • ポイント – 実⾏時にコードを特化 (JIT type specialization) – コードと表現は可能な限り共有 – ボックス化しない – 実⾏時型の効率的なサポート
  • 10. ILの拡張 オブジェクトベースのスタック 多相的なスタック .class Stack { .class Stack<T> { .field private class System.Object[] .field private !0[] store store .field private int32 size .field private int32 size .method public void .ctor() { .method public void .ctor() { ldarg.0 ldarg.0 call void System.Object::.ctor() call void System.Object::.ctor() ldarg.0 ldarg.0 ldc.i4 10 ldc.i4 10 newarr System.Object newarr !0 stfld class System.Object[] stfld !0[] Stack<!0>::store Stack::store ldarg.0 ldarg.0 ldc.i4 0 ldc.i4 0 stfld int32 Stack::size stfld int32 Stack<!0>::size ret ret } }
  • 11. ILの拡張 オブジェクトベースのスタック 多相的なスタック .class Stack { .class Stack<T> { .field private class System.Object[] .field private !0[] store store .field private int32 size .field private int32 size .method public void .ctor() { .method public void .ctor() { ldarg.0 ldarg.0 call void System.Object::.ctor() call void System.Object::.ctor() ldarg.0 ldarg.0 ldc.i4 10 ldc.i4 10 newarr System.Object newarr !0 stfld class System.Object[] stfld !0[] Stack<!0>::store Stack::store ldarg.0 ldarg.0 ldc.i4 0 ldc.i4 0 stfld 型パラメータ情報の追加 int32 Stack::size stfld int32 Stack<!0>::size ret ret } } ldargなどの命令は、もともと複数の型に適用できる (JITが型を自動的に決定して型に応じたコード生成) ので、そのまま。
  • 12. ILの拡張 .method public void Push(class .method public void Push(!0 x) { System.Object x) { .maxstack 4 .maxstack 4 .locals (class System.Object[], int32) .locals (!0[], int32) … … ldarg.0 ldarg.0 ldfld class System.Object[] Stack::store ldfld !0[] Stack<!0>::store ldarg.0 ldarg.0 dup dup ldfld int32 Stack::size ldfld int32 Stack<!0>::size dup dup stloc.1 stloc.1 ldc.i4 1 ldc.i4 1 add add stfld int32 Stack::size stfld int32 Stack<!0>::size ldloc.1 ldloc.1 ldarg.1 ldarg.1 stelem.ref stelem.any !0 ret ret } } stelemは型に依存する命令なので、新たにstelem.anyを追加
  • 13. ILの拡張 .method public static void Main() { .method public static void Main() { .entrypoint .entrypoint .maxstack 3 .maxstack 3 .locals (class Stack) .locals (class Stack<int32>) newobj void Stack::.ctor() newobj void Stack<int32> ::.ctor() stloc.0 stloc.0 ldloc.0 ldloc.0 ldc.i4 17 ldc.i4 17 box System.Int32 call instance void Stack::Push(class call instance void Stack<int32>::Push(!0) System.Object) ldloc.0 ldloc.0 call instance !0 Stack<int32>::Pop() call instance class System.Object Stack::Pop() unbox System.Int32 ldind.i4 ldc.i4 17 ldc.i4 17 ceq ceq call void System.Console::WriteLine(bool) call void System.Console::WriteLine(bool) ret ret } } box/unboxが不要に
  • 14. ILの拡張: 禁⽌されていること • .class Foo<T> extends !0 • !0::.ctor() • !0::.myMethod() • クラスの型パラメータの静的変数での使 ⽤ • パラメタ化されたインターフェースをイ ンスタンス化したものを、複数回実装す ること
  • 15. ランタイム: データ表現とコード • 伝統的には、データ表現とコードを、 – 型パラメータ毎に特化、 – もしくは共有 • CLRではこれらをミックス出来る – あるインスタンス化が必要になった時点で、互換性 のあるインスタンス化がすでにされているか探す – なかったら新たに⽣成 – ⽣成されたvtableのエントリは、呼ばれたときに実 際にコード⽣成するスタブ • polymorphic recursionなどに対応するため: e.g. class C<T> { void m() { ... new C<C<T>>() ... } }
  • 16. ランタイム: 型情報 • 厳密な型情報はvtable内に持つ (vtable を type handle として使う) Dict<int,object> Dict<bool,string>
  • 17. ランタイム: 型パラメタへのアクセス class C { virtual void m(int) { ... } } class D<T> : C { void p(Object x) { ... (Set<T[]>) x ... } override void m(int) { ... new List<T> ... } } class E<U> : D<Tree<U>> { // m inherited void q() { ... y is U[] ... } } 毎回、型情報をlookupするのは大変 なので、dictionaryをlazyに生成して……
  • 18. ランタイム: Eのvtable内のdictionary class C { virtual void class E<U> : m(int) { ... } } D<Tree<U>> { class D<T> : C { // m inherited void p(Object x) { ... void q() { ... y is (Set<T[]>) x ... } U[] ... } override void m(int) } { ... new List<T> ... } }
  • 19. パフォーマンス S := new stack c := constant for m ∈ 1…10000 do S.push(c) m times S.pop() m times
  • 20. パフォーマンス2 • 実⾏時の型操作のオーバーヘッドを測定 • こんなやつ? – class C<T> { Main() { for … { new Dict<T[], List<T>>() } }}
  • 21. Citation Count: 92 Automatic Predicate Abstraction of C Programs Thomas Ball (MSR), Rupak Majumdar (U.C.Berkeley), Todd Millstein (Univ. of Washinton), Sriram K. Rajamani (MSR)
  • 22. • ソフトウェアのモデル検査では抽象化が 重要 – 状態爆発を避けるため – そもそも無限状態の場合には、有限状態にす る必要がある • この論⽂はSLAMが抽象化に使っている C2BPの詳しい話 – CプログラムPと述語の集合Eから、 述語抽象化した Boolean program B(P,E) を ⽣成
  • 23. B(P, E) • 変数はEの要素 • 元のプログラムの保守的な抽象化 – 元のプログラムでfeasibleなパスは、抽象化 後もfeasible
  • 24. 例: 元のCプログラム P typedef struct cell { if (curr == *l) { int val; *l = nextCurr; struct cell* next; } } *list; curr->next = newl; L: newl = curr; list partition(list *l, int v) { } else { list curr, prev, newl, nextCurr; prev = curr; curr = *l; } prev = NULL; curr = nextCurr; newl = NULL; } while (curr != NULL) { return newl; nextCurr = curr->next; } if (curr->val > v) { if (prev != NULL) { prev->next = nextCurr; }
  • 25. 例: 述語の集合E • curr == NULL • prev == NULL • curr->val > v • prev->val > v
  • 26. 例: BP(P, E) void partition() { if (*) { bool {curr==NULL}, {prev==NULL}; skip; bool {curr->val>v}, {prev->val>v}; } {curr==NULL} = unknown(); skip; {curr->val>v} = unknown(); L: skip; {prev==NULL} = true; } else { {prev->val>v} = unknown(); assume(!{curr->val>v}); skip; {prev==NULL} = {curr==NULL}; while(*) { {prev->val>v} = {curr->val>v}; assume(!{curr==NULL}); } skip; {curr==NULL} = unknown(); if (*) { {curr->val>v} = unknown(); assume({curr->val>v}); } if (*) { assume({curr==NULL}); assume(!{prev==NULL}); } skip; }
  • 27. • ⾃明な話だと思ってたけど、⾊々⼯夫が 必要 • 元のプログラムのコードに対応して、ど の述語の真偽がどう変化するかの判定 – 最終的には定理証明器を駆動 • 定理証明器は重いので、⼯夫して呼ぶ回数を削減 – ポインタ解析による精度の改善 • Our implementation uses Das's points-to algorithm [12] to obtain flow-insensitive, context-insensitive may-alias information.
  • 28. Citation Count: 27 The Pointer Assertion Logic Engine Anders Møller & Michael I. Schwartzbach (University of Aarhus, Denmark)
  • 29. 概要 • ヒープの構造に関する性質を、Pointer Assertion Logic というロジックで、アノ テーション(事前条件・事後条件・不変条 件) • プログラムとアノテーションを、 WS2S(weak monadic second-order theory of 2 successors)に変換して、 MONAで検証する、 – 条件を満たさない場合には、反例を出⼒
  • 30. 具体例 type List = {data next:List;} proc reverse(data list:List):List set R:List; pred roots(pointer x,y:List, set [roots(list,null,R)] R:List) { = allpos p of List: data res:List; p in R pointer temp:List; <=> res = null; x<next*>p | y<next*>p; while [roots(list,res,R)] (list!=null) { temp = list.next; list.next = res; res = list; list = temp; } return res; } [roots(return,null,R)]
  • 31. 性能 ※ GTA = Guided Tree Automata
  • 32. • PAL(Pointer Assertion Logic)は、表現⼒ と検証コストの良いバランス • 主なターゲットはデータ構造 • アノテーションを書くのは⼤変だけど、 データ構造の設計は元々invariantを注意 深く考える必要があるから、それを考え れば⼤したことない