Skip to content
This repository has been archived by the owner on Sep 19, 2023. It is now read-only.

Commit

Permalink
Browse files Browse the repository at this point in the history
8289558: Need spec clarification of j.l.foreign.*Layout
Reviewed-by: psandoz, jvernee
  • Loading branch information
mcimadamore committed Jul 7, 2022
1 parent 8dd94a2 commit 889150b
Show file tree
Hide file tree
Showing 5 changed files with 37 additions and 34 deletions.
24 changes: 13 additions & 11 deletions src/java.base/share/classes/java/lang/foreign/AbstractLayout.java
Expand Up @@ -120,12 +120,15 @@ public boolean isPadding() {
return this instanceof PaddingLayout;
}

// the following methods have to copy the same Javadoc as in MemoryLayout, or subclasses will just show
// the Object methods javadoc

/**
* {@return the hash code value for this layout}
*/
@Override
public int hashCode() {
return name.hashCode() << Long.hashCode(alignment);
return Objects.hash(name, size, alignment);
}

/**
Expand All @@ -134,28 +137,27 @@ public int hashCode() {
* the same kind, have the same size, name and alignment constraints. Furthermore, depending on the layout kind, additional
* conditions must be satisfied:
* <ul>
* <li>two value layouts are considered equal if they have the same byte order (see {@link ValueLayout#order()})</li>
* <li>two value layouts are considered equal if they have the same {@linkplain ValueLayout#order() order},
* and {@linkplain ValueLayout#carrier() carrier}</li>
* <li>two sequence layouts are considered equal if they have the same element count (see {@link SequenceLayout#elementCount()}), and
* if their element layouts (see {@link SequenceLayout#elementLayout()}) are also equal</li>
* <li>two group layouts are considered equal if they are of the same kind (see {@link GroupLayout#isStruct()},
* {@link GroupLayout#isUnion()}) and if their member layouts (see {@link GroupLayout#memberLayouts()}) are also equal</li>
* </ul>
*
* @param that the object to be compared for equality with this layout.
* @param other the object to be compared for equality with this layout.
* @return {@code true} if the specified object is equal to this layout.
*/
@Override
public boolean equals(Object that) {
if (this == that) {
public boolean equals(Object other) {
if (this == other) {
return true;
}

if (!(that instanceof AbstractLayout)) {
return false;
}

return Objects.equals(name, ((AbstractLayout) that).name) &&
Objects.equals(alignment, ((AbstractLayout) that).alignment);
return other instanceof AbstractLayout otherLayout &&
name.equals(otherLayout.name) &&
size == otherLayout.size &&
alignment == otherLayout.alignment;
}

/**
Expand Down
Expand Up @@ -143,10 +143,9 @@ public boolean equals(Object other) {
if (!super.equals(other)) {
return false;
}
if (!(other instanceof GroupLayout g)) {
return false;
}
return kind.equals(g.kind) && elements.equals(g.elements);
return other instanceof GroupLayout otherGroup &&
kind == otherGroup.kind &&
elements.equals(otherGroup.elements);
}

/**
Expand Down
Expand Up @@ -584,17 +584,18 @@ static PathElement sequenceElement() {
* the same kind, have the same size, name and alignment constraints. Furthermore, depending on the layout kind, additional
* conditions must be satisfied:
* <ul>
* <li>two value layouts are considered equal if they have the same byte order (see {@link ValueLayout#order()})</li>
* <li>two value layouts are considered equal if they have the same {@linkplain ValueLayout#order() order},
* and {@linkplain ValueLayout#carrier() carrier}</li>
* <li>two sequence layouts are considered equal if they have the same element count (see {@link SequenceLayout#elementCount()}), and
* if their element layouts (see {@link SequenceLayout#elementLayout()}) are also equal</li>
* <li>two group layouts are considered equal if they are of the same kind (see {@link GroupLayout#isStruct()},
* {@link GroupLayout#isUnion()}) and if their member layouts (see {@link GroupLayout#memberLayouts()}) are also equal</li>
* </ul>
*
* @param that the object to be compared for equality with this layout.
* @param other the object to be compared for equality with this layout.
* @return {@code true} if the specified object is equal to this layout.
*/
boolean equals(Object that);
boolean equals(Object other);

/**
* {@return the hash code value for this layout}
Expand Down
Expand Up @@ -124,7 +124,6 @@ public SequenceLayout withElementCount(long elementCount) {
* @param elementCounts an array of element counts, of which at most one can be {@code -1}.
* @return a sequence layout where element layouts in the flattened projection of this
* sequence layout (see {@link #flatten()}) are re-arranged into one or more nested sequence layouts.
* @throws UnsupportedOperationException if this sequence layout does not have an element count.
* @throws IllegalArgumentException if two or more element counts are set to {@code -1}, or if one
* or more element count is {@code <= 0} (but other than {@code -1}) or, if, after any required inference,
* multiplying the element counts does not yield the same element count as the flattened projection of this
Expand Down Expand Up @@ -187,8 +186,6 @@ public SequenceLayout reshape(long... elementCounts) {
* }
* @return a sequence layout with the same size as this layout (but, possibly, with different
* element count), whose element layout is not a sequence layout.
* @throws UnsupportedOperationException if this sequence layout, or one of the nested sequence layouts being
* flattened, does not have an element count.
*/
public SequenceLayout flatten() {
long count = elementCount();
Expand All @@ -214,10 +211,9 @@ public boolean equals(Object other) {
if (!super.equals(other)) {
return false;
}
if (!(other instanceof SequenceLayout s)) {
return false;
}
return elemCount == s.elemCount && elementLayout.equals(s.elementLayout);
return other instanceof SequenceLayout otherSeq &&
elemCount == otherSeq.elemCount &&
elementLayout.equals(otherSeq.elementLayout);
}

@Override
Expand Down
23 changes: 14 additions & 9 deletions src/java.base/share/classes/java/lang/foreign/ValueLayout.java
Expand Up @@ -93,6 +93,9 @@ public ValueLayout withOrder(ByteOrder order) {
return new ValueLayout(carrier, Objects.requireNonNull(order), bitSize(), alignment, name());
}

/**
* {@inheritDoc}
*/
@Override
public String toString() {
char descriptor = carrier == MemoryAddress.class ? 'A' : carrier.descriptorString().charAt(0);
Expand All @@ -102,6 +105,9 @@ public String toString() {
return decorateLayoutString(String.format("%s%d", descriptor, bitSize()));
}

/**
* {@inheritDoc}
*/
@Override
public boolean equals(Object other) {
if (this == other) {
Expand All @@ -110,13 +116,9 @@ public boolean equals(Object other) {
if (!super.equals(other)) {
return false;
}
if (!(other instanceof ValueLayout v)) {
return false;
}
return carrier.equals(v.carrier) &&
order.equals(v.order) &&
bitSize() == v.bitSize() &&
alignment == v.alignment;
return other instanceof ValueLayout otherValue &&
carrier.equals(otherValue.carrier) &&
order.equals(otherValue.order);
}

/**
Expand Down Expand Up @@ -171,7 +173,7 @@ public boolean equals(Object other) {
* @return a var handle which can be used to dereference a multi-dimensional array, featuring {@code shape.length + 1}
* {@code long} coordinates.
* @throws IllegalArgumentException if {@code shape[i] < 0}, for at least one index {@code i}.
* @throws UnsupportedOperationException if the layout path has one or more elements with incompatible alignment constraints.
* @throws UnsupportedOperationException if {@code bitAlignment() > bitSize()}.
* @see MethodHandles#memorySegmentViewVarHandle
* @see MemoryLayout#varHandle(PathElement...)
* @see SequenceLayout
Expand All @@ -198,9 +200,12 @@ public Class<?> carrier() {
return carrier;
}

/**
* {@inheritDoc}
*/
@Override
public int hashCode() {
return Objects.hash(super.hashCode(), order, bitSize(), alignment);
return Objects.hash(super.hashCode(), order, carrier);
}

@Override
Expand Down

1 comment on commit 889150b

@openjdk-notifier
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.