ガード記憶域機能(Guarded-Storage Facility)(*1)は、プログラムによって指定された範囲の仮想記憶域アドレスが汎用レジスターにロードされると予め設定された命令アドレスに制御を移す機能です。記憶域が参照されたかではなく、(参照の為の)記憶域アドレスがロードされたかがCPUによって見張られるもので、問題プログラム状態のプログラムでも利用できるものです。Guardという名称が付いていますが、この場合のガード(Guard)は保護(Protect)よりは「見張り」「監視」の意味合いが適していると思います。
*1 z/Architecture 12th.Edition(2017年9月)にて実装された。
LGG又はLLGFSG命令発行前に、LGSC命令でGSCBに指定したガード記憶域レジスター内容を登録しておく。
LGG又はLLGFSG命令動作の中間結果の先頭からのビット列がGSOと同じ値であれば、中間結果内で続くGSMXが示すガード領域内区画がガード対象なのかGSSMと照らし合わされ、ガード対象ならガード記憶域イベントが発生してGSEHAが示すアドレスに分岐する。ハンドラー・ルーチンに分岐することで、ガード領域へアクセスしようとしていることをアプリケーション自身でインターセプトできる。
GSOとの不一致やガード対象で無ければ、分岐はせずに中間結果が第1オペランドに読み込まれる。
ガード記憶域機能の準備
ガード記憶域機能を利用するには、GSCB及びGSEPLを仮想記憶域に作成して、ガード・ストレージ・レジスターと呼ばれる3つのCPU内部メモリーに格納しておきます。ガード・ストレージ・レジスターへの格納にはLGSC命令を、ガード・ストレージ・レジスター内容を仮想記憶域に格納するにはSTGSC命令を使用できます。どちらの命令も問題プログラム状態で実行できますが、制御レジスター2のbit59が1になっていなければなりません。
GSCB(Guarded-Storage Control Block)
ガード・ストレージ・レジスターに格納する内容を設定する。
Loc | Lng | フィールド | 意味、内容 |
---|---|---|---|
x00 | 8 | ‐‐‐‐‐‐‐‐ | (reserved) |
x08 | 8 | GSD | Guarded-Storage Designation |
x10 | 8 | GSSM | Guarded-Storage Section Mask |
x18 | 8 | GSEPLA | Guarded-Storage-Event Parameter-List Address |
GSD(Guarded-Storage Designation)レジスター
- J :GSOフィールドの右端ビット(可変位置:GSC値で決まる)
- GLS:Guarded load shift amount(bit53-55)
- GSC:Guarded-storage characteristic(bit58-63)
GSC | GSO境界 | GSO位置 | 区画サイズ | GSC | GSO境界 | GSO位置 | 区画サイズ |
---|---|---|---|---|---|---|---|
25 | 32M | bit0-38 | 512K | 41 | 2T | bit0-22 | 32G |
26 | 64M | bit0-37 | 1M | 42 | 4T | bit0-21 | 64G |
27 | 128M | bit0-36 | 2M | 43 | 8T | bit0-20 | 128G |
28 | 256M | bit0-35 | 4M | 44 | 16T | bit0-19 | 256G |
29 | 512M | bit0-34 | 8M | 45 | 32T | bit0-18 | 512G |
30 | 1G | bit0-33 | 16M | 46 | 64T | bit0-17 | 1T |
31 | 2G | bit0-32 | 32M | 47 | 128T | bit0-16 | 2T |
32 | 4G | bit0-31 | 64M | 48 | 256T | bit0-15 | 4T |
33 | 8G | bit0-30 | 128M | 49 | 512T | bit0-14 | 8T |
34 | 16G | bit0-29 | 256M | 50 | 1P | bit0-13 | 16T |
35 | 32G | bit0-28 | 512M | 51 | 2P | bit0-12 | 32T |
36 | 64G | bit0-27 | 1G | 52 | 4P | bit0-11 | 64T |
37 | 128G | bit0-26 | 2G | 53 | 8P | bit0-10 | 128T |
38 | 256G | bit0-25 | 4G | 54 | 16P | bit0-09 | 256T |
39 | 512G | bit0-24 | 8G | 55 | 32P | bit0-08 | 512T |
40 | 1T | bit0-23 | 16G | 56 | 64P | bit0-07 | 1P |
GSOは、ガード領域の起点アドレスとして設定するものですが、必ずしも実在する記憶域アドレスである必要はありません。実際には境界や区画サイズも上記の表通りでなくても動作します。(CPUはガード領域にはアクセスしません)
GSSM(Guarded-Storage Section Mask)レジスター
GSOを起点とするガード領域全体を64個の区画に分けた際に、ガードの対象区画にするか否かをビット列で示します。ビットが1ならガードの対象になり、0なら対象から外れます。
GSEPLA(Guarded-Storage-Event Parameter-List Address)レジスター
GSEPL領域のアドレスを設定します。CPUは、ガード領域にはアクセスしませんがGSEPL領域にはアクセスしますので、制御レジスター2のbit59が1になっている間はGSEPLは主記憶域に存在している必要があります(*1)。
GSEPL(Guarded-Storage-Event Parameter List)
ガード記憶域イベントが発生した際に、CPUによってアクセスされる48バイトの制御パラメーター領域(*2)です。ガード記憶域イベント・ハンドラー・ルーチンのアドレス以外は全てCPUからの出力フィールドです。
Loc | Lng | フィールド | 意味、内容 |
---|---|---|---|
x01 | 1 | GSEAM | イベント発生時のPSWのEAビットとBAビット。 |
x02 | 1 | GSECI | イベント発生時にトランザクション実行モードであったか否か、TXモードの時、制約トランザクション実行モードか否か、イベントを起こした命令がLGG命令なのかLLGFSG命令なのかの識別。 |
x03 | 1 | GSEAI | イベント発生時のPSWのTビットとASビット及びARモードであった場合の、LGG/LLGFSG命令の第2オペランドを示すAR番号。 |
x08 | 8 | GSEHA | ガード記憶域イベント・ハンドラー・ルーチンのアドレス。 |
x10 | 8 | GSEIA | ガード記憶域イベントを引き起こした命令のアドレス(*3)。 |
x18 | 8 | GSEOA | ガード記憶域イベントを引き起こした命令の第2オペランド・アドレス。 |
x20 | 8 | GSEIR | ガード記憶域イベントを引き起こした命令の中間結果内容。 |
x28 | 8 | GSERA | トランザクション実行中の場合のトランザクション再開アドレス(*4)。 (非トランザクション実行モードではGSEIAと同じ) |
*1 実際にCPUがGSEPLにアクセスするのは、LGG又はLLGFSG命令でガード記憶域イベントが発生した場合のみである。
*2 DAT ON時なら仮想記憶域に存在していればよく、ページ・アウトされていても構わない。OSによるページ・イン後に同じLGG/LLGFSG命令が再実行される。但し、トランザクション実行モードではTBEGIN/TBEGINC命令の次の命令アドレスから再実行される。
*3 次の命令アドレスではなく、イベントを起こしたLGG/LLGFSG命令のアドレス。
*4 TBEGIN/TBEGINC命令の次の命令アドレス。ガード記憶域イベント発生によって、トランザクションはコード19で中止されている(CC=2が設定されている)。
IEAGSFマクロ
ガード記憶域機能を使用する場合、制御レジスター2のbit59が1になっていなければなりませんが、問題プログラム状態のプログラムでは制御レジスターを直接変更できません。z/OSでは、IEAGSFマクロを発行することで問題プログラム状態のプログラムからもガード記憶域機能を有効にできます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
IEAGSF START, ENABLE GSF FACILITY + INITIALCONTROLS=GSCB : : IEAGSF STOP DISABLE GSF FACILITY : : GSEHNDLR DS 0H Guard Storage Event Handler LG R1,GSEOA LOAD GUARDED AREA POINTER L R1,0(,R1) LOAD HEAP AREA INDEX : : GSCB DS 0D DC AD(0) --- RESERVED --- GSD DC A(0),AL3(0),AL1(38) GSD REGISTER FIELD GSSM DC XL8'7FFFFFFFFFFFFFFF' GSSM FIELD GSEPLA DC AD(GSEPL) GSEPL POINTER GSEPL DS 0D DC X'00',X'00',X'00',X'00' ,GSEAM,GSECI,GSEAI DC XL4'00' (RESERVED) GSEHA DC AD(GSEHNDLR) GSE HANDLER ENTRY GSEIA DC AD(0) GSE INTERUPPTION ADDRESS GSEOA DC AD(0) GSE OPERAND ADDRESS GSEIR DC AD(0) GSE INTERMEDIATE RESULT GSERA DC AD(0) GSE RETURN ADDRESS |
ガード記憶域機能の動作
LGG命令又はLLGFSG命令を実行すると、命令動作によって64ビットの中間結果が生成されます。中間結果の先頭のbit0からbitJ迄はGSOC(Guarded Storage Operand Comparand)と呼ばれ、GSCBで設定したGSDのGSOと比較されます。bitJのJの値は、GSDのGSC値によって決定され、GSOCとGSOが一致すれば、GSOCに続くGSMXが示す区画に対応したGSSM内のビットが調べられて、ビットが1であればガード記憶域イベントが発生します。
GSMX(Guarded-Storage-Mask index)
GSOCが示すガード領域内のどの区画を示すかの、6ビットの領域内インデックス値です。ガード領域の先頭区画であれば0(b000000)、2番目の区画なら1(b000001)、最後の区画なら63(b111111)です。
LGG/LLGFSG命令中間結果
- J :GSOフィールドの右端ビット(可変位置:GSC値で決まる)
GSMXが0であればGSSM+0のx80ビットが調べられ、GSMXが1であればGSSM+0のx40ビットが調べられ、GSMXが63であればGSSM+7のx01ビットが調べられます。
なお、LLGFSG命令では64ビット・アドレッシング・モードであっても中間結果の上位28(GLS=4)から32(GLS=0)ビットにはゼロが設定され、第2オペランド・アドレスはフルワード領域であるため、64ビット・アドレスそのものではなく64ビット・アドレスを圧縮して格納する圧縮ポインターの処理に有用です。
ガード記憶域イベントの発生
LGG命令又はLLGFSG命令の中間結果とGSO及びGSSMマスク・ビットの整合性が一致すると、ガード記憶域イベントが発生します。この時点で、GSEPLAレジスターがポイントするGSEPLがアクセスされます。イベント発生時のPSW等からGSEHAを除くフィールド内容が設定され、GSEHAフィールドがポイントするGSE(ガード記憶域イベント)ハンドラー・ルーチンに制御が渡ります(*1)。
見た目の動作としては、LGG/LLGFSG命令が分岐命令のように動作するもの(*2)で、ハンドラー・ルーチンに制御が渡ることでガード領域内のガード対象区画へのポインターがロードされたことがわかります。ハンドラー・ルーチンでは、GSEPLにアクセスしてポインターをロードしたLGG/LLGFSG命令のアドレスや命令が示したポインター・フィールドのアドレス等を判別することができます。後は、アプリケーションとしてのハンドラー処理を行い、必要ならばイベントを発生させたLGG/LLGFSG命令を再実行する等を行います。
ガード記憶域機能は、各種プログラミング言語のガベージ・コレクション機能の実装などに応用されています。
*5 PSW内のNSIフィールドがGSEHAフィールドの内容で置き換えられるが、アドレッシング・モードは変更されない。
*6 LGG/LLGFSG命令からハンドラー・ルーチンへの分岐動作のように見える。