モジュール jdk.incubator.foreign
パッケージ jdk.incubator.foreign

クラスMemoryHandles

java.lang.Object
jdk.incubator.foreign.MemoryHandles

public final class MemoryHandles extends Object
このクラスは、メモリー・アクセス変数ハンドルを構成および結合するためのいくつかのファクトリ・メソッドを定義します。 メモリー・アクセス変数ハンドルを取得するには、クライアントが「リーフ」メソッドの(varHandle(Class, ByteOrder)varHandle(Class, long, ByteOrder)を参照してください。)のいずれかから起動する必要があります。 これにより、変数型(すべてのプリミティブ・タイプをサポートしますが、voidbooleanもサポートされます。)、およびメモリー・アクセスのvarハンドルに関連付けられた位置合わせ制約とバイト順序が決定されます。 結果として得られるメモリー・アクセス変数ハンドルを様々な方法で組み合せて、別のアドレス指定モードをエミュレートできます。 このクラスによって作成されるvarハンドルは、「必須」座標型(タイプMemorySegment)と、間接参照が発生するセグメントに対するオフセット(バイト単位)を表すlong座標型を特徴とします。

たとえば、次のように構築されたGroupLayoutインスタンスで表されるメモリー・レイアウトを考えます:


GroupLayout seq = MemoryLayout.structLayout(
        MemoryLayout.paddingLayout(32),
        MemoryLayout.valueLayout(32, ByteOrder.BIG_ENDIAN).withName("value")
);
 
valueという名前のメンバーのレイアウトにアクセスするには、次のようにしてmemory access varハンドルを構築できます:

VarHandle handle = MemoryHandles.varHandle(int.class, ByteOrder.BIG_ENDIAN); //(MemorySegment, long) -> int
handle = MemoryHandles.insertCoordinates(handle, 1, 4); //(MemorySegment) -> int
 

特に指定がないかぎり、null引数、またはこのクラスのメソッドに1つ以上のnull要素を含む配列引数を渡すと、NullPointerExceptionがスローされます。

配置モードとアクセス・モード

メモリー・アクセス・メトリックのハンドルは、アクセス・サイズのSおよび整列制約のB (両方ともバイトで表します)に関連付けられています。 メモリー・アクセス操作が、位置合せ制約SBの両方と互換性のあるメモリー・アドレスAで発生する場合、「完全に整列」であるとします。 アクセスが完全に整列されている場合、次のアクセス・モードがサポートされ、原子性アクセスをサポートする保証があります:
  • 32ビット・プラットフォーム上のlongおよびdoubleのアクセス・モードgetおよびsetを除き、すべてのTの読み取り/書き込みアクセス・モード。
  • intlongfloatまたはdoubleのアトミック更新アクセス・モード。 (JDKの今後の主要なプラットフォーム・リリースは、現在サポートされていない特定のアクセス・モードに対して追加の型をサポートする可能性があります。)
  • intおよびlongの数値アトミック更新アクセス・モード。 (JDKの将来の主要なプラットフォーム・リリースは、現在サポートされていない特定のアクセス・モードに対して、追加の数値型をサポートする可能性があります。)
  • intlongのビット単位アトミック更新アクセス・モード。 (JDKの将来の主要なプラットフォーム・リリースは、現在サポートされていない特定のアクセス・モードに対して、追加の数値型をサポートする可能性があります。)
Tfloatまたはdoubleの場合、アトミック更新アクセス・モードでは、ビット単位表現(それぞれFloat.floatToRawIntBits(float)Double.doubleToRawLongBits(double)を参照してください)を使用して値が比較されます。

あるいは、メモリー・アクセス操作が、位置情報制約Bとのみ互換性のあるメモリー・アドレスAで発生する場合、「部分的に整列」です。その場合、getおよびsetアクセス・モード以外でアクセスするとIllegalStateExceptionになります。 アクセスが部分的に整列されている場合、アトミック・アクセスは、AおよびSのGCDを分割する2の最大電力に関してのみ保証されます。

最後に、他のすべてのケースでは、メモリー・アクセス操作は「右揃え」であると言っています; この場合、使用するアクセス・モードに関係なくIllegalStateExceptionがスローされます。

  • メソッドのサマリー

    修飾子と型
    メソッド
    説明
    static VarHandle
    既存のvarハンドルを、キャリア・タイプがMemorySegmentの新しいvarハンドルに適応させます。
    static VarHandle
    asUnsigned(VarHandle target, Class<?> adaptedType)
    受信値を絞り込み、指定された型との間で送信値を広げることで、ターゲット変数ハンドルを適応させます。
    static VarHandle
    collectCoordinates(VarHandle target, int pos, MethodHandle filter)
    フィルタ(メソッド・ハンドル)を使用して座標値のサブシーケンスを前処理することで、ターゲット変数ハンドルを適応させます。
    static VarHandle
    dropCoordinates(VarHandle target, int pos, Class<?>... valueTypes)
    ターゲットのvarハンドルに委譲する前にダミー座標を破棄するvarハンドルを返します。
    static VarHandle
    filterCoordinates(VarHandle target, int pos, MethodHandle... filters)
    単項フィルタ関数を使用して着信座標値を前処理することで、ターゲット変数ハンドルを適応させます。
    static VarHandle
    filterValue(VarHandle target, MethodHandle filterToTarget, MethodHandle filterFromTarget)
    フィルタ関数のペアを使用して受信値と送信値を事前処理することで、ターゲット変数ハンドルを適応させます。
    static VarHandle
    insertCoordinates(VarHandle target, int pos, Object... values)
    Varハンドル呼出しの前に、1つ以上の「バインド座標」を持つターゲットvarハンドルを提供します。
    static VarHandle
    permuteCoordinates(VarHandle target, List<Class<?>> newCoordinates, int... reorder)
    新しい座標が指定された座標と一致するように再配列することで、ターゲットのvarハンドルの座標値を適応させるvarハンドルを提供します。
    static VarHandle
    varHandle(Class<?> carrier, long alignmentBytes, ByteOrder byteOrder)
    指定されたキャリア・タイプ、位置合せ制約、およびバイト順序でメモリー・アクセス・メトリックを作成します。
    static VarHandle
    varHandle(Class<?> carrier, ByteOrder byteOrder)
    指定されたキャリア・タイプとバイト順序でメモリー・アクセス・メトリックを作成します。

    クラス java.lang.Objectで宣言されたメソッド

    clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
  • メソッドの詳細

    • varHandle

      public static VarHandle varHandle(Class<?> carrier, ByteOrder byteOrder)
      指定されたキャリア・タイプとバイト順序でメモリー・アクセス・メトリックを作成します。 戻されるvarハンドル・タイプはcarrierで、座標タイプのリストは(MemorySegment, long)です。long座標タイプは、指定されたメモリー・セグメントへのバイト・オフセットに対応します。 返されるvarハンドルは、指定されたメモリー・セグメント内のオフセットにあるバイトにアクセスし、指定されたendiannessに従ってcarrier型の値との間でバイトを構成します。生成されるメモリー・アクセスvarハンドルの境界整列制約(バイト単位)は、キャリア型carrierのサイズ(バイト単位)と同じです。
      APIのノート:
      結果の変数ハンドルは、すべてのメモリー・アクセス変数ハンドルに共通な、「アクセス・モード制限」の特定の機能を備えています。
      パラメータ:
      carrier - キャリア・タイプ。 有効なキャリアは、byteshortcharintfloatlongおよびdoubleです。
      byteOrder - 必要なバイト順。
      戻り値:
      新しいメモリー・アクセス・メトリックのハンドル。
      例外:
      IllegalArgumentException - 不正なキャリア・タイプが使用されている場合
    • varHandle

      public static VarHandle varHandle(Class<?> carrier, long alignmentBytes, ByteOrder byteOrder)
      指定されたキャリア・タイプ、位置合せ制約、およびバイト順序でメモリー・アクセス・メトリックを作成します。 戻されるvarハンドル・タイプはcarrierで、座標タイプのリストは(MemorySegment, long)です。long座標タイプは、指定されたメモリー・セグメントへのバイト・オフセットに対応します。 戻されたvarハンドルは、指定されたメモリー・セグメント内のオフセットにあるバイトにアクセスし、指定されたendiannessに従ってcarrier型の値との間でバイトを構成します。結果として得られるメモリー・アクセスvarハンドルの位置合せ制約(バイト単位)は、alignmentBytesによって指定されます。
      APIのノート:
      結果の変数ハンドルは、すべてのメモリー・アクセス変数ハンドルに共通な、「アクセス・モード制限」の特定の機能を備えています。
      パラメータ:
      carrier - キャリア・タイプ。 有効なキャリアは、byteshortcharintfloatlongおよびdoubleです。
      alignmentBytes - 位置合せ制約(バイト単位)です。 2の累乗である必要があります。
      byteOrder - 必要なバイト順。
      戻り値:
      新しいメモリー・アクセス・メトリックのハンドル。
      例外:
      IllegalArgumentException - 不正なキャリア・タイプが使用されている場合、またはalignmentBytesが2の累乗でない場合。
    • asAddressVarHandle

      public static VarHandle asAddressVarHandle(VarHandle target)
      既存のvarハンドルを、キャリア・タイプがMemorySegmentの新しいvarハンドルに適応させます。 つまり、戻されたvarハンドルでVarHandle.get(Object...)をコールすると、読取り数値がメモリー・アドレス(MemoryAddress.ofLong(long)をコールする場合と同様)に変換されます。同様に、VarHandle.set(Object...)をコールすると、設定するメモリー・アドレスが数値に変換され、メモリーに書き込まれます。 (職責:至)メモリーから(resp.書込み)を読み取るバイト数は、元のメモリー・アクセス変数ハンドルのキャリアによって異なります。
      パラメータ:
      target - 適応させるメモリー・アクセス変数ハンドル
      戻り値:
      適応されたvarハンドル。
      例外:
      IllegalArgumentException - varHandleのキャリア・タイプがbooleanfloatまたはdoubleのいずれかであるか、プリミティブ・タイプでない場合。
    • asUnsigned

      public static VarHandle asUnsigned(VarHandle target, Class<?> adaptedType)
      受信値を絞り込み、指定された型との間で送信値を広げることで、ターゲット変数ハンドルを適応させます。

      返されたvarハンドルを使用すると、符号なしプリミティブ・データ型を、より広範囲の符号付きプリミティブ・タイプであるかのように簡単に扱うことができます。 たとえば、unsigned shortをJava intとしてモデル化して、負の値を処理しないようにすると便利な場合があります。これは、Java shortとしてモデル化されている場合です。 これは次の例で説明します。

      
          MemorySegment segment = MemorySegment.allocateNative(2, ResourceScope.newImplicitScope());
          VarHandle SHORT_VH = MemoryLayouts.JAVA_SHORT.varHandle(short.class);
          VarHandle INT_VH = MemoryHandles.asUnsigned(SHORT_VH, int.class);
          SHORT_VH.set(segment, (short)-1);
          INT_VH.get(segment); // returns 65535
       

      たとえば、結果のvarハンドルでVarHandle.set(Object...)をコールすると、受信値(型adaptedTypeの)が「プリミティブ変換を狭める」によって変換され、 target varハンドルに渡されます。 ナロー・プリミティブ・コンバージョンでは、数値の全体的な大きさに関する情報が失われる場合があります。 逆に、結果のvarハンドルでVarHandle.get(Object...)などをコールすると、target varハンドルから取得された戻り値は、コール元に戻される前に「符号なしワイドニング変換」によって変換されます。 符号なしワイド変換では、targetキャリア・タイプより大きい上位ビットはゼロで、下位ビットの(targetキャリア・タイプの幅と等しい)はtarget varハンドルから取得した値のビットと等しくなります。

      返されるvarハンドルは、変数の型adaptedType、同じアクセス座標、同じアクセス・モード(target varハンドルで機能するものと同じアトミック・アクセス保証を備えています(VarHandle.AccessModeおよび同じアトミック・アクセス保証を参照)。

      パラメータ:
      target - 適応させるメモリー・アクセス変数ハンドル
      adaptedType - 適応型
      戻り値:
      適応されたvarハンドル。
      例外:
      IllegalArgumentException - targetのキャリア・タイプがbyteshortまたはintのいずれでもない場合; adaptedTypeintまたはlongのいずれでもない場合; adaptedTypeのビット幅がadaptedTypeキャリア・タイプのビット幅より大きくない場合。
      Java言語仕様を参照してください:
      5.1.3 プリミティブ・コンバージョンの解説
    • filterValue

      public static VarHandle filterValue(VarHandle target, MethodHandle filterToTarget, MethodHandle filterFromTarget)
      フィルタ関数のペアを使用して受信値と送信値を事前処理することで、ターゲット変数ハンドルを適応させます。

      たとえば、結果のvarハンドルでVarHandle.set(Object...)をコールすると、最初のフィルタを使用して受信値(Tタイプ。Tは最初のフィルタ関数のlastパラメータ・タイプです。)が処理され、ターゲットのvarハンドルに渡されます。 逆に、結果のvarハンドルでVarHandle.get(Object...)などをコールすると、ターゲットのvarハンドル(Tタイプ。Tは、2番目のフィルタ関数のlastパラメータ・タイプです。)から取得された戻り値は、2番目のフィルタを使用して処理され、コール元に戻されます。 VarHandle.AccessMode.COMPARE_AND_EXCHANGEなどのより高度なアクセス・モード・タイプでは、両方のフィルタが同時に適用される場合があります。

      ボクシングおよびアン・ボクシング・フィルタを整形式にするには、それぞれ(A... , S) -> Tおよび(A... , T) -> Sの形式にする必要があります。Tはターゲット変数ハンドルの型です。 この場合、結果のvarハンドルはS型になり、追加の座標A... (ターゲット変数ハンドルの座標に追加されます。)を特徴とします。

      結果のvarハンドルは、ターゲットのvarハンドルで機能するアクセス・モードと同じアクセス・モードを備えています(VarHandle.AccessModeおよびアトミック・アクセス保証を参照)。

      パラメータ:
      target - ターゲット変数ハンドル
      filterToTarget - 一部のタイプのStargetのタイプに変換するフィルタ
      filterFromTarget - targetのタイプをSのタイプに変換するフィルタ
      戻り値:
      指定されたボクシング/アン・ボクシング変換を実行して、新しい型を受け入れるアダプタ変数ハンドル。
      例外:
      IllegalArgumentException - filterFromTargetおよびfilterToTargetが整形式でない場合、つまり、(A... , S) -> Tおよび(A... , T) -> S以外の型をそれぞれ持つ場合(Tはターゲット変数ハンドルの型)、またはfilterFromTargetまたはfilterToTargetがチェック例外をスローする場合。
    • filterCoordinates

      public static VarHandle filterCoordinates(VarHandle target, int pos, MethodHandle... filters)
      単項フィルタ関数を使用して着信座標値を前処理することで、ターゲット変数ハンドルを適応させます。

      たとえば、結果のvarハンドルでVarHandle.get(Object...)をコールすると、pos (C1, C2 ... Cn型。C1, C2 ... Cnは単項フィルタ関数の戻り型です。)の位置から始まる着信座標値が新しい値(S1, S2 ... Sn型。S1, S2 ... Snは単項フィルタ関数のパラメータ型です。)に変換され、(適応によって変更されていない座標とともに)がターゲットのvarハンドルに渡されます。

      座標フィルタを整形式にするには、その型がS1 -> T1, S2 -> T1 ... Sn -> Tnの形式である必要があります。ここで、T1, T2 ... Tnはターゲット変数ハンドルのpos位置から始まる座標型です。

      結果のvarハンドルには、ターゲットのvarハンドルの機能と同じアクセス・モードである(VarHandle.AccessModeを参照してください)およびアトミック・アクセスが保証されます。

      パラメータ:
      target - ターゲット変数ハンドル
      pos - 変換する最初の座標の位置
      filters - 位置posから座標を変換するために使用される単項関数
      戻り値:
      指定された変換を新しい座標値に適用して、新しい座標型を受け入れるアダプタ変数ハンドル。
      例外:
      IllegalArgumentException - filtersのハンドルが整形式でない場合、つまりS1 -> T1, S2 -> T2, ... Sn -> Tn以外のタイプを持つ場合、T1, T2 ... Tnは、ターゲットvarハンドルの位置posで始まる座標タイプであり、posが0とターゲットvarハンドル座標引数の間にない場合、またはposで始まる使用可能な座標タイプの数より多くのフィルタが指定されている場合は、いずれかの例外がスローされます。
    • insertCoordinates

      public static VarHandle insertCoordinates(VarHandle target, int pos, Object... values)
      Varハンドル呼出しの前に、1つ以上の「バインド座標」を持つターゲットvarハンドルを提供します。 その結果、結果のvarハンドルは、ターゲットのvarハンドルよりも座標型が少なくなります。

      たとえば、結果のvarハンドルでVarHandle.get(Object...)をコールすると、着信座標値がバインドされた座標値と結合され、ターゲットのvarハンドルに渡されます。

      バインドされた座標を整形式にするには、その型がT1, T2 ... Tn である必要があります。ここで、T1, T2 ... Tnはターゲット変数ハンドルのpos位置から始まる座標型です。

      結果のvarハンドルには、ターゲットのvarハンドルの機能と同じアクセス・モードである(VarHandle.AccessModeを参照してください)およびアトミック・アクセスが保証されます。

      パラメータ:
      target - バインドされた座標が挿入された後に呼び出すvarハンドル
      pos - 挿入する最初の座標の位置
      values - 挿入する一連のバウンド座標
      戻り値:
      ターゲットのvarハンドルを呼び出す前に、追加の座標を挿入するアダプタのvarハンドル
      例外:
      IllegalArgumentException - posが0からターゲットのvarハンドル座標引数(両端を含む)の間にない場合、またはposから使用可能な座標タイプの実際の数よりも多くの値が指定されている場合。
      ClassCastException - valuesのバインドされた座標が整形式でない場合、つまり、T1, T2 ... Tn 以外の型を持つ場合(T1, T2 ... Tnはターゲット変数ハンドルのposの位置から始まる座標型です)。
    • permuteCoordinates

      public static VarHandle permuteCoordinates(VarHandle target, List<Class<?>> newCoordinates, int... reorder)
      新しい座標が指定された座標と一致するように再配列することで、ターゲットのvarハンドルの座標値を適応させるvarハンドルを提供します。

      指定された配列によって並べ替えが制御されます。 #Iに着信座標の数(値はnewCoordinates.size())をコールし、#Oに送信座標の数(ターゲット変数ハンドルに関連付けられた座標の数)をコールします。 このとき、並べ替え配列の長さは#O、各要素は#Iより小さい負でない数でなければいけません。 #O未満のすべてのNについて、N番目の送信座標は、Ireorder[N]であるI番目の受信座標から取得されます。

      座標値の変換は適用されません。 newCoordinatesによって決定される各受信座標の型は、ターゲット変数ハンドル内の対応する送信座標の型と同じである必要があります。

      並べ替え配列では、実際の入れ替えを指定する必要はありません。 入力座標は、そのインデックスが配列内に複数回出現する場合は複製され、インデックスが配列内に存在しない場合は入力座標が削除されます。

      結果のvarハンドルには、ターゲットのvarハンドルの機能と同じアクセス・モードである(VarHandle.AccessModeを参照してください)およびアトミック・アクセスが保証されます。

      パラメータ:
      target - 座標が並べ替えられた後に呼び出すvarハンドル
      newCoordinates - 新しい座標型
      reorder - 並べ替えを制御するインデックス配列
      戻り値:
      ターゲットのvarハンドルを呼び出す前に、着信座標値を再配置するアダプタのvarハンドル
      例外:
      IllegalArgumentException - 索引配列の長さがターゲットのvarハンドルの座標数と等しくない場合、索引配列要素がnewCoordinatesの座標に対して有効な索引でない場合、またはターゲットのvarハンドルとnewCoordinatesの対応する座標タイプが同じでない場合。
    • collectCoordinates

      public static VarHandle collectCoordinates(VarHandle target, int pos, MethodHandle filter)
      フィルタ(メソッド・ハンドル)を使用して座標値のサブシーケンスを前処理することで、ターゲット変数ハンドルを適応させます。 前処理された座標はフィルタ関数の結果(もしあれば)に置き換えられ、変更された(通常は短縮)座標リストでターゲット変数ハンドルが呼び出されます。

      Rがフィルタ(voidにはできません)の戻り型である場合、ターゲット変数ハンドルは、posの位置の座標として、フィルタに渡されない座標の前または後ろ(あるいはその両方)にR型の値を受け入れる必要があります。 座標の順序は変更されず、フィルタから返される結果は、最初にアダプタに渡された座標のサブシーケンス全体を(順番)に置き換えます。

      フィルタの引数の型(もしあれば)は、調整後のvarハンドルの位置posにあるターゲットvarハンドルのゼロまたは1つの座標型を置き換えます。 フィルタの戻り型は、posの位置にあるターゲット変数ハンドルの座標型と同じである必要があり、そのターゲット変数ハンドル座標はフィルタの戻り値によって提供されます。

      結果のvarハンドルには、ターゲットのvarハンドルの機能と同じアクセス・モードである(VarHandle.AccessModeを参照してください)およびアトミック・アクセスが保証されます。

      パラメータ:
      target - 座標がフィルタ処理された後に呼び出すvarハンドル
      pos - フィルタ処理される座標の位置
      filter - フィルタ・メソッド・ハンドル
      戻り値:
      ターゲットのvarハンドルを呼び出す前に、着信座標値をフィルタ処理するアダプタのvarハンドル
      例外:
      IllegalArgumentException - filterの戻り型がvoidの場合、またはターゲットのvarハンドルのpos座標と同じでない場合、posが0からターゲットのvarハンドル座標引数(両端を含む)の間にない場合、結果のvarハンドル型に「座標が多すぎます」が含まれる場合、またはfilterがチェック例外をスローする場合。
    • dropCoordinates

      public static VarHandle dropCoordinates(VarHandle target, int pos, Class<?>... valueTypes)
      ターゲットのvarハンドルに委譲する前にダミー座標を破棄するvarハンドルを返します。 その結果、結果のvarハンドルは、ターゲットのvarハンドルよりも座標型が多くなります。

      pos引数の範囲はゼロからNです。ここで、Nはターゲットのvarハンドル座標型の引数です。 posがゼロの場合、ダミー座標はターゲットの実引数の前に配置され、posNの場合は後ろに配置されます。

      結果のvarハンドルには、ターゲットのvarハンドルの機能と同じアクセス・モードである(VarHandle.AccessModeを参照してください)およびアトミック・アクセスが保証されます。

      パラメータ:
      target - ダミー座標がドロップされた後に呼び出すvarハンドル
      pos - (左端のゼロ)を削除する最初の座標の位置
      valueTypes - ドロップする座標の型
      戻り値:
      ターゲットvarハンドルを呼び出す前にダミー座標をドロップするアダプタvarハンドル
      例外:
      IllegalArgumentException - posが0からターゲットのvarハンドル座標引数(両端を含む)の間にない場合。