2016-12-09 17 views
2

Goでは、最近、特定の機能に関して、「コンテキストレジスタ」の実装に関するコメントがあることに気付きました。コンテキストレジスタとは何ですか?Goコードのコンパイル方法はどのように変更されますか?golangのコンテキストレジスタとは何ですか?

コンテキスト:GOROOTの一部でスタブ関数を使用しています(reflect)が、どのように動作するのかよく分かりません。

+2

"コンテキストレジスタ"は、Go作成者がクロージャのコンテキストを保持するレジスタを呼び出したものです。スタブ関数(アセンブリファイル、ランタイムなど)は実際には関連していません。そして、もしこれについて質問があれば、メーリングリストははるかに適切なフォーラムです。 – JimB

+1

うまくいけば、これはあまりメタではないが、電子メールのリストよりもgo-langの質問には、何らかの形で "はるかに適切ではない"、stackoverflowはなぜ全面的に質問し、プログラミングに関する質問に回答しているサイトですか? – eje

+2

@eje:gcツールチェーンの実装の詳細についての回答が必要な場合、メーリングリストは、開発者がそこで活動しているという理由だけで、より良いフォーラムです。これは、OPがデューデリジェンスを行い、すでにコミットログ(VonCが以下に引用しています)を見て、元の開発者が提供できるより多くのコンテキストを望んでいることを前提としています。 – JimB

答えて

4

式最初Go 1.1 Function Calls

のステップ3変更してもランタイムコードの生成を回避するためreflect.MakeFunc実装を実現するための(1.1rc2を移動し、2013年2月)commit b1b67a3に登場する「コンテキストレジスタ」

アセンブリおよびシステムがsigreturn is managed asネイティブクライアントのx86-64、を要求するためにそれは、1.3beta1を行く、2014年2月にcommit 4a000b9に拾われた。

NaClは従来のオペレーティングシステムの責任を回避し、 'sigreturn'の実装を拒否しました。
プログラムの実行に戻る唯一の方法は、レジスタを自分で復元することです。

  • いずれかせずにシーケンスを終了PCの最終的な更新を実行する方法がないので、残念ながら、それは、厳密な忠実度で行うことは不可能である(1)レジスタへのジャンプ、場合に(2)PCをスタックに格納し、RETを使用して、SPが有効であり、その下にある単語を破棄することができます。

目は、通常のNaClのことを除いて、リンカが「POP reg; AND $~31, reg; JMP reg」にRETを書き直す必要があり、2つの悪の低いだろう、そういずれかの方法は、我々は、入力信号の結果としてレジスタを失うしようとしています。

同様に、EFLAGSを復元する方法はありません。通常はPOPFLを使用しますが、NaClはその命令を拒否します。
ビットを検査し、これらのフラグ設定を再作成するように指示された一連の命令を実行できますが、それは多くの作業です。

ありがたいことに、Goのシグナルハンドラは実行コードに直接戻ろうとはしません。したがって、すべてのレジスタとEFLAGSは死んでしまいます。
重要なレジスタは、シグナルハンドラが作成したシミュレートされたコール用に設定されているレジスタだけです。
今日これらのレジスタは、ちょうどPCSPですが、場合には、追加のレジスタは、我々は可能な限り多くのレジスタを復元する(例えば、DXためは囲碁FUNC context registerです)将来的には関連しています。

さらに最近(Q4 2016)、Go 1の場合。8、私たちはeliminating stack rescanningため、commit d5bd797commit bf9c71cあります

morestackgobuf.ctxtへのコンテキストポインタを書き込みますが、 morestackはアセンブリで書かれているので(と持って 状態に非常に慎重になる)、それはありませんないこの の書き込みに必要な書き込みバリアを呼び出します。代わりに、これを後でnewstackにパッチします。そこで、 をctxtの明示的な書き込みバリアーを呼び出します。

これはすでにいくつかの微妙な推論を必要としており、それはハイブリッドバリアで ロットヘアを得るつもりです。

メカニズム全体を簡素化することでこれを修正します。 morestackで代わりに書き込みgobuf.ctxt
はちょうどnewstackにコンテキストレジスタの値を渡すと、それはgobuf.ctxtにそれを書いてみましょう。これは通常のGoポインタ書き込みであるため、通常のGo書き込みバリアを取得します。微妙な推論は必要ありません。

関連する問題