예제 #1
0
  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!");
  }
예제 #2
0
  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();
      }
    }
  }
예제 #3
0
 public String getSourcePath(Source source) {
   if (source == mainScriptSource) {
     return mainScriptFullPath;
   } else {
     return source.getPath();
   }
 }
예제 #4
0
 /*
  * 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);
 }
예제 #5
0
  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);
    }
  }
예제 #6
0
  /**
   * 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);
    }
  }
예제 #7
0
  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;
  }
예제 #8
0
  @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);
  }
예제 #9
0
 public void setMainScriptSource(Source source) {
   this.mainScriptSource = source;
   if (!source.getPath().equals("-e")) {
     this.mainScriptFullPath = expandPath(context, source.getPath());
   }
 }