Skip to content

Commit f1f7bff

Browse files
committed
Add Truffle::Debug.profile_translator
* Can be used like: jt ruby -e 'Truffle::Debug.profile_translator File.read("src/main/ruby/truffleruby/core/io.rb"), 50_000' jt mx profrecord -E translator -F 10000 $PWD/mxbuild/truffleruby-jvm/languages/ruby/bin/ruby -e 'Truffle::Debug.profile_translator File.read("src/main/ruby/truffleruby/core/io.rb"), 50_000'
1 parent 59f6cc9 commit f1f7bff

File tree

2 files changed

+50
-13
lines changed

2 files changed

+50
-13
lines changed

src/main/java/org/truffleruby/debug/TruffleDebugNodes.java

Lines changed: 36 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
import com.oracle.truffle.api.source.SourceSection;
3535
import com.oracle.truffle.api.strings.TruffleString;
3636
import org.graalvm.collections.Pair;
37+
import org.prism.ParseResult;
3738
import org.truffleruby.Layouts;
3839
import org.truffleruby.RubyLanguage;
3940
import org.truffleruby.annotations.CoreMethod;
@@ -256,19 +257,48 @@ Object ast(Object code,
256257
@Cached TruffleString.FromJavaStringNode fromJavaStringNode) {
257258
var codeString = new TStringWithEncoding(RubyGuards.asTruffleStringUncached(code),
258259
RubyStringLibrary.getUncached().getEncoding(code));
260+
261+
var rubySource = createRubySource(codeString);
262+
var parseResult = getParseResult(getLanguage(), rubySource);
263+
var ast = parseResult.value;
264+
265+
return createString(fromJavaStringNode, ast.toString(), Encodings.UTF_8);
266+
}
267+
268+
private static RubySource createRubySource(TStringWithEncoding code) {
259269
String name = "<parse_ast>";
260-
var source = Source.newBuilder("ruby", new ByteBasedCharSequence(codeString), name).build();
261-
var rubySource = new RubySource(source, name);
270+
var source = Source.newBuilder("ruby", new ByteBasedCharSequence(code), name).build();
271+
return new RubySource(source, name);
272+
}
262273

263-
var language = getLanguage();
274+
private static ParseResult getParseResult(RubyLanguage language, RubySource rubySource) {
264275
var yarpSource = YARPTranslatorDriver.createYARPSource(rubySource.getBytes());
265276
String sourcePath = rubySource.getSourcePath(language).intern();
266277

267-
var parseResult = YARPTranslatorDriver.parseToYARPAST(rubySource, sourcePath, yarpSource,
278+
return YARPTranslatorDriver.parseToYARPAST(rubySource, sourcePath, yarpSource,
268279
Collections.emptyList(), language.options.FROZEN_STRING_LITERALS);
269-
var ast = parseResult.value;
280+
}
281+
}
270282

271-
return createString(fromJavaStringNode, ast.toString(), Encodings.UTF_8);
283+
@CoreMethod(names = "profile_translator", onSingleton = true, required = 2, lowerFixnum = 2)
284+
public abstract static class ProfileTranslatorNode extends CoreMethodArrayArgumentsNode {
285+
@TruffleBoundary
286+
@Specialization
287+
Object profileTranslator(Object code, int repeat) {
288+
var codeString = new TStringWithEncoding(RubyGuards.asTruffleStringUncached(code),
289+
RubyStringLibrary.getUncached().getEncoding(code));
290+
291+
var rubySource = ParseASTNode.createRubySource(codeString);
292+
var parseResult = ParseASTNode.getParseResult(getLanguage(), rubySource);
293+
294+
var translator = new YARPTranslatorDriver(getContext());
295+
296+
for (int i = 0; i < repeat; i++) {
297+
translator.parse(rubySource, ParserContext.TOP_LEVEL, null, null, getContext().getRootLexicalScope(),
298+
this, parseResult);
299+
}
300+
301+
return nil;
272302
}
273303
}
274304

src/main/java/org/truffleruby/parser/YARPTranslatorDriver.java

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,11 @@ public YARPTranslatorDriver(RubyContext context) {
100100

101101
public RootCallTarget parse(RubySource rubySource, ParserContext parserContext, String[] argumentNames,
102102
MaterializedFrame parentFrame, LexicalScope staticLexicalScope, Node currentNode) {
103+
return parse(rubySource, parserContext, argumentNames, parentFrame, staticLexicalScope, currentNode, null);
104+
}
105+
106+
public RootCallTarget parse(RubySource rubySource, ParserContext parserContext, String[] argumentNames,
107+
MaterializedFrame parentFrame, LexicalScope staticLexicalScope, Node currentNode, ParseResult parseResult) {
103108
Nodes.Source yarpSource = createYARPSource(rubySource.getBytes());
104109
this.parseEnvironment = new ParseEnvironment(language, rubySource, yarpSource, parserContext, currentNode);
105110

@@ -157,13 +162,15 @@ public RootCallTarget parse(RubySource rubySource, ParserContext parserContext,
157162

158163
final String sourcePath = rubySource.getSourcePath(language).intern();
159164

160-
printParseTranslateExecuteMetric("before-parsing", context, source);
161-
final ParseResult parseResult = context.getMetricsProfiler().callWithMetrics(
162-
"parsing",
163-
source.getName(),
164-
() -> parseToYARPAST(rubySource, sourcePath, yarpSource, localsInScopes,
165-
language.options.FROZEN_STRING_LITERALS));
166-
printParseTranslateExecuteMetric("after-parsing", context, source);
165+
if (parseResult == null) {
166+
printParseTranslateExecuteMetric("before-parsing", context, source);
167+
parseResult = context.getMetricsProfiler().callWithMetrics(
168+
"parsing",
169+
source.getName(),
170+
() -> parseToYARPAST(rubySource, sourcePath, yarpSource, localsInScopes,
171+
language.options.FROZEN_STRING_LITERALS));
172+
printParseTranslateExecuteMetric("after-parsing", context, source);
173+
}
167174

168175
handleWarningsErrorsPrimitives(context, parseResult, rubySource, sourcePath, parseEnvironment, rubyWarnings);
169176

0 commit comments

Comments
 (0)