A DESCRIPTION OF THE REQUEST :
1.) Replace
if (offset > codePoints.length - count) {
by
if (offset + count > codePoints.length) {
2.) Modify pass 1 loop to:
int n = 0;
for (int i = offset; i < offset + count; i++) {
int c = codePoints[i];
assert Character.MIN_VALUE == 0 && (Character.MAX_VALUE + 1) == (1 << 16)
&& Character.MIN_SUPPLEMENTARY_CODE_POINT == (1 << 16)
&& (Character.MAX_CODE_POINT + 1) % (1 << 16) == 0;
if (c >>> 16 == 0)
// if (Character.isBMPCodePoint(c))
n += 1;
else if ((c >>> 16) < (Character.MAX_CODE_POINT + 1 >>> 16))
// else if (Character.isSupplementaryCodePoint(c))
n += 2;
else
throw new IllegalArgumentException(Integer.toString(c));
}
3.) Ideally provide appropriate methods from class Character.
4.) Modify pass 2 loop to:
for (int i = offset + count; n > 0; ) {
int c = codePoints[--i];
if (c >>> 16 == 0)
// if (Character.isBMPCodePoint(c))
v[--n] = (char)c;
else
Character.toSurrogates(c, v, n-=2);
}
This RFE depends on 6931812
JUSTIFICATION :
1.) Term 'offset + count' could be reused later
2.) If compiled by HotSpot, this loop algorithm only needs 16 bytes in contrast to 36 bytes by the current one (see below).
3.) The advantage of the given code should at least be available for the sun.nio.cs package, but why not too for the public.
4.) See 2.) + reduces register pressure as value of 'offset + count' could be thrown away and
compairing the loop variable against 0 should be little faster than against a constant, which mut be loaded each time.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
if (Character.isBMPCodePoint(c))
...;
else if (Character.isSupplementaryCodePoint(c))
...;
else
...;
compiles to (needs only 16 bytes of machine code):
0x00b87aac: mov %ebx,%ecx
0x00b87aae: sar $0x10,%ecx
0x00b87ab1: test %ecx,%ecx
0x00b87ab3: je 0x00b87acb
0x00b87ab5: cmp $0x11,%ecx
0x00b87ab8: jge 0x00b87ce6
0x00b87abe:
ACTUAL -
if (c >= Character.MIN_CODE_POINT &&
c < Character.MIN_SUPPLEMENTARY_CODE_POINT)
...;
else if (Character.isSupplementaryCodePoint(c))
...;
else
...;
compiles to (needs *36* bytes of machine code):
0x00b87a5c: test %ebp,%ebp
0x00b87a5e: jl 0x00b87a68
0x00b87a60: cmp $0x10000,%ebp
0x00b87a66: jl 0x00b87a8d
0x00b87a68: cmp $0x10000,%ebp
0x00b87a6e: jl 0x00b87c63
0x00b87a74: cmp $0x10ffff,%ebp
0x00b87a7a: jg 0x00b87c63
0x00b87a80:
1.) Replace
if (offset > codePoints.length - count) {
by
if (offset + count > codePoints.length) {
2.) Modify pass 1 loop to:
int n = 0;
for (int i = offset; i < offset + count; i++) {
int c = codePoints[i];
assert Character.MIN_VALUE == 0 && (Character.MAX_VALUE + 1) == (1 << 16)
&& Character.MIN_SUPPLEMENTARY_CODE_POINT == (1 << 16)
&& (Character.MAX_CODE_POINT + 1) % (1 << 16) == 0;
if (c >>> 16 == 0)
// if (Character.isBMPCodePoint(c))
n += 1;
else if ((c >>> 16) < (Character.MAX_CODE_POINT + 1 >>> 16))
// else if (Character.isSupplementaryCodePoint(c))
n += 2;
else
throw new IllegalArgumentException(Integer.toString(c));
}
3.) Ideally provide appropriate methods from class Character.
4.) Modify pass 2 loop to:
for (int i = offset + count; n > 0; ) {
int c = codePoints[--i];
if (c >>> 16 == 0)
// if (Character.isBMPCodePoint(c))
v[--n] = (char)c;
else
Character.toSurrogates(c, v, n-=2);
}
This RFE depends on 6931812
JUSTIFICATION :
1.) Term 'offset + count' could be reused later
2.) If compiled by HotSpot, this loop algorithm only needs 16 bytes in contrast to 36 bytes by the current one (see below).
3.) The advantage of the given code should at least be available for the sun.nio.cs package, but why not too for the public.
4.) See 2.) + reduces register pressure as value of 'offset + count' could be thrown away and
compairing the loop variable against 0 should be little faster than against a constant, which mut be loaded each time.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
if (Character.isBMPCodePoint(c))
...;
else if (Character.isSupplementaryCodePoint(c))
...;
else
...;
compiles to (needs only 16 bytes of machine code):
0x00b87aac: mov %ebx,%ecx
0x00b87aae: sar $0x10,%ecx
0x00b87ab1: test %ecx,%ecx
0x00b87ab3: je 0x00b87acb
0x00b87ab5: cmp $0x11,%ecx
0x00b87ab8: jge 0x00b87ce6
0x00b87abe:
ACTUAL -
if (c >= Character.MIN_CODE_POINT &&
c < Character.MIN_SUPPLEMENTARY_CODE_POINT)
...;
else if (Character.isSupplementaryCodePoint(c))
...;
else
...;
compiles to (needs *36* bytes of machine code):
0x00b87a5c: test %ebp,%ebp
0x00b87a5e: jl 0x00b87a68
0x00b87a60: cmp $0x10000,%ebp
0x00b87a66: jl 0x00b87a8d
0x00b87a68: cmp $0x10000,%ebp
0x00b87a6e: jl 0x00b87c63
0x00b87a74: cmp $0x10ffff,%ebp
0x00b87a7a: jg 0x00b87c63
0x00b87a80: