diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/CachedReplaceVectorNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/CachedReplaceVectorNode.java index 0d528893f47bb81faa8f2e34e8ab5f8526256830..4429a74571ab4551a97343ad78a6bc50dab00339 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/CachedReplaceVectorNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/CachedReplaceVectorNode.java @@ -230,7 +230,7 @@ final class CachedReplaceVectorNode extends CachedVectorNode { value = ((RAbstractVector) value).castSafe(castType, valueIsNA); } - vector = share(vector); + vector = share(vector, value); int maxOutOfBounds = positionsCheckNode.getMaxOutOfBounds(positionProfiles); if (maxOutOfBounds > vectorLength) { @@ -239,7 +239,6 @@ final class CachedReplaceVectorNode extends CachedVectorNode { return wrapResult(vector, repType); } vector = resizeVector(vector, maxOutOfBounds); - vectorLength = maxOutOfBounds; } vector = vector.materialize(); @@ -467,16 +466,18 @@ final class CachedReplaceVectorNode extends CachedVectorNode { private final ValueProfile sharedClassProfile = ValueProfile.createClassProfile(); + private final ConditionProfile valueEqualsVectorProfile = ConditionProfile.createBinaryProfile(); + /* * TODO (chumer) share code between {@link #share(RAbstractVector)} and {@link * #copyValueOnAssignment(RAbstractContainer)} */ - private RAbstractVector share(RAbstractVector vector) { + private RAbstractVector share(RAbstractVector vector, Object value) { RAbstractVector returnVector = vector; if (returnVector instanceof RShareable) { RShareable shareable = (RShareable) returnVector; // TODO find out if we need to copy always in the recursive case - if (sharedConditionProfile.profile(shareable.isShared()) || recursive) { + if (sharedConditionProfile.profile(shareable.isShared()) || recursive || valueEqualsVectorProfile.profile(vector == value)) { sharedProfile.enter(); shareable = (RShareable) returnVector.copy(); returnVector = (RAbstractVector) shareable; 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 e56dcc464d1341cddb360151da793f69638f8734..658617f4effeb12dc66ddf509fe165f037943822 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 @@ -19116,6 +19116,10 @@ Levels: A B C D E [21] 1456434_x_at 1415993_at 1416481_s_at 1452003_at 1439373_x_at 147 Levels: 1415787_at 1415904_at 1415993_at 1416164_at ... 1460359_at +##com.oracle.truffle.r.test.builtins.TestBuiltin_extract_replace.extractAndReplaceByItself +#tmp <- c(1,8,NA,3); pivot <- c(1,2,4,3); tmp[pivot] <- tmp; tmp +[1] 1 8 3 NA + ##com.oracle.truffle.r.test.builtins.TestBuiltin_factor.testFactor #{ as.logical(factor(c("a", "b", "a"))) } [1] NA NA NA diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_extract_replace.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_extract_replace.java new file mode 100644 index 0000000000000000000000000000000000000000..42d60834f20231a063edd61aad795b547d0b39ec --- /dev/null +++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_extract_replace.java @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2016, 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.test.builtins; + +import org.junit.Test; + +import com.oracle.truffle.r.test.TestBase; + +// Checkstyle: stop line length check + +/** + * Tests for assignments that go through {@code CachedReplaceVectorNode}. + */ +public class TestBuiltin_extract_replace extends TestBase { + + @Test + public void extractAndReplaceByItself() { + assertEval("tmp <- c(1,8,NA,3); pivot <- c(1,2,4,3); tmp[pivot] <- tmp; tmp"); + } +}