java.lang.Object
jdk.incubator.foreign.MemoryHandles
public final class MemoryHandles extends Object
このクラスは、メモリー・アクセス変数ハンドルを構成および結合するためのいくつかのファクトリ・メソッドを定義します。 メモリー・アクセス変数ハンドルを取得するには、クライアントが「リーフ」メソッドの(
varHandle(Class, ByteOrder)
、varHandle(Class, long, ByteOrder)
を参照してください。)のいずれかから起動する必要があります。 これにより、変数の型(すべてのプリミティブ・タイプをサポートしますが、void
とboolean
もサポートされます。)に加え、配置制約、およびメモリー・アクセスvarハンドルに関連付けられたバイト順を決定します。 結果として得られるメモリー・アクセス変数ハンドルを様々な方法で組み合せて、別のアドレス指定モードをエミュレートできます。 このクラス機能で作成されるvarハンドルは、「必須」座標型(タイプMemoryAddress
)と、マルチディメンション配列の索引付けをエミュレートするために使用できる0個以上のlong
座標型です。
たとえば、次のように構築されたSequenceLayout
インスタンスで表されるメモリー・レイアウトを考えます:
SequenceLayout seq = MemoryLayout.ofSequence(5, MemoryLayout.ofStruct( MemoryLayout.ofPaddingBits(32), MemoryLayout.ofValueBits(32, ByteOrder.BIG_ENDIAN).withName("value") ));
value
という名前のメンバーのレイアウトにアクセスするには、次のようにしてmemory access varハンドルを構築できます:
VarHandle handle = MemoryHandles.varHandle(int.class, ByteOrder.BIG_ENDIAN); //(MemoryAddress) -> int handle = MemoryHandles.withOffset(handle, 4); //(MemoryAddress) -> int handle = MemoryHandles.withStride(handle, 8); //(MemoryAddress, long) -> int
アドレス指定モード
メモリー・アクセス変数ハンドルがアクセスする最終的なメモリーのロケーションは、次のように計算できます:ここで、address = base + offset
base
はMemoryAddress
アクセス座標で表されるアドレスを表し、offset
は次の形式で表現できます:
ここでoffset = c_1 + c_2 + ... + c_m + (x_1 * s_1) + (x_2 * s_2) + ... + (x_n * s_n)
x_1
、x_2
、... x_n
は、オプションのlong
アクセス座標として提供される「動的」値であり、一方、c_1
、c_2
、... c_m
、s_0
、s_1
、... s_n
はstatic定数で、withOffset(VarHandle, long)
およびwithStride(VarHandle, long)
コンビナータを通じて取得できます。
配置モードとアクセス・モード
メモリー・アクセス・メトリックのハンドルは、アクセス・サイズのS
および整列制約のB
(両方ともバイトで表します)に関連付けられています。 メモリー・アクセス操作が、位置合せ制約S
とB
の両方と互換性のあるメモリー・アドレスA
で発生する場合、「完全に整列」であるとします。 アクセスが完全に整列されている場合、次のアクセス・モードがサポートされ、原子性アクセスをサポートする保証があります:
- 32ビット・プラットフォーム上の
long
およびdouble
のアクセス・モードget
およびset
を除き、すべてのT
の読み取り/書き込みアクセス・モード。 int
、long
、float
またはdouble
のアトミック更新アクセス・モード。 (JDKの今後の主要なプラットフォーム・リリースは、現在サポートされていない特定のアクセス・モードに対して追加の型をサポートする可能性があります。)int
およびlong
の数値アトミック更新アクセス・モード。 (JDKの将来の主要なプラットフォーム・リリースは、現在サポートされていない特定のアクセス・モードに対して、追加の数値型をサポートする可能性があります。)int
とlong
のビット単位アトミック更新アクセス・モード。 (JDKの将来の主要なプラットフォーム・リリースは、現在サポートされていない特定のアクセス・モードに対して、追加の数値型をサポートする可能性があります。)
T
がfloat
またはdouble
の場合、アトミック更新アクセス・モードでは、ビット単位表現(それぞれFloat.floatToRawIntBits(float)
とDouble.doubleToRawLongBits(double)
を参照してください)を使用して値が比較されます。
あるいは、メモリー・アクセス操作が、位置情報制約B
とのみ互換性のあるメモリー・アドレスA
で発生する場合、「部分的に整列」です。その場合、get
およびset
アクセス・モード以外でアクセスするとIllegalStateException
になります。 アクセスが部分的に整列されている場合、アトミック・アクセスは、A
およびS
のGCDを分割する2の最大電力に関してのみ保証されます。
最後に、他のすべてのケースでは、メモリー・アクセス操作は「右揃え」であると言っています; この場合、使用するアクセス・モードに関係なくIllegalStateException
がスローされます。
-
メソッドのサマリー
修飾子と型 メソッド 説明 static VarHandle
varHandle(Class<?> carrier, long alignmentBytes, ByteOrder byteOrder)
指定されたキャリア・タイプ、位置合せ制約、およびバイト順序でメモリー・アクセス・メトリックを作成します。static VarHandle
varHandle(Class<?> carrier, ByteOrder byteOrder)
指定されたキャリア・タイプとバイト順序でメモリー・アクセス・メトリックを作成します。static VarHandle
withOffset(VarHandle target, long bytesOffset)
アクセスされたオフセットに追加された固定オフセットを使用してメモリー・アクセス変数ハンドルを作成します。static VarHandle
withStride(VarHandle target, long bytesStride)
アクセスされたオフセットに追加されたvariableオフセットを使用してメモリー・アクセス変数ハンドルを作成します。
-
メソッドの詳細
-
varHandle
指定されたキャリア・タイプとバイト順序でメモリー・アクセス・メトリックを作成します。 結果としてのメモリー・アクセス変数ハンドルには、MemoryAddress
アクセス座標が1つあり、変数の型は指定されたキャリアの型によって設定されます。 生成されるメモリー・アクセス変数ハンドルの位置合せ制約は、キャリア・タイプのメモリー内サイズと同じで、アクセスされたオフセットは0(ゼロ)に設定されます。- APIのノート:
- 結果の変数ハンドルは、すべてのメモリー・アクセス変数ハンドルに共通な、「アクセス・モード制限」の特定の機能を備えています。
- パラメータ:
carrier
- キャリア・タイプ。 有効なキャリアは、byte
、short
、char
、int
、float
、long
およびdouble
です。byteOrder
- 必要なバイト順。- 戻り値:
- 新しいメモリー・アクセス・メトリックのハンドル。
- 例外:
IllegalArgumentException
- 不正なキャリア・タイプが使用されている場合
-
varHandle
指定されたキャリア・タイプ、位置合せ制約、およびバイト順序でメモリー・アクセス・メトリックを作成します。 結果としてのメモリー・アクセス変数ハンドルには、MemoryAddress
アクセス座標が1つあり、変数の型は指定されたキャリアの型によって設定されます。 アクセスされたオフセットはゼロです。- APIのノート:
- 結果の変数ハンドルは、すべてのメモリー・アクセス変数ハンドルに共通な、「アクセス・モード制限」の特定の機能を備えています。
- パラメータ:
carrier
- キャリア・タイプ。 有効なキャリアは、byte
、short
、char
、int
、float
、long
およびdouble
です。alignmentBytes
- 位置合せ制約(バイト単位)です。 2の累乗である必要があります。byteOrder
- 必要なバイト順。- 戻り値:
- 新しいメモリー・アクセス・メトリックのハンドル。
- 例外:
IllegalArgumentException
- 不正なキャリア・タイプが使用されている場合、またはalignmentBytes
が2の累乗でない場合。
-
withOffset
アクセスされたオフセットに追加された固定オフセットを使用してメモリー・アクセス変数ハンドルを作成します。 つまり、ターゲットのメモリー・アクセスvarハンドルがオフセットOでメモリーのロケーションにアクセスする場合、新しいメモリー・アクセスvarハンドルはオフセットO' + Oでメモリーのロケーションにアクセスします。 結果として得られるメモリー・アクセス変数ハンドルは、ターゲットのメモリー・アクセス変数ハンドルのものと同じアクセス座標を備えています。- APIのノート:
- 結果の変数ハンドルは、すべてのメモリー・アクセス変数ハンドルに共通な、「アクセス・モード制限」の特定の機能を備えています。
- パラメータ:
target
- オフセット調整後にアクセスするターゲット・メモリー・アクセス・ハンドルです。bytesOffset
- オフセット(バイト)。 正またはゼロである必要があります。- 戻り値:
- 新しいメモリー・アクセス・メトリックのハンドル。
- 例外:
IllegalArgumentException
- ターゲットのvarハンドルがメモリー・アクセスのvarハンドルでない場合、またはbytesOffset < 0
の場合、あるいは整列制約と互換性がない場合。
-
withStride
アクセスされたオフセットに追加されたvariableオフセットを使用してメモリー・アクセス変数ハンドルを作成します。 つまり、ターゲットのメモリー・アクセス変数ハンドルがオフセットOでメモリーのロケーションにアクセスする場合、新しいメモリー・アクセス変数ハンドルは、オフセット(S * X) + Oのメモリーのロケーションにアクセスします。ここで、Sは定数「ストライド」ですが、一方、Xは、追加のアクセス座標(型long
の)として提供される動的な値です。 新しいアクセス座標は、ターゲット・メモリー・アクセス変数で(もしあれば)を処理できるものに「先頭」で行われます。- APIのノート:
- 結果の変数ハンドルは、すべてのメモリー・アクセス変数ハンドルに共通な、「アクセス・モード制限」の特定の機能を備えています。
- パラメータ:
target
- スケール調整後にアクセスするターゲット・メモリー・アクセス・ハンドルです。bytesStride
- 座標値を乗算する取消し線(バイト単位)。 0 (ゼロ)より大きくなるようにしてください。- 戻り値:
- 新しいメモリー・アクセス・メトリックのハンドル。
- 例外:
IllegalArgumentException
- ターゲットのvarハンドルがメモリー・アクセスのvarハンドルでない場合、またはbytesStride <= 0
の場合、あるいは整列制約と互換性がない場合。
-