Skip to content
Snippets Groups Projects
Commit 14583a1b authored by stepan's avatar stepan
Browse files

Use RSymbol cache + create CharSXP for RSymbol lazily

parent b7af39ae
No related branches found
No related tags found
No related merge requests found
......@@ -229,8 +229,7 @@ public abstract class Identical extends RBuiltinNode.Arg8 {
@SuppressWarnings("unused")
@Specialization
protected byte doInternalIdentical(RSymbol x, RSymbol y, boolean numEq, boolean singleNA, boolean attribAsSet, boolean ignoreBytecode, boolean ignoreEnvironment, boolean ignoreSrcref) {
assert Utils.isInterned(x.getName()) && Utils.isInterned(y.getName());
return RRuntime.asLogical(x.getName() == y.getName());
return RRuntime.asLogical(x == y);
}
@Specialization
......@@ -343,10 +342,7 @@ public abstract class Identical extends RBuiltinNode.Arg8 {
return RRuntime.LOGICAL_FALSE;
} else {
if (xSubList.getTag() instanceof RSymbol && ySubList.getTag() instanceof RSymbol) {
String xTagName = ((RSymbol) xSubList.getTag()).getName();
String yTagName = ((RSymbol) ySubList.getTag()).getName();
assert Utils.isInterned(xTagName) && Utils.isInterned(yTagName);
if (xTagName != yTagName) {
if (xSubList.getTag() != ySubList.getTag()) {
return RRuntime.LOGICAL_FALSE;
}
} else {
......
......@@ -112,10 +112,6 @@ public abstract class MatchFun extends RBuiltinNode.Arg2 {
return vec.getDataAt(0);
}
protected static String firstString(RSymbol symbol) {
return symbol.getName();
}
private RFunction checkResult(Object result) {
if (result instanceof RFunction) {
return (RFunction) result;
......@@ -140,11 +136,11 @@ public abstract class MatchFun extends RBuiltinNode.Arg2 {
}
@SuppressWarnings("unused")
@Specialization(limit = "LIMIT", guards = {"funValue.getName() == cachedName", "getCallerFrameDescriptor(frame) == cachedCallerFrameDescriptor"})
@Specialization(limit = "LIMIT", guards = {"funValue == cachedFunValue", "getCallerFrameDescriptor(frame) == cachedCallerFrameDescriptor"})
protected RFunction matchfunCached(VirtualFrame frame, RPromise funPromise, RSymbol funValue, boolean descend,
@Cached("firstString(funValue)") String cachedName,
@Cached("funValue") RSymbol cachedFunValue,
@Cached("getCallerFrameDescriptor(frame)") FrameDescriptor cachedCallerFrameDescriptor,
@Cached("createLookup(cachedName, descend)") ReadVariableNode lookup) {
@Cached("createLookup(cachedFunValue.getName(), descend)") ReadVariableNode lookup) {
return checkResult(lookup.execute(frame, getCallerFrame.execute(frame)));
}
......
......@@ -96,7 +96,7 @@ public abstract class BaseAccessSlotNode extends RBaseNode {
}
if (value instanceof RSymbol) {
symbolValue.enter();
if (((RSymbol) value).getName() == RRuntime.PSEUDO_NULL.getName()) {
if (value == RRuntime.PSEUDO_NULL) {
return RNull.instance;
}
}
......
......@@ -46,12 +46,12 @@ import java.util.WeakHashMap;
*/
public final class CharSXPWrapper extends RObject implements RTruffleObject {
private static final CharSXPWrapper NA = new CharSXPWrapper(RRuntime.STRING_NA);
private final String contents;
private String contents;
private byte[] bytes;
private static final Map<CharSXPWrapper, WeakReference<CharSXPWrapper>> instances = new WeakHashMap<>(2048);
private CharSXPWrapper(String contents) {
this.contents = Utils.intern(contents);
this.contents = contents;
}
@TruffleBoundary
......@@ -96,6 +96,16 @@ public final class CharSXPWrapper extends RObject implements RTruffleObject {
}
public static CharSXPWrapper create(String contents) {
return create(contents, false);
}
public static CharSXPWrapper createInterned(String contents) {
assert Utils.isInterned(contents);
return create(contents, true);
}
private static CharSXPWrapper create(String contents, boolean intern) {
assert !intern || Utils.isInterned(contents);
if (contents == RRuntime.STRING_NA) {
return NA;
} else {
......@@ -106,6 +116,9 @@ public final class CharSXPWrapper extends RObject implements RTruffleObject {
if (wr != null) {
cachedWrapper = wr.get();
if (cachedWrapper != null) {
if (intern) {
cachedWrapper.contents = contents;
}
return cachedWrapper;
}
}
......
......@@ -22,11 +22,13 @@
*/
package com.oracle.truffle.r.runtime.data;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
import com.oracle.truffle.api.CompilerDirectives.ValueType;
import com.oracle.truffle.r.runtime.RType;
import com.oracle.truffle.r.runtime.Utils;
/**
* Denotes an R "symbol" or "name". Its rep is a {@code String} but it's a different type in the
......@@ -39,14 +41,15 @@ public final class RSymbol extends RAttributeStorage {
* Note: GnuR caches all symbols and some packages rely on their identity. Moreover, the cached
* symbols are never garbage collected. This table corresponds to {@code R_SymbolTable} in GNUR.
*/
private static final ConcurrentHashMap<String, RSymbol> symbolTable = new ConcurrentHashMap<>(1024);
private static final ConcurrentHashMap<String, RSymbol> symbolTable = new ConcurrentHashMap<>(2551);
public static final RSymbol MISSING = RDataFactory.createSymbol("");
private final CharSXPWrapper name;
private final String name;
private CharSXPWrapper nameWrapper;
private RSymbol(String name) {
this.name = CharSXPWrapper.create(name);
this.name = Utils.intern(name);
}
@TruffleBoundary
......@@ -60,11 +63,14 @@ public final class RSymbol extends RAttributeStorage {
}
public String getName() {
return name.getContents();
return name;
}
public CharSXPWrapper getWrappedName() {
return name;
if (nameWrapper == null) {
nameWrapper = CharSXPWrapper.createInterned(name);
}
return nameWrapper;
}
@Override
......@@ -78,7 +84,7 @@ public final class RSymbol extends RAttributeStorage {
@Override
public int hashCode() {
return this.getName().hashCode();
return System.identityHashCode(this.getName());
}
@Override
......@@ -86,7 +92,7 @@ public final class RSymbol extends RAttributeStorage {
if (obj == this) {
return true;
} else if (obj instanceof RSymbol) {
return ((RSymbol) obj).getName().equals(this.getName());
return ((RSymbol) obj).getName() == this.name;
}
return false;
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment