8340011: Simplify jdk.internal.classfile.impl.EntryMap

Reviewed-by: liach
This commit is contained in:
Claes Redestad 2024-09-12 15:08:11 +00:00
parent 1b17e0b133
commit 0765917dea
2 changed files with 34 additions and 49 deletions

View File

@ -33,10 +33,10 @@ package jdk.internal.classfile.impl;
* element is the hash and the second is the mapped index. To look something up
* in the map, provide a hash value and an index to map it to, and invoke
* firstToken(hash). This returns an opaque token that can be provided to
* nextToken(hash, token) to get the next candidate, or to getElementByToken(token)
* or getIndexByToken to get the mapped element or index.
* nextToken(hash, token) to get the next candidate, or to getIndexByToken to
* get the mapped element or index.
*/
public abstract class EntryMap<T> {
public final class EntryMap {
public static final int NO_VALUE = -1;
/**
@ -77,8 +77,6 @@ public abstract class EntryMap<T> {
data = new int[capacity * 2];
}
protected abstract T fetchElement(int index);
public int firstToken(int hash) {
if (hash == 0)
throw new IllegalArgumentException("hash must be nonzero");
@ -110,10 +108,6 @@ public abstract class EntryMap<T> {
return data[token + 1];
}
public T getElementByToken(int token) {
return fetchElement(data[token + 1]);
}
public void put(int hash, int index) {
if (hash == 0)
throw new IllegalArgumentException("hash must be nonzero");

View File

@ -63,8 +63,8 @@ public final class SplitConstantPool implements ConstantPoolBuilder {
private PoolEntry[] myEntries;
private BootstrapMethodEntryImpl[] myBsmEntries;
private boolean doneFullScan;
private EntryMap<PoolEntry> map;
private EntryMap<BootstrapMethodEntryImpl> bsmMap;
private EntryMap map;
private EntryMap bsmMap;
public SplitConstantPool() {
this.size = 1;
@ -178,14 +178,10 @@ public final class SplitConstantPool implements ConstantPoolBuilder {
}
}
private EntryMap<PoolEntry> map() {
private EntryMap map() {
if (map == null) {
map = new EntryMap<>(Math.max(size, 1024), .75f) {
@Override
protected PoolEntry fetchElement(int index) {
return entryByIndex(index);
}
};
map = new EntryMap(Math.max(size, 1024), .75f);
// Doing a full scan here yields fall-off-the-cliff performance results,
// especially if we only need a few entries that are already
// inflated (such as attribute names).
@ -220,14 +216,9 @@ public final class SplitConstantPool implements ConstantPoolBuilder {
doneFullScan = true;
}
private EntryMap<BootstrapMethodEntryImpl> bsmMap() {
private EntryMap bsmMap() {
if (bsmMap == null) {
bsmMap = new EntryMap<>(Math.max(bsmSize, 16), .75f) {
@Override
protected BootstrapMethodEntryImpl fetchElement(int index) {
return bootstrapMethodEntry(index);
}
};
bsmMap = new EntryMap(Math.max(bsmSize, 16), .75f);
for (int i=0; i<parentBsmSize; i++) {
BootstrapMethodEntryImpl bsm = parent.bootstrapMethodEntry(i);
bsmMap.put(bsm.hash, bsm.index);
@ -268,9 +259,9 @@ public final class SplitConstantPool implements ConstantPoolBuilder {
private IntegerEntry findIntEntry(int val) {
int hash = AbstractPoolEntry.hash1(TAG_INTEGER, Integer.hashCode(val));
EntryMap<PoolEntry> map = map();
EntryMap map = map();
for (int token = map.firstToken(hash); token != -1; token = map.nextToken(hash, token)) {
PoolEntry e = map.getElementByToken(token);
PoolEntry e = entryByIndex(map.getIndexByToken(token));
if (e.tag() == TAG_INTEGER
&& e instanceof AbstractPoolEntry.IntegerEntryImpl ce
&& ce.intValue() == val)
@ -285,9 +276,9 @@ public final class SplitConstantPool implements ConstantPoolBuilder {
private LongEntry findLongEntry(long val) {
int hash = AbstractPoolEntry.hash1(TAG_LONG, Long.hashCode(val));
EntryMap<PoolEntry> map = map();
EntryMap map = map();
for (int token = map.firstToken(hash); token != -1; token = map.nextToken(hash, token)) {
PoolEntry e = map.getElementByToken(token);
PoolEntry e = entryByIndex(map.getIndexByToken(token));
if (e.tag() == TAG_LONG
&& e instanceof AbstractPoolEntry.LongEntryImpl ce
&& ce.longValue() == val)
@ -302,9 +293,9 @@ public final class SplitConstantPool implements ConstantPoolBuilder {
private FloatEntry findFloatEntry(float val) {
int hash = AbstractPoolEntry.hash1(TAG_FLOAT, Float.hashCode(val));
EntryMap<PoolEntry> map = map();
EntryMap map = map();
for (int token = map.firstToken(hash); token != -1; token = map.nextToken(hash, token)) {
PoolEntry e = map.getElementByToken(token);
PoolEntry e = entryByIndex(map.getIndexByToken(token));
if (e.tag() == TAG_FLOAT
&& e instanceof AbstractPoolEntry.FloatEntryImpl ce
&& ce.floatValue() == val)
@ -319,9 +310,9 @@ public final class SplitConstantPool implements ConstantPoolBuilder {
private DoubleEntry findDoubleEntry(double val) {
int hash = AbstractPoolEntry.hash1(TAG_DOUBLE, Double.hashCode(val));
EntryMap<PoolEntry> map = map();
EntryMap map = map();
for (int token = map.firstToken(hash); token != -1; token = map.nextToken(hash, token)) {
PoolEntry e = map.getElementByToken(token);
PoolEntry e = entryByIndex(map.getIndexByToken(token));
if (e.tag() == TAG_DOUBLE
&& e instanceof AbstractPoolEntry.DoubleEntryImpl ce
&& ce.doubleValue() == val)
@ -337,9 +328,9 @@ public final class SplitConstantPool implements ConstantPoolBuilder {
private<T extends AbstractPoolEntry> AbstractPoolEntry findEntry(int tag, T ref1) {
// invariant: canWriteDirect(ref1.constantPool())
int hash = AbstractPoolEntry.hash1(tag, ref1.index());
EntryMap<PoolEntry> map = map();
EntryMap map = map();
for (int token = map.firstToken(hash); token != -1; token = map.nextToken(hash, token)) {
PoolEntry e = map.getElementByToken(token);
PoolEntry e = entryByIndex(map.getIndexByToken(token));
if (e.tag() == tag
&& e instanceof AbstractPoolEntry.AbstractRefEntry<?> re
&& re.ref1 == ref1)
@ -356,9 +347,9 @@ public final class SplitConstantPool implements ConstantPoolBuilder {
AbstractPoolEntry findEntry(int tag, T ref1, U ref2) {
// invariant: canWriteDirect(ref1.constantPool()), canWriteDirect(ref2.constantPool())
int hash = AbstractPoolEntry.hash2(tag, ref1.index(), ref2.index());
EntryMap<PoolEntry> map = map();
EntryMap map = map();
for (int token = map.firstToken(hash); token != -1; token = map.nextToken(hash, token)) {
PoolEntry e = map.getElementByToken(token);
PoolEntry e = entryByIndex(map.getIndexByToken(token));
if (e.tag() == tag
&& e instanceof AbstractPoolEntry.AbstractRefsEntry<?, ?> re
&& re.ref1 == ref1
@ -374,10 +365,10 @@ public final class SplitConstantPool implements ConstantPoolBuilder {
}
private AbstractPoolEntry.Utf8EntryImpl tryFindUtf8(int hash, String target) {
EntryMap<PoolEntry> map = map();
EntryMap map = map();
for (int token = map.firstToken(hash); token != -1;
token = map.nextToken(hash, token)) {
PoolEntry e = map.getElementByToken(token);
PoolEntry e = entryByIndex(map.getIndexByToken(token));
if (e.tag() == ClassFile.TAG_UTF8
&& e instanceof AbstractPoolEntry.Utf8EntryImpl ce
&& ce.hashCode() == hash
@ -392,9 +383,9 @@ public final class SplitConstantPool implements ConstantPoolBuilder {
}
private AbstractPoolEntry.Utf8EntryImpl tryFindUtf8(int hash, AbstractPoolEntry.Utf8EntryImpl target) {
EntryMap<PoolEntry> map = map();
EntryMap map = map();
for (int token = map.firstToken(hash); token != -1; token = map.nextToken(hash, token)) {
PoolEntry e = map.getElementByToken(token);
PoolEntry e = entryByIndex(map.getIndexByToken(token));
if (e.tag() == ClassFile.TAG_UTF8
&& e instanceof AbstractPoolEntry.Utf8EntryImpl ce
&& target.equalsUtf8(ce))
@ -513,9 +504,9 @@ public final class SplitConstantPool implements ConstantPoolBuilder {
}
int hash = AbstractPoolEntry.hash2(TAG_METHODHANDLE, refKind, reference.index());
EntryMap<PoolEntry> map1 = map();
EntryMap map1 = map();
for (int token = map1.firstToken(hash); token != -1; token = map1.nextToken(hash, token)) {
PoolEntry e = map1.getElementByToken(token);
PoolEntry e = entryByIndex(map1.getIndexByToken(token));
if (e.tag() == TAG_METHODHANDLE
&& e instanceof AbstractPoolEntry.MethodHandleEntryImpl ce
&& ce.kind() == refKind && ce.reference() == reference)
@ -539,9 +530,9 @@ public final class SplitConstantPool implements ConstantPoolBuilder {
nameAndType = nameAndTypeEntry(nameAndType.name(), nameAndType.type());
int hash = AbstractPoolEntry.hash2(TAG_INVOKEDYNAMIC,
bootstrapMethodEntry.bsmIndex(), nameAndType.index());
EntryMap<PoolEntry> map1 = map();
EntryMap map1 = map();
for (int token = map1.firstToken(hash); token != -1; token = map1.nextToken(hash, token)) {
PoolEntry e = map1.getElementByToken(token);
PoolEntry e = entryByIndex(map1.getIndexByToken(token));
if (e.tag() == TAG_INVOKEDYNAMIC
&& e instanceof AbstractPoolEntry.InvokeDynamicEntryImpl ce
&& ce.bootstrap() == bootstrapMethodEntry && ce.nameAndType() == nameAndType)
@ -570,9 +561,9 @@ public final class SplitConstantPool implements ConstantPoolBuilder {
nameAndType = nameAndTypeEntry(nameAndType.name(), nameAndType.type());
int hash = AbstractPoolEntry.hash2(TAG_CONSTANTDYNAMIC,
bootstrapMethodEntry.bsmIndex(), nameAndType.index());
EntryMap<PoolEntry> map1 = map();
EntryMap map1 = map();
for (int token = map1.firstToken(hash); token != -1; token = map1.nextToken(hash, token)) {
PoolEntry e = map1.getElementByToken(token);
PoolEntry e = entryByIndex(map1.getIndexByToken(token));
if (e.tag() == TAG_CONSTANTDYNAMIC
&& e instanceof AbstractPoolEntry.ConstantDynamicEntryImpl ce
&& ce.bootstrap() == bootstrapMethodEntry && ce.nameAndType() == nameAndType)
@ -640,9 +631,9 @@ public final class SplitConstantPool implements ConstantPoolBuilder {
}
AbstractPoolEntry.MethodHandleEntryImpl mre = (AbstractPoolEntry.MethodHandleEntryImpl) methodReference;
int hash = BootstrapMethodEntryImpl.computeHashCode(mre, arguments);
EntryMap<BootstrapMethodEntryImpl> map = bsmMap();
EntryMap map = bsmMap();
for (int token = map.firstToken(hash); token != -1; token = map.nextToken(hash, token)) {
BootstrapMethodEntryImpl e = map.getElementByToken(token);
BootstrapMethodEntryImpl e = bootstrapMethodEntry(map.getIndexByToken(token));
if (e.bootstrapMethod() == mre && e.arguments().equals(arguments)) {
return e;
}