-
Enhancement
-
Resolution: Won't Fix
-
P5
-
None
-
6u10
-
x86
-
windows_xp
A DESCRIPTION OF THE REQUEST :
Current xBufferLoop checks the bounds of the buffers by querying Buffer by its remaining() method.
After, the bounds are checked 2nd time internally by Buffer's get()/put() methods.
JUSTIFICATION :
If the first of this redundunt checks would be saved, xBufferLoop would become faster.
See my example from UTF_8$Encoder below ...
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
private CoderResult encodeBufferLoop(CharBuffer src, ByteBuffer dst) {
int mark = src.position(); // TODO: maybe instead use src.mark(); evaluate by microbenchmark!
while (true) try {
dst.mark();
int c = src.get();
if (c < 0x80) {
// Have at most seven bits
dst.put((byte)c);
} else if (c < 0x800) {
// 2 bytes, 11 bits
dst.put((byte)(0xc0 | ((c >> 06))));
dst.put((byte)(0x80 | (c & 0x3f)));
} else if (Surrogate.is(c)) {
// Have a surrogate pair
if (sgp == null)
sgp = new Surrogate.Parser();
int uc = sgp.parse((char)c, src); // TODO: throw exception there, if src is empty
if (uc < 0) {
src.position(mark);
return sgp.error();
}
dst.put((byte)(0xf0 | ((uc >> 18))));
dst.put((byte)(0x80 | ((uc >> 12) & 0x3f)));
dst.put((byte)(0x80 | ((uc >> 06) & 0x3f)));
dst.put((byte)(0x80 | (uc & 0x3f)));
mark++; //2 chars
} else {
// 3 bytes, 16 bits
dst.put((byte)(0xe0 | ((c >> 12))));
dst.put((byte)(0x80 | ((c >> 06) & 0x3f)));
dst.put((byte)(0x80 | (c & 0x3f)));
}
mark++;
} catch (BufferUnderflowException bue) {
return underflow(src, mark);
} catch (BufferOverflowException boe) {
dst.reset();
return overflow(src, mark);
}
}
ACTUAL -
private CoderResult encodeBufferLoop(CharBuffer src, ByteBuffer dst) {
int mark = src.position();
while (src.hasRemaining()) {
int c = src.get();
if (c < 0x80) {
// Have at most seven bits
if (!dst.hasRemaining())
return overflow(src, mark);
dst.put((byte)c);
} else if (c < 0x800) {
// 2 bytes, 11 bits
if (dst.remaining() < 2)
return overflow(src, mark);
dst.put((byte)(0xc0 | ((c >> 06))));
dst.put((byte)(0x80 | (c & 0x3f)));
} else if (Surrogate.is(c)) {
// Have a surrogate pair
if (sgp == null)
sgp = new Surrogate.Parser();
int uc = sgp.parse((char)c, src);
if (uc < 0) {
src.position(mark);
return sgp.error();
}
if (dst.remaining() < 4)
return overflow(src, mark);
dst.put((byte)(0xf0 | ((uc >> 18))));
dst.put((byte)(0x80 | ((uc >> 12) & 0x3f)));
dst.put((byte)(0x80 | ((uc >> 06) & 0x3f)));
dst.put((byte)(0x80 | (uc & 0x3f)));
mark++; //2 chars
} else {
// 3 bytes, 16 bits
if (dst.remaining() < 3)
return overflow(src, mark);
dst.put((byte)(0xe0 | ((c >> 12))));
dst.put((byte)(0x80 | ((c >> 06) & 0x3f)));
dst.put((byte)(0x80 | (c & 0x3f)));
}
mark++;
}
src.position(mark);
return CoderResult.UNDERFLOW;
}
Current xBufferLoop checks the bounds of the buffers by querying Buffer by its remaining() method.
After, the bounds are checked 2nd time internally by Buffer's get()/put() methods.
JUSTIFICATION :
If the first of this redundunt checks would be saved, xBufferLoop would become faster.
See my example from UTF_8$Encoder below ...
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
private CoderResult encodeBufferLoop(CharBuffer src, ByteBuffer dst) {
int mark = src.position(); // TODO: maybe instead use src.mark(); evaluate by microbenchmark!
while (true) try {
dst.mark();
int c = src.get();
if (c < 0x80) {
// Have at most seven bits
dst.put((byte)c);
} else if (c < 0x800) {
// 2 bytes, 11 bits
dst.put((byte)(0xc0 | ((c >> 06))));
dst.put((byte)(0x80 | (c & 0x3f)));
} else if (Surrogate.is(c)) {
// Have a surrogate pair
if (sgp == null)
sgp = new Surrogate.Parser();
int uc = sgp.parse((char)c, src); // TODO: throw exception there, if src is empty
if (uc < 0) {
src.position(mark);
return sgp.error();
}
dst.put((byte)(0xf0 | ((uc >> 18))));
dst.put((byte)(0x80 | ((uc >> 12) & 0x3f)));
dst.put((byte)(0x80 | ((uc >> 06) & 0x3f)));
dst.put((byte)(0x80 | (uc & 0x3f)));
mark++; //2 chars
} else {
// 3 bytes, 16 bits
dst.put((byte)(0xe0 | ((c >> 12))));
dst.put((byte)(0x80 | ((c >> 06) & 0x3f)));
dst.put((byte)(0x80 | (c & 0x3f)));
}
mark++;
} catch (BufferUnderflowException bue) {
return underflow(src, mark);
} catch (BufferOverflowException boe) {
dst.reset();
return overflow(src, mark);
}
}
ACTUAL -
private CoderResult encodeBufferLoop(CharBuffer src, ByteBuffer dst) {
int mark = src.position();
while (src.hasRemaining()) {
int c = src.get();
if (c < 0x80) {
// Have at most seven bits
if (!dst.hasRemaining())
return overflow(src, mark);
dst.put((byte)c);
} else if (c < 0x800) {
// 2 bytes, 11 bits
if (dst.remaining() < 2)
return overflow(src, mark);
dst.put((byte)(0xc0 | ((c >> 06))));
dst.put((byte)(0x80 | (c & 0x3f)));
} else if (Surrogate.is(c)) {
// Have a surrogate pair
if (sgp == null)
sgp = new Surrogate.Parser();
int uc = sgp.parse((char)c, src);
if (uc < 0) {
src.position(mark);
return sgp.error();
}
if (dst.remaining() < 4)
return overflow(src, mark);
dst.put((byte)(0xf0 | ((uc >> 18))));
dst.put((byte)(0x80 | ((uc >> 12) & 0x3f)));
dst.put((byte)(0x80 | ((uc >> 06) & 0x3f)));
dst.put((byte)(0x80 | (uc & 0x3f)));
mark++; //2 chars
} else {
// 3 bytes, 16 bits
if (dst.remaining() < 3)
return overflow(src, mark);
dst.put((byte)(0xe0 | ((c >> 12))));
dst.put((byte)(0x80 | ((c >> 06) & 0x3f)));
dst.put((byte)(0x80 | (c & 0x3f)));
}
mark++;
}
src.position(mark);
return CoderResult.UNDERFLOW;
}