Skip to content

Commit

Permalink
lua4jvm: Use tombstones to fix LuaTable consistency issues
Browse files Browse the repository at this point in the history
  • Loading branch information
bensku committed Jul 10, 2024
1 parent 57c43c1 commit 191b1e4
Showing 1 changed file with 4 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ public class LuaTable {
public static final Type TYPE = Type.of(LuaTable.class);

private static final Object[] EMPTY = new Object[0];
private static final Object TOMBSTONE = new Object();

private Object[] table;
private int arraySize, arrayCapacity;
Expand All @@ -43,6 +44,7 @@ int getSlot(Object key) {
var slot = hash(key) & (keys.length - 1);
for (; slot < keys.length; slot++) {
var actualKey = keys[slot];
// TODO consider storing hashes and checking against them; equality checks may be slow
if (actualKey == null) {
return -1;
} else if (key.equals(actualKey)) {
Expand Down Expand Up @@ -122,6 +124,7 @@ void setAt(int slot, Object key, Object value) {
// If a key is removed from table, a different key could be placed to same slot
// Additionally, this affects __index and __newindex if those exist
shapeChanged();
key = TOMBSTONE; // We might be punching a hole to a cluster of hash collisions
} else if (metatable != null && oldKey == null) {
// If an entirely new key is written AND we have a metatable
// get/set on that key will no longer be sent to __index/__newindex
Expand Down Expand Up @@ -195,7 +198,7 @@ int getFreeSlot(Object key) {
var slot = hash(key) & (keys.length - 1);
for (; slot < keys.length; slot++) {
var actualKey = keys[slot];
if (actualKey == null || key.equals(actualKey)) {
if (actualKey == null || actualKey == TOMBSTONE || key.equals(actualKey)) {
return slot;
}
}
Expand Down

0 comments on commit 191b1e4

Please sign in to comment.