diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/UpdateShareableChildValueNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/UpdateShareableChildValueNode.java index 34ec1499908e9ba7a14eaf497867b6c34f753f36..73077edfd5a750b9ade99926ba88a80f97f5379a 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/UpdateShareableChildValueNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/UpdateShareableChildValueNode.java @@ -48,8 +48,9 @@ public abstract class UpdateShareableChildValueNode extends RBaseNode { @Specialization protected void doShareableValues(RShareable owner, RShareable value, - @Cached("createClassProfile()") ValueProfile ownerProfile, @Cached("createClassProfile()") ValueProfile valueProfile, + @Cached("createBinaryProfile()") ConditionProfile sharingAttrsStorageOwner, + @Cached("createClassProfile()") ValueProfile ownerProfile, @Cached("createBinaryProfile()") ConditionProfile sharedValue, @Cached("createBinaryProfile()") ConditionProfile temporaryOwner) { RShareable profiledValue = valueProfile.profile(value); @@ -58,7 +59,7 @@ public abstract class UpdateShareableChildValueNode extends RBaseNode { return; } - if (owner instanceof RSharingAttributeStorage) { + if (sharingAttrsStorageOwner.profile(owner instanceof RSharingAttributeStorage)) { // monomorphic invocations of the owner RSharingAttributeStorage shOwner = (RSharingAttributeStorage) owner; incRef(shOwner, profiledValue, temporaryOwner); diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/opt/ShareObjectNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/opt/ShareObjectNode.java index de2c9eda806469d95e22a5c8c9962e4cafe612a0..81ac78c1819f2a472380e7e554f8a6eb87eae8db 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/opt/ShareObjectNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/opt/ShareObjectNode.java @@ -30,8 +30,10 @@ import com.oracle.truffle.api.dsl.TypeSystemReference; import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.api.nodes.NodeInfo; import com.oracle.truffle.api.profiles.ConditionProfile; +import com.oracle.truffle.api.profiles.ValueProfile; import com.oracle.truffle.r.nodes.EmptyTypeSystemFlatLayout; import com.oracle.truffle.r.runtime.data.RShareable; +import com.oracle.truffle.r.runtime.data.RSharingAttributeStorage; /** * Internal node that should be used whenever you need to increment reference count of some object. @@ -48,7 +50,7 @@ public abstract class ShareObjectNode extends Node { } @Specialization - protected Object doShareable(RShareable obj, + protected Object doShareable(RSharingAttributeStorage obj, @Cached("createBinaryProfile()") ConditionProfile sharedPermanent) { if (sharedPermanent.profile(!obj.isSharedPermanent())) { obj.incRefCount(); @@ -56,6 +58,17 @@ public abstract class ShareObjectNode extends Node { return obj; } + @Specialization + protected Object doShareable(RShareable obj, + @Cached("createBinaryProfile()") ConditionProfile sharedPermanent, + @Cached("createClassProfile()") ValueProfile typeProfile) { + RShareable objProfiled = typeProfile.profile(obj); + if (sharedPermanent.profile(!objProfiled.isSharedPermanent())) { + objProfiled.incRefCount(); + } + return obj; + } + @Specialization(guards = "!isRShareable(obj)") protected Object doNonShareable(Object obj) { return obj; diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/ExpectedTestOutput.test b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/ExpectedTestOutput.test index d4ff74b7edd2ff56450aa5e776f77dbbc7b1f116..3c60a594048996145b6a9c778cb12784babfaecc 100644 --- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/ExpectedTestOutput.test +++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/ExpectedTestOutput.test @@ -8309,6 +8309,16 @@ Error in attr(x, 42) <- NULL : 'name' must be non-null character string #x<-42; attr(x, NULL) <- NULL Error in attr(x, NULL) <- NULL : 'name' must be non-null character string +##com.oracle.truffle.r.test.builtins.TestBuiltin_attrassign.testRefCount# +#x <- c(1,2); attr(x, "foo") <- c("a","b"); y <- x; attr(x,"foo")[[1]] <- "c"; y +[1] 1 2 +attr(,"foo") +[1] "a" "b" + +##com.oracle.truffle.r.test.builtins.TestBuiltin_attrassign.testRefCount# +#x <- c(1,2,3); y <- 42; attr(y, 'at') <- x; x[[1]] <- 2; attr(y, 'at') +[1] 1 2 3 + ##com.oracle.truffle.r.test.builtins.TestBuiltin_attrassign.testattrassign1# #argv <- list(structure(1, foo = structure(list(a = 'a'), .Names = 'a')), 'foo', value = structure(list(a = 'a'), .Names = 'a'));`attr<-`(argv[[1]],argv[[2]],argv[[3]]); [1] 1 @@ -27555,6 +27565,12 @@ $z [1] 42 +##com.oracle.truffle.r.test.builtins.TestBuiltin_list.testRefCount# +#{ l <- list(a=c(1,2)); l2 <- l; l$a[[1]] <- 3; l2 } +$a +[1] 1 2 + + ##com.oracle.truffle.r.test.builtins.TestBuiltin_list.testlist1# #argv <- list(surname = structure(c('McNeil', 'Ripley', 'Ripley', 'Tierney', 'Tukey', 'Venables', 'R Core'), class = 'AsIs'), nationality = structure(c('Australia', 'UK', 'UK', 'US', 'US', 'Australia', NA), class = 'AsIs'), deceased = structure(c('no', 'no', 'no', 'no', 'yes', 'no', NA), class = 'AsIs'), title = structure(c('Interactive Data Analysis', 'Spatial Statistics', 'Stochastic Simulation', 'LISP-STAT', 'Exploratory Data Analysis', 'Modern Applied Statistics ...', 'An Introduction to R'), class = 'AsIs'), other.author = structure(c(NA, NA, NA, NA, NA, 'Ripley', 'Venables & Smith'), class = 'AsIs'));list(argv[[1]],argv[[2]],argv[[3]],argv[[4]],argv[[5]]); [[1]]