Skip to content
Snippets Groups Projects
Commit 5c2d0033 authored by Lukas Stadler's avatar Lukas Stadler
Browse files

factor out String interning in Attr/UpdateAttr and make it thread safe

parent 19997b86
No related branches found
No related tags found
No related merge requests found
...@@ -28,8 +28,6 @@ import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.toBoolean; ...@@ -28,8 +28,6 @@ import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.toBoolean;
import static com.oracle.truffle.r.runtime.builtins.RBehavior.PURE; import static com.oracle.truffle.r.runtime.builtins.RBehavior.PURE;
import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.PRIMITIVE; import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.PRIMITIVE;
import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.CompilerDirectives.CompilationFinal;
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Cached;
import com.oracle.truffle.api.dsl.Fallback; import com.oracle.truffle.api.dsl.Fallback;
...@@ -42,11 +40,12 @@ import com.oracle.truffle.r.nodes.attributes.IterableAttributeNode; ...@@ -42,11 +40,12 @@ import com.oracle.truffle.r.nodes.attributes.IterableAttributeNode;
import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetRowNamesAttributeNode; import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetRowNamesAttributeNode;
import com.oracle.truffle.r.nodes.builtin.CastBuilder; import com.oracle.truffle.r.nodes.builtin.CastBuilder;
import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode;
import com.oracle.truffle.r.nodes.builtin.base.UpdateAttr.InternStringNode;
import com.oracle.truffle.r.nodes.builtin.base.UpdateAttrNodeGen.InternStringNodeGen;
import com.oracle.truffle.r.nodes.function.opt.UpdateShareableChildValueNode; import com.oracle.truffle.r.nodes.function.opt.UpdateShareableChildValueNode;
import com.oracle.truffle.r.runtime.RError; import com.oracle.truffle.r.runtime.RError;
import com.oracle.truffle.r.runtime.RError.Message; import com.oracle.truffle.r.runtime.RError.Message;
import com.oracle.truffle.r.runtime.RRuntime; import com.oracle.truffle.r.runtime.RRuntime;
import com.oracle.truffle.r.runtime.Utils;
import com.oracle.truffle.r.runtime.builtins.RBuiltin; import com.oracle.truffle.r.runtime.builtins.RBuiltin;
import com.oracle.truffle.r.runtime.data.RAttributable; import com.oracle.truffle.r.runtime.data.RAttributable;
import com.oracle.truffle.r.runtime.data.RAttributesLayout; import com.oracle.truffle.r.runtime.data.RAttributesLayout;
...@@ -64,9 +63,9 @@ public abstract class Attr extends RBuiltinNode { ...@@ -64,9 +63,9 @@ public abstract class Attr extends RBuiltinNode {
private final ConditionProfile searchPartialProfile = ConditionProfile.createBinaryProfile(); private final ConditionProfile searchPartialProfile = ConditionProfile.createBinaryProfile();
private final BranchProfile errorProfile = BranchProfile.create(); private final BranchProfile errorProfile = BranchProfile.create();
@CompilationFinal private String cachedName = "";
@CompilationFinal private String cachedInternedName = "";
@Child private UpdateShareableChildValueNode sharedAttrUpdate = UpdateShareableChildValueNode.create(); @Child private UpdateShareableChildValueNode sharedAttrUpdate = UpdateShareableChildValueNode.create();
@Child private InternStringNode intern = InternStringNodeGen.create();
@Child private GetAttributeNode attrAccess = GetAttributeNode.create(); @Child private GetAttributeNode attrAccess = GetAttributeNode.create();
@Child private IterableAttributeNode iterAttrAccess = IterableAttributeNode.create(); @Child private IterableAttributeNode iterAttrAccess = IterableAttributeNode.create();
...@@ -83,28 +82,6 @@ public abstract class Attr extends RBuiltinNode { ...@@ -83,28 +82,6 @@ public abstract class Attr extends RBuiltinNode {
casts.arg("exact").asLogicalVector().findFirst().map(toBoolean()); casts.arg("exact").asLogicalVector().findFirst().map(toBoolean());
} }
private String intern(String name) {
if (cachedName == null) {
// unoptimized case
return Utils.intern(name);
}
if (cachedName == name) {
// cached case
return cachedInternedName;
}
CompilerDirectives.transferToInterpreterAndInvalidate();
// Checkstyle: stop StringLiteralEquality
if (cachedName == "") {
// Checkstyle: resume StringLiteralEquality
cachedName = name;
cachedInternedName = Utils.intern(name);
} else {
cachedName = null;
cachedInternedName = null;
}
return Utils.intern(name);
}
private Object searchKeyPartial(DynamicObject attributes, String name) { private Object searchKeyPartial(DynamicObject attributes, String name) {
Object val = RNull.instance; Object val = RNull.instance;
...@@ -141,7 +118,7 @@ public abstract class Attr extends RBuiltinNode { ...@@ -141,7 +118,7 @@ public abstract class Attr extends RBuiltinNode {
@Specialization(guards = "!isRowNamesAttr(name)") @Specialization(guards = "!isRowNamesAttr(name)")
protected Object attr(RAbstractContainer container, String name, boolean exact) { protected Object attr(RAbstractContainer container, String name, boolean exact) {
return attrRA(container, intern(name), exact); return attrRA(container, intern.execute(name), exact);
} }
@Specialization(guards = "isRowNamesAttr(name)") @Specialization(guards = "isRowNamesAttr(name)")
...@@ -163,7 +140,7 @@ public abstract class Attr extends RBuiltinNode { ...@@ -163,7 +140,7 @@ public abstract class Attr extends RBuiltinNode {
@TruffleBoundary @TruffleBoundary
protected Object attr(Object object, Object name, Object exact) { protected Object attr(Object object, Object name, Object exact) {
if (object instanceof RAttributable) { if (object instanceof RAttributable) {
return attrRA((RAttributable) object, intern((String) name), (boolean) exact); return attrRA((RAttributable) object, intern.execute((String) name), (boolean) exact);
} else { } else {
errorProfile.enter(); errorProfile.enter();
throw RError.nyi(this, "object cannot be attributed"); throw RError.nyi(this, "object cannot be attributed");
......
...@@ -29,17 +29,21 @@ import static com.oracle.truffle.r.runtime.builtins.RBehavior.PURE; ...@@ -29,17 +29,21 @@ import static com.oracle.truffle.r.runtime.builtins.RBehavior.PURE;
import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.PRIMITIVE; import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.PRIMITIVE;
import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.CompilerDirectives.CompilationFinal;
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
import com.oracle.truffle.api.dsl.Cached;
import com.oracle.truffle.api.dsl.Fallback; import com.oracle.truffle.api.dsl.Fallback;
import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.dsl.TypeSystemReference;
import com.oracle.truffle.api.nodes.Node;
import com.oracle.truffle.api.profiles.BranchProfile; import com.oracle.truffle.api.profiles.BranchProfile;
import com.oracle.truffle.r.nodes.EmptyTypeSystemFlatLayout;
import com.oracle.truffle.r.nodes.attributes.SetAttributeNode; import com.oracle.truffle.r.nodes.attributes.SetAttributeNode;
import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.SetClassAttributeNode; import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.SetClassAttributeNode;
import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.SetDimAttributeNode; import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.SetDimAttributeNode;
import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.SetRowNamesAttributeNode; import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.SetRowNamesAttributeNode;
import com.oracle.truffle.r.nodes.builtin.CastBuilder; import com.oracle.truffle.r.nodes.builtin.CastBuilder;
import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode;
import com.oracle.truffle.r.nodes.builtin.base.UpdateAttrNodeGen.InternStringNodeGen;
import com.oracle.truffle.r.nodes.unary.CastIntegerNode; import com.oracle.truffle.r.nodes.unary.CastIntegerNode;
import com.oracle.truffle.r.nodes.unary.CastIntegerNodeGen; import com.oracle.truffle.r.nodes.unary.CastIntegerNodeGen;
import com.oracle.truffle.r.nodes.unary.CastListNode; import com.oracle.truffle.r.nodes.unary.CastListNode;
...@@ -75,8 +79,25 @@ public abstract class UpdateAttr extends RBuiltinNode { ...@@ -75,8 +79,25 @@ public abstract class UpdateAttr extends RBuiltinNode {
@Child private SetAttributeNode setGenAttrNode; @Child private SetAttributeNode setGenAttrNode;
@Child private SetDimAttributeNode setDimNode; @Child private SetDimAttributeNode setDimNode;
@CompilationFinal private String cachedName = ""; @Child private InternStringNode intern = InternStringNodeGen.create();
@CompilationFinal private String cachedInternedName = "";
@TypeSystemReference(EmptyTypeSystemFlatLayout.class)
public abstract static class InternStringNode extends Node {
public abstract String execute(String value);
@Specialization(limit = "3", guards = "value == cachedValue")
protected static String internCached(@SuppressWarnings("unused") String value,
@SuppressWarnings("unused") @Cached("value") String cachedValue,
@Cached("intern(value)") String interned) {
return interned;
}
@Specialization(contains = "internCached")
protected static String intern(String value) {
return Utils.intern(value);
}
}
@Override @Override
protected void createCasts(CastBuilder casts) { protected void createCasts(CastBuilder casts) {
...@@ -118,31 +139,9 @@ public abstract class UpdateAttr extends RBuiltinNode { ...@@ -118,31 +139,9 @@ public abstract class UpdateAttr extends RBuiltinNode {
return (RAbstractVector) castVector.execute(value); return (RAbstractVector) castVector.execute(value);
} }
private String intern(String name) {
if (cachedName == null) {
// unoptimized case
return Utils.intern(name);
}
if (cachedName == name) {
// cached case
return cachedInternedName;
}
CompilerDirectives.transferToInterpreterAndInvalidate();
// Checkstyle: stop StringLiteralEquality
if (cachedName == "") {
// Checkstyle: resume StringLiteralEquality
cachedName = name;
cachedInternedName = Utils.intern(name);
} else {
cachedName = null;
cachedInternedName = null;
}
return Utils.intern(name);
}
@Specialization @Specialization
protected RAbstractContainer updateAttr(RAbstractContainer container, String name, RNull value) { protected RAbstractContainer updateAttr(RAbstractContainer container, String name, RNull value) {
String internedName = intern(name); String internedName = intern.execute(name);
RAbstractContainer result = (RAbstractContainer) container.getNonShared(); RAbstractContainer result = (RAbstractContainer) container.getNonShared();
// the name is interned, so identity comparison is sufficient // the name is interned, so identity comparison is sufficient
if (internedName == RRuntime.DIM_ATTR_KEY) { if (internedName == RRuntime.DIM_ATTR_KEY) {
...@@ -187,7 +186,7 @@ public abstract class UpdateAttr extends RBuiltinNode { ...@@ -187,7 +186,7 @@ public abstract class UpdateAttr extends RBuiltinNode {
@Specialization(guards = "!nullValue(value)") @Specialization(guards = "!nullValue(value)")
protected RAbstractContainer updateAttr(RAbstractContainer container, String name, Object value) { protected RAbstractContainer updateAttr(RAbstractContainer container, String name, Object value) {
String internedName = intern(name); String internedName = intern.execute(name);
RAbstractContainer result = (RAbstractContainer) container.getNonShared(); RAbstractContainer result = (RAbstractContainer) container.getNonShared();
// the name is interned, so identity comparison is sufficient // the name is interned, so identity comparison is sufficient
if (internedName == RRuntime.DIM_ATTR_KEY) { if (internedName == RRuntime.DIM_ATTR_KEY) {
...@@ -246,7 +245,7 @@ public abstract class UpdateAttr extends RBuiltinNode { ...@@ -246,7 +245,7 @@ public abstract class UpdateAttr extends RBuiltinNode {
if (object instanceof RShareable) { if (object instanceof RShareable) {
object = ((RShareable) object).getNonShared(); object = ((RShareable) object).getNonShared();
} }
String internedName = intern((String) name); String internedName = intern.execute((String) name);
if (object instanceof RAttributable) { if (object instanceof RAttributable) {
RAttributable attributable = (RAttributable) object; RAttributable attributable = (RAttributable) object;
if (value == RNull.instance) { if (value == RNull.instance) {
......
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