Skip to content

Commit

Permalink
Introduce HashMapInt for int values
Browse files Browse the repository at this point in the history
Avoid creating all those Integer objects.
  • Loading branch information
headius committed May 26, 2024
1 parent f5007a2 commit b6c4bc8
Show file tree
Hide file tree
Showing 3 changed files with 483 additions and 18 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,11 @@
import org.jruby.runtime.ThreadContext;
import org.jruby.runtime.builtin.IRubyObject;
import org.jruby.util.ByteList;
import org.jruby.util.collections.HashMapInt;

public class MarshalCache {
private final Map<IRubyObject, Integer> linkCache = new IdentityHashMap();
private final Map<ByteList, Integer> symbolCache = new HashMap();
private final HashMapInt linkCache = new HashMapInt<>(true);
private final HashMapInt symbolCache = new HashMapInt<ByteList>();

public boolean isRegistered(IRubyObject value) {
assert !(value instanceof RubySymbol) : "Use isSymbolRegistered for symbol links";
Expand Down Expand Up @@ -90,7 +91,7 @@ public void writeSymbolLink(NewMarshal output, NewMarshal.RubyOutputStream out,
}

private int registeredIndex(IRubyObject value) {
return linkCache.get(value).intValue();
return linkCache.get(value);
}

private int registeredSymbolIndex(ByteList sym) {
Expand Down
32 changes: 17 additions & 15 deletions core/src/main/java/org/jruby/runtime/marshal/NewMarshal.java
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,9 @@ private void writeAndRegister(ThreadContext context, RubyOutputStream out, IRuby
}
}

boolean doVariables;
int variableCount;

public void writeDirectly(ThreadContext context, RubyOutputStream out, IRubyObject value) {
ClassIndex nativeClassIndex;
boolean shouldMarshalEncoding;
Expand All @@ -210,18 +213,17 @@ public void writeDirectly(ThreadContext context, RubyOutputStream out, IRubyObje

} else {

boolean doVariables = shouldMarshalEncoding;
int size = 0;
doVariables = shouldMarshalEncoding;
variableCount = 0;

// check if any variables are set and collect size
Map<String, VariableAccessor> ivarAccessors = getMetaClass(value).getVariableAccessorsForRead();
var entries = ivarAccessors.entrySet();
for (var entry : entries) {
Object varValue = entry.getValue().get(value);
if (varValue == null || !(varValue instanceof Serializable)) continue;
ivarAccessors.forEach((name, accessor) -> {
Object varValue = accessor.get(value);
if (!(varValue instanceof Serializable)) return;
doVariables = true;
size++;
}
variableCount++;
});

if (doVariables) {
// object has instance vars and isn't a class, get a snapshot to be marshalled
Expand All @@ -232,17 +234,17 @@ public void writeDirectly(ThreadContext context, RubyOutputStream out, IRubyObje
dumpBaseObject(context, out, value, nativeClassIndex);

if (shouldMarshalEncoding) {
writeInt(out, size + 1); // vars preceded by encoding
writeInt(out, variableCount + 1); // vars preceded by encoding
writeEncoding(context, out, ((MarshalEncoding) value).getMarshalEncoding());
} else {
writeInt(out, size);
writeInt(out, variableCount);
}

for (var entry : entries) {
Object varValue = entry.getValue().get(value);
if (varValue == null || !(varValue instanceof Serializable)) continue;
dumpVariable(this, context, out, entry.getKey(), varValue);
}
ivarAccessors.forEach((name, accessor) -> {
Object varValue = accessor.get(value);
if (!(varValue instanceof Serializable)) return;
dumpVariable(this, context, out, name, varValue);
});
} else {
// no variables, no encoding
dumpBaseObject(context, out, value, nativeClassIndex);
Expand Down
Loading

0 comments on commit b6c4bc8

Please sign in to comment.