< prev index next >

src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/AbstractLayout.java

Print this page
*** 23,81 ***
   *  questions.
   *
   */
  package jdk.incubator.foreign;
  
  import java.lang.constant.ClassDesc;
- import java.lang.constant.Constable;
  import java.lang.constant.ConstantDesc;
- import java.lang.constant.ConstantDescs;
  import java.lang.constant.DirectMethodHandleDesc;
  import java.lang.constant.DynamicConstantDesc;
  import java.lang.constant.MethodHandleDesc;
  import java.lang.constant.MethodTypeDesc;
  import java.nio.ByteOrder;
- import java.util.Collections;
- import java.util.HashMap;
- import java.util.Map;
  import java.util.Objects;
  import java.util.Optional;
  import java.util.OptionalLong;
- import java.util.stream.Collectors;
- import java.util.stream.Stream;
  
  import static java.lang.constant.ConstantDescs.BSM_GET_STATIC_FINAL;
  import static java.lang.constant.ConstantDescs.BSM_INVOKE;
  import static java.lang.constant.ConstantDescs.CD_String;
  import static java.lang.constant.ConstantDescs.CD_long;
  
  abstract non-sealed class AbstractLayout implements MemoryLayout {
  
      private final OptionalLong size;
      final long alignment;
!     final Map<String, Constable> attributes;
  
!     public AbstractLayout(OptionalLong size, long alignment, Map<String, Constable> attributes) {
          this.size = size;
          this.alignment = alignment;
!         this.attributes = Collections.unmodifiableMap(attributes);
      }
  
      @Override
      public AbstractLayout withName(String name) {
          Objects.requireNonNull(name);
!         return withAttribute(LAYOUT_NAME, name);
      }
  
      @Override
      public final Optional<String> name() {
!         return attribute(LAYOUT_NAME).map(String.class::cast);
-     }
- 
-     @Override
-     public Optional<Constable> attribute(String name) {
-         Objects.requireNonNull(name);
-         return Optional.ofNullable(attributes.get(name));
-     }
- 
-     @Override
-     public Stream<String> attributes() {
-         return attributes.keySet().stream();
-     }
- 
-     @Override
-     public AbstractLayout withAttribute(String name, Constable value) {
-         Objects.requireNonNull(name);
-         Map<String, Constable> newAttributes = new HashMap<>(attributes);
-         newAttributes.put(name, value);
-         return dup(alignment, newAttributes);
      }
  
!     abstract AbstractLayout dup(long alignment, Map<String, Constable> annos);
  
      @Override
      public AbstractLayout withBitAlignment(long alignmentBits) {
          checkAlignment(alignmentBits);
!         return dup(alignmentBits, attributes);
      }
  
      void checkAlignment(long alignmentBitCount) {
          if (((alignmentBitCount & (alignmentBitCount - 1)) != 0L) || //alignment must be a power of two
                  (alignmentBitCount < 8)) { //alignment must be greater than 8
--- 23,61 ---
   *  questions.
   *
   */
  package jdk.incubator.foreign;
  
+ import jdk.internal.foreign.Utils;
+ import jdk.internal.vm.annotation.Stable;
+ 
  import java.lang.constant.ClassDesc;
  import java.lang.constant.ConstantDesc;
  import java.lang.constant.DirectMethodHandleDesc;
  import java.lang.constant.DynamicConstantDesc;
  import java.lang.constant.MethodHandleDesc;
  import java.lang.constant.MethodTypeDesc;
  import java.nio.ByteOrder;
  import java.util.Objects;
  import java.util.Optional;
  import java.util.OptionalLong;
  
  import static java.lang.constant.ConstantDescs.BSM_GET_STATIC_FINAL;
  import static java.lang.constant.ConstantDescs.BSM_INVOKE;
+ import static java.lang.constant.ConstantDescs.CD_Class;
  import static java.lang.constant.ConstantDescs.CD_String;
  import static java.lang.constant.ConstantDescs.CD_long;
  
  abstract non-sealed class AbstractLayout implements MemoryLayout {
  
      private final OptionalLong size;
      final long alignment;
!     private final Optional<String> name;
+     @Stable
+     long cachedSize;
  
!     public AbstractLayout(OptionalLong size, long alignment, Optional<String> name) {
          this.size = size;
          this.alignment = alignment;
!         this.name = name;
      }
  
      @Override
      public AbstractLayout withName(String name) {
          Objects.requireNonNull(name);
!         return dup(alignment, Optional.of(name));
      }
  
      @Override
      public final Optional<String> name() {
!         return name;
      }
  
!     abstract AbstractLayout dup(long alignment, Optional<String> name);
  
      @Override
      public AbstractLayout withBitAlignment(long alignmentBits) {
          checkAlignment(alignmentBits);
!         return dup(alignmentBits, name);
      }
  
      void checkAlignment(long alignmentBitCount) {
          if (((alignmentBitCount & (alignmentBitCount - 1)) != 0L) || //alignment must be a power of two
                  (alignmentBitCount < 8)) { //alignment must be greater than 8

*** 118,10 ***
--- 98,19 ---
      @Override
      public final long bitAlignment() {
          return alignment;
      }
  
+     @Override
+     public long byteSize() {
+         if (cachedSize == 0) {
+             cachedSize = Utils.bitsToBytesOrThrow(bitSize(),
+                     () -> new UnsupportedOperationException("Cannot compute byte size; bit size is not a multiple of 8"));
+         }
+         return cachedSize;
+     }
+ 
      @Override
      public boolean hasSize() {
          return size.isPresent();
      }
  

*** 143,26 ***
              s = String.format("%s(%s)", s, name().get());
          }
          if (!hasNaturalAlignment()) {
              s = alignment + "%" + s;
          }
-         if (!attributes.isEmpty()) {
-             s += attributes.entrySet().stream()
-                                       .map(e -> e.getKey() + "=" + e.getValue())
-                                       .collect(Collectors.joining(",", "[", "]"));
-         }
          return s;
      }
  
      <T> DynamicConstantDesc<T> decorateLayoutConstant(DynamicConstantDesc<T> desc) {
          if (!hasNaturalAlignment()) {
              desc = DynamicConstantDesc.ofNamed(BSM_INVOKE, "withBitAlignment", desc.constantType(), MH_WITH_BIT_ALIGNMENT,
                      desc, bitAlignment());
          }
!         for (var e : attributes.entrySet()) {
!             desc = DynamicConstantDesc.ofNamed(BSM_INVOKE, "withAttribute", desc.constantType(), MH_WITH_ATTRIBUTE,
!                     desc, e.getKey(), e.getValue().describeConstable().orElseThrow());
          }
  
          return desc;
      }
  
--- 132,21 ---
              s = String.format("%s(%s)", s, name().get());
          }
          if (!hasNaturalAlignment()) {
              s = alignment + "%" + s;
          }
          return s;
      }
  
      <T> DynamicConstantDesc<T> decorateLayoutConstant(DynamicConstantDesc<T> desc) {
          if (!hasNaturalAlignment()) {
              desc = DynamicConstantDesc.ofNamed(BSM_INVOKE, "withBitAlignment", desc.constantType(), MH_WITH_BIT_ALIGNMENT,
                      desc, bitAlignment());
          }
!         if (name().isPresent()) {
!             desc = DynamicConstantDesc.ofNamed(BSM_INVOKE, "withName", desc.constantType(), MH_WITH_NAME,
!                     desc, name().get().describeConstable().orElseThrow());
          }
  
          return desc;
      }
  

*** 175,11 ***
          return this instanceof PaddingLayout;
      }
  
      @Override
      public int hashCode() {
!         return attributes.hashCode() << Long.hashCode(alignment);
      }
  
      @Override
      public boolean equals(Object other) {
          if (this == other) {
--- 159,11 ---
          return this instanceof PaddingLayout;
      }
  
      @Override
      public int hashCode() {
!         return name.hashCode() << Long.hashCode(alignment);
      }
  
      @Override
      public boolean equals(Object other) {
          if (this == other) {

*** 188,11 ***
  
          if (!(other instanceof AbstractLayout)) {
              return false;
          }
  
!         return Objects.equals(attributes, ((AbstractLayout) other).attributes) &&
                  Objects.equals(alignment, ((AbstractLayout) other).alignment);
      }
  
      /*** Helper constants for implementing Layout::describeConstable ***/
  
--- 172,11 ---
  
          if (!(other instanceof AbstractLayout)) {
              return false;
          }
  
!         return Objects.equals(name, ((AbstractLayout) other).name) &&
                  Objects.equals(alignment, ((AbstractLayout) other).alignment);
      }
  
      /*** Helper constants for implementing Layout::describeConstable ***/
  

*** 206,22 ***
  
      static final ClassDesc CD_BYTEORDER = ByteOrder.class.describeConstable().get();
  
      static final ClassDesc CD_FUNCTION_DESC = FunctionDescriptor.class.describeConstable().get();
  
-     static final ClassDesc CD_Constable = Constable.class.describeConstable().get();
- 
      static final ConstantDesc BIG_ENDIAN = DynamicConstantDesc.ofNamed(BSM_GET_STATIC_FINAL, "BIG_ENDIAN", CD_BYTEORDER, CD_BYTEORDER);
  
      static final ConstantDesc LITTLE_ENDIAN = DynamicConstantDesc.ofNamed(BSM_GET_STATIC_FINAL, "LITTLE_ENDIAN", CD_BYTEORDER, CD_BYTEORDER);
  
      static final MethodHandleDesc MH_PADDING = MethodHandleDesc.ofMethod(DirectMethodHandleDesc.Kind.INTERFACE_STATIC, CD_MEMORY_LAYOUT, "paddingLayout",
                  MethodTypeDesc.of(CD_MEMORY_LAYOUT, CD_long));
  
-     static final MethodHandleDesc MH_VALUE = MethodHandleDesc.ofMethod(DirectMethodHandleDesc.Kind.INTERFACE_STATIC, CD_MEMORY_LAYOUT, "valueLayout",
-                 MethodTypeDesc.of(CD_VALUE_LAYOUT, CD_long, CD_BYTEORDER));
- 
      static final MethodHandleDesc MH_SIZED_SEQUENCE = MethodHandleDesc.ofMethod(DirectMethodHandleDesc.Kind.INTERFACE_STATIC, CD_MEMORY_LAYOUT, "sequenceLayout",
                  MethodTypeDesc.of(CD_SEQUENCE_LAYOUT, CD_long, CD_MEMORY_LAYOUT));
  
      static final MethodHandleDesc MH_UNSIZED_SEQUENCE = MethodHandleDesc.ofMethod(DirectMethodHandleDesc.Kind.INTERFACE_STATIC, CD_MEMORY_LAYOUT, "sequenceLayout",
                  MethodTypeDesc.of(CD_SEQUENCE_LAYOUT, CD_MEMORY_LAYOUT));
--- 190,17 ---

*** 230,17 ***
                  MethodTypeDesc.of(CD_GROUP_LAYOUT, CD_MEMORY_LAYOUT.arrayType()));
  
      static final MethodHandleDesc MH_UNION = MethodHandleDesc.ofMethod(DirectMethodHandleDesc.Kind.INTERFACE_STATIC, CD_MEMORY_LAYOUT, "unionLayout",
                  MethodTypeDesc.of(CD_GROUP_LAYOUT, CD_MEMORY_LAYOUT.arrayType()));
  
      static final MethodHandleDesc MH_VOID_FUNCTION = MethodHandleDesc.ofMethod(DirectMethodHandleDesc.Kind.STATIC, CD_FUNCTION_DESC, "ofVoid",
                  MethodTypeDesc.of(CD_FUNCTION_DESC, CD_MEMORY_LAYOUT.arrayType()));
  
      static final MethodHandleDesc MH_FUNCTION = MethodHandleDesc.ofMethod(DirectMethodHandleDesc.Kind.STATIC, CD_FUNCTION_DESC, "of",
                  MethodTypeDesc.of(CD_FUNCTION_DESC, CD_MEMORY_LAYOUT, CD_MEMORY_LAYOUT.arrayType()));
  
      static final MethodHandleDesc MH_WITH_BIT_ALIGNMENT = MethodHandleDesc.ofMethod(DirectMethodHandleDesc.Kind.INTERFACE_VIRTUAL, CD_MEMORY_LAYOUT, "withBitAlignment",
                  MethodTypeDesc.of(CD_MEMORY_LAYOUT, CD_long));
  
!     static final MethodHandleDesc MH_WITH_ATTRIBUTE = MethodHandleDesc.ofMethod(DirectMethodHandleDesc.Kind.INTERFACE_VIRTUAL, CD_MEMORY_LAYOUT, "withAttribute",
!                 MethodTypeDesc.of(CD_MEMORY_LAYOUT, CD_String, CD_Constable));
  }
--- 209,20 ---
                  MethodTypeDesc.of(CD_GROUP_LAYOUT, CD_MEMORY_LAYOUT.arrayType()));
  
      static final MethodHandleDesc MH_UNION = MethodHandleDesc.ofMethod(DirectMethodHandleDesc.Kind.INTERFACE_STATIC, CD_MEMORY_LAYOUT, "unionLayout",
                  MethodTypeDesc.of(CD_GROUP_LAYOUT, CD_MEMORY_LAYOUT.arrayType()));
  
+     static final MethodHandleDesc MH_VALUE = MethodHandleDesc.ofMethod(DirectMethodHandleDesc.Kind.INTERFACE_STATIC, CD_MEMORY_LAYOUT, "valueLayout",
+             MethodTypeDesc.of(CD_VALUE_LAYOUT, CD_Class, CD_BYTEORDER));
+ 
      static final MethodHandleDesc MH_VOID_FUNCTION = MethodHandleDesc.ofMethod(DirectMethodHandleDesc.Kind.STATIC, CD_FUNCTION_DESC, "ofVoid",
                  MethodTypeDesc.of(CD_FUNCTION_DESC, CD_MEMORY_LAYOUT.arrayType()));
  
      static final MethodHandleDesc MH_FUNCTION = MethodHandleDesc.ofMethod(DirectMethodHandleDesc.Kind.STATIC, CD_FUNCTION_DESC, "of",
                  MethodTypeDesc.of(CD_FUNCTION_DESC, CD_MEMORY_LAYOUT, CD_MEMORY_LAYOUT.arrayType()));
  
      static final MethodHandleDesc MH_WITH_BIT_ALIGNMENT = MethodHandleDesc.ofMethod(DirectMethodHandleDesc.Kind.INTERFACE_VIRTUAL, CD_MEMORY_LAYOUT, "withBitAlignment",
                  MethodTypeDesc.of(CD_MEMORY_LAYOUT, CD_long));
  
!     static final MethodHandleDesc MH_WITH_NAME = MethodHandleDesc.ofMethod(DirectMethodHandleDesc.Kind.INTERFACE_VIRTUAL, CD_MEMORY_LAYOUT, "withName",
!                 MethodTypeDesc.of(CD_MEMORY_LAYOUT, CD_String));
  }
< prev index next >