Skip to content

Commit

Permalink
Showing 3 changed files with 15 additions and 28 deletions.
Original file line number Diff line number Diff line change
@@ -37,7 +37,6 @@ public int hashCode() {

void setSymbol(DynamicObject symbol) {
assert RubyGuards.isRubySymbol(symbol);
assert symbol != null;
this.symbol = symbol;
}
}
Original file line number Diff line number Diff line change
@@ -12,6 +12,7 @@
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
import com.oracle.truffle.api.nodes.Node;
import com.oracle.truffle.api.object.DynamicObject;
import com.oracle.truffle.api.object.DynamicObjectFactory;
import org.jcodings.specific.USASCIIEncoding;
import org.jruby.truffle.Layouts;
import org.jruby.truffle.RubyContext;
@@ -21,7 +22,6 @@
import org.jruby.truffle.language.control.RaiseException;
import org.jruby.util.ByteList;
import org.jruby.util.IdUtil;

import java.lang.ref.Reference;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
@@ -33,7 +33,7 @@

public class SymbolTable {

private final RubyContext context;
private final DynamicObjectFactory symbolFactory;

private final ReadWriteLock lock = new ReentrantReadWriteLock();

@@ -46,34 +46,30 @@ public class SymbolTable {
private final Map<SymbolEquality, Reference<DynamicObject>> symbolSet = new WeakHashMap<>();

public SymbolTable(RubyContext context) {
this.context = context;
this.symbolFactory = Layouts.CLASS.getInstanceFactory(context.getCoreLibrary().getSymbolClass());
}

@TruffleBoundary
public DynamicObject getSymbol(String stringKey) {
lock.readLock().lock();
DynamicObject symbol = null;
try {
final Reference<DynamicObject> reference = stringSymbolMap.get(stringKey);
symbol = reference == null ? null : reference.get();
symbol = readRef(stringSymbolMap, stringKey);
if (symbol != null) {
return symbol;
}

} finally {
lock.readLock().unlock();
}

lock.writeLock().lock();
try {
final Reference<DynamicObject> reference1 = stringSymbolMap.get(stringKey);
symbol = reference1 == null ? null : reference1.get();
symbol = readRef(stringSymbolMap, stringKey);
if (symbol != null) {
return symbol;
}

final Rope rope = StringOperations.createRope(stringKey, USASCIIEncoding.INSTANCE);

symbol = getDeduplicatedSymbol(rope);

stringSymbolMap.put(stringKey, new WeakReference<DynamicObject>(symbol));
@@ -89,26 +85,22 @@ public DynamicObject getSymbol(Rope ropeKey) {
lock.readLock().lock();
DynamicObject symbol = null;
try {
final Reference<DynamicObject> reference = ropeSymbolMap.get(ropeKey);
symbol = reference == null ? null : reference.get();
symbol = readRef(ropeSymbolMap, ropeKey);
if (symbol != null) {
return symbol;
}

} finally {
lock.readLock().unlock();
}

lock.writeLock().lock();
try {
final Reference<DynamicObject> reference1 = ropeSymbolMap.get(ropeKey);
symbol = reference1 == null ? null : reference1.get();
symbol = readRef(ropeSymbolMap, ropeKey);
if (symbol != null) {
return symbol;
}

final Rope rope = RopeOperations.flatten(ropeKey);

symbol = getDeduplicatedSymbol(rope);

ropeSymbolMap.put(rope, new WeakReference<DynamicObject>(symbol));
@@ -122,8 +114,7 @@ public DynamicObject getSymbol(Rope ropeKey) {
private DynamicObject getDeduplicatedSymbol(Rope rope) {
final DynamicObject newSymbol = createSymbol(rope);
final SymbolEquality newKey = Layouts.SYMBOL.getEqualityWrapper(newSymbol);
final Reference<DynamicObject> reference = symbolSet.get(newKey);
final DynamicObject currentSymbol = reference == null ? null : reference.get();
final DynamicObject currentSymbol = readRef(symbolSet, newKey);

if (currentSymbol == null) {
symbolSet.put(newKey, new WeakReference<DynamicObject>(newSymbol));
@@ -134,16 +125,11 @@ private DynamicObject getDeduplicatedSymbol(Rope rope) {
}

private DynamicObject createSymbol(Rope rope) {
final DynamicObject symbolClass = context.getCoreLibrary().getSymbolClass();
final String string = ByteList.decode(
rope.getBytes(),
0,
rope.byteLength(),
"ISO-8859-1");
final String string = ByteList.decode(rope.getBytes(), 0, rope.byteLength(), "ISO-8859-1");
// Symbol has to have reference to its SymbolEquality otherwise it would be GCed.
final SymbolEquality equalityWrapper = new SymbolEquality();
final DynamicObject symbol = Layouts.SYMBOL.createSymbol(
Layouts.CLASS.getInstanceFactory(symbolClass),
symbolFactory,
string,
rope,
string.hashCode(),
@@ -153,12 +139,16 @@ private DynamicObject createSymbol(Rope rope) {
return symbol;
}

private <K, V> V readRef(Map<K, Reference<V>> map, K key) {
Reference<V> reference = map.get(key);
return reference == null ? null : reference.get();
}

@TruffleBoundary
public Collection<DynamicObject> allSymbols() {
final Collection<Reference<DynamicObject>> symbolReferences;

lock.readLock().lock();

try {
symbolReferences = symbolSet.values();
} finally {
Original file line number Diff line number Diff line change
@@ -11,11 +11,9 @@

import com.oracle.truffle.api.CompilerAsserts;
import com.oracle.truffle.api.interop.ForeignAccess;
import com.oracle.truffle.api.interop.TruffleObject;
import com.oracle.truffle.api.object.DynamicObject;
import com.oracle.truffle.api.object.ObjectType;
import org.jruby.truffle.Layouts;
import org.jruby.truffle.RubyContext;
import org.jruby.truffle.core.rope.RopeOperations;
import org.jruby.truffle.core.string.StringOperations;
import org.jruby.truffle.interop.RubyMessageResolutionAccessor;

0 comments on commit 39a9016

Please sign in to comment.