From c4a0e4a93e10f89dbddd5491248b40b42d5ada2d Mon Sep 17 00:00:00 2001 From: Zbynek Slajchrt <zbynek.slajchrt@oracle.com> Date: Fri, 16 Dec 2016 19:00:06 +0100 Subject: [PATCH] Iterative attribute nodes never return null --- .../nodes/attributes/ArrayAttributeNode.java | 36 +++++++++++++++++-- .../attributes/IterableAttributeNode.java | 33 ++++++++++++++++- .../r/runtime/data/RAttributesLayout.java | 10 +++++- 3 files changed, 75 insertions(+), 4 deletions(-) diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/ArrayAttributeNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/ArrayAttributeNode.java index 7671b2971d..cfe144c94a 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/ArrayAttributeNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/ArrayAttributeNode.java @@ -24,23 +24,33 @@ package com.oracle.truffle.r.nodes.attributes; import java.util.List; +import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.nodes.ExplodeLoop; import com.oracle.truffle.api.object.DynamicObject; import com.oracle.truffle.api.object.Property; import com.oracle.truffle.api.object.Shape; +import com.oracle.truffle.api.profiles.BranchProfile; +import com.oracle.truffle.api.profiles.ConditionProfile; +import com.oracle.truffle.api.profiles.ValueProfile; +import com.oracle.truffle.r.runtime.data.RAttributable; +import com.oracle.truffle.r.runtime.data.RAttributeStorage; import com.oracle.truffle.r.runtime.data.RAttributesLayout; import com.oracle.truffle.r.runtime.data.RAttributesLayout.AttrsLayout; import com.oracle.truffle.r.runtime.data.RAttributesLayout.RAttribute; public abstract class ArrayAttributeNode extends AttributeIterativeAccessNode { + private static final RAttribute[] EMPTY = new RAttribute[0]; + + @Child private ArrayAttributeNode recursive; + public static ArrayAttributeNode create() { return ArrayAttributeNodeGen.create(); } - public abstract RAttribute[] execute(DynamicObject attrs); + public abstract RAttribute[] execute(Object attrs); @Specialization(limit = "CACHE_LIMIT", guards = {"attrsLayout != null", "attrsLayout.shape.check(attrs)"}) @ExplodeLoop @@ -69,7 +79,29 @@ public abstract class ArrayAttributeNode extends AttributeIterativeAccessNode { } return result; - } + @Specialization + protected RAttribute[] getArrayFallback(RAttributable x, + @Cached("create()") BranchProfile attrNullProfile, + @Cached("createBinaryProfile()") ConditionProfile attrStorageProfile, + @Cached("createClassProfile()") ValueProfile xTypeProfile) { + DynamicObject attributes; + if (attrStorageProfile.profile(x instanceof RAttributeStorage)) { + attributes = ((RAttributeStorage) x).getAttributes(); + } else { + attributes = xTypeProfile.profile(x).getAttributes(); + } + + if (attributes == null) { + attrNullProfile.enter(); + return EMPTY; + } + if (recursive == null) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + recursive = insert(create()); + } + + return recursive.execute(attributes); + } } diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/IterableAttributeNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/IterableAttributeNode.java index 99decfc061..9032aaefed 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/IterableAttributeNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/IterableAttributeNode.java @@ -22,20 +22,28 @@ */ package com.oracle.truffle.r.nodes.attributes; +import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.object.DynamicObject; +import com.oracle.truffle.api.profiles.BranchProfile; +import com.oracle.truffle.api.profiles.ConditionProfile; +import com.oracle.truffle.api.profiles.ValueProfile; +import com.oracle.truffle.r.runtime.data.RAttributable; +import com.oracle.truffle.r.runtime.data.RAttributeStorage; import com.oracle.truffle.r.runtime.data.RAttributesLayout; import com.oracle.truffle.r.runtime.data.RAttributesLayout.AttrsLayout; public abstract class IterableAttributeNode extends AttributeIterativeAccessNode { + @Child private IterableAttributeNode recursive; + public static IterableAttributeNode create() { return IterableAttributeNodeGen.create(); } - public abstract RAttributesLayout.RAttributeIterable execute(DynamicObject attrs); + public abstract RAttributesLayout.RAttributeIterable execute(Object attr); @Specialization(limit = "CACHE_LIMIT", guards = {"attrsLayout != null", "shapeCheck(attrsLayout.shape, attrs)"}) protected RAttributesLayout.RAttributeIterable getArrayFromConstantLayouts(DynamicObject attrs, @@ -49,4 +57,27 @@ public abstract class IterableAttributeNode extends AttributeIterativeAccessNode return RAttributesLayout.asIterable(attrs); } + @Specialization + protected RAttributesLayout.RAttributeIterable getArrayFallback(RAttributable x, + @Cached("create()") BranchProfile attrNullProfile, + @Cached("createBinaryProfile()") ConditionProfile attrStorageProfile, + @Cached("createClassProfile()") ValueProfile xTypeProfile) { + DynamicObject attributes; + if (attrStorageProfile.profile(x instanceof RAttributeStorage)) { + attributes = ((RAttributeStorage) x).getAttributes(); + } else { + attributes = xTypeProfile.profile(x).getAttributes(); + } + + if (attributes == null) { + attrNullProfile.enter(); + return RAttributesLayout.RAttributeIterable.EMPTY; + } + if (recursive == null) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + recursive = insert(create()); + } + + return recursive.execute(attributes); + } } diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RAttributesLayout.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RAttributesLayout.java index 8f35974969..523100966b 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RAttributesLayout.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RAttributesLayout.java @@ -22,6 +22,7 @@ */ package com.oracle.truffle.r.runtime.data; +import java.util.Collections; import java.util.HashMap; import java.util.Iterator; import java.util.List; @@ -257,6 +258,9 @@ public final class RAttributesLayout { } public static final class RAttributeIterable implements Iterable<RAttributesLayout.RAttribute> { + + public static final RAttributeIterable EMPTY = new RAttributeIterable(null, null); + private final DynamicObject attrs; private final List<Property> properties; @@ -267,7 +271,11 @@ public final class RAttributesLayout { @Override public Iterator<RAttributesLayout.RAttribute> iterator() { - return new Iter(attrs, properties.iterator()); + if (attrs == null || properties == null) { + return Collections.emptyIterator(); + } else { + return new Iter(attrs, properties.iterator()); + } } } -- GitLab