public synchronized void attach(String file, int line, final DynamicObject block) { assert RubyGuards.isRubyProc(block); final Instrument instrument = Instrument.create( new StandardInstrumentListener() { @Override public void enter(Probe probe, Node node, VirtualFrame frame) { final DynamicObject binding = BindingNodes.createRubyBinding( context.getCoreLibrary().getBindingClass(), RubyArguments.getSelf(frame.getArguments()), frame.materialize()); ProcNodes.rootCall(block, binding); } @Override public void returnVoid(Probe probe, Node node, VirtualFrame virtualFrame) {} @Override public void returnValue( Probe probe, Node node, VirtualFrame virtualFrame, Object o) {} @Override public void returnExceptional( Probe probe, Node node, VirtualFrame virtualFrame, Exception e) {} }, String.format("Truffle::Primitive.attach@%s:%d", file, line)); final Source source = context.getSourceManager().forFileBestFuzzily(file); final LineLocation lineLocation = source.createLineLocation(line); List<Instrument> instruments = attachments.get(lineLocation); if (instruments == null) { instruments = new ArrayList<>(); attachments.put(lineLocation, instruments); } instruments.add(instrument); for (Probe probe : lineToProbesMap.findProbes(lineLocation)) { if (probe.isTaggedAs(StandardSyntaxTag.STATEMENT)) { probe.attach(instrument); return; } } throw new RuntimeException("couldn't find a statement!"); }
public synchronized void detach(String file, int line) { final Source source = context.getSourceManager().forFileBestFuzzily(file); final LineLocation lineLocation = source.createLineLocation(line); final List<Instrument> instruments = attachments.remove(lineLocation); if (instruments != null) { for (Instrument instrument : instruments) { instrument.dispose(); } } }
public String getSourcePath(Source source) { if (source == mainScriptSource) { return mainScriptFullPath; } else { return source.getPath(); } }
/* * TODO get rid of this access and replace it with an API in {@link TruffleInstrument.Env}. * I don't think {@link CallTarget} is the right return type here as we want to make it * embeddable into the current AST. */ @SuppressWarnings("rawtypes") protected CallTarget parse(Source code, Node context, String... argumentNames) { RootNode rootNode = context.getRootNode(); Class<? extends TruffleLanguage> languageClass = nodes().findLanguage(rootNode); if (languageClass == null) { throw new IllegalStateException( "Could not resolve language class for root node " + rootNode); } final TruffleLanguage<?> truffleLanguage = engineSupport().findLanguageImpl(null, languageClass, code.getMimeType()); return languageSupport().parse(truffleLanguage, code, context, argumentNames); }
public static void main(String[] args) throws Exception { final PolyglotEngine polyglotEngine = PolyglotEngine.newBuilder().globalSymbol("file", args[0]).build(); polyglotEngine.eval( Source.newBuilder("require 'asciidoctor'") .name("hello") .mimeType("application/x-ruby") .build()); final Source convertSource = Source.newBuilder( "Asciidoctor.load(Truffle::Interop.from_java_string(Truffle::Interop.import('file'))).convert") .name("convert") .mimeType("application/x-ruby") .build(); while (true) { final long startTime = System.currentTimeMillis(); polyglotEngine.eval(convertSource); System.err.println(System.currentTimeMillis() - startTime); } }
/** * Executes the passed in test case. Instrumentation is added according to the name of the file as * explained in {@link #createTests(Class)}. Note that this code is not generalizable. */ @Override protected void runChild(InstrumentTestCase testCase, RunNotifier notifier) { // TODO Current tests are hard-coded, automate this eventually notifier.fireTestStarted(testCase.name); ByteArrayOutputStream out = new ByteArrayOutputStream(); PrintStream ps = new PrintStream(out); PolyglotEngine vm = null; try { // We use the name of the file to determine what visitor to attach to it. if (testCase.baseName.endsWith(ASSIGNMENT_VALUE_SUFFIX)) { // Set up the execution context for Simple and register our two listeners vm = PolyglotEngine.newBuilder() .setIn(new ByteArrayInputStream(testCase.testInput.getBytes("UTF-8"))) .setOut(out) .build(); final String src = readAllLines(testCase.path); vm.eval(Source.fromText(src, testCase.path.toString()).withMimeType("application/x-sl")); PolyglotEngine.Value main = vm.findGlobalSymbol("main"); main.execute(); } else { notifier.fireTestFailure( new Failure( testCase.name, new UnsupportedOperationException("No instrumentation found."))); } ps.flush(); String actualOutput = new String(out.toByteArray()); Assert.assertEquals(testCase.expectedOutput, actualOutput); } catch (Throwable ex) { notifier.fireTestFailure(new Failure(testCase.name, ex)); } finally { if (vm != null) { vm.dispose(); } notifier.fireTestFinished(testCase.name); } }
private static SourceSection considerExtendingMethodToCoverEnd(SourceSection sourceSection) { final Source source = sourceSection.getSource(); if (sourceSection.getEndLine() + 1 >= source.getLineCount()) { return sourceSection; } final String indentationOnFirstLine = indentation(source.getCode(sourceSection.getStartLine())); final int lineAfter = sourceSection.getEndLine() + 1; final String lineAfterString = source.getCode(lineAfter).replaceAll("\\s+$", ""); if (lineAfterString.equals(indentationOnFirstLine + "end") || lineAfterString.equals(indentationOnFirstLine + "}")) { return source.createSection( sourceSection.getIdentifier(), sourceSection.getCharIndex(), sourceSection.getCharLength() + 1 + source.getLineLength(lineAfter)); } return sourceSection; }
@Test public void testInvocationCounts() throws IOException { // Checkstyle: stop Source source = lines( "ROOT(", // 0-126 "DEFINE(foo,ROOT(EXPRESSION)),", // 17-17+16 "DEFINE(bar,ROOT(LOOP(10 , CALL(foo)))),", // 47-47+25 "DEFINE(baz,ROOT(LOOP(10 , CALL(bar)))),", // 86-86+25 "CALL(baz),CALL(baz)", // ")"); // Checkstyle: resume Map<SourceSection, Counter> counters = profiler.getCounters(); Assert.assertEquals(0, counters.size()); run(source); counters = profiler.getCounters(); Assert.assertEquals(4, counters.size()); final SourceSection rootSection = source.createSection(null, 0, 140); final SourceSection leafSection = source.createSection(null, 17, 16); final SourceSection callfooSection = source.createSection(null, 47, 27); final SourceSection callbarSection = source.createSection(null, 88, 27); Counter root = counters.get(rootSection); Counter leaf = counters.get(leafSection); Counter callfoo = counters.get(callfooSection); Counter callbar = counters.get(callbarSection); Assert.assertNotNull(root); Assert.assertNotNull(leaf); Assert.assertNotNull(callfoo); Assert.assertNotNull(callbar); final TimeKind testTimeKind = TimeKind.INTERPRETED_AND_COMPILED; Assert.assertEquals(1L, root.getInvocations(testTimeKind)); Assert.assertEquals(200L, leaf.getInvocations(testTimeKind)); Assert.assertEquals(20L, callfoo.getInvocations(testTimeKind)); Assert.assertEquals(2L, callbar.getInvocations(testTimeKind)); engine.getInstruments().get(TruffleProfiler.ID).setEnabled(false); run(source); Assert.assertEquals(1L, root.getInvocations(testTimeKind)); Assert.assertEquals(200L, leaf.getInvocations(testTimeKind)); Assert.assertEquals(20L, callfoo.getInvocations(testTimeKind)); Assert.assertEquals(2L, callbar.getInvocations(testTimeKind)); engine.getInstruments().get(TruffleProfiler.ID).setEnabled(true); counters = profiler.getCounters(); Assert.assertEquals(0, counters.size()); for (int i = 0; i < 10000; i++) { run(source); } root = counters.get(rootSection); leaf = counters.get(leafSection); callfoo = counters.get(callfooSection); callbar = counters.get(callbarSection); Assert.assertEquals(10000L, root.getInvocations(testTimeKind)); Assert.assertEquals(2000000L, leaf.getInvocations(testTimeKind)); Assert.assertEquals(200000L, callfoo.getInvocations(testTimeKind)); Assert.assertEquals(20000L, callbar.getInvocations(testTimeKind)); engine.dispose(); engine = null; String o = getOut(); Assert.assertTrue(o != null && o.trim().length() > 0); }
public void setMainScriptSource(Source source) { this.mainScriptSource = source; if (!source.getPath().equals("-e")) { this.mainScriptFullPath = expandPath(context, source.getPath()); } }