Skip to content

Commit

Permalink
Add an empty slot map for cases where no slots exist.
Browse files Browse the repository at this point in the history
  • Loading branch information
aardvark179 authored and gbrail committed Jan 9, 2025
1 parent 316fe29 commit 79c31a7
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 2 deletions.
50 changes: 48 additions & 2 deletions rhino/src/main/java/org/mozilla/javascript/SlotMapContainer.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

package org.mozilla.javascript;

import java.util.Collections;
import java.util.Iterator;

/**
Expand All @@ -23,14 +24,56 @@ class SlotMapContainer implements SlotMap {

private static final int DEFAULT_SIZE = 10;

private static class EmptySlotMap implements SlotMap {

@Override
public Iterator<Slot> iterator() {
return Collections.emptyIterator();
}

@Override
public int size() {
return 0;
}

@Override
public boolean isEmpty() {
return true;
}

@Override
public Slot modify(Object key, int index, int attributes) {
return null;
}

@Override
public Slot query(Object key, int index) {
return null;
}

@Override
public void add(Slot newSlot) {
throw new IllegalStateException();
}

@Override
public <S extends Slot> S compute(Object key, int index, SlotComputer<S> compute) {
throw new IllegalStateException();
}
}

private static EmptySlotMap EMPTY_SLOT_MAP = new EmptySlotMap();

protected SlotMap map;

SlotMapContainer() {
this(DEFAULT_SIZE);
}

SlotMapContainer(int initialSize) {
if (initialSize > LARGE_HASH_SIZE) {
if (initialSize == 0) {
map = EMPTY_SLOT_MAP;
} else if (initialSize > LARGE_HASH_SIZE) {
map = new HashSlotMap();
} else {
map = new EmbeddedSlotMap();
Expand Down Expand Up @@ -59,6 +102,7 @@ public Slot modify(Object key, int index, int attributes) {

@Override
public <S extends Slot> S compute(Object key, int index, SlotComputer<S> c) {
checkMapSize();
return map.compute(key, index, c);
}

Expand Down Expand Up @@ -92,7 +136,9 @@ public void unlockRead(long stamp) {
* map to a HashMap that is more robust against large numbers of hash collisions.
*/
protected void checkMapSize() {
if ((map instanceof EmbeddedSlotMap) && map.size() >= LARGE_HASH_SIZE) {
if (map == EMPTY_SLOT_MAP) {
map = new EmbeddedSlotMap();
} else if ((map instanceof EmbeddedSlotMap) && map.size() >= LARGE_HASH_SIZE) {
SlotMap newMap = new HashSlotMap(map);
map = newMap;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ public Slot modify(Object key, int index, int attributes) {
public <S extends Slot> S compute(Object key, int index, SlotComputer<S> c) {
final long stamp = lock.writeLock();
try {
checkMapSize();
return map.compute(key, index, c);
} finally {
lock.unlockWrite(stamp);
Expand Down

0 comments on commit 79c31a7

Please sign in to comment.