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

インタフェースMemoryLayout

すべてのスーパー・インタフェース:
Constable
既知のすべての実装クラス:
GroupLayout, SequenceLayout, ValueLayout

public interface MemoryLayout
extends Constable
メモリー・レイアウトを使用すると、「言語選択なし」方式でメモリー・セグメントのコンテンツを記述できます。 レイアウト階層には、「値レイアウト」という2つのリーフがあり、特定のサイズおよび使用される種類の(ValueLayoutを参照してください)および「パディング・レイアウト」の値を表すために使用されます。名前の推奨は、内容を無視する必要があるメモリー・セグメントの一部を表し、主に位置合せ(ofPaddingBits(long)を参照してください)のために存在します。 一般的な値レイアウトの定数の一部は、MemoryLayoutsクラスで定義されます。

より複雑なレイアウトをより単純なものから導出できます: 「順序レイアウト」は1つ以上の要素レイアウト(SequenceLayoutを参照してください)の繰返しを示し、「グループ・レイアウト」は、(typically)異種メンバーのレイアウト(GroupLayoutを参照してください)の集計を示します。

このインタフェースのすべての実装はvalue-basedである必要があります。MemoryLayoutのインスタンスでアイデンティティに依存する操作(参照の等価性の(==)、アイデンティティ・ハッシュ・コード、同期化など)を使用すると、予期しない結果が生じる可能性があるため、使用しないでください。 比較する場合は、equalsメソッドを使用することをお薦めします。

非プラットフォーム・クラスは、MemoryLayoutを直接実装することはできません。

サイズ、位置合せおよびバイト順序

すべてのレイアウトにはサイズが設定され、値とパディングのレイアウト・サイズは常に明示的に指定されています。これは、使用されているプラットフォームに関係なく、レイアウト摘要が常に同じサイズであることを意味します。 派生レイアウトの場合、サイズは次のように計算されます:
  • 要素レイアウトがEで、サイズがlの「有限」順序レイアウトSの場合、SのサイズはEのサイズにLを乗算した値です
  • 「制限なし」順序レイアウトのサイズは、「不明」です。
  • メンバー・レイアウトM1を含むグループ・レイアウトGの場合、サイズがS1S2、... Sn、それぞれM2、... MnGのサイズは、グループが「構造体」であるかunionであるかに応じて、それぞれS1 + S2 + ... + Snまたはmax(S1, S2, ... Sn)のどちらかになります

さらに、すべてのレイアウトは、次のように推測できる「自然整列」の機能です:

  • サイズがNの、値とパディングのレイアウトLの場合、Lの自然な位置合せはNです
  • 要素レイアウトがEである順序レイアウトSの場合、Sでは自然の位置合せがEです。
  • メンバー・レイアウトがM1M2、... Mnのグループ・レイアウトGの場合、位置がA1A2、... 「1つの」となります。Gの自然な位置合せはmax(A1, A2 ... An)です。
必要な(withBitAlignment(long)を参照してください)が必要な場合は、レイアウトの自然位置合せを上書きできます。これは、ハイパーリンク化されたレイアウトを記述するのに役立ちます。

すべての値レイアウトには、レイアウトの作成時に設定されるexplicitバイト順(ByteOrderを参照してください)があります。

レイアウト・パス

「レイアウト・パス」rootレイアウト(通常、グループまたは順序レイアウトです)から派生し、ルート・レイアウト内にネストされたレイアウトで終了 - これはレイアウト・パスによってレイアウトselectedされたものです。 レイアウト・パスは通常、1つ以上のMemoryLayout.PathElementインスタンスのシーケンスとして表現されます。

レイアウト・パスは、別のレイアウト(offset(PathElement...)を参照してください)内で任意にネストされたレイアウトのオフセットを取得し、選択されたレイアウト(varHandle(Class, PathElement...)を参照してください)に対応するメモリー・アクセス・ハンドルを迅速に取得して、別のレイアウト内で任意にネストされたレイアウトを選択する場合(select(PathElement...)を参照)、または別のレイアウト(map(UnaryOperator, PathElement...)を参照してください)内でネストされたレイアウト要素を変換する場合に役立ちます。

このような「レイアウト・パス」は、このクラスのメソッドを使用してプログラムで作成できます。 たとえば、次のようにレイアウトを作成します:


SequenceLayout seq = MemoryLayout.ofSequence(5,
    MemoryLayout.ofStruct(
        MemoryLayout.ofPaddingBits(32),
        MemoryLayout.ofValueBits(32, ByteOrder.BIG_ENDIAN).withName("value")
));
 
次のように、seqからvalueという名前のメンバー・レイアウトのオフセットを取得できます:

long valueOffset = seq.addOffset(PathElement.sequenceElement(), PathElement.groupElement("value"));
 
同様に、valueという名前のメンバー・レイアウトを次のように選択できます:

MemoryLayout value = seq.select(PathElement.sequenceElement(), PathElement.groupElement("value"));
 
また、次のように、valueという名前のレイアウトを別のレイアウトに置換することもできます:

MemoryLayout newSeq = seq.map(l -> MemoryLayout.ofPadding(32), PathElement.sequenceElement(), PathElement.groupElement("value"));
 
つまり、前述の宣言は、次のように、より詳細なものと同じです:

MemoryLayout newSeq = MemoryLayout.ofSequence(5,
    MemoryLayout.ofStruct(
        MemoryLayout.ofPaddingBits(32),
        MemoryLayout.ofPaddingBits(32)
));
 
レイアウト・パスには、1つ以上の「フリー・ディメンション」を含めることができます。 たとえば、未指定のシーケンス要素(つまり、パス・コンポーネントの1つがMemoryLayout.PathElement.sequenceElement()メソッドを使用して取得された場合です。)をたどるレイアウト・パスは、実行時にバインドする必要がある追加の空きディメンションを持ちます。 これは、次のコードに示すように、レイアウトからメモリー・アクセス変数ハンドルを取得するときに重要です:

VarHandle valueHandle = seq.map(int.class, PathElement.sequenceElement(), PathElement.groupElement("value"));
 
前述の例で構成されたレイアウト・パスseqは1つのフリー・ディメンションのみを備えているため、メモリー・アクセス変数ハンドルvalueHandleによってlongアクセス座標が追加されます。

APIのノート:
将来、Java言語で許可される場合、MemoryLayoutsealedインタフェースになる可能性があり、明示的に許可されているタイプ以外はサブクラス化できなくなります。
実装要件:
このクラスの実装は、不変でスレッド・セーフです。
  • ネストされたクラスのサマリー

    ネストされたクラス 
    修飾子と型 インタフェース 説明
    static interface  MemoryLayout.PathElement
    このクラスのインスタンスは、レイアウト・パスの形成に使用されます。
  • メソッドのサマリー

    修飾子と型 メソッド 説明
    long bitAlignment()
    このレイアウトに関連付けられている配置制約をビット単位で返します。
    long bitSize()
    レイアウト・サイズをビット単位で計算します。
    default long byteAlignment()
    このレイアウトに関連付けられているバイト単位の配置制約を返します。
    default long byteSize()
    レイアウト・サイズをバイト単位で計算します。
    Optional<? extends DynamicConstantDesc<? extends MemoryLayout>> describeConstable()
    このレイアウトの公称記述子を含むOptional(構成できる場合)または空のOptional(作成できない場合)を返します。
    boolean equals​(Object that)
    指定されたオブジェクトをこのレイアウトと比較し、等価性を維持します。
    int hashCode()
    このレイアウトのハッシュ・コード値を返します。
    boolean hasSize()
    このレイアウトには指定されたサイズがありますか?
    default MemoryLayout map​(UnaryOperator<MemoryLayout> op, MemoryLayout.PathElement... elements)
    このレイアウトのルートにあるパスから選択したレイアウトが、指定された操作の適用結果で置き換えられるこのレイアウトの変換済コピーが作成されます。
    Optional<String> name()
    このレイアウトに関連するname (もしあれば)を返します。
    default long offset​(MemoryLayout.PathElement... elements)
    指定されたレイアウト・パスによって選択されたレイアウトのオフセットをビット単位で計算します。この場合、パスはこのレイアウトのルートとみなされます。
    static MemoryLayout ofPaddingBits​(long size)
    指定したサイズで新しいパディング・レイアウトを作成します。
    static SequenceLayout ofSequence​(long elementCount, MemoryLayout elementLayout)
    指定された要素レイアウトおよび要素数を使用して、新規順序レイアウトを作成します。
    static SequenceLayout ofSequence​(MemoryLayout elementLayout)
    バインドなし要素カウントと指定された要素レイアウトを使用して、新しい順序レイアウトを作成します。
    static GroupLayout ofStruct​(MemoryLayout... elements)
    指定したメンバー・レイアウトで新しい「構造体」グループ・レイアウトを作成します。
    static GroupLayout ofUnion​(MemoryLayout... elements)
    指定したメンバー・レイアウトで新しいunionグループ・レイアウトを作成します。
    static ValueLayout ofValueBits​(long size, ByteOrder order)
    指定されたバイト順とサイズの値レイアウトを作成します。
    default MemoryLayout select​(MemoryLayout.PathElement... elements)
    このレイアウトのルートとなっているパスからレイアウトを選択します。
    String toString()
    このレイアウトの文字列表現を返します。
    default VarHandle varHandle​(Class<?> carrier, MemoryLayout.PathElement... elements)
    特定のレイアウト・パスで選択されたレイアウトでメモリーを参照解除するために使用できるメモリー・アクセス変数ハンドルを作成します。この場合、パスはこのレイアウトのルートとみなされます。
    MemoryLayout withBitAlignment​(long bitAlignment)
    目的の位置合せ制約を機能する新しいレイアウトを作成します。
    MemoryLayout withName​(String name)
    必要なレイアウトnameが機能する新しいレイアウトを作成します。
  • メソッドの詳細

    • describeConstable

      Optional<? extends DynamicConstantDesc<? extends MemoryLayout>> describeConstable()
      このレイアウトの公称記述子を含むOptional(構成できる場合)または空のOptional(作成できない場合)を返します。
      定義:
      インタフェースConstable内のdescribeConstable
      戻り値:
      最終的な名目記述子を含むOptional、または作成できない場合は空のOptional
    • hasSize

      boolean hasSize()
      このレイアウトには指定されたサイズがありますか? レイアウトが(次を含む)でサイズが未指定の(SequenceLayout.elementCount()を参照してください)の順序レイアウトである場合、そのレイアウトには指定されたサイズがありません。 値レイアウト(ValueLayoutを参照してください)およびパディングのレイアウト(ofPaddingBits(long)を参照してください) alwaysには指定されたサイズがあるため、このメソッドは常にtrueを返します。
      戻り値:
      このレイアウトが指定されたサイズの場合、true
    • bitSize

      long bitSize()
      レイアウト・サイズをビット単位で計算します。
      戻り値:
      レイアウトのサイズ(ビット単位)。
      例外:
      UnsupportedOperationException - レイアウトが、またはレイアウトに含まれている場合、(SequenceLayoutを参照してください)は未指定のサイズの順序レイアウトです。
    • byteSize

      default long byteSize()
      レイアウト・サイズをバイト単位で計算します。
      戻り値:
      レイアウト・サイズ(バイト)。
      例外:
      UnsupportedOperationException - レイアウトが次のものであるか、またはレイアウトが含まれている場合、(SequenceLayoutを参照してください)のサイズが指定されていないシーケンス・レイアウトであるか、bitSize()が8の倍数でないとき。
    • name

      Optional<String> name()
      このレイアウトに関連するname (もしあれば)を返します。
      戻り値:
      レイアウトname (もしあれば)。
      関連項目:
      withName(String)
    • withName

      MemoryLayout withName​(String name)
      必要なレイアウトnameが機能する新しいレイアウトを作成します。
      パラメータ:
      name - レイアウト名。
      戻り値:
      関連付けられたnameを除き、このレイアウトと同じ新しいレイアウト。
      関連項目:
      name()
    • bitAlignment

      long bitAlignment()
      このレイアウトに関連付けられている配置制約をビット単位で返します。 レイアウトの位置合せにより、レイアウトのビット単位の位置合せである2つのAの機能が定義されます。 A <= 8の場合、A/8は、このレイアウトを適切にポイントするポインタに対して整列する必要があるバイト数です。 このため、:
      • A=8では、すべての(通常の意味で)がパケットで共有されないことを意味します。
      • A=64は、aligned (on LP64)、A=32 int aligned、A=16 short alignedなどの単語を意味します。
      • A=512は、x86/SV ABI (AVX-512データ)で必要とされる最も厳密な位置合せです。
      このレイアウト(withBitAlignment(long)を参照してください)に明示的な位置合せ制約が設定されていない場合、このメソッドはこのレイアウトに関連付けられた「自然整列」制約(ビット単位)を返します。
      戻り値:
      レイアウト位置合せ制約をビット単位で指定します。
    • byteAlignment

      default long byteAlignment()
      このレイアウトに関連付けられているバイト単位の配置制約を返します。 レイアウトの位置合せでは、レイアウトのバイト単位の位置合せである2つのAの累乗を定義します。Aは、このレイアウトを適切に示すポインタに対して整列する必要があるバイト数です。 このため、:
      • A=1では、すべての(通常の意味で)がパケットで共有されないことを意味します。
      • A=8は、aligned (on LP64)、A=4 int aligned、A=2 short alignedなどの単語を意味します。
      • A=64は、x86/SV ABI (AVX-512データ)で必要とされる最も厳密な位置合せです。
      このレイアウト(withBitAlignment(long)を参照してください)に明示的な位置合せ制約が設定されていない場合、このメソッドはこのレイアウトに関連付けられた「自然整列」制約(バイト単位)を返します。
      戻り値:
      レイアウト位置合せ制約(バイト)。
      例外:
      UnsupportedOperationException - bitAlignment()が8の倍数でない場合。
    • withBitAlignment

      MemoryLayout withBitAlignment​(long bitAlignment)
      目的の位置合せ制約を機能する新しいレイアウトを作成します。
      パラメータ:
      bitAlignment - レイアウト位置合せ制約。ビットで表されます。
      戻り値:
      このレイアウトと同じ新しいレイアウト。ただし、関連付けられている位置合せ制約を除きます。
      例外:
      IllegalArgumentException - bitAlignmentが2の累乗でない場合、または8未満の場合。
    • offset

      default long offset​(MemoryLayout.PathElement... elements)
      指定されたレイアウト・パスによって選択されたレイアウトのオフセットをビット単位で計算します。この場合、パスはこのレイアウトのルートとみなされます。
      APIのノート:
      レイアウト・パスに(以上)空きディメンションが1つある場合、そのようなディメンションに対応するすべてのインデックスが0に設定されているかのようにオフセットが計算されます。
      パラメータ:
      elements - レイアウト・パスの要素。
      戻り値:
      elementsのレイアウト・パスで選択されるレイアウトのオフセット(ビット単位)。
      例外:
      IllegalArgumentException - レイアウト・パスで、このレイアウト内にネストされたレイアウトが選択されない場合、または複数の順序要素インデックスを(MemoryLayout.PathElement.sequenceElement()およびMemoryLayout.PathElement.sequenceElement(long, long)を参照してください)で選択する1つ以上のパス要素がレイアウト・パスに含まれている場合。
      UnsupportedOperationException - レイアウト・パスによってトラバースされるレイアウトの1つが未指定のサイズである場合。
    • varHandle

      default VarHandle varHandle​(Class<?> carrier, MemoryLayout.PathElement... elements)
      特定のレイアウト・パスで選択されたレイアウトでメモリーを参照解除するために使用できるメモリー・アクセス変数ハンドルを作成します。この場合、パスはこのレイアウトのルートとみなされます。
      APIのノート:
      結果のvarハンドルには、このレイアウト・パスに含まれる未指定の各シーケンス・アクセス・コンポーネントについて、追加のlongアクセス座標があります。 さらに、結果の変数ハンドルは、すべてのメモリー・アクセス変数ハンドルに共通している特定の「アクセス・モード制限」の機能も備えています。
      パラメータ:
      carrier - varハンドルというキャリアのタイプ。
      elements - レイアウト・パスの要素。
      戻り値:
      elementsのレイアウト・パスで選択された(ネストする可能性がある)レイアウトでメモリーを参照解除するために使用できるvarハンドルです。
      例外:
      UnsupportedOperationException - レイアウト・パスに、互換性のない位置合せ制約を持つ1つ以上の要素がある場合、またはレイアウト・パスによってトラバースされるレイアウトの1つが未指定のサイズを持っている場合。
      IllegalArgumentException - キャリアがプリミティブ・タイプを表していない場合、キャリアがvoidbooleanの場合、またはelementsのレイアウト・パスで値レイアウト(ValueLayoutを参照してください)が選択されていない場合、または選択された値レイアウトのサイズが、指定されたキャリア・タイプのものと一致しない場合、。
    • select

      default MemoryLayout select​(MemoryLayout.PathElement... elements)
      このレイアウトのルートとなっているパスからレイアウトを選択します。
      パラメータ:
      elements - レイアウト・パスの要素。
      戻り値:
      elementsでレイアウト・パスによって選択されるレイアウト。
      例外:
      IllegalArgumentException - レイアウト・パスがこのレイアウトでネストされたレイアウトを選択しない場合、またはレイアウト・パスに、1つ以上の順序要素インデックスを(MemoryLayout.PathElement.sequenceElement(long)およびMemoryLayout.PathElement.sequenceElement(long, long)を参照してください)で選択する1つ以上のパス要素が含まれている場合。
    • map

      このレイアウトのルートにあるパスから選択したレイアウトが、指定された操作の適用結果で置き換えられるこのレイアウトの変換済コピーが作成されます。
      パラメータ:
      op - 選択したレイアウトに適用される単項操作。
      elements - レイアウト・パスの要素。
      戻り値:
      elementsのレイアウト・パスで選択されたレイアウトが、選択されたレイアウトにopを適用した結果で置き換えられた新しいレイアウト。
      例外:
      IllegalArgumentException - レイアウト・パスがこのレイアウトでネストされたレイアウトを選択しない場合、またはレイアウト・パスに、1つ以上の順序要素インデックスを(MemoryLayout.PathElement.sequenceElement(long)およびMemoryLayout.PathElement.sequenceElement(long, long)を参照してください)で選択する1つ以上のパス要素が含まれている場合。
    • equals

      boolean equals​(Object that)
      指定されたオブジェクトをこのレイアウトと比較し、等価性を維持します。 指定されたオブジェクトもレイアウトであり、このレイアウトと等しい場合にのみ、trueを返します。 2つのレイアウトが同じ種類であり、同じサイズ、名前および位置合せ制約を持つ場合は、それらが等価であるとみなされます。 また、レイアウトの種類に応じて、追加の条件を満たす必要があります:
      • 2つの値レイアウトが同じエンディアン(ValueLayout.order()を参照してください)を持つ場合、これらのレイアウトは等価とみなされます
      • 2つのシーケンス・レイアウトが同じ要素カウント(SequenceLayout.elementCount()を参照してください)を持つ場合、およびその要素レイアウト(SequenceLayout.elementLayout()を参照してください)も同じである場合は、2つのシーケンス・レイアウトが等しいとみなされます
      • 2つのグループ・レイアウトが同じ種類の(GroupLayout.isStruct()GroupLayout.isUnion()を参照してください。)である場合、およびそのメンバー・レイアウト(GroupLayout.memberLayouts()を参照してください)も同じである場合は、等価であるとみなされます。
      オーバーライド:
      equals 、クラス:  Object
      パラメータ:
      that - このレイアウトと等価性を持たせるために比較するオブジェクト。
      戻り値:
      指定されたオブジェクトがこのレイアウトに等しい場合、true
      関連項目:
      Object.hashCode()HashMap
    • hashCode

      int hashCode()
      このレイアウトのハッシュ・コード値を返します。
      オーバーライド:
      hashCode 、クラス:  Object
      戻り値:
      このレイアウトのハッシュ・コード値。
      関連項目:
      Object.equals(java.lang.Object), System.identityHashCode(java.lang.Object)
    • toString

      String toString()
      このレイアウトの文字列表現を返します。
      オーバーライド:
      toString 、クラス:  Object
      戻り値:
      このレイアウトの文字列表現
    • ofPaddingBits

      static MemoryLayout ofPaddingBits​(long size)
      指定したサイズで新しいパディング・レイアウトを作成します。
      パラメータ:
      size - パディングのサイズ(ビット)。
      戻り値:
      新しいセレクタ・レイアウト。
      例外:
      IllegalArgumentException - size <= 0の場合
    • ofValueBits

      static ValueLayout ofValueBits​(long size, ByteOrder order)
      指定されたバイト順とサイズの値レイアウトを作成します。
      パラメータ:
      size - 値レイアウトのサイズ。
      order - 値レイアウトのバイト順。
      戻り値:
      新しい値のレイアウト。
      例外:
      IllegalArgumentException - size <= 0の場合
    • ofSequence

      static SequenceLayout ofSequence​(long elementCount, MemoryLayout elementLayout)
      指定された要素レイアウトおよび要素数を使用して、新規順序レイアウトを作成します。
      パラメータ:
      elementCount - 順序要素の数。
      elementLayout - 順序要素レイアウト。
      戻り値:
      指定された要素のレイアウトとサイズを使用した新しい順序レイアウト。
      例外:
      IllegalArgumentException - elementCount < 0の場合。
    • ofSequence

      static SequenceLayout ofSequence​(MemoryLayout elementLayout)
      バインドなし要素カウントと指定された要素レイアウトを使用して、新しい順序レイアウトを作成します。
      パラメータ:
      elementLayout - 順序レイアウトの要素レイアウト。
      戻り値:
      指定された要素レイアウトを使用した新しい順序レイアウト。
    • ofStruct

      static GroupLayout ofStruct​(MemoryLayout... elements)
      指定したメンバー・レイアウトで新しい「構造体」グループ・レイアウトを作成します。
      パラメータ:
      elements - 「構造体」グループ・レイアウトのメンバー・レイアウト。
      戻り値:
      指定したメンバー・レイアウトを含む新しい「構造体」グループ・レイアウト。
    • ofUnion

      static GroupLayout ofUnion​(MemoryLayout... elements)
      指定したメンバー・レイアウトで新しいunionグループ・レイアウトを作成します。
      パラメータ:
      elements - unionレイアウトのメンバー・レイアウト。
      戻り値:
      指定したメンバー・レイアウトを含む新しいunionグループ・レイアウト。