mirror of
https://github.com/openjdk/jdk.git
synced 2026-07-28 11:53:09 +00:00
8359955: Regressions ~7% in several J2DBench in 25-b26
Reviewed-by: prr, serb
This commit is contained in:
parent
40bc083267
commit
c220a6c7bb
@ -33,9 +33,10 @@ import static sun.font.FontUtilities.isIgnorableWhitespace;
|
||||
public final class CCharToGlyphMapper extends CharToGlyphMapper {
|
||||
private static native int countGlyphs(final long nativeFontPtr);
|
||||
|
||||
private Cache cache = new Cache();
|
||||
CFont fFont;
|
||||
int numGlyphs = -1;
|
||||
private final Cache rawCache = new Cache(true);
|
||||
private final Cache modCache = new Cache(false);
|
||||
private final CFont fFont;
|
||||
private int numGlyphs = -1;
|
||||
|
||||
public CCharToGlyphMapper(CFont font) {
|
||||
fFont = font;
|
||||
@ -101,13 +102,18 @@ public final class CCharToGlyphMapper extends CharToGlyphMapper {
|
||||
}
|
||||
|
||||
private int charToGlyph(char unicode, boolean raw) {
|
||||
int glyph = cache.get(unicode, raw);
|
||||
Cache cache = raw ? rawCache : modCache;
|
||||
int glyph = cache.get(unicode);
|
||||
if (glyph != 0) return glyph;
|
||||
|
||||
final char[] unicodeArray = new char[] { unicode };
|
||||
final int[] glyphArray = new int[1];
|
||||
nativeCharsToGlyphs(fFont.getNativeFontPtr(), 1, unicodeArray, glyphArray);
|
||||
glyph = glyphArray[0];
|
||||
if (isIgnorableWhitespace(unicode) || (isDefaultIgnorable(unicode) && !raw)) {
|
||||
glyph = INVISIBLE_GLYPH_ID;
|
||||
} else {
|
||||
final char[] unicodeArray = new char[]{unicode};
|
||||
final int[] glyphArray = new int[1];
|
||||
nativeCharsToGlyphs(fFont.getNativeFontPtr(), 1, unicodeArray, glyphArray);
|
||||
glyph = glyphArray[0];
|
||||
}
|
||||
|
||||
cache.put(unicode, glyph);
|
||||
|
||||
@ -131,7 +137,8 @@ public final class CCharToGlyphMapper extends CharToGlyphMapper {
|
||||
int base = unicode - 0x10000;
|
||||
surrogates[0] = (char)((base >>> 10) + HI_SURROGATE_START);
|
||||
surrogates[1] = (char)((base % 0x400) + LO_SURROGATE_START);
|
||||
cache.get(2, surrogates, glyphs, raw);
|
||||
Cache cache = raw ? rawCache : modCache;
|
||||
cache.get(2, surrogates, glyphs);
|
||||
return glyphs[0];
|
||||
} else {
|
||||
return charToGlyph((char) unicode, raw);
|
||||
@ -140,7 +147,7 @@ public final class CCharToGlyphMapper extends CharToGlyphMapper {
|
||||
|
||||
@Override
|
||||
public synchronized void charsToGlyphs(int count, char[] unicodes, int[] glyphs) {
|
||||
cache.get(count, unicodes, glyphs, false);
|
||||
modCache.get(count, unicodes, glyphs);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -164,20 +171,18 @@ public final class CCharToGlyphMapper extends CharToGlyphMapper {
|
||||
private static final int FIRST_LAYER_SIZE = 256;
|
||||
private static final int SECOND_LAYER_SIZE = 16384; // 16384 = 128x128
|
||||
|
||||
private final boolean raw;
|
||||
private final int[] firstLayerCache = new int[FIRST_LAYER_SIZE];
|
||||
private SparseBitShiftingTwoLayerArray secondLayerCache;
|
||||
private HashMap<Integer, Integer> generalCache;
|
||||
|
||||
Cache() {
|
||||
Cache(boolean raw) {
|
||||
this.raw = raw;
|
||||
// <rdar://problem/5331678> need to prevent getting '-1' stuck in the cache
|
||||
firstLayerCache[1] = 1;
|
||||
}
|
||||
|
||||
public synchronized int get(final int index, final boolean raw) {
|
||||
if (isIgnorableWhitespace(index) || (isDefaultIgnorable(index) && !raw)) {
|
||||
return INVISIBLE_GLYPH_ID;
|
||||
}
|
||||
|
||||
public synchronized int get(final int index) {
|
||||
if (index < FIRST_LAYER_SIZE) {
|
||||
// catch common glyphcodes
|
||||
return firstLayerCache[index];
|
||||
@ -248,7 +253,7 @@ public final class CCharToGlyphMapper extends CharToGlyphMapper {
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void get(int count, char[] indices, int[] values, boolean raw)
|
||||
public synchronized void get(int count, char[] indices, int[] values)
|
||||
{
|
||||
// "missed" is the count of 'char' that are not mapped.
|
||||
// Surrogates count for 2.
|
||||
@ -270,13 +275,16 @@ public final class CCharToGlyphMapper extends CharToGlyphMapper {
|
||||
}
|
||||
}
|
||||
|
||||
final int value = get(code, raw);
|
||||
final int value = get(code);
|
||||
if (value != 0 && value != -1) {
|
||||
values[i] = value;
|
||||
if (code >= 0x10000) {
|
||||
values[i+1] = INVISIBLE_GLYPH_ID;
|
||||
i++;
|
||||
}
|
||||
} else if (isIgnorableWhitespace(code) || (isDefaultIgnorable(code) && !raw)) {
|
||||
values[i] = INVISIBLE_GLYPH_ID;
|
||||
put(code, INVISIBLE_GLYPH_ID);
|
||||
} else {
|
||||
values[i] = 0;
|
||||
put(code, -1);
|
||||
|
||||
@ -25,7 +25,7 @@
|
||||
|
||||
package sun.font;
|
||||
|
||||
/* remember that the API requires a Font use a
|
||||
/* Remember that the API requires a Font use a
|
||||
* consistent glyph id. for a code point, and this is a
|
||||
* problem if a particular strike uses native scaler sometimes
|
||||
* and the JDK scaler others. That needs to be dealt with somewhere, but
|
||||
@ -36,9 +36,9 @@ package sun.font;
|
||||
* to the maximum surrogate pair code point.
|
||||
* This implementation will not cache as much, since the storage
|
||||
* requirements are not justifiable. Even so it still can use up
|
||||
* to 216*256*4 bytes of storage per composite font. If an app
|
||||
* to 2*216*256*4 bytes of storage per composite font. If an app
|
||||
* calls canDisplay on this range for all 20 composite fonts that's
|
||||
* over 1Mb of cached data. May need to employ WeakReferences if
|
||||
* over 2Mb of cached data. May need to employ WeakReferences if
|
||||
* this appears to cause problems.
|
||||
*/
|
||||
|
||||
@ -54,14 +54,20 @@ public class CompositeGlyphMapper extends CharToGlyphMapper {
|
||||
public static final int BLOCKSZ = 256;
|
||||
public static final int MAXUNICODE = NBLOCKS*BLOCKSZ;
|
||||
|
||||
CompositeFont font;
|
||||
CharToGlyphMapper[] slotMappers;
|
||||
int[][] glyphMaps;
|
||||
private boolean hasExcludes;
|
||||
private final CompositeFont font;
|
||||
private final CharToGlyphMapper[] slotMappers;
|
||||
private final int[][] glyphMapsRaw;
|
||||
private final int[][] glyphMapsMod;
|
||||
private final boolean hasExcludes;
|
||||
|
||||
public CompositeGlyphMapper(CompositeFont compFont) {
|
||||
font = compFont;
|
||||
initMapper();
|
||||
glyphMapsRaw = new int[NBLOCKS][];
|
||||
glyphMapsMod = new int[NBLOCKS][];
|
||||
slotMappers = new CharToGlyphMapper[font.numSlots];
|
||||
/* This requires that slot 0 is never empty. */
|
||||
missingGlyph = font.getSlotFont(0).getMissingGlyphCode();
|
||||
missingGlyph = compositeGlyphCode(0, missingGlyph);
|
||||
/* This is often false which saves the overhead of a
|
||||
* per-mapped char method call.
|
||||
*/
|
||||
@ -73,34 +79,24 @@ public class CompositeGlyphMapper extends CharToGlyphMapper {
|
||||
return (slot << 24 | (glyphCode & GLYPHMASK));
|
||||
}
|
||||
|
||||
private void initMapper() {
|
||||
if (missingGlyph == CharToGlyphMapper.UNINITIALIZED_GLYPH) {
|
||||
if (glyphMaps == null) {
|
||||
glyphMaps = new int[NBLOCKS][];
|
||||
}
|
||||
slotMappers = new CharToGlyphMapper[font.numSlots];
|
||||
/* This requires that slot 0 is never empty. */
|
||||
missingGlyph = font.getSlotFont(0).getMissingGlyphCode();
|
||||
missingGlyph = compositeGlyphCode(0, missingGlyph);
|
||||
}
|
||||
}
|
||||
|
||||
private int getCachedGlyphCode(int unicode) {
|
||||
private int getCachedGlyphCode(int unicode, boolean raw) {
|
||||
if (unicode >= MAXUNICODE) {
|
||||
return UNINITIALIZED_GLYPH; // don't cache surrogates
|
||||
}
|
||||
int[] gmap;
|
||||
int[][] glyphMaps = raw ? glyphMapsRaw : glyphMapsMod;
|
||||
if ((gmap = glyphMaps[unicode >> 8]) == null) {
|
||||
return UNINITIALIZED_GLYPH;
|
||||
}
|
||||
return gmap[unicode & 0xff];
|
||||
}
|
||||
|
||||
private void setCachedGlyphCode(int unicode, int glyphCode) {
|
||||
private void setCachedGlyphCode(int unicode, int glyphCode, boolean raw) {
|
||||
if (unicode >= MAXUNICODE) {
|
||||
return; // don't cache surrogates
|
||||
}
|
||||
int index0 = unicode >> 8;
|
||||
int[][] glyphMaps = raw ? glyphMapsRaw : glyphMapsMod;
|
||||
if (glyphMaps[index0] == null) {
|
||||
glyphMaps[index0] = new int[BLOCKSZ];
|
||||
for (int i=0;i<BLOCKSZ;i++) {
|
||||
@ -120,20 +116,22 @@ public class CompositeGlyphMapper extends CharToGlyphMapper {
|
||||
}
|
||||
|
||||
private int getGlyph(int unicode, boolean raw) {
|
||||
if (isIgnorableWhitespace(unicode) || (isDefaultIgnorable(unicode) && !raw)) {
|
||||
return INVISIBLE_GLYPH_ID;
|
||||
}
|
||||
int glyphCode = getCachedGlyphCode(unicode);
|
||||
int glyphCode = getCachedGlyphCode(unicode, raw);
|
||||
if (glyphCode != UNINITIALIZED_GLYPH) {
|
||||
return glyphCode;
|
||||
}
|
||||
if (isIgnorableWhitespace(unicode) || (isDefaultIgnorable(unicode) && !raw)) {
|
||||
glyphCode = INVISIBLE_GLYPH_ID;
|
||||
setCachedGlyphCode(unicode, glyphCode, raw);
|
||||
return glyphCode;
|
||||
}
|
||||
for (int slot = 0; slot < font.numSlots; slot++) {
|
||||
if (!hasExcludes || !font.isExcludedChar(slot, unicode)) {
|
||||
CharToGlyphMapper mapper = getSlotMapper(slot);
|
||||
glyphCode = mapper.charToGlyphRaw(unicode);
|
||||
if (glyphCode != mapper.getMissingGlyphCode()) {
|
||||
glyphCode = compositeGlyphCode(slot, glyphCode);
|
||||
setCachedGlyphCode(unicode, glyphCode);
|
||||
setCachedGlyphCode(unicode, glyphCode, raw);
|
||||
return glyphCode;
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user