This is the mail archive of the java@gcc.gnu.org mailing list for the Java project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: RFC: Character set converters...


Bryce McKinlay wrote:

That would work, but it complicates things a bit, and the public char[] variants, called by user code, would still have to copy or wrap.

Yes, but we can write a CharBuffer that is "resettable" - i.e. we can change it to temporarily use the user-supplied array. I.e. it's wrap that reuses an existing CharArray.

With direct buffers, there is another problem, in that the encoder implementation itself will have to either be written in native code, or copy the contents of the buffer into its own array in order to efficiently access the data.

Yes. It may be possible to optimize buffers. Note that the various methods on a Buffer are final. Thus the compiler can inline them all. Furthermore, the (Rawdata address, int offset) representation currently used by DirectByteBufferImpl can be used for *all* buffers (at least all ByteBuffers): for non-direct or wrapped buffers the address is the address of the data array elements. Going further, all the position and limits offsets can be replaced by pointers, though that may have some GC implications.

Unfortunuately, the {Byte,Char}Buffer put/get operations are not final.
However, we can implement gnu.java.nio.ByteBuffer which would have
most of these methods final, and that we can use for standard methods
that create a ByteBuffer (including allocate and wrap).  In that case
the compiler can inline put/get methods.

The class gnu.java.nio.CharBuffer would be similar.  It would be
returned by CharBuffer.allocate and CharBuffer.wrap, as well as
ByteBuffer.asCharBuffer if the byte oder is native and the offset
is char-aligned.  In that case a compiler can generate efficient
code if it knows the CharBuffer is the gnu.java.nio one.  Specifically,
the CharBuffer used by InputStreamReader and OutputSteamWriter
would be the gnu.java.nio version, so these classes can be optimized.

The encoder/decode classes do not know if the passed-on classes are
our internals ones, so they have to check at run-time.  However,
there are tricks to combine this test with the buffer full/empty test:

public class Buffer {
  Object array;  // Used by GC, as well as array() methods
  boolean quick = false; // safe for optimization?
  final RawData base = buffer_start;
  RawData mark = base;
  RawData position;
  RawData limit;
  RawData readLimit = quick ? limit : base;
  RawData writeLimit = quick && ! isReadOnly() ? limit : base;
  final RawData capacity = buffer_start + buffer_capacity;

  final int position() { return pointer_diff(position, base); }
  final Buffer position(int newPosition) {
    if (newPosition < 0 || newPosition > pointer_diff(limit, base))
      throw IllegalArgumentException();
    position = pointer_add(base, newPosition);
  }
  final int limit() { return pointer_diff(limit, base); }
  final int limit(int newLimit) {
    if (newLimit < 0 || newLimit > capacity()) throw ...;
    limit = pointer_add(base, newLimit);
    readLimit = quick ? limit : base;
    writeLimit = quick && ! isReadOnly() ? limit : base;
  }
}

public class ByteBuffer extends Buffer {
  // This method is private, but the compiler replaces
  // any calls to get() by this method.
  private final byte getQuick() {
    if (position < readLimit) // Quick test, case be inlined.
      return *position++; // Common case
    return qet();  // Slow case.
  }
}

public class gnu.java.nio.ByteBuffer extends ByteBuffer {

  ByteBuffer() {
    super.quick = true;
    super.readLimit = super.limit;
    super.writeLimit = isReadOnly() ? super.base : super.limit;
  }
  // This can be used portably in Classpath without compiler tricks.
  public final byte getQuick() {
    if (position < readLimit) // Quick test, case be inlined.
      return *position++; // Common case
    return qet();  // Slow case; should only happen on errors.
  }
}

CharBuffer is similar; quick is set if the byte order is native,
and the alignment correct.
--
	--Per Bothner
per@bothner.com   http://per.bothner.com/


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]