From 8ade4d32c62940cdfb8c7f0d04d861e84cc5affb Mon Sep 17 00:00:00 2001 From: Doug Simon Date: Sun, 20 Apr 2025 13:43:05 +0200 Subject: [PATCH] copied BinaryInput and BinaryOutput classes into libgraal and removed org.graalvm.nativebridge dependency --- compiler/mx.compiler/suite.py | 3 +- .../libgraal/truffle/BinaryInput.java | 635 +++++++++++++++++ .../libgraal/truffle/BinaryOutput.java | 667 ++++++++++++++++++ .../libgraal/truffle/HSTruffleCompilable.java | 1 - .../truffle/HSTruffleCompilationTask.java | 1 - .../truffle/HSTruffleCompilerRuntime.java | 1 - .../truffle/LibGraalTruffleEntryPoints.java | 1 - 7 files changed, 1303 insertions(+), 6 deletions(-) create mode 100644 compiler/src/jdk.graal.compiler.libgraal/src/jdk/graal/compiler/libgraal/truffle/BinaryInput.java create mode 100644 compiler/src/jdk.graal.compiler.libgraal/src/jdk/graal/compiler/libgraal/truffle/BinaryOutput.java diff --git a/compiler/mx.compiler/suite.py b/compiler/mx.compiler/suite.py index 334cc280392f..66f6f0a74deb 100644 --- a/compiler/mx.compiler/suite.py +++ b/compiler/mx.compiler/suite.py @@ -488,8 +488,7 @@ "GRAAL", "GRAAL_MANAGEMENT", "sdk:NATIVEIMAGE_LIBGRAAL", - "sdk:JNIUTILS", - "sdk:NATIVEBRIDGE" + "sdk:JNIUTILS" ], "requiresConcealed" : { "java.base" : [ diff --git a/compiler/src/jdk.graal.compiler.libgraal/src/jdk/graal/compiler/libgraal/truffle/BinaryInput.java b/compiler/src/jdk.graal.compiler.libgraal/src/jdk/graal/compiler/libgraal/truffle/BinaryInput.java new file mode 100644 index 000000000000..4709daf692fb --- /dev/null +++ b/compiler/src/jdk.graal.compiler.libgraal/src/jdk/graal/compiler/libgraal/truffle/BinaryInput.java @@ -0,0 +1,635 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.graal.compiler.libgraal.truffle; + +import org.graalvm.nativeimage.c.type.CCharPointer; +import org.graalvm.nativeimage.c.type.CTypeConversion; + +import java.nio.ByteBuffer; +import java.nio.ByteOrder; + +import static jdk.graal.compiler.libgraal.truffle.BinaryOutput.ARRAY; +import static jdk.graal.compiler.libgraal.truffle.BinaryOutput.BOOLEAN; +import static jdk.graal.compiler.libgraal.truffle.BinaryOutput.BYTE; +import static jdk.graal.compiler.libgraal.truffle.BinaryOutput.CHAR; +import static jdk.graal.compiler.libgraal.truffle.BinaryOutput.DOUBLE; +import static jdk.graal.compiler.libgraal.truffle.BinaryOutput.FLOAT; +import static jdk.graal.compiler.libgraal.truffle.BinaryOutput.INT; +import static jdk.graal.compiler.libgraal.truffle.BinaryOutput.LARGE_STRING_TAG; +import static jdk.graal.compiler.libgraal.truffle.BinaryOutput.LONG; +import static jdk.graal.compiler.libgraal.truffle.BinaryOutput.NULL; +import static jdk.graal.compiler.libgraal.truffle.BinaryOutput.SHORT; +import static jdk.graal.compiler.libgraal.truffle.BinaryOutput.STRING; +import static jdk.graal.compiler.libgraal.truffle.BinaryOutput.bufferSize; + +/** + * This is a copy of {@code org.graalvm.nativebridge.BinaryInput} to avoid an external dependency. + */ +public abstract class BinaryInput { + + private static final int EOF = -1; + + private byte[] tempEncodingByteBuffer; + private char[] tempEncodingCharBuffer; + protected final int length; + protected int pos; + + private BinaryInput(int length) { + this.length = length; + } + + /** + * Reads a single byte and returns {@code true} if that byte is non-zero, {@code false} if that + * byte is zero. + * + * @throws IndexOutOfBoundsException if there are not enough bytes to read. + */ + public final boolean readBoolean() throws IndexOutOfBoundsException { + int b = read(); + if (b < 0) { + throw new IndexOutOfBoundsException(); + } + return b != 0; + } + + /** + * Reads and returns a single byte. + * + * @throws IndexOutOfBoundsException if there are not enough bytes to read. + */ + public final byte readByte() throws IndexOutOfBoundsException { + int b = read(); + if (b < 0) { + throw new IndexOutOfBoundsException(); + } + return (byte) b; + } + + /** + * Reads two bytes and returns a {@code short} value. + * + * @throws IndexOutOfBoundsException if there are not enough bytes to read. + */ + public final short readShort() throws IndexOutOfBoundsException { + int b1 = read(); + int b2 = read(); + if ((b1 | b2) < 0) { + throw new IndexOutOfBoundsException(); + } + return packShort(b1, b2); + } + + /** + * Creates a Java {@code short} from given unsigned bytes, where {@code b1} is the most + * significant byte {@code byte} and {@code b2} is the least significant {@code byte}. + */ + private static short packShort(int b1, int b2) { + return (short) ((b1 << 8) + b2); + } + + /** + * Reads two bytes and returns a {@code char} value. + * + * @throws IndexOutOfBoundsException if there are not enough bytes to read. + */ + public final char readChar() throws IndexOutOfBoundsException { + int b1 = read(); + int b2 = read(); + if ((b1 | b2) < 0) { + throw new IndexOutOfBoundsException(); + } + return packChar(b1, b2); + } + + /** + * Creates a Java {@code char} from given unsigned bytes, where {@code b1} is the most + * significant byte {@code byte} and {@code b2} is the least significant {@code byte}. + */ + private static char packChar(int b1, int b2) { + return (char) ((b1 << 8) + b2); + } + + /** + * Reads four bytes and returns an {@code int} value. + * + * @throws IndexOutOfBoundsException if there are not enough bytes to read. + */ + public final int readInt() throws IndexOutOfBoundsException { + int b1 = read(); + int b2 = read(); + int b3 = read(); + int b4 = read(); + if ((b1 | b2 | b3 | b4) < 0) { + throw new IndexOutOfBoundsException(); + } + return packInt(b1, b2, b3, b4); + } + + /** + * Creates a Java {@code int} from given unsigned bytes, where {@code b1} is the most + * significant byte {@code byte} and {@code b4} is the least significant {@code byte}. + */ + private static int packInt(int b1, int b2, int b3, int b4) { + return (b1 << 24) + (b2 << 16) + (b3 << 8) + b4; + } + + /** + * Reads eight bytes and returns a {@code long} value. + * + * @throws IndexOutOfBoundsException if there are not enough bytes to read. + */ + public final long readLong() throws IndexOutOfBoundsException { + int b1 = read(); + int b2 = read(); + int b3 = read(); + int b4 = read(); + int b5 = read(); + int b6 = read(); + int b7 = read(); + int b8 = read(); + if ((b1 | b2 | b3 | b4 | b5 | b6 | b7 | b8) < 0) { + throw new IndexOutOfBoundsException(); + } + return packLong(b1, b2, b3, b4, b5, b6, b7, b8); + } + + /** + * Creates a Java {@code long} from given unsigned bytes, where {@code b1} is the most + * significant byte {@code byte} and {@code b8} is the least significant {@code byte}. + */ + private static long packLong(int b1, int b2, int b3, int b4, int b5, int b6, int b7, int b8) { + return ((long) b1 << 56) + ((long) b2 << 48) + ((long) b3 << 40) + ((long) b4 << 32) + + ((long) b5 << 24) + ((long) b6 << 16) + ((long) b7 << 8) + b8; + } + + /** + * Reads four bytes and returns a {@code float} value. It does this by reading an {@code int} + * value and converting the {@code int} value to a {@code float} using + * {@link Float#intBitsToFloat(int)}. + * + * @throws IndexOutOfBoundsException if there are not enough bytes to read. + */ + public final float readFloat() throws IndexOutOfBoundsException { + return Float.intBitsToFloat(readInt()); + } + + /** + * Reads eight bytes and returns a {@code double} value. It does this by reading a {@code long} + * value and converting the {@code long} value to a {@code double} using + * {@link Double#longBitsToDouble(long)}. + * + * @throws IndexOutOfBoundsException if there are not enough bytes to read. + */ + public final double readDouble() throws IndexOutOfBoundsException { + return Double.longBitsToDouble(readLong()); + } + + /** + * Reads a single byte. The byte value is returned as an {@code int} in the range {@code 0} to + * {@code 255}. If no byte is available because the end of the stream has been reached, the + * value {@code -1} is returned. + */ + public abstract int read(); + + /** + * Reads {@code len} bytes into a byte array starting at offset {@code off}. + * + * @throws IndexOutOfBoundsException if there are not enough bytes to read + */ + public abstract void read(byte[] b, int off, int len) throws IndexOutOfBoundsException; + + /** + * Reads a string using a modified UTF-8 encoding in a machine-independent manner. + * + * @throws IndexOutOfBoundsException if there are not enough bytes to read. + * @throws IllegalArgumentException if the bytes do not represent a valid modified UTF-8 + * encoding of a string. + */ + public final String readUTF() throws IndexOutOfBoundsException, IllegalArgumentException { + int len; + int b1 = read(); + int b2 = read(); + if ((b1 | b2) < 0) { + throw new IndexOutOfBoundsException(); + } + if ((b1 & LARGE_STRING_TAG) == LARGE_STRING_TAG) { + int b3 = read(); + int b4 = read(); + if ((b3 | b4) < 0) { + throw new IndexOutOfBoundsException(); + } + len = ((b1 & ~LARGE_STRING_TAG) << 24) + (b2 << 16) + (b3 << 8) + b4; + } else { + len = (b1 << 8) + b2; + } + ensureBufferSize(len); + if (tempEncodingCharBuffer == null || tempEncodingCharBuffer.length < len) { + tempEncodingCharBuffer = new char[Math.max(bufferSize(0, len), 80)]; + } + + int c1; + int c2; + int c3; + int byteCount = 0; + int charCount = 0; + + read(tempEncodingByteBuffer, 0, len); + + while (byteCount < len) { + c1 = tempEncodingByteBuffer[byteCount] & 0xff; + if (c1 > 127) { + break; + } + byteCount++; + tempEncodingCharBuffer[charCount++] = (char) c1; + } + + while (byteCount < len) { + c1 = tempEncodingByteBuffer[byteCount] & 0xff; + switch (c1 >> 4) { + case 0: + case 1: + case 2: + case 3: + case 4: + case 5: + case 6: + case 7: + /* 0xxxxxxx */ + byteCount++; + tempEncodingCharBuffer[charCount++] = (char) c1; + break; + case 12: + case 13: + /* 110x xxxx 10xx xxxx */ + byteCount += 2; + if (byteCount > len) { + throw new IllegalArgumentException("Partial character at end"); + } + c2 = tempEncodingByteBuffer[byteCount - 1]; + if ((c2 & 0xC0) != 0x80) { + throw new IllegalArgumentException("malformed input around byte " + byteCount); + } + tempEncodingCharBuffer[charCount++] = (char) (((c1 & 0x1F) << 6) | (c2 & 0x3F)); + break; + case 14: + /* 1110 xxxx 10xx xxxx 10xx xxxx */ + byteCount += 3; + if (byteCount > len) { + throw new IllegalArgumentException("malformed input: partial character at end"); + } + c2 = tempEncodingByteBuffer[byteCount - 2]; + c3 = tempEncodingByteBuffer[byteCount - 1]; + if (((c2 & 0xC0) != 0x80) || ((c3 & 0xC0) != 0x80)) { + throw new IllegalArgumentException("malformed input around byte " + (byteCount - 1)); + } + tempEncodingCharBuffer[charCount++] = (char) (((c1 & 0x0F) << 12) | ((c2 & 0x3F) << 6) | (c3 & 0x3F)); + break; + default: + /* 10xx xxxx, 1111 xxxx */ + throw new IllegalArgumentException("malformed input around byte " + byteCount); + } + } + // The number of chars produced may be less than len + return new String(tempEncodingCharBuffer, 0, charCount); + } + + /** + * Reads a single value, using the data type encoded in the marshalled data. + * + * @return The read value, such as a boxed Java primitive, a {@link String}, a {@code null}, or + * an array of these types. + * @throws IndexOutOfBoundsException if there are not enough bytes to read. + * @throws IllegalArgumentException when the marshaled type is not supported or if the bytes do + * not represent a valid modified UTF-8 encoding of a string. + */ + public final Object readTypedValue() throws IndexOutOfBoundsException, IllegalArgumentException { + byte tag = readByte(); + switch (tag) { + case ARRAY: + int len = readInt(); + Object[] arr = new Object[len]; + for (int i = 0; i < len; i++) { + arr[i] = readTypedValue(); + } + return arr; + case NULL: + return null; + case BOOLEAN: + return readBoolean(); + case BYTE: + return readByte(); + case SHORT: + return readShort(); + case CHAR: + return readChar(); + case INT: + return readInt(); + case LONG: + return readLong(); + case FLOAT: + return readFloat(); + case DOUBLE: + return readDouble(); + case STRING: + return readUTF(); + default: + throw new IllegalArgumentException(String.format("Unknown tag %d", tag)); + } + } + + /** + * Reads {@code len} bytes into a boolean array starting at offset {@code off}. + * + * @throws IndexOutOfBoundsException if there are not enough bytes to read + */ + public final void read(boolean[] b, int off, int len) { + ensureBufferSize(len); + read(tempEncodingByteBuffer, 0, len); + int limit = off + len; + for (int i = off, j = 0; i < limit; i++) { + b[i] = tempEncodingByteBuffer[j++] != 0; + } + } + + /** + * Reads {@code len} shorts into a short array starting at offset {@code off}. + * + * @throws IndexOutOfBoundsException if there are not enough bytes to read + */ + public final void read(short[] b, int off, int len) { + int size = len * Short.BYTES; + ensureBufferSize(size); + read(tempEncodingByteBuffer, 0, size); + int limit = off + len; + for (int i = off, j = 0; i < limit; i++) { + int b1 = (tempEncodingByteBuffer[j++] & 0xff); + int b2 = (tempEncodingByteBuffer[j++] & 0xff); + b[i] = packShort(b1, b2); + } + } + + /** + * Reads {@code len} chars into a char array starting at offset {@code off}. + * + * @throws IndexOutOfBoundsException if there are not enough bytes to read + */ + public final void read(char[] b, int off, int len) { + int size = len * Character.BYTES; + ensureBufferSize(size); + read(tempEncodingByteBuffer, 0, size); + int limit = off + len; + for (int i = off, j = 0; i < limit; i++) { + int b1 = (tempEncodingByteBuffer[j++] & 0xff); + int b2 = (tempEncodingByteBuffer[j++] & 0xff); + b[i] = packChar(b1, b2); + } + } + + /** + * Reads {@code len} ints into an int array starting at offset {@code off}. + * + * @throws IndexOutOfBoundsException if there are not enough bytes to read + */ + public final void read(int[] b, int off, int len) { + int size = len * Integer.BYTES; + ensureBufferSize(size); + read(tempEncodingByteBuffer, 0, size); + int limit = off + len; + for (int i = off, j = 0; i < limit; i++) { + int b1 = (tempEncodingByteBuffer[j++] & 0xff); + int b2 = (tempEncodingByteBuffer[j++] & 0xff); + int b3 = (tempEncodingByteBuffer[j++] & 0xff); + int b4 = (tempEncodingByteBuffer[j++] & 0xff); + b[i] = packInt(b1, b2, b3, b4); + } + } + + /** + * Reads {@code len} longs into a long array starting at offset {@code off}. + * + * @throws IndexOutOfBoundsException if there are not enough bytes to read + */ + public final void read(long[] b, int off, int len) { + int size = len * Long.BYTES; + ensureBufferSize(size); + read(tempEncodingByteBuffer, 0, size); + int limit = off + len; + for (int i = off, j = 0; i < limit; i++) { + int b1 = (tempEncodingByteBuffer[j++] & 0xff); + int b2 = (tempEncodingByteBuffer[j++] & 0xff); + int b3 = (tempEncodingByteBuffer[j++] & 0xff); + int b4 = (tempEncodingByteBuffer[j++] & 0xff); + int b5 = (tempEncodingByteBuffer[j++] & 0xff); + int b6 = (tempEncodingByteBuffer[j++] & 0xff); + int b7 = (tempEncodingByteBuffer[j++] & 0xff); + int b8 = (tempEncodingByteBuffer[j++] & 0xff); + b[i] = packLong(b1, b2, b3, b4, b5, b6, b7, b8); + } + } + + /** + * Reads {@code len} floats into a float array starting at offset {@code off}. + * + * @throws IndexOutOfBoundsException if there are not enough bytes to read + */ + public final void read(float[] b, int off, int len) { + int size = len * Float.BYTES; + ensureBufferSize(size); + read(tempEncodingByteBuffer, 0, size); + int limit = off + len; + for (int i = off, j = 0; i < limit; i++) { + int b1 = (tempEncodingByteBuffer[j++] & 0xff); + int b2 = (tempEncodingByteBuffer[j++] & 0xff); + int b3 = (tempEncodingByteBuffer[j++] & 0xff); + int b4 = (tempEncodingByteBuffer[j++] & 0xff); + b[i] = Float.intBitsToFloat(packInt(b1, b2, b3, b4)); + } + } + + /** + * Reads {@code len} doubles into a double array starting at offset {@code off}. + * + * @throws IndexOutOfBoundsException if there are not enough bytes to read + */ + public final void read(double[] b, int off, int len) { + int size = len * Double.BYTES; + ensureBufferSize(size); + read(tempEncodingByteBuffer, 0, size); + int limit = off + len; + for (int i = off, j = 0; i < limit; i++) { + int b1 = (tempEncodingByteBuffer[j++] & 0xff); + int b2 = (tempEncodingByteBuffer[j++] & 0xff); + int b3 = (tempEncodingByteBuffer[j++] & 0xff); + int b4 = (tempEncodingByteBuffer[j++] & 0xff); + int b5 = (tempEncodingByteBuffer[j++] & 0xff); + int b6 = (tempEncodingByteBuffer[j++] & 0xff); + int b7 = (tempEncodingByteBuffer[j++] & 0xff); + int b8 = (tempEncodingByteBuffer[j++] & 0xff); + b[i] = Double.longBitsToDouble(packLong(b1, b2, b3, b4, b5, b6, b7, b8)); + } + } + + /** + * Returns a read only {@link ByteBuffer} backed by the {@link BinaryInput} internal buffer. The + * content of the buffer will start at the {@link BinaryInput}'s current position. The buffer's + * capacity and limit will be {@code len}, its position will be zero, its mark will be + * undefined, and its byte order will be {@link ByteOrder#BIG_ENDIAN BIG_ENDIAN}. After a + * successful call, the {@link BinaryInput}'s current position is incremented by the + * {@code len}. + * + * @throws IndexOutOfBoundsException if the BinaryInput has not enough remaining bytes. + */ + public abstract ByteBuffer asByteBuffer(int len); + + /** + * Creates a new buffer backed by a byte array. + */ + public static BinaryInput create(byte[] buffer) { + return new ByteArrayBinaryInput(buffer); + } + + /** + * Creates a new buffer backed by a byte array only up to a given length. + */ + public static BinaryInput create(byte[] buffer, int length) { + return new ByteArrayBinaryInput(buffer, length); + } + + /** + * Creates a new buffer wrapping an off-heap memory segment starting at an {@code address} + * having {@code length} bytes. + */ + public static BinaryInput create(CCharPointer address, int length) { + return new CCharPointerInput(address, length); + } + + private void ensureBufferSize(int len) { + if (tempEncodingByteBuffer == null || tempEncodingByteBuffer.length < len) { + tempEncodingByteBuffer = new byte[Math.max(bufferSize(0, len), 80)]; + } + } + + private static final class ByteArrayBinaryInput extends BinaryInput { + + private final byte[] buffer; + + ByteArrayBinaryInput(byte[] buffer) { + super(buffer.length); + this.buffer = buffer; + } + + ByteArrayBinaryInput(byte[] buffer, int length) { + super(length); + this.buffer = buffer; + } + + @Override + public int read() { + if (pos >= length) { + return EOF; + } + return (buffer[pos++] & 0xff); + } + + @Override + public void read(byte[] b, int off, int len) { + if (len < 0) { + throw new IllegalArgumentException(String.format("Len must be non negative but was %d", len)); + } + if (pos + len > length) { + throw new IndexOutOfBoundsException(); + } + System.arraycopy(buffer, pos, b, off, len); + pos += len; + } + + @Override + public ByteBuffer asByteBuffer(int len) { + ByteBuffer result = ByteBuffer.wrap(buffer, pos, len).slice().asReadOnlyBuffer(); + pos += len; + return result; + } + } + + private static final class CCharPointerInput extends BinaryInput { + + /** + * Represents the point at which the average cost of a JNI call exceeds the expense of an + * element by element copy. See {@code java.nio.Bits#JNI_COPY_TO_ARRAY_THRESHOLD}. + */ + private static final int BYTEBUFFER_COPY_TO_ARRAY_THRESHOLD = 6; + + private final CCharPointer address; + /** + * ByteBuffer view of this {@link CCharPointerInput} direct memory. The ByteBuffer is used + * for bulk data transfers, where the bulk ByteBuffer operations outperform element by + * element copying by an order of magnitude. + */ + private ByteBuffer byteBufferView; + + CCharPointerInput(CCharPointer address, int length) { + super(length); + this.address = address; + } + + @Override + public int read() { + if (pos >= length) { + return EOF; + } + return (address.read(pos++) & 0xff); + } + + @Override + public void read(byte[] b, int off, int len) { + if (len < 0) { + throw new IllegalArgumentException(String.format("Len must be non negative but was %d", len)); + } + if (pos + len > length) { + throw new IndexOutOfBoundsException(); + } + if (len > BYTEBUFFER_COPY_TO_ARRAY_THRESHOLD) { + if (byteBufferView == null) { + byteBufferView = CTypeConversion.asByteBuffer(address, length); + } + byteBufferView.position(pos); + byteBufferView.get(b, off, len); + } else { + for (int i = 0, j = pos; i < len; i++, j++) { + b[off + i] = address.read(j); + } + } + pos += len; + } + + @Override + public ByteBuffer asByteBuffer(int len) { + ByteBuffer result = CTypeConversion.asByteBuffer(address.addressOf(pos), len).order(ByteOrder.BIG_ENDIAN).asReadOnlyBuffer(); + pos += len; + return result; + } + } +} diff --git a/compiler/src/jdk.graal.compiler.libgraal/src/jdk/graal/compiler/libgraal/truffle/BinaryOutput.java b/compiler/src/jdk.graal.compiler.libgraal/src/jdk/graal/compiler/libgraal/truffle/BinaryOutput.java new file mode 100644 index 000000000000..a2190eec77d6 --- /dev/null +++ b/compiler/src/jdk.graal.compiler.libgraal/src/jdk/graal/compiler/libgraal/truffle/BinaryOutput.java @@ -0,0 +1,667 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.graal.compiler.libgraal.truffle; + +import org.graalvm.nativeimage.UnmanagedMemory; +import org.graalvm.nativeimage.c.type.CCharPointer; +import org.graalvm.nativeimage.c.type.CTypeConversion; +import org.graalvm.word.WordFactory; + +import java.io.Closeable; +import java.nio.ByteBuffer; +import java.util.Arrays; +import java.util.Objects; + +/** + * This is a copy of {@code org.graalvm.nativebridge.BinaryInput} to avoid an external dependency. + */ +public abstract class BinaryOutput { + + /** + * Maximum string length for string encoded by 4 bytes length followed be content. + */ + private static final int MAX_LENGTH = Integer.MAX_VALUE - Integer.BYTES; + /** + * Maximum string length for string encoded by 2 bytes length followed be content. + */ + private static final int MAX_SHORT_LENGTH = Short.MAX_VALUE; + /** + * Tag to distinguish between long and short string. The tag is set in the first string length + * byte. + */ + static final int LARGE_STRING_TAG = 1 << 7; + + // Type tags used by writeTypedValue + static final byte NULL = 0; + static final byte BOOLEAN = NULL + 1; + static final byte BYTE = BOOLEAN + 1; + static final byte SHORT = BYTE + 1; + static final byte CHAR = SHORT + 1; + static final byte INT = CHAR + 1; + static final byte LONG = INT + 1; + static final byte FLOAT = LONG + 1; + static final byte DOUBLE = FLOAT + 1; + static final byte STRING = DOUBLE + 1; + static final byte ARRAY = STRING + 1; + + private byte[] tempDecodingBuffer; + protected int pos; + + private BinaryOutput() { + } + + /** + * Writes a {@code boolean} as a single byte value. The value {@code true} is written as the + * value {@code (byte)1}, the value {@code false} is written as the value {@code (byte)0}. The + * buffer position is incremented by {@code 1}. + */ + public final void writeBoolean(boolean value) { + write(value ? 1 : 0); + } + + /** + * Writes a {@code byte} as a single byte value. The buffer position is incremented by + * {@code 1}. + */ + public final void writeByte(int value) { + write(value); + } + + /** + * Writes a {@code short} as two bytes, high byte first. The buffer position is incremented by + * {@code 2}. + */ + public final void writeShort(int value) { + write((value >>> 8) & 0xff); + write(value & 0xff); + } + + /** + * Writes a {@code char} as two bytes, high byte first. The buffer position is incremented by + * {@code 2}. + */ + public final void writeChar(int value) { + write((value >>> 8) & 0xff); + write(value & 0xff); + } + + /** + * Writes an {@code int} as four bytes, high byte first. The buffer position is incremented by + * {@code 4}. + */ + public final void writeInt(int value) { + write((value >>> 24) & 0xff); + write((value >>> 16) & 0xff); + write((value >>> 8) & 0xff); + write(value & 0xff); + } + + /** + * Writes a {@code long} as eight bytes, high byte first. The buffer position is incremented by + * {@code 8}. + */ + public final void writeLong(long value) { + write((int) ((value >>> 56) & 0xff)); + write((int) ((value >>> 48) & 0xff)); + write((int) ((value >>> 40) & 0xff)); + write((int) ((value >>> 32) & 0xff)); + write((int) ((value >>> 24) & 0xff)); + write((int) ((value >>> 16) & 0xff)); + write((int) ((value >>> 8) & 0xff)); + write((int) (value & 0xff)); + } + + /** + * Converts a {@code float} value to an {@code int} using the + * {@link Float#floatToIntBits(float)}, and then writes that {@code int} as four bytes, high + * byte first. The buffer position is incremented by {@code 4}. + */ + public final void writeFloat(float value) { + writeInt(Float.floatToIntBits(value)); + } + + /** + * Converts a {@code double} value to a {@code long} using the + * {@link Double#doubleToLongBits(double)}, and then writes that {@code long} as eight bytes, + * high byte first. The buffer position is incremented by {@code 8}. + */ + public final void writeDouble(double value) { + writeLong(Double.doubleToLongBits(value)); + } + + /** + * Writes the lowest byte of the argument as a single byte value. The buffer position is + * incremented by {@code 1}. + */ + public abstract void write(int b); + + /** + * Writes {@code len} bytes from the byte {@code array} starting at offset {@code off}. The + * buffer position is incremented by {@code len}. + */ + public abstract void write(byte[] array, int off, int len); + + /** + * Reserves a buffer space. The reserved space can be used for out parameters. + * + * @param numberOfBytes number of bytes to reserve. + */ + public abstract void skip(int numberOfBytes); + + /** + * Writes a string using a modified UTF-8 encoding in a machine-independent manner. + * + * @throws IllegalArgumentException if the {@code string} cannot be encoded using modified UTF-8 + * encoding. + */ + public final void writeUTF(String string) throws IllegalArgumentException { + int len = string.length(); + long utfLen = 0; + int c; + int count = 0; + + for (int i = 0; i < len; i++) { + c = string.charAt(i); + if ((c >= 0x0001) && (c <= 0x007F)) { + utfLen++; + } else if (c > 0x07FF) { + utfLen += 3; + } else { + utfLen += 2; + } + } + + if (utfLen > MAX_LENGTH) { + throw new IllegalArgumentException("String too long to encode, " + utfLen + " bytes"); + } + int headerSize; + if (utfLen > MAX_SHORT_LENGTH) { + headerSize = Integer.BYTES; + ensureBufferSize(headerSize, (int) utfLen); + tempDecodingBuffer[count++] = (byte) ((LARGE_STRING_TAG | (utfLen >>> 24)) & 0xff); + tempDecodingBuffer[count++] = (byte) ((utfLen >>> 16) & 0xFF); + } else { + headerSize = Short.BYTES; + ensureBufferSize(headerSize, (int) utfLen); + } + tempDecodingBuffer[count++] = (byte) ((utfLen >>> 8) & 0xFF); + tempDecodingBuffer[count++] = (byte) (utfLen & 0xFF); + + int i = 0; + for (; i < len; i++) { + c = string.charAt(i); + if (!((c >= 0x0001) && (c <= 0x007F))) { + break; + } + tempDecodingBuffer[count++] = (byte) c; + } + + for (; i < len; i++) { + c = string.charAt(i); + if ((c >= 0x0001) && (c <= 0x007F)) { + tempDecodingBuffer[count++] = (byte) c; + } else if (c > 0x07FF) { + tempDecodingBuffer[count++] = (byte) (0xE0 | ((c >> 12) & 0x0F)); + tempDecodingBuffer[count++] = (byte) (0x80 | ((c >> 6) & 0x3F)); + tempDecodingBuffer[count++] = (byte) (0x80 | (c & 0x3F)); + } else { + tempDecodingBuffer[count++] = (byte) (0xC0 | ((c >> 6) & 0x1F)); + tempDecodingBuffer[count++] = (byte) (0x80 | (c & 0x3F)); + } + } + write(tempDecodingBuffer, 0, (int) (headerSize + utfLen)); + } + + /** + * Returns this buffer's position. + */ + public int getPosition() { + return pos; + } + + /** + * Returns true if a value is a typed value writable using + * {@link #writeTypedValue(Object)}, else false. + */ + public static boolean isTypedValue(Object value) { + if (value == null) { + return true; + } + return value instanceof Object[] || value instanceof Boolean || value instanceof Byte || + value instanceof Short || value instanceof Character || value instanceof Integer || + value instanceof Long || value instanceof Float || value instanceof Double || value instanceof String; + } + + /** + * Writes the value that is represented by the given object, together with information on the + * value's data type. Supported types are boxed Java primitive types, {@link String}, + * {@code null}, and arrays of these types. + * + * @throws IllegalArgumentException when the {@code value} type is not supported or the + * {@code value} is a string which cannot be encoded using modified UTF-8 encoding. + * @see #isTypedValue(Object) to find out whether a value can be serialized. + */ + public final void writeTypedValue(Object value) throws IllegalArgumentException { + if (value instanceof Object[] arr) { + writeByte(ARRAY); + writeInt(arr.length); + for (Object arrElement : arr) { + writeTypedValue(arrElement); + } + } else if (value == null) { + writeByte(NULL); + } else if (value instanceof Boolean) { + writeByte(BOOLEAN); + writeBoolean((boolean) value); + } else if (value instanceof Byte) { + writeByte(BYTE); + writeByte((byte) value); + } else if (value instanceof Short) { + writeByte(SHORT); + writeShort((short) value); + } else if (value instanceof Character) { + writeByte(CHAR); + writeChar((char) value); + } else if (value instanceof Integer) { + writeByte(INT); + writeInt((int) value); + } else if (value instanceof Long) { + writeByte(LONG); + writeLong((long) value); + } else if (value instanceof Float) { + writeByte(FLOAT); + writeFloat((float) value); + } else if (value instanceof Double) { + writeByte(DOUBLE); + writeDouble((double) value); + } else if (value instanceof String) { + writeByte(STRING); + writeUTF((String) value); + } else { + throw new IllegalArgumentException(String.format("Unsupported type %s", value.getClass())); + } + } + + /** + * Writes {@code len} bytes from the boolean {@code array} starting at offset {@code off}. The + * value {@code true} is written as the value {@code (byte)1}, the value {@code false} is + * written as the value {@code (byte)0}. The buffer position is incremented by {@code len}. + */ + public final void write(boolean[] array, int off, int len) { + ensureBufferSize(0, len); + for (int i = 0, j = 0; i < len; i++, j++) { + tempDecodingBuffer[j] = (byte) (array[off + i] ? 1 : 0); + } + write(tempDecodingBuffer, 0, len); + } + + /** + * Writes {@code len} shorts from the {@code array} starting at offset {@code off}. The buffer + * position is incremented by {@code 2 * len}. + */ + public final void write(short[] array, int off, int len) { + int size = len * Short.BYTES; + ensureBufferSize(0, size); + for (int i = 0, j = 0; i < len; i++) { + tempDecodingBuffer[j++] = (byte) ((array[off + i] >>> 8) & 0xff); + tempDecodingBuffer[j++] = (byte) (array[off + i] & 0xff); + } + write(tempDecodingBuffer, 0, size); + } + + /** + * Writes {@code len} chars from the {@code array} starting at offset {@code off}. The buffer + * position is incremented by {@code 2 * len}. + */ + public final void write(char[] array, int off, int len) { + int size = len * Character.BYTES; + ensureBufferSize(0, size); + for (int i = 0, j = 0; i < len; i++) { + tempDecodingBuffer[j++] = (byte) ((array[off + i] >>> 8) & 0xff); + tempDecodingBuffer[j++] = (byte) (array[off + i] & 0xff); + } + write(tempDecodingBuffer, 0, size); + } + + /** + * Writes {@code len} ints from the {@code array} starting at offset {@code off}. The buffer + * position is incremented by {@code 4 * len}. + */ + public final void write(int[] array, int off, int len) { + int size = len * Integer.BYTES; + ensureBufferSize(0, size); + for (int i = 0, j = 0; i < len; i++) { + tempDecodingBuffer[j++] = (byte) ((array[off + i] >>> 24) & 0xff); + tempDecodingBuffer[j++] = (byte) ((array[off + i] >>> 16) & 0xff); + tempDecodingBuffer[j++] = (byte) ((array[off + i] >>> 8) & 0xff); + tempDecodingBuffer[j++] = (byte) (array[off + i] & 0xff); + } + write(tempDecodingBuffer, 0, size); + } + + /** + * Writes {@code len} longs from the {@code array} starting at offset {@code off}. The buffer + * position is incremented by {@code 8 * len}. + */ + public final void write(long[] array, int off, int len) { + int size = len * Long.BYTES; + ensureBufferSize(0, size); + for (int i = 0, j = 0; i < len; i++) { + tempDecodingBuffer[j++] = (byte) ((array[off + i] >>> 56) & 0xff); + tempDecodingBuffer[j++] = (byte) ((array[off + i] >>> 48) & 0xff); + tempDecodingBuffer[j++] = (byte) ((array[off + i] >>> 40) & 0xff); + tempDecodingBuffer[j++] = (byte) ((array[off + i] >>> 32) & 0xff); + tempDecodingBuffer[j++] = (byte) ((array[off + i] >>> 24) & 0xff); + tempDecodingBuffer[j++] = (byte) ((array[off + i] >>> 16) & 0xff); + tempDecodingBuffer[j++] = (byte) ((array[off + i] >>> 8) & 0xff); + tempDecodingBuffer[j++] = (byte) (array[off + i] & 0xff); + } + write(tempDecodingBuffer, 0, size); + } + + /** + * Writes {@code len} floats from the {@code array} starting at offset {@code off}. Each + * {@code float} value is converted to an {@code int} using the + * {@link Float#floatToIntBits(float)} and written as an int. The buffer position is incremented + * by {@code 4 * len}. + */ + public final void write(float[] array, int off, int len) { + int size = len * Float.BYTES; + ensureBufferSize(0, size); + for (int i = 0, j = 0; i < len; i++) { + int bits = Float.floatToIntBits(array[off + i]); + tempDecodingBuffer[j++] = (byte) ((bits >>> 24) & 0xff); + tempDecodingBuffer[j++] = (byte) ((bits >>> 16) & 0xff); + tempDecodingBuffer[j++] = (byte) ((bits >>> 8) & 0xff); + tempDecodingBuffer[j++] = (byte) (bits & 0xff); + } + write(tempDecodingBuffer, 0, size); + } + + /** + * Writes {@code len} doubles from the {@code array} starting at offset {@code off}. Each + * {@code double} value is converted to an {@code lang} using the + * {@link Double#doubleToLongBits(double)} and written as a long. The buffer position is + * incremented by {@code 8 * len}. + */ + public final void write(double[] array, int off, int len) { + int size = len * Double.BYTES; + ensureBufferSize(Integer.BYTES, size); + for (int i = 0, j = 0; i < len; i++) { + long bits = Double.doubleToLongBits(array[off + i]); + tempDecodingBuffer[j++] = (byte) ((bits >>> 56) & 0xff); + tempDecodingBuffer[j++] = (byte) ((bits >>> 48) & 0xff); + tempDecodingBuffer[j++] = (byte) ((bits >>> 40) & 0xff); + tempDecodingBuffer[j++] = (byte) ((bits >>> 32) & 0xff); + tempDecodingBuffer[j++] = (byte) ((bits >>> 24) & 0xff); + tempDecodingBuffer[j++] = (byte) ((bits >>> 16) & 0xff); + tempDecodingBuffer[j++] = (byte) ((bits >>> 8) & 0xff); + tempDecodingBuffer[j++] = (byte) (bits & 0xff); + } + write(tempDecodingBuffer, 0, size); + } + + private void ensureBufferSize(int headerSize, int dataSize) { + if (tempDecodingBuffer == null || tempDecodingBuffer.length < (headerSize + dataSize)) { + tempDecodingBuffer = new byte[bufferSize(headerSize, dataSize)]; + } + } + + /** + * Creates a new buffer backed by a byte array. + */ + public static ByteArrayBinaryOutput create() { + return new ByteArrayBinaryOutput(ByteArrayBinaryOutput.INITIAL_SIZE); + } + + /** + * Creates a new buffer wrapping the {@code initialBuffer}. If the {@code initialBuffer} + * capacity is not sufficient for writing the data, a new array is allocated. Always use + * {@link ByteArrayBinaryOutput#getArray()} to obtain the marshaled data. + */ + public static ByteArrayBinaryOutput create(byte[] initialBuffer) { + Objects.requireNonNull(initialBuffer, "InitialBuffer must be non null."); + return new ByteArrayBinaryOutput(initialBuffer); + } + + /** + * Creates a new buffer wrapping an off-heap memory segment starting at {@code address} having + * {@code length} bytes. If the capacity of an off-heap memory segment is not sufficient for + * writing the data, a new off-heap memory is allocated. Always use + * {@link CCharPointerBinaryOutput#getAddress()} to obtain the marshaled data. + * + * @param address the off-heap memory address + * @param length the off-heap memory size + * @param dynamicallyAllocated {@code true} if the memory was dynamically allocated and should + * be freed when the buffer is closed; {@code false} for the stack allocated memory. + */ + public static CCharPointerBinaryOutput create(CCharPointer address, int length, boolean dynamicallyAllocated) { + return new CCharPointerBinaryOutput(address, length, dynamicallyAllocated); + } + + static int bufferSize(int headerSize, int dataSize) { + return headerSize + (dataSize <= MAX_SHORT_LENGTH ? dataSize << 1 : dataSize); + } + + /** + * A {@link BinaryOutput} backed by a byte array. + */ + public static final class ByteArrayBinaryOutput extends BinaryOutput { + + private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8; + static final int INITIAL_SIZE = 32; + + private byte[] buffer; + + private ByteArrayBinaryOutput(int size) { + buffer = new byte[size]; + } + + private ByteArrayBinaryOutput(byte[] initialBuffer) { + buffer = initialBuffer; + } + + @Override + public void write(int b) { + ensureCapacity(pos + 1); + buffer[pos] = (byte) b; + pos += 1; + } + + @Override + public void write(byte[] b, int off, int len) { + ensureCapacity(pos + len); + System.arraycopy(b, off, buffer, pos, len); + pos += len; + } + + @Override + public void skip(int numberOfBytes) { + ensureCapacity(pos + numberOfBytes); + pos += numberOfBytes; + } + + /** + * Returns the byte array containing the marshalled data. + */ + public byte[] getArray() { + return buffer; + } + + private void ensureCapacity(int neededCapacity) { + if (neededCapacity - buffer.length > 0) { + int newCapacity = buffer.length << 1; + if (newCapacity - neededCapacity < 0) { + newCapacity = neededCapacity; + } + if (newCapacity - MAX_ARRAY_SIZE > 0) { + throw new OutOfMemoryError(); + } + buffer = Arrays.copyOf(buffer, newCapacity); + } + } + + /** + * Creates a new buffer backed by a byte array. The buffer initial size is + * {@code initialSize}. + */ + public static ByteArrayBinaryOutput create(int initialSize) { + return new ByteArrayBinaryOutput(initialSize); + } + } + + /** + * A {@link BinaryOutput} backed by an off-heap memory. + */ + public static final class CCharPointerBinaryOutput extends BinaryOutput implements Closeable { + + /** + * Represents the point at which the average cost of a JNI call exceeds the expense of an + * element by element copy. See {@code java.nio.Bits#JNI_COPY_FROM_ARRAY_THRESHOLD}. + */ + private static final int BYTEBUFFER_COPY_FROM_ARRAY_THRESHOLD = 6; + + private CCharPointer address; + private int length; + private boolean unmanaged; + /** + * ByteBuffer view of this {@link CCharPointerBinaryOutput} direct memory. The ByteBuffer is + * used for bulk data transfers, where the bulk ByteBuffer operations outperform element by + * element copying by an order of magnitude. + */ + private ByteBuffer byteBufferView; + + private CCharPointerBinaryOutput(CCharPointer address, int length, boolean unmanaged) { + this.address = address; + this.length = length; + this.unmanaged = unmanaged; + } + + @Override + public int getPosition() { + checkClosed(); + return super.getPosition(); + } + + /** + * Returns an address of an off-heap memory segment containing the marshalled data. + */ + public CCharPointer getAddress() { + checkClosed(); + return address; + } + + @Override + public void write(int b) { + checkClosed(); + ensureCapacity(pos + 1); + address.write(pos++, (byte) b); + } + + @Override + public void write(byte[] b, int off, int len) { + checkClosed(); + if ((off | len | b.length) < 0 || b.length - off < len) { + throw new IndexOutOfBoundsException("offset: " + off + ", length: " + len + ", array length: " + b.length); + } + ensureCapacity(pos + len); + if (len > BYTEBUFFER_COPY_FROM_ARRAY_THRESHOLD) { + if (byteBufferView == null) { + byteBufferView = CTypeConversion.asByteBuffer(address, length); + } + byteBufferView.position(pos); + byteBufferView.put(b, off, len); + } else { + for (int i = 0; i < len; i++) { + address.write(pos + i, b[off + i]); + } + } + pos += len; + } + + @Override + public void skip(int numberOfBytes) { + ensureCapacity(pos + numberOfBytes); + pos += numberOfBytes; + } + + /** + * Closes the buffer and frees off-heap allocated resources. + */ + @Override + public void close() { + if (unmanaged) { + UnmanagedMemory.free(address); + byteBufferView = null; + address = WordFactory.nullPointer(); + length = 0; + unmanaged = false; + pos = Integer.MIN_VALUE; + } + } + + private void checkClosed() { + if (pos == Integer.MIN_VALUE) { + throw new IllegalStateException("Already closed"); + } + } + + private void ensureCapacity(int neededCapacity) { + if (neededCapacity - length > 0) { + byteBufferView = null; + int newCapacity = length << 1; + if (newCapacity - neededCapacity < 0) { + newCapacity = neededCapacity; + } + if (newCapacity - Integer.MAX_VALUE > 0) { + throw new OutOfMemoryError(); + } + if (unmanaged) { + address = UnmanagedMemory.realloc(address, WordFactory.unsigned(newCapacity)); + } else { + CCharPointer newAddress = UnmanagedMemory.malloc(newCapacity); + memcpy(newAddress, address, pos); + address = newAddress; + } + length = newCapacity; + unmanaged = true; + } + } + + private static void memcpy(CCharPointer dst, CCharPointer src, int len) { + for (int i = 0; i < len; i++) { + dst.write(i, src.read(i)); + } + } + + /** + * Creates a new buffer backed by an off-heap memory segment. The buffer initial size is + * {@code initialSize}. + */ + public static CCharPointerBinaryOutput create(int initialSize) { + return new CCharPointerBinaryOutput(UnmanagedMemory.malloc(initialSize), initialSize, true); + } + } +} diff --git a/compiler/src/jdk.graal.compiler.libgraal/src/jdk/graal/compiler/libgraal/truffle/HSTruffleCompilable.java b/compiler/src/jdk.graal.compiler.libgraal/src/jdk/graal/compiler/libgraal/truffle/HSTruffleCompilable.java index 891e6a9d297c..c633bedbf9a6 100644 --- a/compiler/src/jdk.graal.compiler.libgraal/src/jdk/graal/compiler/libgraal/truffle/HSTruffleCompilable.java +++ b/compiler/src/jdk.graal.compiler.libgraal/src/jdk/graal/compiler/libgraal/truffle/HSTruffleCompilable.java @@ -40,7 +40,6 @@ import org.graalvm.jniutils.JNICalls.JNIMethod; import org.graalvm.jniutils.JNIMethodScope; import org.graalvm.jniutils.JNIUtil; -import org.graalvm.nativebridge.BinaryInput; import org.graalvm.nativeimage.StackValue; import org.graalvm.word.WordFactory; diff --git a/compiler/src/jdk.graal.compiler.libgraal/src/jdk/graal/compiler/libgraal/truffle/HSTruffleCompilationTask.java b/compiler/src/jdk.graal.compiler.libgraal/src/jdk/graal/compiler/libgraal/truffle/HSTruffleCompilationTask.java index b9bc48926451..d5a3c0c10dd3 100644 --- a/compiler/src/jdk.graal.compiler.libgraal/src/jdk/graal/compiler/libgraal/truffle/HSTruffleCompilationTask.java +++ b/compiler/src/jdk.graal.compiler.libgraal/src/jdk/graal/compiler/libgraal/truffle/HSTruffleCompilationTask.java @@ -36,7 +36,6 @@ import org.graalvm.jniutils.JNI.JObject; import org.graalvm.jniutils.JNIMethodScope; import org.graalvm.jniutils.JNIUtil; -import org.graalvm.nativebridge.BinaryInput; import java.util.LinkedHashMap; import java.util.Map; diff --git a/compiler/src/jdk.graal.compiler.libgraal/src/jdk/graal/compiler/libgraal/truffle/HSTruffleCompilerRuntime.java b/compiler/src/jdk.graal.compiler.libgraal/src/jdk/graal/compiler/libgraal/truffle/HSTruffleCompilerRuntime.java index d2cf241da28f..09a69ec990fc 100644 --- a/compiler/src/jdk.graal.compiler.libgraal/src/jdk/graal/compiler/libgraal/truffle/HSTruffleCompilerRuntime.java +++ b/compiler/src/jdk.graal.compiler.libgraal/src/jdk/graal/compiler/libgraal/truffle/HSTruffleCompilerRuntime.java @@ -54,7 +54,6 @@ import org.graalvm.jniutils.JNI.JString; import org.graalvm.jniutils.JNIMethodScope; import org.graalvm.jniutils.JNIUtil; -import org.graalvm.nativebridge.BinaryInput; import org.graalvm.nativeimage.StackValue; import org.graalvm.nativeimage.c.type.CCharPointer; import org.graalvm.word.WordFactory; diff --git a/compiler/src/jdk.graal.compiler.libgraal/src/jdk/graal/compiler/libgraal/truffle/LibGraalTruffleEntryPoints.java b/compiler/src/jdk.graal.compiler.libgraal/src/jdk/graal/compiler/libgraal/truffle/LibGraalTruffleEntryPoints.java index 50612c3fd3c8..b8ac6074159a 100644 --- a/compiler/src/jdk.graal.compiler.libgraal/src/jdk/graal/compiler/libgraal/truffle/LibGraalTruffleEntryPoints.java +++ b/compiler/src/jdk.graal.compiler.libgraal/src/jdk/graal/compiler/libgraal/truffle/LibGraalTruffleEntryPoints.java @@ -40,7 +40,6 @@ import org.graalvm.jniutils.JNIExceptionWrapper; import org.graalvm.jniutils.JNIMethodScope; import org.graalvm.jniutils.JNIUtil; -import org.graalvm.nativebridge.BinaryOutput; import org.graalvm.nativeimage.ObjectHandles; import org.graalvm.nativeimage.c.function.CEntryPoint; import org.graalvm.nativeimage.c.function.CEntryPoint.IsolateThreadContext;