From 8eb4e7e07e9211aabcb0f22696e9c572dac7a59f Mon Sep 17 00:00:00 2001 From: "Archie L. Cobbs" Date: Fri, 31 Mar 2023 23:17:56 +0000 Subject: [PATCH] 8277501: Revisit PathFileObject.getCharContent and friends Reviewed-by: vromero, jjg --- .../sun/tools/javac/file/BaseFileManager.java | 61 ++++++------------- .../com/sun/tools/javac/jvm/ClassReader.java | 4 +- .../com/sun/tools/javac/util/ByteBuffer.java | 58 +++++++++++------- 3 files changed, 58 insertions(+), 65 deletions(-) diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/file/BaseFileManager.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/file/BaseFileManager.java index fbd4506ed53..3999cf0c36b 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/file/BaseFileManager.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/file/BaseFileManager.java @@ -75,10 +75,12 @@ import com.sun.tools.javac.util.Options; * java.io.File or java.nio.file.Path. */ public abstract class BaseFileManager implements JavaFileManager { + + private static final byte[] EMPTY_ARRAY = new byte[0]; + @SuppressWarnings("this-escape") protected BaseFileManager(Charset charset) { this.charset = charset; - byteBufferCache = new ByteBufferCache(); locations = createLocations(); } @@ -403,56 +405,33 @@ public abstract class BaseFileManager implements JavaFileManager { // /** - * Make a byte buffer from an input stream. + * Make a {@link ByteBuffer} from an input stream. * @param in the stream * @return a byte buffer containing the contents of the stream * @throws IOException if an error occurred while reading the stream */ - public ByteBuffer makeByteBuffer(InputStream in) - throws IOException { - int limit = in.available(); - if (limit < 1024) limit = 1024; - ByteBuffer result = byteBufferCache.get(limit); - int position = 0; - while (in.available() != 0) { - if (position >= limit) - // expand buffer - result = ByteBuffer. - allocate(limit <<= 1). - put(result.flip()); - int count = in.read(result.array(), - position, - limit - position); - if (count < 0) break; - result.position(position += count); + public ByteBuffer makeByteBuffer(InputStream in) throws IOException { + byte[] array; + synchronized (this) { + if ((array = byteArrayCache) != null) + byteArrayCache = null; + else + array = EMPTY_ARRAY; } - return result.flip(); + com.sun.tools.javac.util.ByteBuffer buf = new com.sun.tools.javac.util.ByteBuffer(array); + buf.appendStream(in); + return buf.asByteBuffer(); } - public void recycleByteBuffer(ByteBuffer bb) { - byteBufferCache.put(bb); - } - - /** - * A single-element cache of direct byte buffers. - */ - private static class ByteBufferCache { - private ByteBuffer cached; - ByteBuffer get(int capacity) { - if (capacity < 20480) capacity = 20480; - ByteBuffer result = - (cached != null && cached.capacity() >= capacity) - ? cached.clear() - : ByteBuffer.allocate(capacity); - cached = null; - return result; - } - void put(ByteBuffer x) { - cached = x; + public void recycleByteBuffer(ByteBuffer buf) { + if (buf.hasArray()) { + synchronized (this) { + byteArrayCache = buf.array(); + } } } - private final ByteBufferCache byteBufferCache; + private byte[] byteArrayCache; // // diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassReader.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassReader.java index ace14349214..63d4fa11b6b 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassReader.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassReader.java @@ -2741,7 +2741,9 @@ public class ClassReader { try { bp = 0; buf.reset(); - buf.appendStream(c.classfile.openInputStream()); + try (InputStream input = c.classfile.openInputStream()) { + buf.appendStream(input); + } readClassBuffer(c); if (!missingTypeVariables.isEmpty() && !foundTypeVariables.isEmpty()) { List missing = missingTypeVariables; diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/util/ByteBuffer.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/util/ByteBuffer.java index 0f87667a8f0..c035263e34c 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/util/ByteBuffer.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/util/ByteBuffer.java @@ -56,8 +56,13 @@ public class ByteBuffer { * of given size. */ public ByteBuffer(int initialSize) { - elems = new byte[initialSize]; - length = 0; + this(new byte[initialSize]); + } + + /** Create a new byte buffer using the given array for storage. + */ + public ByteBuffer(byte[] elems) { + this.elems = elems; } /** Append byte to this buffer. @@ -147,30 +152,28 @@ public class ByteBuffer { appendBytes(name.getByteArray(), name.getByteOffset(), name.getByteLength()); } - /** Append the content of a given input stream, and then close the stream. + /** Append the content of the given input stream. */ - public void appendStream(InputStream is) throws IOException { - try (InputStream input = is) { - while (true) { + public void appendStream(InputStream input) throws IOException { + while (true) { - // Read another chunk of data, using size hint from available(). - // If available() is accurate, the array size should be just right. - int amountToRead = Math.max(input.available(), 64); - elems = ArrayUtils.ensureCapacity(elems, length + amountToRead); - int amountRead = input.read(elems, length, amountToRead); - if (amountRead == -1) + // Read another chunk of data, using size hint from available(). + // If available() is accurate, the array size should be just right. + int amountToRead = Math.max(input.available(), 64); + elems = ArrayUtils.ensureCapacity(elems, length + amountToRead); + int amountRead = input.read(elems, length, amountToRead); + if (amountRead == -1) + break; + length += amountRead; + + // Check for the common case where input.available() returned the + // entire remaining input; in that case, avoid an extra array extension. + // Note we are guaranteed that elems.length >= length + 1 at this point. + if (amountRead == amountToRead) { + int byt = input.read(); + if (byt == -1) break; - length += amountRead; - - // Check for the common case where input.available() returned the - // entire remaining input; in that case, avoid an extra array extension. - // Note we are guaranteed that elems.length >= length + 1 at this point. - if (amountRead == amountToRead) { - int byt = input.read(); - if (byt == -1) - break; - elems[length++] = (byte)byt; - } + elems[length++] = (byte)byt; } } } @@ -292,6 +295,15 @@ public class ByteBuffer { throw new UnderflowException(length); } + /** Create a {@link java.nio.ByteBuffer} view of this instance. + * + *

+ * If this instance is modified, the returned buffer may no longer reflect it. + */ + public java.nio.ByteBuffer asByteBuffer() { + return java.nio.ByteBuffer.wrap(elems, 0, length); + } + // UnderflowException /** Thrown when trying to read past the end of the buffer.