1 /* 2 * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 * 25 */ 26 package jdk.incubator.foreign; 27 28 import java.lang.constant.ConstantDescs; 29 import java.lang.constant.DynamicConstantDesc; 30 import java.lang.constant.MethodHandleDesc; 31 import java.nio.ByteOrder; 32 import java.util.Objects; 33 import java.util.Optional; 34 import java.util.OptionalLong; 35 36 /** 37 * A value layout. A value layout is used to model the memory layout associated with values of basic data types, such as <em>integral</em> types 38 * (either signed or unsigned) and <em>floating-point</em> types. Each value layout has a size and a byte order (see {@link ByteOrder}). 39 * 40 * <p> 41 * This is a <a href="{@docRoot}/java.base/java/lang/doc-files/ValueBased.html">value-based</a> 42 * class; use of identity-sensitive operations (including reference equality 43 * ({@code ==}), identity hash code, or synchronization) on instances of 44 * {@code ValueLayout} may have unpredictable results and should be avoided. 45 * The {@code equals} method should be used for comparisons. 46 * 47 * @implSpec 48 * This class is immutable and thread-safe. 49 */ 50 public final class ValueLayout extends AbstractLayout implements MemoryLayout { 51 52 private final ByteOrder order; 53 54 ValueLayout(ByteOrder order, long size) { 55 this(order, size, size, Optional.empty()); 56 } 57 58 ValueLayout(ByteOrder order, long size, long alignment, Optional<String> name) { 59 super(OptionalLong.of(size), alignment, name); 60 this.order = order; 61 } 62 63 /** 64 * Returns the value's byte order. 65 * 66 * @return the value's byte order. 67 */ 68 public ByteOrder order() { 69 return order; 70 } 71 72 /** 73 * Returns a new value layout with given byte order. 74 * 75 * @param order the desired byte order. 76 * @return a new value layout with given byte order. 77 */ 78 public ValueLayout withOrder(ByteOrder order) { 79 return new ValueLayout(order, bitSize(), alignment, optName()); 80 } 81 82 @Override 83 public String toString() { 84 return decorateLayoutString(String.format("%s%d", 85 order == ByteOrder.BIG_ENDIAN ? "B" : "b", 86 bitSize())); 87 } 88 89 @Override 90 public boolean equals(Object other) { 91 if (this == other) { 92 return true; 93 } 94 if (!super.equals(other)) { 95 return false; 96 } 97 if (!(other instanceof ValueLayout)) { 98 return false; 99 } 100 ValueLayout v = (ValueLayout)other; 101 return order.equals(v.order) && 102 bitSize() == v.bitSize() && 103 alignment == v.alignment; 104 } 105 106 @Override 107 public int hashCode() { 108 return Objects.hash(super.hashCode(), order, bitSize(), alignment); 109 } 110 111 @Override 112 ValueLayout dup(long alignment, Optional<String> name) { 113 return new ValueLayout(order, bitSize(), alignment, name); 114 } 115 116 @Override 117 public Optional<DynamicConstantDesc<ValueLayout>> describeConstable() { 118 return Optional.of(DynamicConstantDesc.ofNamed(ConstantDescs.BSM_INVOKE, "value", 119 CD_VALUE_LAYOUT, MH_VALUE, bitSize(), order == ByteOrder.BIG_ENDIAN ? BIG_ENDIAN : LITTLE_ENDIAN)); 120 } 121 122 //hack: the declarations below are to make javadoc happy; we could have used generics in AbstractLayout 123 //but that causes issues with javadoc, see JDK-8224052 124 125 /** 126 * {@inheritDoc} 127 */ 128 @Override 129 public ValueLayout withName(String name) { 130 return (ValueLayout)super.withName(name); 131 } 132 133 /** 134 * {@inheritDoc} 135 */ 136 @Override 137 public ValueLayout withBitAlignment(long alignmentBits) { 138 return (ValueLayout)super.withBitAlignment(alignmentBits); 139 } 140 }