Skip to content

Commit

Permalink
Showing 4 changed files with 43 additions and 0 deletions.
2 changes: 2 additions & 0 deletions core/src/main/java/org/jruby/util/cli/Options.java
Original file line number Diff line number Diff line change
@@ -231,7 +231,9 @@ public class Options {
public static final Option<Integer> TRUFFLE_ARRAY_UNINITIALIZED_SIZE = integer(TRUFFLE, "truffle.array.uninitialized_size", 32, "How large an Array to allocate when we have no other information to go on.");
public static final Option<Integer> TRUFFLE_ARRAY_SMALL = integer(TRUFFLE, "truffle.array.small", 3, "Maximum size of an Array to consider small for optimisations.");
public static final Option<Integer> TRUFFLE_HASH_PACKED_ARRAY_MAX = integer(TRUFFLE, "truffle.hash.packed_array.max", 3, "Maximum size of a Hash to consider using the packed array storage strategy for.");

public static final Option<Boolean> TRUFFLE_ROPE_LAZY_SUBSTRINGS = bool(TRUFFLE, "truffle.rope.lazy_substrings", true, "Indicates whether a substring operation on a rope should be performed lazily.");
public static final Option<Boolean> TRUFFLE_ROPE_PRINT_INTERN_STATS = bool(TRUFFLE, "truffle.rope.print_intern_stats", false, "Print interned rope stats at application exit.");

public static final Option<Integer> TRUFFLE_DEFAULT_CACHE = integer(TRUFFLE, "truffle.default_cache", 8, "Default size for caches.");

7 changes: 7 additions & 0 deletions truffle/src/main/java/org/jruby/truffle/RubyContext.java
Original file line number Diff line number Diff line change
@@ -184,6 +184,13 @@ public Object send(Object object, String methodName, DynamicObject block, Object
}

public void shutdown() {
if (getOptions().ROPE_PRINT_INTERN_STATS) {
System.out.println("Ropes re-used: " + getRopeTable().getRopesReusedCount());
System.out.println("Rope byte arrays re-used: " + getRopeTable().getByteArrayReusedCount());
System.out.println("Rope bytes saved: " + getRopeTable().getRopeBytesSaved());
System.out.println("Total ropes interned: " + getRopeTable().totalRopes());
}

atExitManager.runSystemExitHooks();

if (instrumentationServerManager != null) {
32 changes: 32 additions & 0 deletions truffle/src/main/java/org/jruby/truffle/core/rope/RopeTable.java
Original file line number Diff line number Diff line change
@@ -15,6 +15,8 @@

import java.lang.ref.WeakReference;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
import java.util.WeakHashMap;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
@@ -23,6 +25,11 @@ public class RopeTable {

private final ReadWriteLock lock = new ReentrantReadWriteLock();
private final WeakHashMap<Key, WeakReference<Rope>> ropesTable = new WeakHashMap<>();
private final Set<Key> keys = new HashSet<>();

private int byteArrayReusedCount;
private int ropesReusedCount;
private int ropeBytesSaved;

@TruffleBoundary
public Rope getRope(byte[] bytes, Encoding encoding, CodeRange codeRange) {
@@ -37,6 +44,9 @@ public Rope getRope(byte[] bytes, Encoding encoding, CodeRange codeRange) {
final Rope rope = ropeReference.get();

if (rope != null) {
++ropesReusedCount;
ropeBytesSaved += rope.byteLength();

return rope;
}
}
@@ -74,18 +84,40 @@ public Rope getRope(byte[] bytes, Encoding encoding, CodeRange codeRange) {
final Rope rope;
if (ropeWithSameBytesButDifferentEncoding != null) {
rope = RopeOperations.create(ropeWithSameBytesButDifferentEncoding.getBytes(), encoding, codeRange);

++byteArrayReusedCount;
ropeBytesSaved += rope.byteLength();
} else {
rope = RopeOperations.create(bytes, encoding, codeRange);
}

ropesTable.put(key, new WeakReference<>(rope));

// TODO (nirvdrum 30-Mar-16): Revisit this. The purpose is to keep all keys live so the weak rope table never expunges results. We don't want that -- we want something that naturally ties to lifetime. Unfortunately, the old approach expunged live values because the key is synthetic.
keys.add(key);

return rope;
} finally {
lock.writeLock().unlock();
}
}

public int getByteArrayReusedCount() {
return byteArrayReusedCount;
}

public int getRopesReusedCount() {
return ropesReusedCount;
}

public int getRopeBytesSaved() {
return ropeBytesSaved;
}

public int totalRopes() {
return ropesTable.size();
}

public static class Key {

private final byte[] bytes;
2 changes: 2 additions & 0 deletions truffle/src/main/java/org/jruby/truffle/language/Options.java
Original file line number Diff line number Diff line change
@@ -48,6 +48,7 @@
import static org.jruby.util.cli.Options.TRUFFLE_PLATFORM_USE_JAVA;
import static org.jruby.util.cli.Options.TRUFFLE_ROPE_CLASS_CACHE;
import static org.jruby.util.cli.Options.TRUFFLE_ROPE_LAZY_SUBSTRINGS;
import static org.jruby.util.cli.Options.TRUFFLE_ROPE_PRINT_INTERN_STATS;
import static org.jruby.util.cli.Options.TRUFFLE_SYMBOL_TO_PROC_CACHE;
import static org.jruby.util.cli.Options.TRUFFLE_THREAD_CACHE;
import static org.jruby.util.cli.Options.TRUFFLE_UNPACK_CACHE;
@@ -75,6 +76,7 @@ public class Options {
public final int HASH_PACKED_ARRAY_MAX = TRUFFLE_HASH_PACKED_ARRAY_MAX.load();

public final boolean ROPE_LAZY_SUBSTRINGS = TRUFFLE_ROPE_LAZY_SUBSTRINGS.load();
public final boolean ROPE_PRINT_INTERN_STATS = TRUFFLE_ROPE_PRINT_INTERN_STATS.load();

// Caches

0 comments on commit 91ec95f

Please sign in to comment.