Skip to content
Snippets Groups Projects
Commit d9177b1a authored by Mick Jordan's avatar Mick Jordan
Browse files

Merge

parents 91fb66f0 64ef1a40
No related branches found
No related tags found
No related merge requests found
Showing
with 160 additions and 189 deletions
......@@ -30,6 +30,8 @@ import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.dsl.*;
import com.oracle.truffle.api.profiles.*;
import com.oracle.truffle.r.nodes.builtin.*;
import com.oracle.truffle.r.nodes.control.SequenceNode;
import com.oracle.truffle.r.nodes.function.FunctionBodyNode;
import com.oracle.truffle.r.runtime.*;
import com.oracle.truffle.r.runtime.data.*;
import com.oracle.truffle.r.runtime.data.RAttributes.RAttribute;
......@@ -156,6 +158,20 @@ public abstract class Identical extends RBuiltinNode {
}
RSyntaxNode xNode = x.getRep().asRSyntaxNode();
RSyntaxNode yNode = y.getRep().asRSyntaxNode();
// the following is (at least) needed by setGeneric function which expects a call node
// and function body node containing a single (same) call node to be identical
if (xNode instanceof FunctionBodyNode) {
xNode = ((FunctionBodyNode) xNode).getStatements();
}
if (yNode instanceof FunctionBodyNode) {
yNode = ((FunctionBodyNode) yNode).getStatements();
}
if (xNode instanceof SequenceNode && ((SequenceNode) xNode).getSequence().length == 1) {
xNode = ((SequenceNode) xNode).getSequence()[0].asRSyntaxNode();
}
if (yNode instanceof SequenceNode && ((SequenceNode) yNode).getSequence().length == 1) {
yNode = ((SequenceNode) yNode).getSequence()[0].asRSyntaxNode();
}
return RRuntime.asLogical(xNode.getRequalsImpl(yNode));
}
return RRuntime.LOGICAL_FALSE;
......
......@@ -41,9 +41,9 @@ import com.oracle.truffle.r.runtime.Utils;
import com.oracle.truffle.r.runtime.conn.StdConnections;
import com.oracle.truffle.r.runtime.context.RContext;
import com.oracle.truffle.r.runtime.data.RArgsValuesAndNames;
import com.oracle.truffle.r.runtime.data.RAttributable;
import com.oracle.truffle.r.runtime.data.RAttributeProfiles;
import com.oracle.truffle.r.runtime.data.RFunction;
import com.oracle.truffle.r.runtime.data.RS4Object;
import com.oracle.truffle.r.runtime.data.RTypedValue;
public class PrintFunctions {
......@@ -102,7 +102,7 @@ public class PrintFunctions {
// chacking for class attribute is a bit of a hack but GNU R has a hack in place here as
// well to avoid recursively calling show via print in showDefault (we just can't use
// the same hack at this point - for details see definition of showDefault in show.R)
return o instanceof RS4Object && ((RS4Object) o).getClassAttr(attrProfiles) != null;
return o instanceof RAttributable && ((RAttributable) o).isS4() && ((RAttributable) o).getClassAttr(attrProfiles) != null;
}
}
......
......@@ -110,11 +110,13 @@ public abstract class UnClass extends RBuiltinNode {
objectProfile.enter();
// TODO: should we make S4 objects shareable?
RS4Object resultS4 = RDataFactory.createS4Object();
RAttributes newAttributes = resultS4.initAttributes();
for (RAttribute attr : arg.getAttributes()) {
newAttributes.put(attr.getName(), attr.getValue());
if (arg.getAttributes() != null) {
RAttributes newAttributes = resultS4.initAttributes();
for (RAttribute attr : arg.getAttributes()) {
newAttributes.put(attr.getName(), attr.getValue());
}
newAttributes.remove(RRuntime.CLASS_ATTR_KEY);
}
newAttributes.remove(RRuntime.CLASS_ATTR_KEY);
return resultS4;
}
return arg;
......
......@@ -43,6 +43,7 @@ import com.oracle.truffle.r.runtime.data.RAttributable;
import com.oracle.truffle.r.runtime.data.RAttributeProfiles;
import com.oracle.truffle.r.runtime.data.RDataFactory;
import com.oracle.truffle.r.runtime.data.RNull;
import com.oracle.truffle.r.runtime.data.RShareable;
import com.oracle.truffle.r.runtime.data.RStringVector;
import com.oracle.truffle.r.runtime.data.model.RAbstractContainer;
import com.oracle.truffle.r.runtime.data.model.RAbstractIntVector;
......@@ -196,13 +197,17 @@ public abstract class UpdateAttr extends RInvisibleBuiltinNode {
* All other, non-performance centric, {@link RAttributable} types.
*/
@Fallback
protected Object updateAttr(Object object, Object name, Object value) {
protected Object updateAttr(Object obj, Object name, Object value) {
Object object = obj;
controlVisibility();
String sname = RRuntime.asString(name);
if (sname == null) {
errorProfile.enter();
throw RError.error(this, RError.Message.MUST_BE_NONNULL_STRING, "name");
}
if (object instanceof RShareable) {
object = ((RShareable) object).getNonShared();
}
String internedName = intern(sname);
if (object instanceof RAttributable) {
RAttributable attributable = (RAttributable) object;
......
......@@ -44,6 +44,7 @@ import com.oracle.truffle.r.runtime.data.RAttributeProfiles;
import com.oracle.truffle.r.runtime.data.RDataFactory;
import com.oracle.truffle.r.runtime.data.RList;
import com.oracle.truffle.r.runtime.data.RNull;
import com.oracle.truffle.r.runtime.data.RShareable;
import com.oracle.truffle.r.runtime.data.RStringVector;
import com.oracle.truffle.r.runtime.data.model.RAbstractContainer;
import com.oracle.truffle.r.runtime.data.model.RAbstractIntVector;
......@@ -209,8 +210,12 @@ public abstract class UpdateAttributes extends RInvisibleBuiltinNode {
*/
@Fallback
@TruffleBoundary
public Object doOther(Object obj, Object operand) {
public Object doOther(Object o, Object operand) {
controlVisibility();
Object obj = o;
if (obj instanceof RShareable) {
obj = ((RShareable) obj).getNonShared();
}
if (obj instanceof RAttributable) {
RAttributable attrObj = (RAttributable) obj;
attrObj.removeAllAttributes();
......
......@@ -17,7 +17,10 @@ import com.oracle.truffle.api.dsl.*;
import com.oracle.truffle.r.nodes.attributes.PutAttributeNode;
import com.oracle.truffle.r.nodes.attributes.PutAttributeNodeGen;
import com.oracle.truffle.r.nodes.function.ClassHierarchyNode;
import com.oracle.truffle.r.runtime.RRuntime;
import com.oracle.truffle.r.runtime.context.RContext;
import com.oracle.truffle.r.runtime.data.*;
import com.oracle.truffle.r.runtime.env.REnvironment;
import com.oracle.truffle.r.runtime.nodes.*;
@NodeChildren({@NodeChild(value = "object", type = RNode.class), @NodeChild(value = "name", type = RNode.class), @NodeChild(value = "value", type = RNode.class)})
......@@ -34,17 +37,39 @@ public abstract class UpdateSlotNode extends RNode {
}
@SuppressWarnings("unused")
@Specialization(guards = "name == cachedName")
@Specialization(guards = {"!isData(name)", "name == cachedName"})
protected Object updateSlotS4Cached(RAttributable object, String name, Object value, @Cached("name") String cachedName, @Cached("createAttrUpdate(cachedName)") PutAttributeNode attributeUpdate) {
attributeUpdate.execute(object.initAttributes(), value);
return object;
}
@Specialization(contains = "updateSlotS4Cached")
@Specialization(contains = "updateSlotS4Cached", guards = "!isData(name)")
protected Object updateSlotS4(RAttributable object, String name, Object value) {
assert name == name.intern();
object.setAttr(name, value);
return object;
}
protected RFunction setDataPartFunction(REnvironment methodsNamespace) {
Object f = methodsNamespace.findFunction("setDataPart");
return (RFunction) RContext.getRRuntimeASTAccess().forcePromise(f);
}
private Object setDataPart(RAttributable object, Object value) {
// TODO: any way to cache it or use a mechanism similar to overrides?
REnvironment methodsNamespace = REnvironment.getRegisteredNamespace("methods");
RFunction dataPart = setDataPartFunction(methodsNamespace);
return RContext.getEngine().evalFunction(dataPart, methodsNamespace.getFrame(), object, value, RRuntime.LOGICAL_TRUE);
}
@Specialization(guards = "isData(name)")
protected Object updateSlotS4Data(RAttributable object, @SuppressWarnings("unused") String name, Object value) {
return setDataPart(object, value);
}
protected boolean isData(String name) {
assert name == name.intern();
return name == RRuntime.DOT_DATA;
}
}
......@@ -131,7 +131,7 @@ public final class FunctionDefinitionNode extends RRootNode implements RSyntaxNo
public RRootNode duplicateWithNewFrameDescriptor() {
FrameDescriptor frameDesc = new FrameDescriptor();
FrameSlotChangeMonitor.initializeFunctionFrameDescriptor(description != null && !description.isEmpty() ? description : "<function>", frameDesc);
return new FunctionDefinitionNode(getSourceSection(), frameDesc, (BodyNode) body.deepCopy(), getFormalArguments(), description, substituteFrame, argPostProcess == null ? null
return new FunctionDefinitionNode(getSourceSection(), frameDesc, (BodyNode) body.unwrap().deepCopy(), getFormalArguments(), description, substituteFrame, argPostProcess == null ? null
: (PostProcessArgumentsNode) argPostProcess.deepCopy());
}
......
......@@ -51,18 +51,18 @@ public abstract class DuplicateNode extends RBaseNode {
@Specialization
protected Object duplicate(RS4Object object) {
RS4Object newObject = RDataFactory.createS4Object();
RAttributes newAttributes = newObject.initAttributes();
for (RAttribute attr : object.getAttributes()) {
newAttributes.put(attr.getName(), attr.getValue());
if (object.getAttributes() != null) {
RAttributes newAttributes = newObject.initAttributes();
for (RAttribute attr : object.getAttributes()) {
newAttributes.put(attr.getName(), attr.getValue());
}
}
return newObject;
}
@Specialization
protected Object duplicate(RFunction f) {
RFunction newObject = RDataFactory.createFunction(f.getName(), f.getTarget(), f.getRBuiltin(), f.getEnclosingFrame(), f.getFastPath(), f.containsDispatch());
newObject.initAttributes(f.getAttributes());
return newObject;
return f.copy();
}
// TODO: support more types when required
......
......@@ -1522,6 +1522,10 @@ public class RSerialize {
break;
}
case S4SXP: {
break;
}
/*
* FastR scalar, (length 1) "vectors"
*/
......
......@@ -105,7 +105,11 @@ public interface RAttributable extends RTypedValue {
}
default RAttributable setClassAttr(RStringVector classAttr, @SuppressWarnings("unused") boolean convertToInt) {
setAttr(RRuntime.CLASS_ATTR_KEY, classAttr);
if (classAttr == null && getAttributes() != null) {
getAttributes().remove(RRuntime.CLASS_ATTR_KEY);
} else {
setAttr(RRuntime.CLASS_ATTR_KEY, classAttr);
}
return this;
}
......
......@@ -85,7 +85,7 @@ public final class RDataFrame implements RShareable, RAbstractContainer {
}
@Override
public RVector makeShared() {
public RSharingAttributeStorage makeShared() {
return vector.makeShared();
}
......@@ -109,6 +109,12 @@ public final class RDataFrame implements RShareable, RAbstractContainer {
vector.makeSharedPermanent();
}
@Override
public RShareable getNonShared() {
RVector newVector = (RVector) vector.getNonShared();
return newVector == vector ? this : RDataFactory.createDataFrame(newVector);
}
@Override
public RDataFrame copy() {
return RDataFactory.createDataFrame(vector.copy());
......
......@@ -180,7 +180,7 @@ public class RExpression implements RShareable, RAbstractContainer {
}
@Override
public RVector makeShared() {
public RSharingAttributeStorage makeShared() {
return data.makeShared();
}
......@@ -204,6 +204,12 @@ public class RExpression implements RShareable, RAbstractContainer {
data.makeSharedPermanent();
}
@Override
public RShareable getNonShared() {
RList newData = (RList) data.getNonShared();
return newData == data ? this : RDataFactory.createExpression(newData);
}
@Override
public RExpression copy() {
return RDataFactory.createExpression((RList) data.copy());
......
......@@ -83,7 +83,7 @@ public final class RFactor implements RShareable, RAbstractContainer {
}
@Override
public RVector makeShared() {
public RSharingAttributeStorage makeShared() {
return vector.makeShared();
}
......@@ -107,6 +107,12 @@ public final class RFactor implements RShareable, RAbstractContainer {
vector.makeSharedPermanent();
}
@Override
public RShareable getNonShared() {
RIntVector newVector = (RIntVector) vector.getNonShared();
return newVector == vector ? this : RDataFactory.createFactor(newVector, ordered);
}
@Override
public RFactor copy() {
return RDataFactory.createFactor((RIntVector) vector.copy(), ordered);
......
......@@ -31,6 +31,7 @@ import com.oracle.truffle.r.runtime.RBuiltin;
import com.oracle.truffle.r.runtime.RType;
import com.oracle.truffle.r.runtime.VirtualEvalFrame;
import com.oracle.truffle.r.runtime.context.RContext;
import com.oracle.truffle.r.runtime.data.RAttributes.RAttribute;
/**
* An instance of {@link RFunction} represents a function defined in R. The properties of a function
......@@ -44,7 +45,7 @@ import com.oracle.truffle.r.runtime.context.RContext;
* {@link #enclosingFrame}.
* </ul>
*/
public final class RFunction extends RAttributeStorage implements RTypedValue, TruffleObject {
public final class RFunction extends RSharingAttributeStorage implements RTypedValue, TruffleObject {
public static final String NO_NAME = new String("");
......@@ -126,4 +127,19 @@ public final class RFunction extends RAttributeStorage implements RTypedValue, T
public void setFastPath(FastPathFactory fastPath) {
this.fastPath = fastPath;
}
@Override
public RShareable copy() {
RFunction newFunction = RDataFactory.createFunction(getName(), getTarget(), getRBuiltin(), getEnclosingFrame(), getFastPath(), containsDispatch());
if (getAttributes() != null) {
RAttributes newAttributes = newFunction.initAttributes();
for (RAttribute attr : getAttributes()) {
newAttributes.put(attr.getName(), attr.getValue());
}
newFunction.initAttributes(newAttributes);
}
return newFunction;
}
}
......@@ -36,11 +36,6 @@ import com.oracle.truffle.r.runtime.nodes.*;
* instances. R allows a language element to be treated as a list, hence the support for
* {@link RAbstractContainer}, which is implemented via AST walk operations.
*
* The representation is inherited from {@link RLanguageRep}. This is a Truffle AST ({@code RNode}),
* although that type is not statically used here due to project circularities. A related
* consequence is the the implementation of the {@link RAbstractContainer} methods are delegated to
* a helper class from a project that can access {@code RNode}.
*
* {@link RLanguage} instances are almost completely immutable, <i>except</i> for the ability for
* {@code}names} updates which manifests itself as actually transforming the AST. S we do have to
* implement the {@link RShareable} interface.
......@@ -48,11 +43,9 @@ import com.oracle.truffle.r.runtime.nodes.*;
*
*/
@ValueType
public class RLanguage extends RLanguageRep implements RAbstractContainer, RAttributable, RShareable {
private RAttributes attributes;
public class RLanguage extends RSharingAttributeStorage implements RAbstractContainer, RAttributable, RShareable {
private int gpbits;
private RBaseNode rep;
/**
* Lazily computed value.
......@@ -60,31 +53,24 @@ public class RLanguage extends RLanguageRep implements RAbstractContainer, RAttr
private int length = -1;
RLanguage(RNode rep) {
super(rep);
this.rep = rep;
}
RLanguage(RNode rep, int length) {
super(rep);
this.rep = rep;
this.length = length;
}
public RType getRType() {
return RType.Language;
public RBaseNode getRep() {
return rep;
}
public RAttributes getAttributes() {
return attributes;
public void setRep(RBaseNode rep) {
this.rep = rep;
}
public RAttributes initAttributes() {
if (attributes == null) {
attributes = RAttributes.create();
}
return attributes;
}
public final void initAttributes(RAttributes newAttributes) {
attributes = newAttributes;
public RType getRType() {
return RType.Language;
}
public boolean isComplete() {
......@@ -124,15 +110,7 @@ public class RLanguage extends RLanguageRep implements RAbstractContainer, RAttr
}
public RLanguage materializeNonShared() {
if (this.isShared()) {
RLanguage res = this.copy();
res.markNonTemporary();
return res;
}
if (this.isTemporary()) {
this.markNonTemporary();
}
return this;
return (RLanguage) getNonShared();
}
public RShareable materializeToShareable() {
......@@ -183,10 +161,7 @@ public class RLanguage extends RLanguageRep implements RAbstractContainer, RAttr
setAttr(RRuntime.ROWNAMES_ATTR_KEY, rowNames);
}
public RStringVector getClassHierarchy() {
return RDataFactory.createStringVector(RRuntime.CLASS_LANGUAGE);
}
@Override
public RStringVector getImplicitClass() {
return RDataFactory.createStringVector(RRuntime.CLASS_LANGUAGE);
}
......@@ -206,78 +181,9 @@ public class RLanguage extends RLanguageRep implements RAbstractContainer, RAttr
return l;
}
/*
* RShareable support. Code is cloned directly from RVector.
*/
private boolean shared;
private boolean temporary = true;
private int refCount;
public void markNonTemporary() {
assert !FastROptions.NewStateTransition.getBooleanValue();
temporary = false;
}
public boolean isTemporary() {
if (FastROptions.NewStateTransition.getBooleanValue()) {
return refCount == 0;
} else {
return temporary;
}
}
public boolean isShared() {
if (FastROptions.NewStateTransition.getBooleanValue()) {
return refCount > 1;
} else {
return shared;
}
}
public RShareable makeShared() {
assert !FastROptions.NewStateTransition.getBooleanValue();
if (temporary) {
temporary = false;
}
shared = true;
return this;
}
public void incRefCount() {
refCount++;
}
public void decRefCount() {
assert refCount > 0;
refCount--;
}
@Override
public boolean isSharedPermanent() {
return refCount == SHARED_PERMANENT_VAL;
}
@Override
public void makeSharedPermanent() {
if (FastROptions.NewStateTransition.getBooleanValue()) {
refCount = SHARED_PERMANENT_VAL;
} else {
// old scheme never reverts states
makeShared();
}
}
@Override
public String toString() {
return String.format("RLanguage(rep=%s)", getRep());
}
public int getGPBits() {
return gpbits;
}
public void setGPBits(int value) {
gpbits = value;
}
}
/*
* Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.oracle.truffle.r.runtime.data;
import com.oracle.truffle.r.runtime.nodes.*;
/**
* Denotes an (unevaluated) element of the R language.
*
* This type is not part of the {@code TypeSystem} but it used as a superclass by {@link RLanguage}
* and {@link RPromise}.
*/
public abstract class RLanguageRep {
private RBaseNode rep;
public RLanguageRep(RBaseNode rep) {
this.rep = rep;
}
public RBaseNode getRep() {
return rep;
}
public void setRep(RBaseNode rep) {
this.rep = rep;
}
}
......@@ -38,7 +38,7 @@ import com.oracle.truffle.r.runtime.nodes.*;
* which is used for manual method dispatch.
*/
@ValueType
public class RPromise extends RLanguageRep implements RTypedValue {
public class RPromise implements RTypedValue {
/**
* Different to GNU R, FastR has no additional binding information (a "origin" where the binding
......@@ -79,6 +79,8 @@ public class RPromise extends RLanguageRep implements RTypedValue {
public static final String CLOSURE_WRAPPER_NAME = new String("<promise>");
private RBaseNode rep;
/**
* @see PromiseType
*/
......@@ -112,7 +114,7 @@ public class RPromise extends RLanguageRep implements RTypedValue {
* This creates a new tuple (expr, env, closure, value=null), which may later be evaluated.
*/
RPromise(PromiseType type, OptType optType, MaterializedFrame execFrame, Closure closure) {
super(closure.getExpr());
this.rep = closure.getExpr();
assert type != PromiseType.ARG_DEFAULT || execFrame != null;
this.type = type;
this.optType = optType;
......@@ -124,7 +126,7 @@ public class RPromise extends RLanguageRep implements RTypedValue {
* This creates a new tuple (expr, null, null, value), which is already evaluated.
*/
RPromise(PromiseType type, OptType optType, RBaseNode expr, Object value) {
super(expr);
this.rep = expr;
assert value != null;
this.type = type;
this.optType = optType;
......@@ -139,7 +141,7 @@ public class RPromise extends RLanguageRep implements RTypedValue {
* called via {@link VarargPromise#VarargPromise(PromiseType, RPromise, Closure)} only!
*/
private RPromise(PromiseType type, OptType optType, RBaseNode expr) {
super(expr);
this.rep = expr;
this.type = type;
this.optType = optType;
// Not needed as already evaluated:
......@@ -147,6 +149,14 @@ public class RPromise extends RLanguageRep implements RTypedValue {
this.closure = null;
}
public RBaseNode getRep() {
return rep;
}
public void setRep(RBaseNode rep) {
this.rep = rep;
}
public RType getRType() {
return RType.Promise;
}
......@@ -192,15 +202,6 @@ public class RPromise extends RLanguageRep implements RTypedValue {
return frame == execFrame;
}
/**
* @return The representation of expression (a RNode). May contain <code>null</code> if no expr
* is provided!
*/
@Override
public final RBaseNode getRep() {
return super.getRep();
}
/**
* @return {@link #closure}
*/
......@@ -485,4 +486,9 @@ public class RPromise extends RLanguageRep implements RTypedValue {
throw RInternalError.shouldNotReachHere();
}
@Override
public boolean isS4() {
return false;
}
}
......@@ -38,4 +38,9 @@ public abstract class RScalar implements RTypedValue {
throw RInternalError.shouldNotReachHere();
}
@Override
public boolean isS4() {
return false;
}
}
......@@ -199,4 +199,9 @@ public abstract class RSequence implements RAbstractVector {
throw RInternalError.shouldNotReachHere();
}
@Override
public boolean isS4() {
return false;
}
}
......@@ -52,4 +52,6 @@ public interface RShareable {
void makeSharedPermanent();
RShareable getNonShared();
}
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