# HG changeset patch # User Michael Van De Vanter # Date 1390453326 28800 # Node ID 2c1c805153e62d9235f24b624fad5c18857222f1 # Parent 7bab96d62fa39bf68092ca37723849d499c83446 Ruby: refactor low level instrumentation services diff -r 7bab96d62fa3 -r 2c1c805153e6 graal/com.oracle.truffle.ruby.parser/src/com/oracle/truffle/ruby/parser/DefaultRubyNodeInstrumenter.java --- /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 tracing + * facility. 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; + } + +} diff -r 7bab96d62fa3 -r 2c1c805153e6 graal/com.oracle.truffle.ruby.parser/src/com/oracle/truffle/ruby/parser/JRubyParser.java --- 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; diff -r 7bab96d62fa3 -r 2c1c805153e6 graal/com.oracle.truffle.ruby.parser/src/com/oracle/truffle/ruby/parser/RubyNodeInstrumenter.java --- /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); + +} diff -r 7bab96d62fa3 -r 2c1c805153e6 graal/com.oracle.truffle.ruby.parser/src/com/oracle/truffle/ruby/parser/Translator.java --- 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 diff -r 7bab96d62fa3 -r 2c1c805153e6 graal/com.oracle.truffle.ruby.parser/src/com/oracle/truffle/ruby/parser/TranslatorEnvironment.java --- 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 getFlipFlopStates() { return flipFlopStates; } + + public RubyNodeInstrumenter getNodeInstrumenter() { + return parser.getNodeInstrumenter(); + } } diff -r 7bab96d62fa3 -r 2c1c805153e6 graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/RubyContext.java --- 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() {