JP4806060B2 - コンパイラ・プログラム、コンパイル方法及びコンピュータ・システム - Google Patents

コンパイラ・プログラム、コンパイル方法及びコンピュータ・システム Download PDF

Info

Publication number
JP4806060B2
JP4806060B2 JP2009212881A JP2009212881A JP4806060B2 JP 4806060 B2 JP4806060 B2 JP 4806060B2 JP 2009212881 A JP2009212881 A JP 2009212881A JP 2009212881 A JP2009212881 A JP 2009212881A JP 4806060 B2 JP4806060 B2 JP 4806060B2
Authority
JP
Japan
Prior art keywords
code
delay
source code
computer
generating
Prior art date
Legal status (The legal status is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the status listed.)
Expired - Fee Related
Application number
JP2009212881A
Other languages
English (en)
Other versions
JP2011065220A (ja
Inventor
晶彦 戸澤
清久仁 河内谷
道昭 立堀
民也 小野寺
Current Assignee (The listed assignees may be inaccurate. Google has not performed a legal analysis and makes no representation or warranty as to the accuracy of the list.)
International Business Machines Corp
Original Assignee
International Business Machines Corp
Priority date (The priority date is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the date listed.)
Filing date
Publication date
Application filed by International Business Machines Corp filed Critical International Business Machines Corp
Priority to JP2009212881A priority Critical patent/JP4806060B2/ja
Priority to US12/881,667 priority patent/US20110067018A1/en
Publication of JP2011065220A publication Critical patent/JP2011065220A/ja
Application granted granted Critical
Publication of JP4806060B2 publication Critical patent/JP4806060B2/ja
Expired - Fee Related legal-status Critical Current
Anticipated expiration legal-status Critical

Links

Images

Classifications

    • GPHYSICS
    • G06COMPUTING; CALCULATING OR COUNTING
    • G06FELECTRIC DIGITAL DATA PROCESSING
    • G06F8/00Arrangements for software engineering
    • G06F8/40Transformation of program code
    • G06F8/41Compilation
    • G06F8/44Encoding
    • G06F8/443Optimisation
    • G06F8/4441Reducing the execution time required by the program code
    • G06F8/4443Inlining
    • GPHYSICS
    • G06COMPUTING; CALCULATING OR COUNTING
    • G06FELECTRIC DIGITAL DATA PROCESSING
    • G06F8/00Arrangements for software engineering
    • G06F8/40Transformation of program code
    • G06F8/41Compilation
    • G06F8/43Checking; Contextual analysis
    • G06F8/433Dependency analysis; Data or control flow analysis

Landscapes

  • Engineering & Computer Science (AREA)
  • General Engineering & Computer Science (AREA)
  • Theoretical Computer Science (AREA)
  • Software Systems (AREA)
  • Physics & Mathematics (AREA)
  • General Physics & Mathematics (AREA)
  • Devices For Executing Special Programs (AREA)

Description

この発明は、コンパイラ技術に関し、特に、プログラムの実行時の性能を向上させるための技術に関する。
近年PHP、Perl、Ruby、Javascript(R)などの動的スクリプティング言語が主流になってきている。これらの言語は静的な型を持たず、そのかわり動的に、また緩くモジュール間を結合する仕組みを特徴とする。例えば、PHPのアプリケーションではモジュール間のデータのやりとりがJava(R)のようなクラス/オブジェクトベースではなく、連想配列(ハッシュテーブル)を用いたものになっていることが多い。これは型ではなく名前でモジュール間のインタフェースを決めるということであり、このことは、アプリケーションの自由度を高くするが、同時にデータのやりとりのコストも高い。そのため、効果的なコンパイル時の最適化手法が大切になってきている。例えば、米国SugarCRM社のCRMソフトウェアである、PHPのSugarCRMでのベンチマークの結果では連想配列のランタイム処理が合計で約30%を占めていた。また、PHPではグローバル変数やオブジェクトのフィールドなど、ほぼ全てのものが連想配列で表現されている。
このような問題を解くのに、部分評価その他のデータ構造を除去するような最適化を使えるとよいが、そのためには、連想配列の生成サイトと使用サイトの間のデータフローが明らかになっている必要がある。しかし、大きなアプリケーションでは、連想配列の生成サイトと使用サイトが離れているため、その間の大域的なデータフローを、解析で得ることは難しい。また、動的なモジュール結合自体がデータフローをわかりにくくすることなどが問題をさらに難しくしている。
Java(R)のようなオブジェクト指向系言語も、より以前の言語に比べクラスベース抽象のコストと呼ばれる実行時コストがかかる。しかも、オブジェクト指向系言語の継承や仮想メソッドなどが、プログラムのデータフローを静的にわかりにくくするため、静的な最適化手法だけでこのようなコストを取り除くのは難しい。そこで、オブジェクト指向系言語の世界では今まで、多相インラインキャッシュやオブジェクト・プロファイリングなどの動的なフィードバック駆動の最適化技術が発展してきた。これらの技術のアイディアは、プログラムの大域的なデータフローを実行時のフィードバックに基づいて推測することで、最適化を可能にするというものである。例えば、オブジェクトのクラス情報の大域的なデータフローを推測すれば、推測されたクラスの仮想メソッドをインライン展開してその後続コードと組み合わせて最適化することができた。しかし、このフィードバック駆動の最適化技術を、動的スクリプティング言語の連想配列などの問題に適用するのは自明ではない。なぜなら、たとえ大域的なデータフローが推測できたとしても、その後で連想配列の生成サイトのコードと使用サイトのコードを組み合わせて最適化する手法が明らかでないためである。
別の背景として、JavaのWebSphere(R) Application ServerやPHPのSugarCRMのような大きなアプリケーションで遅延評価が効果的だという知見がある。特に、PHPのようなリクエスト毎にプログラムが一回走るようなステートレスな実行モデルでは、リクエスト毎にアプリケーションの初期化のロジックが走る。この初期化で生成されたデータは実はごく一部しか使われない可能性があり、遅延評価の効果が期待される。しかし、このような遅延評価を、JavaやPHPのような副作用のある命令型言語について、体系的にコンパイラ・レベルで行う手法はあまり実用化されてこなかった。原因のひとつには、遅延された評価が最後まで強制されなければコストの削減になるが、評価が強制された場合は遅延しない場合よりも高いコストがかかるということが考えられる。
特開平10−11299号公報は、前方参照を指示する命令文がどのような構文解析の要素であるかにかかわらず、該命令文を含むソースプログラムを構文解析し、効率良くコンパイルすることができるようにするために、ソースプログラムに含まれるトークン列からトークンを順次読み込むトークン選択読み込み部と、前記トークン選択読み込み部が読み込んだトークンが、予め前記トークン列の任意の区間に設定した遅延評価区間内のトークンである場合には、該トークンを遅延評価トークン記憶テーブルに記憶する遅延評価部分記憶部と、前記遅延評価部分記憶部により前記遅延評価トークン記憶テーブルに記憶されたトークンを順次読み込み、オブジェクト化してオブジェクトファイルへ出力する評価処理部とから構成されるコンパイル装置を開示する。
しかし、このようなコンパイラにおける遅延評価技法は、評価が強制された場合は遅延しない場合よりも高いコストがかかるという問題に効果的な解法を与えるものではない。
特開平10−11299号公報
この発明の目的は、JavaやPHPのような副作用のある命令型言語に遅延評価を適用して実行コードの性能を向上させることが可能なコンパイラ技法を提供することにある。
本発明では、上記目的を達成するためになされたものであり、PHPなどの比較的高いデータ操作の実行時コストを持つ言語と連想配列などによる緩いモジュール間の結合をもつアプリケーションを対象に、その大きな実行時コストの問題を、フィードバックに基づく大域的コード移動という手法によって解決する。
この手法は、
1.高い実行時コストをもち、かつ安全に移動することが可能なデータの生成サイトのコード・フラグメントを解析によって判定し、この部分に対して評価を遅延するコードを生成する(レベル1コンパイル)。
2.ステップ1で生成された遅延が高頻度で強制される場所(データの使用サイト)を実行時フィードバックに基づいて推定し、この遅延をこの使用サイトのコードにインライン展開することでコード移動を実現し、部分評価などの強力な最適化を可能にする(レベル2コンパイル)。
という二つのコンパイルステップで実現される。
ステップ1の遅延生成は、一時的にクロージャ作成のための実行時コストを増やす。ただし、もし遅延されたコードが作る値が以降でまったく必要にならない場合は、通常の遅延評価の技術と同じようにそのコードの評価のコストが省かれ、これにより結果的に利得が得られる。すなわち、ある程度高いコストの処理を選択的に遅延することで、遅延生成自体のコストが遅延なしの評価のコストと比べると小さくなるようにすればよい。
本発明による特徴的な効果が得られるのは、ステップ1で作られた遅延が強制される場合である。この場合は、ステップ2が、大域的コード移動による最適化を行い新しい種類のコスト削減を試みる。ここで、慣用的なコンパイラ技術では、コード移動といえば通常はコンパイル単位内での局所的な移動だけであり、また、インライン展開も元から存在している関数やメソッドについてしか行うことができなかった。しかし、本発明のステップ1は、積極的に高いコストをもつ移動可能なコードを発見して遅延を生成する。ここで作られた遅延は、関数クロージャ(オブジェクト)と同じように扱えるので、プロファイリングによってそれが必要になりそうな使用サイトを推定し、そのコードにガードつきでインライン展開することができる。これによってコンパイル単位を越えた大域的なコード移動が実現される。
こうして、大域的なコード移動 (遅延コードのインライン展開) を行うと、より強力な最適化の機会が得られる。例えば、連想配列の生成サイトのコードを移動した場合には部分評価の手法を使って、連想配列の生成およびストア/ロード操作を取り除くことができる。PHPでは、連想配列処理のコストが非常に高いので、この部分評価による利得が、多くのケースで遅延生成・クロージャ操作のコストを上回る.また本発明は、連想配列処理以外でも、後で発明を実施するための形態の節で説明するが、ファイルからの非常に長い文字列の生成などの他の高コストの処理に対しても適用することができる。一例として、文字列の使用サイトのコードが文字列のI/O出力であった場合、この処理をsendfileによるDMA処理(zero-copyデータ転送)に書き換える最適化で、文字列生成のコストを取り除くことができる。
例えば、以下のPHPのコードを例にとる。PHPでは、トップレベルで定義された変数はグローバル変数の扱いになることに注意する。
<?php
$user = "akihiko"; $date = date(DATE_RFC822);
start();
?>
この start() からのアプリケーションのどこかで、login() が呼ばれるとする。
function login() {
global $user, $date;
echo "user $user logined at $date";
}
まずレベル1コンパイラは、コードの中の遅延可能な箇所を探し出し、これを遅延する。ここでは、コンパイラが以下のような関数型の中間言語 (A正規形) を作ることとするが、 遅延されたコードを表現することができるなら、SSAなど他の中間言語でもかまわない。 なお、A正規形については、C. Flanagan, A. Sabry, B. F. Duba, and M.
Felleisen. The essence of compiling with continuations. In Proceedings of
the ACM SIGPLAN ’93 Conference on Programming Language Design and
Implementation, pages 237-247, 1993. In ACM SIGPLAN Notices, 28(6), June 1993などを参照されたい。また、SSAとは、静的単一代入形式(Static Simple Assignment)のことであり、変数の定義が字面上唯一になるように添字をつけた中間表現形式であり、コンパイラにおけるデータフロー解析や最適化を見通しよく行うのに適した形式のことである。
let _0 = date(DATE_RFC822) in
let _ = delay_global(fun _ ->
let _ = upd_global "user" "akihiko" in
upd_global "date" _0)
in
start()
ここで、delay_global操作は、global変数に対する更新処理を遅延するものであり、(fun _ -> …) で表現される遅延された処理は実行されることなく実行系に登録される。この遅延処理はクロージャc = (fn, record)で表現されていて、fnは関数の実体をあらわし、 遅延できなかった値たとえば _0は、クロージャレコードrecord中に捕獲されている。fnはコンパイル時定数となり、 一方 recordは、実行時に作られることに注意する。各クロージャは、インタプリタで処理される形でもコンパイルした形でもよいが、後の部分評価のために(fun _ -> …) という中間言語のコード断片が付随しているものとする。
実行時には login() の場所でglobal変数に対する読み込みを行う。
let login _ =
let _0 = load_global "user" in
let _1 = load_global "date" in
echo ("user ". _0."logined at"._1)
もし、start()からlogin()までの間にglobal変数の定義がなければ、load_globalの実行時に先ほど遅延されたクロージャc = (fn,record) が実行系から取り出され処理される。実行時プロファイラは、クロージャcがこのlogin()の実行時に強制されたことをプロファイルしておく。
レベル2コンパイラはまず、プロファイル情報を元に遅延されたクロージャ中のコード fnをlogin() 関数の中にインラインする。このとき実際に実行されるコードfn’がfnと等しいかどうかのガードを同時に生成し、もしガードにヒットすれば、fnに相当するインラインしたコードが実行されるようにする。
let login_fast _ =
let (fn’, record) = delayed_global() in
if (fn’ == fn) then
let _ = upd_global "user" "akihiko" in
let _ = upd_global "date" record#_0 in
let _0 = load_global "user" in
let _1 = load_global "date" in
echo("user" . _0 . "logined at" ._1)
else login()
ただし、record#_0 はレコード中の_0フィールドからの読みだしを意味するとする。 最終的には部分評価器が、以下のようにコードを簡単化する。
let login_fast _ =
let (fn’, record) = delayed_global () in
if (fn’ == fn) then
echo("user akihiko logined at" . record#_0)
else login()
すなわち、定数畳み込みや中間データ構造除去の効果を大域的なデータフローの解析なしで得ることができるようになった。また遅延したグローバル変数テーブルの更新処理をこの場所では省くことができた。もし、このlogin()以降にもうグローバル変数の更新がないなら、グローバル変数テーブル生成のコストを完全に除去することができたことになる。
この発明によれば、高い実行時コストをもち、かつ安全に移動することが可能なデータの生成サイトのコードフラグメントを解析によって判定し、この部分に対して評価を遅延するコードを生成するステップと、そのステップで生成された遅延が高頻度で強制される場所(データの使用サイト)を実行時フィードバックに基づいて推定し、この遅延をこの使用サイトのコードにインライン展開することでコード移動を実現するステップを実行することによって、JavaやPHPのような副作用のある命令型言語においても、部分評価などの強力な最適化を可能にするという効果が提供される。
本発明を実行するためのハードウェアのブロック図である。 本発明で使用される機能のブロック図である。 中間言語と、実行系及びプロファイル情報の関係を示す図である。 本発明に係るコンパイル処理のフローチャートを示す図である。 依存解析によって生成されるデータ依存グラフと、後支配木の例を示す図である。 副作用の種別を考えた場合の、データ依存グラフと、後支配木の例を示す図である。
以下、図面に基づき、この発明の実施例を説明する。特に断わらない限り、同一の参照番号は、図面を通して、同一の対象を指すものとする。尚、以下で説明するのは、本発明の一実施形態であり、この発明を、この実施例で説明する内容に限定する意図はないことを理解されたい。
図1を参照すると、本発明の一実施例に係るシステム構成及び処理を実現するためのコンピュータ・ハードウェアのブロック図が示されている。図1において、システム・バス102には、CPU104と、主記憶(RAM)106と、ハードディスク・ドライブ(HDD)108と、キーボード110と、マウス112と、ディスプレイ114が接続されている。CPU104は、これには限定されないが、好適には、32ビットまたは64ビットのアーキテクチャに基づくCPUであり、例えば、インテル社のPentium(商標) 4、Core(商標)2 Duo、Core(商標)2 Quad、Xeon(商標)、AMD社のAthlon(商標)、Turion(商標)などを使用することができる。主記憶106は、好適には、2GB以上の容量をもつものである。ハードディスク・ドライブ108は、例えば、320GB以上の容量をもつものである。
ハードディスク・ドライブ108には、個々に図示しないが、オペレーティング・システムが、予め格納されている。オペレーティング・システムは、Linux(商標)、マイクロソフト社のWindows Vista(商標)、Windows XP(商標)、Windows(商標)2000、アップルコンピュータのMac OS(商標)などの、CPU104に適合する任意のものでよい。
ハードディスク・ドライブ108にはまた、本発明に係るプログラム言語処理系その他のプログラムも格納される。これには限定されないが、この実施例では、プログラム言語として、PHPを想定する。
なお、PHPの仕様については、http://www.php.net/などを参照されたい。
ハードディスク・ドライブ108にはさらに、プログラム言語処理系でコンパイルするためのソースコードを書くためのテキスト・エディタ、及び、Eclipse(商標)などの開発環境を含んでいてもよい。
キーボード110及びマウス112は、オペレーティング・システムまたは、ハードディスク・ドライブ108から主記憶106にロードされ、ディスプレイ114に表示されたプログラム(図示しない)を起動したり、文字を打ち込んだりするために使用される。
ディスプレイ114は、好適には、液晶ディスプレイであり、例えば、XGA(1024×768の解像度)、またはUXGA(1600×1200の解像度)などの任意の解像度のものを使用することができる。ディスプレイ114は、本発明に係るコンパイラの処理結果やエラーなどを表示するために使用される。
図2は、本発明に係る機能の概要ブロック図である。図2において、ソース・プログラム202は、例えば、PHPで書かれたソース・プログラムであり、ハードディスク・ドライブ108に保存されている。
変換モジュール204は、ハードディスク・ドライブ108に保存され、オペレーティング・システムの働きによって主記憶106にロードされ、ソース・プログラム202をパースして、A正規形変換、またはSSA変換を施し、中間言語を生成する機能を有する。生成された中間言語は、主記憶106に配置されるか、またはハードディスク・ドライブ108に保存される。
コンパイラ206は、本発明に従いコンパイル処理を行うものであり、ハードディスク・ドライブ108に保存され、オペレーティング・システムの働きによって主記憶106にロードされ、変換モジュール204によって生成された中間言語を、実行コードに変換する。特にコンパイラ206は、後で詳述するが、レベル1コンパイラと、レベル2コンパイラからなる。
コンパイラ206によって生成された実行コードは、好適にはハードディスク・ドライブ108に一旦保存され、オペレーティング・システムによって用意された実行系208において実行される。
コンパイラ206によって生成された実行コードが実行系208において実行されたときに、実行時プロファイラ(図示しない)が、プロファイル情報210を生成する。実行時プロファイラは、以下では単にプロファイラとも呼ぶが、コンパイラ206によって生成されるコードの機能の一部と考えることができる。プロファイル情報210は、好適にはハードディスク・ドライブ108に書き出されるが、主記憶106に配置してもよい。
本発明によれば、こうして生成されたプロファイル情報210は、コンパイラ206によって利用される。
図3は、生成された中間言語レベルのブロック図である。図3において、ソース・プログラム202は、変換モジュール204によってパース及びSSA変換され(または、AA正規形変換され)、レベル0中間言語302に変換される。
こうして生成されたレベル0中間言語302は、コンパイラ206のレベル1コンパイラによって、処理の遅延及びプロファイル操作を伴ったレベル1中間言語304が生成される。
レベル1中間言語304を実行コードに変換して実行系208で走らせると、遅延の強制に関するプロファイル情報210が収集される。
ある程度の回数のコードの実行の後に、高頻度で特定の遅延コードが強制されると分かる場所が見つかった場合、レベル2コンパイラが発動して、部分評価により、この箇所を含むコードを最適化し、より高速なレベル2中間言語306に置き換える。
図4は、コンパイラ206の処理ステップをより詳細に説明するためのフローチャートである。前述のように、コンパイラ206は、レベル1およびレベル2の2つの最適化レベルを持ち、実行時プロファイラを持つ実行系208と協働する。レベル1コンパイラは、逐次評価型の言語のコード解析を行い、 その中で評価が遅延できるコードフラグメントを特定し、この部分に対して遅延クロージャの生成を行う。
図4において、ステップ402では、レベル1コンパイラは、コードの解析においてデータおよび副作用の依存グラフを生成し、その後支配木を元に遅延できるプログラムの部分を特定する。
ステップ404では、レベル1コンパイラは、データ構造の更新を遅延していいかどうかの判断がエイリアスの可能性のため難しい場合、データ構造内部のエイリアスの可能性を調べ、安全な場合のみに遅延を行うようなコードを生成する。
ステップ406では、レベル1コンパイラが生成したコードが作る遅延クロージャは、実行時に必要な箇所で強制されるが、実行時プロファイラはこの遅延がどこで強制されたかをプロファイルする。
ステップ408では、レベル2コンパイラは、プロファイルによって高頻度で強制されると判定された遅延クロージャのコードをその強制される箇所にインラインすることで移動し、さらに部分評価を適用して高速なコードを生成する。
ステップ410では、レベル2コンパイラは、配列などのデータ構造の内部を陽に表現できるような中間言語を使うことで、中間データ構造を部分評価で除去する。 このコンパイル時データ構造の形は実行時データ構造のヒープ内での形と同じ必要はなく、データ構造への操作の意味だけを保存する。
次に、個々のステップの具体的処理について説明する。
<レベル1コンパイラ>
ここでは、 A正規形やCPSなどの各関数定義の実体 (制御グラフの基本ブロックに対応している) について、 データの依存解析をおこない、 遅延できる箇所を特定する方法を示す。例えば、以下のようなコードを考える。今回は $x, $y, $z などはローカル変数であるとし、最初は I/Oの遅延については考えないとする。
0: let $x = 1 in
1: let $y = 2 in
2: let $z = $x + $y in
3: let _ = echo $x in (* 副作用 *)
4: let _ = callfunc "foo" $z in (* 副作用 *)
5: () (* 副作用 = この関数の継続で副作用が起こるため *)
依存解析は、図5(a)のグラフを生成し、 その後支配木は、図5(b)のようである。この処理は、図4のステップ402に対応する。
この左のグラフで枝があるところはデータの依存関係を示している、例えば、2 → 4の枝はcallfunc(PHP関数呼び出し)は引数の$zに依存することを表現する。また3 → 4の枝は関数呼び出しの持つ大域的な副作用の間の依存関係として生成される。遅延コードの生成はこのグラフの後支配木を下から再帰的に見ていくことで実現できる。いま、echoやcallfuncは遅延せず、またそれ以外のところは遅延できるかぎり遅延する。例えば、4:let_ = callfunc "foo" $z in[]を処理するときは、その後支配木の親0,2,3について0,2,3の間のデータ依存の関係を保持するようにこの順で上からコード生成をする。また例えば、ノード2を処理するときは、まずその親1についてのコード let $y = 2 in []を作り、続いてlet $y = 2 in let $z = $x + $y in []を作る。最後にこのノード2は副作用がないため、これを遅延したコード2’を生成する。ノード3は副作用があるので遅延しない。ここでの処理は、図4のステップ404に関連する。結果のコードは以下のようになる。
0’: let $x = delay (fun _ ->
0: 1) in
2’: let $z = delay ( fun _ ->
1: let $y = 2 in
2: $x + $y)
3: let _ = echo $x in
4: let _ = callfunc "foo" $z in
5: ()
ここで、現実には、遅延可能であるものの全てを遅延する必要はない。何を遅延するかは、コストの判断を行って決める。例えば、echoのように値を即座にしかも必ず使うことがわかっているものについて、その使う値を遅延する価値はないので 0’の遅延は不要である。 もしechoがない場合に0’のような定数を遅延するどうかは判断が分かれる。 もし定数が連想配列やデータ構造であるならば、遅延してもよい。なぜなら、後の部分評価の仕組みを使って定数データへのアクセスのコストを省略することができる可能性が高いからである。あるいは、このような定数は遅延しないとし、定数データ構造からの読み出しとクロージャの強制とは別個にプロファイルしてから、レベル2コンパイラにフィードバックしてもよい。$z = $x + $y の計算などは、PHPではある程度コストが高いので遅延してもよい。もしこれが連想配列の操作などであれば、さらにコストが高いので遅延する。
<データ構造の更新を遅延する場合の注意点>
PHPの場合、連想配列のデータ構造は、デフォルトではエイリアスを含まない。すなわち
$x = null;
$x["key"] = "hello";
$y = $x;
$y["key"] = "world";
echo $x["key"]; // hello
この2行目の代入は、Javaのオブジェクトの場合のようなエイリアス生成ではなく値のコピーとなる。本発明のコンパイラでは、PHPは連想配列を不変の値として扱っていると考え、上のプログラムを下のようなヒープへの副作用を考えないプログラムに変換する。
let $x = null in .
let $x = update "key" "hello" $x in
let $y = $x in
let $y = update "key" "world" $y in
echo (load "key" $x)
実行時には、このようなupdate操作は、参照カウントや解析を元に効率のよいヒープへの破壊的な操作に戻してもよい。例えば、参照カウントを使う場合には、$y = $xのところで、コンパイル時には意味を持たない実行時の参照カウント加算が入る。
問題となるのは、変数やデータ構造の中にエイリアスを生成する参照代入(=&)の操作があった場合である。例えば、$y =& $x["abc"] は、そのようなエイリアスを作る。これによって配列が不変値だという先ほどの仮定が崩れる。このようなエイリアスはupdate操作を<レベル1コンパイラ>のところで述べた手法で遅延することを考えるときに問題となる。例えば、以下のような関数を考える。
let foo $x $y =
let $x = update "abc" "def" $x in
let _ = echo $y in
bar $x
まずこのPHP関数がソースプログラム中で function foo($x, $y) {…} のように定義されており、PHPの意味論として値の深いコピーを採用するならば、$xと$yの間にエイリアスがあることはありえないので、いつでも以下のような遅延が許される(なお、値の深いコピーについては、Akihiko Tozawa, Michiaki Tatsubori, Tamiya Onodera, and Yasuhiko Minamide, Copy-on-Write in the PHP Language, In Proceedings of the 36th Annual ACM SIGPLAN - SIGACT Symposium on Principles of Programming Languages (POPL 2009), Savannah, Georgia, USA, January 21-23, 2009, pp.200-212, January, 2009. (C) ACM のPHP(d) あるいは PHP(g)を参照されたい)。
let foo $x $y =
let $x = delay (fun _ -> update "abc" "def" $x)
let _ = echo $y in
bar $x
しかし、PHPの意味論として浅いコピーを採用した場合や、PHP関数が参照渡しで function foo(&$x, &$y) {…} のように定義されている場合はこの遅延は危険である可能性がある。配列の更新が実は $y に影響するかもしれないからである。
本実施例では、この問題については以下の実行系レベルの解決策を使う。すなわち、配列$xの中にエイリアスが存在するかどうかをフラグ$x#contains_aliasで持っておき、このフラグを実行時にチェックして遅延が許されるかどうかを判断する。もしチェックに失敗したら、update操作を実際に行うパスを作る。あるいはパスはひとつのままにして、いま作った遅延を強制してしまう処理を加えてもよく、これで遅延が起きなかったのと同等のことになる。すると、コードは以下のようになる。
let foo $x $y =
let delay_ok = not $x#contains_alias in
let $x = delay (fun _ -> update "abc" "def" $x)
let $x = if delay_ok then $x else force $x in
let _ = echo $y in
bar $x
フラグ$x#contains_aliasは、$y =& $x["abc"]のような参照代入の際にセットすることができる。
PHPのオブジェクトについても、同様の検査で遅延をすることができる。注意点として, 以下のようなプログラムに<レベル1コンパイラ>のアルゴリズムを適用するときには、$o1と$o2の操作の間に依存がある可能性があるので、これはグラフの枝として追加しておく必要がある。この枝は必ず依存があることを意味するわけではないため、$o1からecho文への依存があるからといって、$o1の遅延をあきらめる必要はない。
function foo($o1, $o2) {
$o1->name = "akihiko";
$o1->address = "yamato";
echo $o2->name;
bar($o1);
}
上記プログラムは、下記のように遅延される。 ただし、本実施例のコンパイラでは、PHPのオブジェクト$o1は、フィールドを表現する連想配列$o1#filedsへのポインタ参照を持つ値として扱っている。操作<-は書き込み可能レコードの更新を表している。
let foo $o1 $o2 =
let fields = $o1#fields in
let delay_ok = not fields#contains_alias in
let fields = delay (fun _ ->
let fields = update "name" "akihiko" fields in
update "address" "yamato" fields)
in
let _= $o1#fields <- (if delay_ok then fields else force fields) in
let _ = echo (load $o2#fields "name") in
bar $o1
もし、$o1と$o2のルートがエイリアスしていれば、load処理の際に$o2#fileds配列の更新が強制されるので安全である。オブジェクトの更新を遅延するとまず、配列の場合と同等のコストが省ける。PHPは型無し言語であるため、その処理系ではフィールド操作が連想配列の操作(ハッシュテーブル操作)で表現されているためである。さらに、PHPでは、フィールドのデフォルト値をクラス宣言中に書くことができる。処理系によっては、これらの値はコンパイル時定数の配列に保存し、フィールド読み込みの際にその定数配列をそのまま使う。この場合、オブジェクトに書き込みが行われる時点ではじめてこの配列の各オブジェクト用の複製が作られるが、この複製のコストはかなり大きくなる。もし次に述べる部分評価のテクニックを使いオブジェクトへの書き込みがプログラム終了まで遅延できればこのコストを除去することができる。
<副作用の種別を考えたより精緻な遅延の生成>
<レベル1コンパイラ>の節で説明した手法でのデータ依存グラフ生成の際に, 副作用間の詳細なデータ依存関係を明らかにするようにするとより精緻な遅延が可能になる。これにより、例えば前述のように、グローバルテーブル操作が副作用で表現されている場合でも、操作を遅延することができるようになる。
副作用の種別を以下のように考える。
- GW: グローバル変数への書き込み
- GR: グローバル変数の読み込み
- IO: IO 処理
- T: 最大の副作用
例えば、前述の例のコードには次のように各let文をラベルづけして副作用を指定できる。
0: letIO _0 = date(DATE_RFC822) in
1: letGW _ = upd_global "user" "akihiko" in
2: letGW _ =upd_global "date" _0 in
3: letT _ = start () in
4: ()
いま、IOとGWの間には干渉がないので、枝は作らない。GW どうし、および、Tから任意の直近の副作用への依存関係を追加して図6(a)に示すグラフと、図6(b)に示す後支配木が得られる。このためには例えば、上からプログラムを見ていき、今までみた副作用の履歴から依存するノードを判断して依存関係を追加すればよい。
GR, GW: 直近のTあるいはGWのうち近い方への枝を追加する。
IO: 直近のTあるいはIOのうち近い方への枝を追加する。
T: 直近がTならば枝を追加する。Tより近いGWおよびIOについては双方への依存を追加する。
あとは<レベル1コンパイラ>の節で示したのと同様に遅延生成を追加することができる。
let _0 = date(DATE_RFC822) in
let _ = delay_global (fun _ ->
let _ = upd_global "user" "akihiko" in
upd_global "date"_0)
in
start ()
ただし、この場合の注意点として、グローバル変数テーブルの遅延クロージャを登録するためにはdelay_globalという特殊な操作を使う必要がある。実行系は、このような副作用を含む遅延クロージャについては各副作用について常にもっとも最後に登録されたクロージャを覚えておき、さらに、delay_globalが新しいクロージャを登録する際にはこのクロージャからもっとも最後に登録されたクロージャへのリンクを覚えておく必要がある。クロージャが強制されるときには、このリンクを辿って、過去にさかのぼってリンク上のすべてのクロージャを強制する。
グローバル変数については、各変数の更新について別々に遅延を考えることもできる。この場合にはGW/GRのアノテーションを各変数に関するより詳細なものにする必要がある。
<プロファイラ>
プロファイラは、遅延がどこで強制されたかをプロファイルする。以下で述べる処理は、図4のステップ406に対応する。いま、データの遅延の強制は通常データの読みこみ (例えばecho文)や、データへの書き込み (連想配列のupdate操作) などのためにライブラリ内で起こるが、実際のプロファイルはそれよりも外側のユーザレベルコードの地点で行いたい。理由は:
- PHPでは連想配列などのデータ構造の操作などは、Cで書かれたネイティブ・ライブラリ内で起こるため、そのライブラリ内部のレベルでのプロファイルはしにくい。
- またライブラリは多くの箇所から呼ばれるため、ライブラリ内 (例えば、echoの実装の中で) で遅延強制のプロファイルを行った場合、よくヒットするようなガードは生成できない可能性が高い。
この問題を解決するために、プロファイラは、ユーザ・レベル・コードの地点で実際のデータの遅延の強制よりも早いタイミングで値のプロファイリングを行う。具体的には、レベル1コンパイラが適切なprofileコードを生成コード中に入れるなどの手法が考えられる。いまPHPに関して引数の値を即座に使うことがわかっているライブラリ操作とその引数、例えば:
- echo xの引数x
- update k v xのキーkおよび配列x (配列に入る値vは即座には使わないことに注意)
- ・・・
を列挙することができる。このような操作と引数の組に対して、レベル1コンパイラが、ユーザレベルコード中に
let x = profile x 0 in echo x
let k = profile k 1 in let x = profile x 2 in update k v x
のような形でprofile操作を入れる。このprofile操作の第1引数は遅延であるかもしれない値であり、第2引数はすべてのprofile操作に対してユニークなコールサイトの識別子である。コードの実行時にはprofile x id 操作はプロファイルする値xとコールサイトの識別子idを引数として取り、もしxが遅延クロージャ(fn, record)であれば、このfnとコールサイト識別子idとの組を大域的な場所に記憶しておく。
<レベル2コンパイラ>
レベル2コンパイラは2つの処理を行う。
1) 各コールサイト識別子idについて対応するprofile操作で高頻度で強制されたクロージャのコードfnがあると判定された場合、このコードをガード付でコールサイトにインラインする。これは、図4のステップ408に対応する。
2) 結果として得られたコードを部分評価によって、最適化する。
1) に関しては、具体的にはレベル1コンパイラが出力したprofile操作を、ガードつきでfnの中間コードに置き換えてしまえばよい。このとき、後続のコードのバージョニング(versioning)も行わないと後の部分評価で効率のよいコードが得られない可能性があるが、この方法は既知なので、詳しくは述べない。
2) に関しては部分評価器の実現の手法の一例を示す。
LetGW _ = upd_global "user" "akihiko" in
LetGW _ = upd_global "date" record#_0 in
LetGR _0 = load_global "user" in
letGR _1 = load_global "date" in
echo ("user " . _0 . "logined at " . _1)
上記のクロージャのインライン後のコード・フラグメントを考える。まず部分評価器は通常、環境などの副作用のパラメタを明示的にしたほうがやりやすいので、これを明示的にする。
fun global->
let global = upd_global "user" "akihiko" global in
let global = upd_global "date" record#_0 global in
let _0 = load_global "user" global in
let _1 = load_global "date" global in
echo ("user " . _0 . "logined at " . _1)
この変換は、副作用のアノテーションに基づいて
letGW _ = e1 in e2 -> fun global -> let global = e1 global in e2 global
letGR x = e1 in e2 -> fun global -> let x = e1 global in e2 global
と書き換えたあとで、これをベータ簡約で簡単化すれば実現できる。
さて、いまひとつの問題として、普通の定数畳み込みでは、record#_0のような実行時の値を連想配列上に計算することができない。そのため、実行時ではなくコンパイル時のupd_global, load_globalを以下のように定義する。
upd_global key val arry = fun cons nil -> cons key val (arry cons nil)
load_global key arry = arry (fun key’ val a -> if key = key’ then val else a) error
この手法は、実行時配列の代わりに、チャーチ符号化(Church encoding)された key valのリストをコンパイル時配列の表現とすることであり、上の定義はこのような配列を処理する関数である。このようなチャーチ符号化でなくても、通常のリストを使ったコードを生成しても同様のことは可能である。ポイントは、データ構造の中身が中間コード中で明示的にあらわれるような (要は関数型言語の) 中間言語を使うことで、実行時の値を含むデータ構造が表現できることである。
上の定義を上のプログラムにインラインした後、プログラムの網羅的なベータ簡約および定数畳み込みを行うと、以下のようなコードを得ることができる。
fun global -> echo ("user akhiko logined at " . record#_0)
あとは、一旦明示的にした副作用のパラメタを、再び隠蔽すれば、欲しい形のコードを得ることができる。
echo ("user akhiko logined at " . record#_0)
注意点として、うまく部分評価ができなかった場合には、コンパイル時配列の操作 (リストの操作なので遅い) ではなく、実行時配列の操作 (ハッシュテーブル操作の呼び出し) を残余コードに残さないと効率が落ちるという点がある。このための工夫は、例えば住井の部分評価器 (コンパイル時の値と残余コードの組をかえすようなプログラムの評価器( Eijiro Sumii and Naoki Kobayashi. A Hybrid Approach to Online and Offline Partial Evaluation. Higher-Order and Symbolic Computation, Kluwer Academic Publishers, the Netherlands, vol. 14, no. 2/3, pp. 101-142, September 2001. (.dvi, .ps.gz, .pdf, abstract)参照) に、コンパイル時配列の操作は、コンパイル時の値のみとして、結果コードには見せないような改変を加えることで実現できた。
<遅延の除去>
以下の処理は、図4のステップ410に対応する。遅延処理にはコストがかかるので、もし遅延のコストを上回るような利得がレベル2コンパイルによって得られない場合は、 遅延処理をキャンセルするような再コンパイルを行ってもよい。このようなケースには次の二通りがあると考えられる。
1. 遅延を生成したが、それが拡張ライブラリの中など、遅延をプロファイルによって捕獲できない場所で高頻度で強制されることが判明した場合、または遅延がユーザーコード中で使用されるが、その頻度があまり高くないため、レベル2コンパイルで使用サイトをこの遅延コードのために最適化するとの判断がされなかった場合。
2. 遅延を生成し、それがユーザーレベルコード中で高頻度で強制されるが、レベル2コンパイルを試行してみたところ、あまり性能があがるようなコスト削減が期待できなかった場合。
ここで、1のケースは、プロファイラが判別することができる。2のケースの判断手法は、ヒューリスティクスに頼るしかないが、例えば、部分評価後のコードが部分評価前と較べ、どの程度のコスト削減を実現しているかを推測するようなヒューリスティクスが考えられる。いま、連想配列を扱っている場合ならば、単純に結果コードの中に出現するload/update操作の回数が、部分評価前と比べてどの程度削減しているかを調べれば、ある程度の推測が可能だと考えられる。もし、1回の遅延評価のインラインあたり削減された処理の回数が設定された閾値よりも小さければ、生成された遅延を取り消すとの判断をする。
一旦生成された遅延が取り消されるべきであると判断された場合には、該当する遅延生成を含むコードについてレベル1コンパイルを再実行し、該当部分について遅延を行わないようなコードを生成して元のコードを置き換えればよい。
なお、上記実施例は、プログラミング言語としてPHPを例にとって説明したが、本発明はこれには限定されず、Java(R)など、遅延評価が行われる任意の言語に適用可能である。
また、示されている例は、スタンドアロンであるが、通常PHPが使用される、サーバ上でのコンパイル環境を想定してもよい。
102 システム・バス
104 CPU
110 キーボード
112 マウス
114 ディスプレイ
106 主記憶
108 ハードディスク・ドライブ
202 ソース・プログラム
204 変換モジュール
206 コンパイラ
208 実行系
210 プロファイル情報

Claims (12)

  1. コンピュータの処理によって、ソースコードを、実行可能コードに変換するためのコンパイル方法であって、
    前記コンピュータの処理によって、前記コンピュータの記憶装置に格納された前記ソースコードを読み込むステップと、
    前記コンピュータの処理によって、前記ソースコードの解析においてデータおよび副作用の依存グラフを生成し、その後支配木を元に遅延できるプログラムの部分を特定するステップと、
    前記コンピュータの処理によって、遅延を行うコードを生成するステップと、
    前記コンピュータの処理によって、プロファイラの作用で、前記遅延がどこで強制されたかをプロファイルするステップと、
    前記コンピュータの処理によって、前記プロファイルによって高頻度で強制されると判定された遅延クロージャのコードをその強制される箇所にインラインすることで移動し、さらに部分評価を適用してコードを生成するステップと、
    前記コンピュータの処理によって、前記生成されたコードにおいて、中間データ構造を部分評価で除去するステップを有する、
    コンパイル方法。
  2. 前記遅延を行うコードを生成するステップが、データ構造の更新を遅延していいかどうかの判断がエイリアスの可能性のため難しい場合、データ構造内部のエイリアスの可能性を調べ、安全な場合のみに実行される、請求項1に記載のコンパイル方法。
  3. 遅延を行うコードを生成するステップの前に、前記ソースコードをSSA変換するステップを有する、請求項1に記載のコンパイル方法。
  4. 前記ソースコードがPHPで書かれている、請求項1に記載のコンパイル方法。
  5. コンピュータの処理によって、ソースコードを、実行可能コードに変換するためのコンパイラ・プログラムであって、
    前記コンピュータをして、
    前記コンピュータの記憶装置に格納された前記ソースコードを読み込むステップと、
    前記ソースコードの解析においてデータおよび副作用の依存グラフを生成し、その後支配木を元に遅延できるプログラムの部分を特定するステップと、
    遅延を行うコードを生成するステップと、
    プロファイラの作用により、前記遅延がどこで強制されたかをプロファイルするステップと、
    前記プロファイルによって高頻度で強制されると判定された遅延クロージャのコードをその強制される箇所にインラインすることで移動し、さらに部分評価を適用してコードを生成するステップと、
    前記生成されたコードにおいて、中間データ構造を部分評価で除去するステップを実行させる、
    コンパイラ・プログラム。
  6. 前記遅延を行うコードを生成するステップが、データ構造の更新を遅延していいかどうかの判断がエイリアスの可能性のため難しい場合、データ構造内部のエイリアスの可能性を調べ、安全な場合のみに実行される、請求項5に記載のコンパイラ・プログラム。
  7. 遅延を行うコードを生成するステップの前に、前記ソースコードをSSA変換するステップを有する、請求項5に記載のコンパイラ・プログラム。
  8. 前記ソースコードがPHPで書かれている、請求項5に記載のコンパイラ・プログラム。
  9. ソースコードを、実行可能コードに変換する処理を行うコンピュータ・システムであって、
    前記ソースコードを格納した記憶装置と、
    主記憶と、
    前記ソースコードを前記主記憶に読み込む手段と、
    前記ソースコードの解析においてデータおよび副作用の依存グラフを生成し、その後支配木を元に遅延できるプログラムの部分を特定する手段と、
    遅延を行うコードを生成する手段と、
    プロファイラの作用により、前記遅延がどこで強制されたかをプロファイルする手段と、
    前記プロファイルによって高頻度で強制されると判定された遅延クロージャのコードをその強制される箇所にインラインすることで移動し、さらに部分評価を適用してコードを生成する手段と、
    前記生成されたコードにおいて、中間データ構造を部分評価で除去する手段を含む、
    コンピュータ・システム。
  10. 前記遅延を行うコードを生成する手段が、データ構造の更新を遅延していいかどうかの判断がエイリアスの可能性のため難しい場合、データ構造内部のエイリアスの可能性を調べ、安全な場合のみに実行される、請求項9に記載のコンピュータ・システム。
  11. 遅延を行うコードを生成する手段に入力するために、前記ソースコードをSSA変換する手段をさらに有する、請求項9に記載のコンピュータ・システム。
  12. 前記ソースコードがPHPで書かれている、請求項9に記載のコンピュータ・システム。
JP2009212881A 2009-09-15 2009-09-15 コンパイラ・プログラム、コンパイル方法及びコンピュータ・システム Expired - Fee Related JP4806060B2 (ja)

Priority Applications (2)

Application Number Priority Date Filing Date Title
JP2009212881A JP4806060B2 (ja) 2009-09-15 2009-09-15 コンパイラ・プログラム、コンパイル方法及びコンピュータ・システム
US12/881,667 US20110067018A1 (en) 2009-09-15 2010-09-14 Compiler program, compilation method, and computer system

Applications Claiming Priority (1)

Application Number Priority Date Filing Date Title
JP2009212881A JP4806060B2 (ja) 2009-09-15 2009-09-15 コンパイラ・プログラム、コンパイル方法及びコンピュータ・システム

Publications (2)

Publication Number Publication Date
JP2011065220A JP2011065220A (ja) 2011-03-31
JP4806060B2 true JP4806060B2 (ja) 2011-11-02

Family

ID=43731735

Family Applications (1)

Application Number Title Priority Date Filing Date
JP2009212881A Expired - Fee Related JP4806060B2 (ja) 2009-09-15 2009-09-15 コンパイラ・プログラム、コンパイル方法及びコンピュータ・システム

Country Status (2)

Country Link
US (1) US20110067018A1 (ja)
JP (1) JP4806060B2 (ja)

Families Citing this family (11)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
US8370821B2 (en) * 2007-08-21 2013-02-05 International Business Machines Corporation Method for enabling profile-based call site tailor-ing using profile gathering of cloned functions
US20120143866A1 (en) * 2010-12-02 2012-06-07 Microsoft Corporation Client Performance Optimization by Delay-Loading Application Files with Cache
US8943476B2 (en) 2011-06-14 2015-01-27 Google Inc. System and method to in-line script dependencies
US8924945B1 (en) * 2012-10-04 2014-12-30 Google Inc. Managing dependencies on multi-threaded environment
US9830134B2 (en) * 2015-06-15 2017-11-28 Qualcomm Incorporated Generating object code from intermediate code that includes hierarchical sub-routine information
US20170090890A1 (en) * 2015-09-30 2017-03-30 Semmle Limited Virtual compositions
US9495141B1 (en) 2015-12-01 2016-11-15 International Business Machines Corporation Expanding inline function calls in nested inlining scenarios
US11755382B2 (en) 2017-11-03 2023-09-12 Coherent Logix, Incorporated Programming flow for multi-processor system
US11288046B2 (en) 2019-10-30 2022-03-29 International Business Machines Corporation Methods and systems for program optimization utilizing intelligent space exploration
US11221835B2 (en) * 2020-02-10 2022-01-11 International Business Machines Corporation Determining when to perform and performing runtime binary slimming
CN114356311B (zh) * 2022-01-07 2024-07-19 北京字节跳动网络技术有限公司 代码性能数据的交互方法、装置、介质及电子设备

Family Cites Families (8)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
JPH11149380A (ja) * 1997-11-18 1999-06-02 Hitachi Ltd コンパイラとプログラム最適化方法およびその処理プログラムを記録した記録媒体
JP3651774B2 (ja) * 2000-09-12 2005-05-25 インターナショナル・ビジネス・マシーンズ・コーポレーション コンパイラ及びそのレジスタ割付方法
JP2002259135A (ja) * 2001-02-28 2002-09-13 Internatl Business Mach Corp <Ibm> プログラムの最適化方法及びこれを用いたコンパイラ
WO2004015570A1 (en) * 2002-08-02 2004-02-19 Telefonaktiebolaget Lm Ericsson (Publ) Optimised code generation
JP4184900B2 (ja) * 2003-08-26 2008-11-19 富士通株式会社 変数の統計処理を行うコンパイル処理プログラム、およびその記録媒体、およびその処理方法ならびにその処理装置
JP4093484B2 (ja) * 2004-01-28 2008-06-04 インターナショナル・ビジネス・マシーンズ・コーポレーション コンパイラ、コンパイル方法、コンパイルプログラム、及び記録媒体
US7882498B2 (en) * 2006-03-31 2011-02-01 Intel Corporation Method, system, and program of a compiler to parallelize source code
JP4747209B2 (ja) * 2009-04-17 2011-08-17 インターナショナル・ビジネス・マシーンズ・コーポレーション 高速ウェブサーバ

Also Published As

Publication number Publication date
JP2011065220A (ja) 2011-03-31
US20110067018A1 (en) 2011-03-17

Similar Documents

Publication Publication Date Title
JP4806060B2 (ja) コンパイラ・プログラム、コンパイル方法及びコンピュータ・システム
Gal et al. Trace-based just-in-time type specialization for dynamic languages
Würthinger et al. One VM to rule them all
US7493610B1 (en) Versioning optimization for dynamically-typed languages
US20090024986A1 (en) Runtime code modification
US8843920B2 (en) Systems and methods for deferring software implementation decisions until load time
US8510724B2 (en) Reconstructing program control flow
US9134973B2 (en) Dynamic compiling and loading at runtime
Castanos et al. On the benefits and pitfalls of extending a statically typed language JIT compiler for dynamic scripting languages
US20090328013A1 (en) Componentization of compiler functionality
EP3084598B1 (en) Execution guards in dynamic programming
US20240103821A1 (en) Optimising computer program code
Fourtounis et al. Deep static modeling of invokedynamic
Garcia et al. Design and implementation of an efficient hybrid dynamic and static typing language
US11379195B2 (en) Memory ordering annotations for binary emulation
US20210303283A1 (en) Generating compilable machine code programs from dynamic language code
Ali et al. Constructing call graphs of Scala programs
JP2013186647A (ja) 難読化装置、難読化方法、及び難読化プログラム、並びに難読化されたソースコード
Mosaner et al. Supporting on-stack replacement in unstructured languages by loop reconstruction and extraction
Ali et al. Type-based call graph construction algorithms for Scala
Hu et al. A static timing analysis environment using Java architecture for safety critical real-time systems
Mohan Comparative Analysis Of JavaScript And WebAssembly In The Browser Environment
EP4196874A1 (en) Representing asynchronous state machine in intermediate code
Snavely et al. Unpredication, unscheduling, unspeculation: reverse engineering Itanium executables
Munsters et al. Oron: Towards a dynamic analysis instrumentation platform for AssemblyScript

Legal Events

Date Code Title Description
A977 Report on retrieval

Free format text: JAPANESE INTERMEDIATE CODE: A971007

Effective date: 20110712

TRDD Decision of grant or rejection written
A01 Written decision to grant a patent or to grant a registration (utility model)

Free format text: JAPANESE INTERMEDIATE CODE: A01

Effective date: 20110726

A01 Written decision to grant a patent or to grant a registration (utility model)

Free format text: JAPANESE INTERMEDIATE CODE: A01

A61 First payment of annual fees (during grant procedure)

Free format text: JAPANESE INTERMEDIATE CODE: A61

Effective date: 20110811

R150 Certificate of patent or registration of utility model

Free format text: JAPANESE INTERMEDIATE CODE: R150

FPAY Renewal fee payment (event date is renewal date of database)

Free format text: PAYMENT UNTIL: 20140819

Year of fee payment: 3

LAPS Cancellation because of no payment of annual fees