changeset 21138:7a62f41ed610

Merge
author Stefan Anzinger <stefan.anzinger@oracle.com>
date Tue, 28 Apr 2015 18:35:16 +0200
parents fb2b27418347 a5faa9aafc80
children 0b221b4ad707
files graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/SyntaxTagged.java
diffstat 7 files changed, 127 insertions(+), 85 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/G1PostWriteBarrier.java	Tue Apr 28 18:35:01 2015 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/G1PostWriteBarrier.java	Tue Apr 28 18:35:16 2015 +0200
@@ -22,14 +22,13 @@
  */
 package com.oracle.graal.hotspot.nodes;
 
-import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.nodeinfo.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.extended.*;
 
 @NodeInfo
-public class G1PostWriteBarrier extends WriteBarrier implements MemoryCheckpoint.Single {
+public class G1PostWriteBarrier extends WriteBarrier {
 
     public static final NodeClass<G1PostWriteBarrier> TYPE = NodeClass.create(G1PostWriteBarrier.class);
     protected final boolean alwaysNull;
@@ -46,8 +45,4 @@
     public boolean alwaysNull() {
         return alwaysNull;
     }
-
-    public LocationIdentity getLocationIdentity() {
-        return LocationIdentity.any();
-    }
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/WriteBarrierSnippets.java	Tue Apr 28 18:35:01 2015 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/WriteBarrierSnippets.java	Tue Apr 28 18:35:16 2015 +0200
@@ -212,13 +212,13 @@
 
             // If the written value is not null continue with the barrier addition.
             if (probability(FREQUENT_PROBABILITY, writtenValue.notEqual(0))) {
-                byte cardByte = cardAddress.readByte(0);
+                byte cardByte = cardAddress.readByte(0, GC_CARD_LOCATION);
                 g1EffectiveAfterNullPostWriteBarrierCounter.inc();
 
                 // If the card is already dirty, (hence already enqueued) skip the insertion.
                 if (probability(NOT_FREQUENT_PROBABILITY, cardByte != g1YoungCardValue())) {
-                    MembarNode.memoryBarrier(STORE_LOAD);
-                    byte cardByteReload = cardAddress.readByte(0);
+                    MembarNode.memoryBarrier(STORE_LOAD, GC_CARD_LOCATION);
+                    byte cardByteReload = cardAddress.readByte(0, GC_CARD_LOCATION);
                     if (probability(NOT_FREQUENT_PROBABILITY, cardByteReload != dirtyCardValue())) {
                         log(trace, "[%d] G1-Post Thread: %p Card: %p \n", gcCycle, thread.rawValue(), Word.unsigned(cardByte).rawValue());
                         cardAddress.writeByte(0, (byte) 0, GC_CARD_LOCATION);
@@ -298,11 +298,11 @@
 
         while (count-- > 0) {
             Word cardAddress = Word.unsigned((start + cardStart) + count);
-            byte cardByte = cardAddress.readByte(0);
+            byte cardByte = cardAddress.readByte(0, GC_CARD_LOCATION);
             // If the card is already dirty, (hence already enqueued) skip the insertion.
             if (probability(NOT_FREQUENT_PROBABILITY, cardByte != g1YoungCardValue())) {
-                MembarNode.memoryBarrier(STORE_LOAD);
-                byte cardByteReload = cardAddress.readByte(0);
+                MembarNode.memoryBarrier(STORE_LOAD, GC_CARD_LOCATION);
+                byte cardByteReload = cardAddress.readByte(0, GC_CARD_LOCATION);
                 if (probability(NOT_FREQUENT_PROBABILITY, cardByteReload != dirtyCardValue())) {
                     cardAddress.writeByte(0, (byte) 0, GC_CARD_LOCATION);
                     // If the thread local card queue is full, issue a native call which will
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/MembarNode.java	Tue Apr 28 18:35:01 2015 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/MembarNode.java	Tue Apr 28 18:35:16 2015 +0200
@@ -37,15 +37,21 @@
 
     public static final NodeClass<MembarNode> TYPE = NodeClass.create(MembarNode.class);
     protected final int barriers;
+    protected final LocationIdentity location;
 
     public MembarNode(int barriers) {
+        this(barriers, LocationIdentity.any());
+    }
+
+    public MembarNode(int barriers, LocationIdentity location) {
         super(TYPE, StampFactory.forVoid());
         this.barriers = barriers;
+        this.location = location;
     }
 
     @Override
     public LocationIdentity getLocationIdentity() {
-        return LocationIdentity.any();
+        return location;
     }
 
     @Override
@@ -55,4 +61,7 @@
 
     @NodeIntrinsic
     public static native void memoryBarrier(@ConstantNodeParameter int barriers);
+
+    @NodeIntrinsic
+    public static native void memoryBarrier(@ConstantNodeParameter int barriers, @ConstantNodeParameter LocationIdentity location);
 }
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/Probe.java	Tue Apr 28 18:35:01 2015 +0200
+++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/Probe.java	Tue Apr 28 18:35:16 2015 +0200
@@ -39,7 +39,8 @@
 /**
  * A <em>binding</em> between:
  * <ol>
- * <li>A program location in an executing Truffle AST (defined by a {@link SourceSection}), and</li>
+ * <li>A program location in an executing Truffle AST (corresponding to a {@link SourceSection}),
+ * and</li>
  * <li>A dynamically managed collection of "attached" {@linkplain Instrument Instruments} that
  * receive event notifications on behalf of external clients.</li>
  * </ol>
@@ -97,7 +98,7 @@
  * @see ProbeListener
  * @see SyntaxTag
  */
-public final class Probe implements SyntaxTagged {
+public final class Probe {
 
     private static final List<ASTProber> astProbers = new ArrayList<>();
 
@@ -108,7 +109,17 @@
      */
     private static final List<WeakReference<Probe>> probes = new ArrayList<>();
 
-    @CompilationFinal private static SyntaxTagTrap tagTrap = null;
+    /**
+     * A global trap that triggers notification just before executing any Node that is Probed with a
+     * matching tag.
+     */
+    @CompilationFinal private static SyntaxTagTrap beforeTagTrap = null;
+
+    /**
+     * A global trap that triggers notification just after executing any Node that is Probed with a
+     * matching tag.
+     */
+    @CompilationFinal private static SyntaxTagTrap afterTagTrap = null;
 
     private static final class FindSourceVisitor implements NodeVisitor {
 
@@ -198,24 +209,50 @@
         return taggedProbes;
     }
 
-    // TODO (mlvdv) can this be generalized to permit multiple traps without a performance hit?
+    // TODO (mlvdv) generalize to permit multiple "before traps" without a performance hit?
     /**
-     * Sets the current "tag trap"; there can be no more than one set at a time.
+     * Sets the current "<em>before</em> tag trap"; there can be no more than one in effect.
      * <ul>
-     * <li>A non-null trap sets a callback to be triggered whenever execution reaches a
-     * {@link Probe} (either existing or subsequently created) with the specified tag.</li>
-     * <li>Setting the trap to null clears the existing trap.</li>
-     * <li>Setting a non-null trap when one is already set will clear the previously set trap.</li>
+     * <li>The before-trap triggers a callback just <strong><em>before</em></strong> execution
+     * reaches <strong><em>any</em></strong> {@link Probe} (either existing or subsequently created)
+     * with the specified {@link SyntaxTag}.</li>
+     * <li>Setting the before-trap to {@code null} clears an existing before-trap.</li>
+     * <li>Setting a non{@code -null} before-trap when one is already set clears the previously set
+     * before-trap.</li>
      * </ul>
      *
-     * @param newTagTrap The {@link SyntaxTagTrap} to set.
+     * @param newBeforeTagTrap The new "before" {@link SyntaxTagTrap} to set.
      */
-    public static void setTagTrap(SyntaxTagTrap newTagTrap) {
-        tagTrap = newTagTrap;
+    public static void setBeforeTagTrap(SyntaxTagTrap newBeforeTagTrap) {
+        beforeTagTrap = newBeforeTagTrap;
         for (WeakReference<Probe> ref : probes) {
             final Probe probe = ref.get();
             if (probe != null) {
-                probe.notifyTrapSet();
+                probe.notifyTrapsChanged();
+            }
+        }
+    }
+
+    // TODO (mlvdv) generalize to permit multiple "after traps" without a performance hit?
+    /**
+     * Sets the current "<em>after</em> tag trap"; there can be no more than one in effect.
+     * <ul>
+     * <li>The after-trap triggers a callback just <strong><em>after</em></strong> execution leaves
+     * <strong><em>any</em></strong> {@link Probe} (either existing or subsequently created) with
+     * the specified {@link SyntaxTag}.</li>
+     * <li>Setting the after-trap to {@code null} clears an existing after-trap.</li>
+     * <li>Setting a non{@code -null} after-trap when one is already set clears the previously set
+     * after-trap.</li>
+     * </ul>
+     *
+     * @param newAfterTagTrap The new "after" {@link SyntaxTagTrap} to set.
+     */
+    public static void setAfterTagTrap(SyntaxTagTrap newAfterTagTrap) {
+        afterTagTrap = newAfterTagTrap;
+        for (WeakReference<Probe> ref : probes) {
+            final Probe probe = ref.get();
+            if (probe != null) {
+                probe.notifyTrapsChanged();
             }
         }
     }
@@ -236,8 +273,11 @@
      */
     @CompilationFinal private Assumption probeStateUnchangedAssumption = probeStateUnchangedCyclic.getAssumption();
 
-    // Must invalidate whenever this changes.
-    @CompilationFinal private boolean isTrapActive = false;
+    // Must invalidate whenever changed
+    @CompilationFinal private boolean isBeforeTrapActive = false;
+
+    // Must invalidate whenever changed
+    @CompilationFinal private boolean isAfterTrapActive = false;
 
     /**
      * Intended for use only by {@link ProbeNode}.
@@ -251,11 +291,18 @@
         }
     }
 
+    /**
+     * Is this node tagged as belonging to a particular human-sensible category of language
+     * constructs?
+     */
     public boolean isTaggedAs(SyntaxTag tag) {
         assert tag != null;
         return tags.contains(tag);
     }
 
+    /**
+     * In which user-sensible categories has this node been tagged (<em>empty set</em> if none).
+     */
     public Collection<SyntaxTag> getSyntaxTags() {
         return Collections.unmodifiableCollection(tags);
     }
@@ -271,8 +318,18 @@
             for (ProbeListener listener : probeListeners) {
                 listener.probeTaggedAs(this, tag, tagValue);
             }
-            if (tagTrap != null && tag == tagTrap.getTag()) {
-                this.isTrapActive = true;
+
+            // Update the status of this Probe with respect to global tag traps
+            boolean tagTrapsChanged = false;
+            if (beforeTagTrap != null && tag == beforeTagTrap.getTag()) {
+                this.isBeforeTrapActive = true;
+                tagTrapsChanged = true;
+            }
+            if (afterTagTrap != null && tag == afterTagTrap.getTag()) {
+                this.isAfterTrapActive = true;
+                tagTrapsChanged = true;
+            }
+            if (tagTrapsChanged) {
                 invalidateProbeUnchanged();
             }
         }
@@ -341,11 +398,25 @@
     }
 
     /**
-     * Gets the currently active {@linkplain SyntaxTagTrap tagTrap}; {@code null} if not set.
+     * Gets the currently active <strong><em>before</em></strong> {@linkplain SyntaxTagTrap Tag
+     * Trap} at this Probe. Non{@code -null} if the global
+     * {@linkplain Probe#setBeforeTagTrap(SyntaxTagTrap) Before Tag Trap} is set and if this Probe
+     * holds the {@link SyntaxTag} specified in the trap.
      */
-    SyntaxTagTrap getTrap() {
+    SyntaxTagTrap getBeforeTrap() {
         checkProbeUnchanged();
-        return isTrapActive ? tagTrap : null;
+        return isBeforeTrapActive ? beforeTagTrap : null;
+    }
+
+    /**
+     * Gets the currently active <strong><em>after</em></strong> {@linkplain SyntaxTagTrap Tag Trap}
+     * at this Probe. Non{@code -null} if the global
+     * {@linkplain Probe#setAfterTagTrap(SyntaxTagTrap) After Tag Trap} is set and if this Probe
+     * holds the {@link SyntaxTag} specified in the trap.
+     */
+    SyntaxTagTrap getAfterTrap() {
+        checkProbeUnchanged();
+        return isAfterTrapActive ? afterTagTrap : null;
     }
 
     /**
@@ -366,8 +437,9 @@
         probeStateUnchangedCyclic.invalidate();
     }
 
-    private void notifyTrapSet() {
-        this.isTrapActive = tagTrap != null && this.isTaggedAs(tagTrap.getTag());
+    private void notifyTrapsChanged() {
+        this.isBeforeTrapActive = beforeTagTrap != null && this.isTaggedAs(beforeTagTrap.getTag());
+        this.isAfterTrapActive = afterTagTrap != null && this.isTaggedAs(afterTagTrap.getTag());
         invalidateProbeUnchanged();
     }
 
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/ProbeNode.java	Tue Apr 28 18:35:01 2015 +0200
+++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/ProbeNode.java	Tue Apr 28 18:35:16 2015 +0200
@@ -153,9 +153,9 @@
 
     public void enter(Node node, VirtualFrame vFrame) {
         this.probe.checkProbeUnchanged();
-        final SyntaxTagTrap trap = probe.getTrap();
-        if (trap != null) {
-            trap.tagTrappedAt(((WrapperNode) this.getParent()).getChild(), vFrame.materialize());
+        final SyntaxTagTrap beforeTagTrap = probe.getBeforeTrap();
+        if (beforeTagTrap != null) {
+            beforeTagTrap.tagTrappedAt(((WrapperNode) this.getParent()).getChild(), vFrame.materialize());
         }
         if (firstInstrumentNode != null) {
             firstInstrumentNode.enter(node, vFrame);
@@ -167,6 +167,10 @@
         if (firstInstrumentNode != null) {
             firstInstrumentNode.returnVoid(node, vFrame);
         }
+        final SyntaxTagTrap afterTagTrap = probe.getAfterTrap();
+        if (afterTagTrap != null) {
+            afterTagTrap.tagTrappedAt(((WrapperNode) this.getParent()).getChild(), vFrame.materialize());
+        }
     }
 
     public void returnValue(Node node, VirtualFrame vFrame, Object result) {
@@ -174,6 +178,10 @@
         if (firstInstrumentNode != null) {
             firstInstrumentNode.returnValue(node, vFrame, result);
         }
+        final SyntaxTagTrap afterTagTrap = probe.getAfterTrap();
+        if (afterTagTrap != null) {
+            afterTagTrap.tagTrappedAt(((WrapperNode) this.getParent()).getChild(), vFrame.materialize());
+        }
     }
 
     public void returnExceptional(Node node, VirtualFrame vFrame, Exception exception) {
@@ -181,6 +189,10 @@
         if (firstInstrumentNode != null) {
             firstInstrumentNode.returnExceptional(node, vFrame, exception);
         }
+        final SyntaxTagTrap afterTagTrap = probe.getAfterTrap();
+        if (afterTagTrap != null) {
+            afterTagTrap.tagTrappedAt(((WrapperNode) this.getParent()).getChild(), vFrame.materialize());
+        }
     }
 
     public String instrumentationInfo() {
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/SyntaxTagTrap.java	Tue Apr 28 18:35:01 2015 +0200
+++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/SyntaxTagTrap.java	Tue Apr 28 18:35:16 2015 +0200
@@ -45,7 +45,7 @@
     }
 
     /**
-     * Callback that will be received whenever execution enters a node with the specified tag.
+     * Notifies that execution is halted at a node with the specified tag.
      */
     public abstract void tagTrappedAt(Node node, MaterializedFrame frame);
 }
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/SyntaxTagged.java	Tue Apr 28 18:35:01 2015 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,46 +0,0 @@
-/*
- * Copyright (c) 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.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * 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.api.instrument;
-
-import java.util.*;
-
-/**
- * Information about a guest language program element in a Truffle AST that can be marked as
- * belonging to 0 or more {@linkplain SyntaxTag tags}.
- */
-public interface SyntaxTagged {
-
-    /**
-     * Is this node tagged as belonging to a particular human-sensible category of language
-     * constructs?
-     */
-    boolean isTaggedAs(SyntaxTag tag);
-
-    /**
-     * In which user-sensible categories has this node been tagged (<em>empty set</em> if none).
-     */
-    Collection<SyntaxTag> getSyntaxTags();
-
-}