changeset 13735:2c1c805153e6

Ruby: refactor low level instrumentation services
author Michael Van De Vanter <michael.van.de.vanter@oracle.com>
date Wed, 22 Jan 2014 21:02:06 -0800
parents 7bab96d62fa3
children 64fa70319890
files graal/com.oracle.truffle.ruby.parser/src/com/oracle/truffle/ruby/parser/DefaultRubyNodeInstrumenter.java graal/com.oracle.truffle.ruby.parser/src/com/oracle/truffle/ruby/parser/JRubyParser.java graal/com.oracle.truffle.ruby.parser/src/com/oracle/truffle/ruby/parser/RubyNodeInstrumenter.java graal/com.oracle.truffle.ruby.parser/src/com/oracle/truffle/ruby/parser/Translator.java graal/com.oracle.truffle.ruby.parser/src/com/oracle/truffle/ruby/parser/TranslatorEnvironment.java graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/RubyContext.java
diffstat 6 files changed, 134 insertions(+), 21 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.ruby.parser/src/com/oracle/truffle/ruby/parser/DefaultRubyNodeInstrumenter.java	Wed Jan 22 21:02:06 2014 -0800
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved. This
+ * code is released under a tri EPL/GPL/LGPL license. You can use it,
+ * redistribute it and/or modify it under the terms of the:
+ *
+ * Eclipse Public License version 1.0
+ * GNU General Public License version 2
+ * GNU Lesser General Public License version 2.1
+ */
+package com.oracle.truffle.ruby.parser;
+
+import com.oracle.truffle.api.nodes.instrument.*;
+import com.oracle.truffle.ruby.nodes.*;
+import com.oracle.truffle.ruby.nodes.debug.*;
+import com.oracle.truffle.ruby.runtime.*;
+import com.oracle.truffle.ruby.runtime.debug.*;
+import com.oracle.truffle.ruby.runtime.methods.*;
+
+/**
+ * Utility for instrumenting Ruby AST nodes to support the language's built-in <A
+ * href="http://www.ruby-doc.org/core-2.0.0/Kernel.html#method-i-set_trace_func">tracing
+ * facility</A>. It ignores nodes other than {@linkplain NodePhylum#STATEMENT statements}.
+ */
+final class DefaultRubyNodeInstrumenter implements RubyNodeInstrumenter {
+
+    public DefaultRubyNodeInstrumenter() {
+    }
+
+    public RubyNode instrumentAsStatement(RubyNode rubyNode) {
+        assert rubyNode != null;
+        assert !(rubyNode instanceof RubyProxyNode);
+        final RubyContext context = rubyNode.getContext();
+        if (context.getConfiguration().getTrace()) {
+            final RubyProxyNode proxy = new RubyProxyNode(context, rubyNode);
+            proxy.markAs(NodePhylum.STATEMENT);
+            proxy.getProbeChain().appendProbe(new RubyTraceProbe(context));
+            return proxy;
+        }
+        return rubyNode;
+    }
+
+    public RubyNode instrumentAsCall(RubyNode node, String callName) {
+        return node;
+    }
+
+    public RubyNode instrumentAsLocalAssignment(RubyNode node, UniqueMethodIdentifier methodIdentifier, String localName) {
+        return node;
+    }
+
+}
--- a/graal/com.oracle.truffle.ruby.parser/src/com/oracle/truffle/ruby/parser/JRubyParser.java	Wed Jan 22 20:35:00 2014 -0800
+++ b/graal/com.oracle.truffle.ruby.parser/src/com/oracle/truffle/ruby/parser/JRubyParser.java	Wed Jan 22 21:02:06 2014 -0800
@@ -27,8 +27,20 @@
 
     private long nextReturnID = 0;
 
+    private final RubyNodeInstrumenter instrumenter;
+
+    public JRubyParser() {
+        this(new DefaultRubyNodeInstrumenter());
+    }
+
+    public JRubyParser(RubyNodeInstrumenter instrumenter) {
+        assert instrumenter != null;
+        this.instrumenter = instrumenter;
+    }
+
     @Override
     public RubyParserResult parse(RubyContext context, Source source, ParserContext parserContext, MaterializedFrame parentFrame) {
+
         // Set up the JRuby parser
 
         final org.jrubyparser.Parser parser = new org.jrubyparser.Parser();
@@ -171,6 +183,10 @@
         return allocated;
     }
 
+    public RubyNodeInstrumenter getNodeInstrumenter() {
+        return instrumenter;
+    }
+
     private TranslatorEnvironment environmentForFrame(RubyContext context, MaterializedFrame frame) {
         if (frame == null) {
             return null;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.ruby.parser/src/com/oracle/truffle/ruby/parser/RubyNodeInstrumenter.java	Wed Jan 22 21:02:06 2014 -0800
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2014, 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.ruby.parser;
+
+import com.oracle.truffle.api.nodes.instrument.*;
+import com.oracle.truffle.ruby.nodes.*;
+import com.oracle.truffle.ruby.runtime.methods.*;
+
+public interface RubyNodeInstrumenter {
+
+    /**
+     * Adds instrumentation support at a node that should be considered a member of
+     * {@link NodePhylum#STATEMENT}, possibly returning a new {@link InstrumentationProxyNode} that
+     * holds the original as its child.
+     */
+    RubyNode instrumentAsStatement(RubyNode node);
+
+    /**
+     * Adds instrumentation support at a node that should be considered a member of
+     * {@link NodePhylum#CALL}, possibly returning a new {@link InstrumentationProxyNode} that holds
+     * the original as its child.
+     */
+    RubyNode instrumentAsCall(RubyNode node, String callName);
+
+    /**
+     * Adds instrumentation support at a node that should be considered a member of
+     * {@link NodePhylum#ASSIGNMENT}, possibly returning a new {@link InstrumentationProxyNode} that
+     * holds the original as its child.
+     */
+    RubyNode instrumentAsLocalAssignment(RubyNode node, UniqueMethodIdentifier methodIdentifier, String localName);
+
+}
--- a/graal/com.oracle.truffle.ruby.parser/src/com/oracle/truffle/ruby/parser/Translator.java	Wed Jan 22 20:35:00 2014 -0800
+++ b/graal/com.oracle.truffle.ruby.parser/src/com/oracle/truffle/ruby/parser/Translator.java	Wed Jan 22 21:02:06 2014 -0800
@@ -22,7 +22,6 @@
 import com.oracle.truffle.ruby.nodes.constants.*;
 import com.oracle.truffle.ruby.nodes.control.*;
 import com.oracle.truffle.ruby.nodes.core.*;
-import com.oracle.truffle.ruby.nodes.debug.*;
 import com.oracle.truffle.ruby.nodes.literal.*;
 import com.oracle.truffle.ruby.nodes.literal.array.*;
 import com.oracle.truffle.ruby.nodes.methods.*;
@@ -33,7 +32,6 @@
 import com.oracle.truffle.ruby.runtime.*;
 import com.oracle.truffle.ruby.runtime.core.*;
 import com.oracle.truffle.ruby.runtime.core.range.*;
-import com.oracle.truffle.ruby.runtime.debug.*;
 import com.oracle.truffle.ruby.runtime.methods.*;
 
 /**
@@ -48,6 +46,7 @@
     protected final RubyContext context;
     protected final TranslatorEnvironment environment;
     protected final Source source;
+    protected final RubyNodeInstrumenter instrumenter;
 
     private boolean translatingForStatement = false;
 
@@ -97,6 +96,7 @@
         this.parent = parent;
         this.environment = environment;
         this.source = source;
+        this.instrumenter = environment.getNodeInstrumenter();
     }
 
     @Override
@@ -291,7 +291,7 @@
 
         RubyNode translated = new CallNode(context, sourceSection, node.getName(), receiverTranslated, argumentsAndBlock.getBlock(), argumentsAndBlock.isSplatted(), argumentsAndBlock.getArguments());
 
-        return translated;
+        return instrumenter.instrumentAsCall(translated, node.getName());
     }
 
     protected class ArgumentsAndBlockTranslation {
@@ -1140,7 +1140,9 @@
 
         RubyNode translated = ((ReadNode) lhs).makeWriteNode(rhs);
 
-        return translated;
+        final UniqueMethodIdentifier methodIdentifier = environment.findMethodForLocalVar(node.getName());
+
+        return instrumenter.instrumentAsLocalAssignment(translated, methodIdentifier, node.getName());
     }
 
     @Override
@@ -1439,20 +1441,7 @@
     @Override
     public Object visitNewlineNode(org.jrubyparser.ast.NewlineNode node) {
         RubyNode translated = (RubyNode) node.getNextNode().accept(this);
-
-        if (context.getConfiguration().getTrace()) {
-            RubyProxyNode proxy;
-            if (translated instanceof RubyProxyNode) {
-                proxy = (RubyProxyNode) translated;
-            } else {
-                proxy = new RubyProxyNode(context, translated);
-            }
-            proxy.getProbeChain().appendProbe(new RubyTraceProbe(context));
-
-            translated = proxy;
-        }
-
-        return translated;
+        return instrumenter.instrumentAsStatement(translated);
     }
 
     @Override
--- a/graal/com.oracle.truffle.ruby.parser/src/com/oracle/truffle/ruby/parser/TranslatorEnvironment.java	Wed Jan 22 20:35:00 2014 -0800
+++ b/graal/com.oracle.truffle.ruby.parser/src/com/oracle/truffle/ruby/parser/TranslatorEnvironment.java	Wed Jan 22 21:02:06 2014 -0800
@@ -224,4 +224,8 @@
     public List<FrameSlot> getFlipFlopStates() {
         return flipFlopStates;
     }
+
+    public RubyNodeInstrumenter getNodeInstrumenter() {
+        return parser.getNodeInstrumenter();
+    }
 }
--- a/graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/RubyContext.java	Wed Jan 22 20:35:00 2014 -0800
+++ b/graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/RubyContext.java	Wed Jan 22 21:02:06 2014 -0800
@@ -76,7 +76,7 @@
         atExitManager = new AtExitManager();
         sourceManager = new SourceManager();
 
-        debugManager = configuration.getDebug() ? new DefaultDebugManager(this) : null;
+        debugManager = new DefaultDebugManager(this);
 
         // Must initialize threads before fibers
 
@@ -84,8 +84,8 @@
         fiberManager = new FiberManager(this);
     }
 
-    public String getLanguageShortName() {
-        return "Ruby";
+    public final String getLanguageShortName() {
+        return "Ruby " + CoreLibrary.RUBY_VERSION;
     }
 
     public DebugManager getDebugManager() {