<commit_before>package som;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import com.oracle.truffle.api.CompilerAsserts;
import com.oracle.truffle.api.CompilerDirectives.CompilationFinal;
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
import com.oracle.truffle.api.debug.Debugger;
import com.oracle.truffle.api.instrumentation.InstrumentableFactory.WrapperNode;
import com.oracle.truffle.api.instrumentation.InstrumentationHandler;
import com.oracle.truffle.api.nodes.Node;
import com.oracle.truffle.api.nodes.RootNode;
import com.oracle.truffle.api.source.Source;
import com.oracle.truffle.api.source.SourceSection;
import com.oracle.truffle.api.vm.PolyglotEngine;
import com.oracle.truffle.api.vm.PolyglotEngine.Builder;
import com.oracle.truffle.api.vm.PolyglotEngine.Instrument;
import com.oracle.truffle.tools.Profiler;
import com.oracle.truffle.tools.ProfilerInstrument;
import com.oracle.truffle.tools.debug.shell.client.SimpleREPLClient;
import com.oracle.truffle.tools.debug.shell.server.REPLServer;

import coveralls.truffle.Coverage;
import som.compiler.MixinDefinition;
import som.compiler.SourcecodeCompiler;
import som.interpreter.SomLanguage;
import som.interpreter.TruffleCompiler;
import som.interpreter.actors.Actor;
import som.interpreter.actors.SFarReference;
import som.interpreter.actors.SPromise;
import som.interpreter.actors.SPromise.SResolver;
import som.primitives.processes.ChannelPrimitives;
import som.primitives.threading.ThreadingModule;
import som.vm.ObjectSystem;
import som.vm.Primitives;
import som.vm.VmOptions;
import som.vm.VmSettings;
import som.vm.constants.KernelObj;
import som.vmobjects.SObjectWithClass.SObjectWithoutFields;
import tools.concurrency.ActorExecutionTrace;
import tools.debugger.Tags;
import tools.debugger.WebDebugger;
import tools.dym.DynamicMetrics;
import tools.language.StructuralProbe;


public final class VM {

  @CompilationFinal private static PolyglotEngine engine;
  @CompilationFinal private static VM vm;
  @CompilationFinal private static StructuralProbe structuralProbe;
  @CompilationFinal private static WebDebugger webDebugger;
  private static Profiler truffleProfiler;

  public static WebDebugger getWebDebugger() {
    return webDebugger;
  }

  private final Map<String, Object> exports = new HashMap<>();

  public boolean registerExport(final String name, final Object value) {
    boolean wasExportedAlready = exports.containsKey(name);
    exports.put(name, value);
    return wasExportedAlready;
  }

  public Object getExport(final String name) {
    return exports.get(name);
  }

  /**
   * @return last VM instance, for tests only
   */
  public static VM getVM() {
    return vm;
  }

  public static void setEngine(final PolyglotEngine e) {
    engine = e;
  }

  private final boolean avoidExitForTesting;
  private final ObjectSystem objectSystem;

  private int lastExitCode = 0;
  private volatile boolean shouldExit = false;
  private final VmOptions options;

  @CompilationFinal
  private SObjectWithoutFields vmMirror;
  @CompilationFinal
  private Actor mainActor;

  public SObjectWithoutFields getVmMirror() {
    return vmMirror;
  }

  public Primitives getPrimitives() {
    return objectSystem.getPrimitives();
  }

  public static void thisMethodNeedsToBeOptimized(final String msg) {
    if (VmSettings.FAIL_ON_MISSING_OPTIMIZATIONS) {
      CompilerAsserts.neverPartOfCompilation(msg);
    }
  }

  public static void callerNeedsToBeOptimized(final String msg) {
    if (VmSettings.FAIL_ON_MISSING_OPTIMIZATIONS) {
      CompilerAsserts.neverPartOfCompilation(msg);
    }
  }

  public static void insertInstrumentationWrapper(final Node node) {
    // TODO: make thread-safe!!!
    // TODO: can I assert that it is locked?? helper on Node??
    if (VmSettings.INSTRUMENTATION) {
      assert node.getSourceSection() != null || (node instanceof WrapperNode) : "Node needs source section, or needs to be wrapper";
      InstrumentationHandler.insertInstrumentationWrapper(node);
    }
  }

  public VM(final String[] args, final boolean avoidExitForTesting) throws IOException {
    vm = this;

    this.avoidExitForTesting = avoidExitForTesting;
    options = new VmOptions(args);
    objectSystem = new ObjectSystem(new SourcecodeCompiler(), structuralProbe);
    objectSystem.loadKernelAndPlatform(options.platformFile, options.kernelFile);

    if (options.showUsage) {
      VmOptions.printUsageAndExit();
    }
  }

  public VM(final String[] args) throws IOException {
    this(args, false);
  }

  public static void reportSyntaxElement(final Class<? extends Tags> type,
      final SourceSection source) {
    if (webDebugger != null) {
      webDebugger.reportSyntaxElement(type, source);
    }
  }

  public static void reportParsedRootNode(final RootNode rootNode) {
    if (webDebugger != null) {
      webDebugger.reportRootNodeAfterParsing(rootNode);
    }
  }

  public static void reportLoadedSource(final Source source) {<commit_msg>Added method for graphical representation of Truffle Methods<commit_after>package som;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.oracle.truffle.api.CompilerAsserts;
import com.oracle.truffle.api.CompilerDirectives.CompilationFinal;
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
import com.oracle.truffle.api.debug.Debugger;
import com.oracle.truffle.api.instrumentation.InstrumentableFactory.WrapperNode;
import com.oracle.truffle.api.instrumentation.InstrumentationHandler;
import com.oracle.truffle.api.nodes.GraphPrintVisitor;
import com.oracle.truffle.api.nodes.Node;
import com.oracle.truffle.api.nodes.RootNode;
import com.oracle.truffle.api.source.Source;
import com.oracle.truffle.api.source.SourceSection;
import com.oracle.truffle.api.vm.PolyglotEngine;
import com.oracle.truffle.api.vm.PolyglotEngine.Builder;
import com.oracle.truffle.api.vm.PolyglotEngine.Instrument;
import com.oracle.truffle.tools.Profiler;
import com.oracle.truffle.tools.ProfilerInstrument;
import com.oracle.truffle.tools.debug.shell.client.SimpleREPLClient;
import com.oracle.truffle.tools.debug.shell.server.REPLServer;

import coveralls.truffle.Coverage;
import som.compiler.MixinDefinition;
import som.compiler.SourcecodeCompiler;
import som.interpreter.SomLanguage;
import som.interpreter.TruffleCompiler;
import som.interpreter.actors.Actor;
import som.interpreter.actors.SFarReference;
import som.interpreter.actors.SPromise;
import som.interpreter.actors.SPromise.SResolver;
import som.interpreter.nodes.dispatch.Dispatchable;
import som.primitives.processes.ChannelPrimitives;
import som.primitives.threading.ThreadingModule;
import som.vm.ObjectSystem;
import som.vm.Primitives;
import som.vm.VmOptions;
import som.vm.VmSettings;
import som.vm.constants.KernelObj;
import som.vmobjects.SInvokable;
import som.vmobjects.SObjectWithClass.SObjectWithoutFields;
import tools.concurrency.ActorExecutionTrace;
import tools.debugger.Tags;
import tools.debugger.WebDebugger;
import tools.dym.DynamicMetrics;
import tools.language.StructuralProbe;


public final class VM {

  @CompilationFinal private static PolyglotEngine engine;
  @CompilationFinal private static VM vm;
  @CompilationFinal private static StructuralProbe structuralProbe;
  @CompilationFinal private static WebDebugger webDebugger;
  private static Profiler truffleProfiler;

  public static WebDebugger getWebDebugger() {
    return webDebugger;
  }

  private final Map<String, Object> exports = new HashMap<>();

  public boolean registerExport(final String name, final Object value) {
    boolean wasExportedAlready = exports.containsKey(name);
    exports.put(name, value);
    return wasExportedAlready;
  }

  public Object getExport(final String name) {
    return exports.get(name);
  }

  /**
   * @return last VM instance, for tests only
   */
  public static VM getVM() {
    return vm;
  }

  public static void setEngine(final PolyglotEngine e) {
    engine = e;
  }

  private final boolean avoidExitForTesting;
  private final ObjectSystem objectSystem;

  private int lastExitCode = 0;
  private volatile boolean shouldExit = false;
  private final VmOptions options;

  @CompilationFinal
  private SObjectWithoutFields vmMirror;
  @CompilationFinal
  private Actor mainActor;

  public SObjectWithoutFields getVmMirror() {
    return vmMirror;
  }

  public Primitives getPrimitives() {
    return objectSystem.getPrimitives();
  }

  public static void thisMethodNeedsToBeOptimized(final String msg) {
    if (VmSettings.FAIL_ON_MISSING_OPTIMIZATIONS) {
      CompilerAsserts.neverPartOfCompilation(msg);
    }
  }

  public static void callerNeedsToBeOptimized(final String msg) {
    if (VmSettings.FAIL_ON_MISSING_OPTIMIZATIONS) {
      CompilerAsserts.neverPartOfCompilation(msg);
    }
  }

  public static void insertInstrumentationWrapper(final Node node) {
    // TODO: make thread-safe!!!
    // TODO: can I assert that it is locked?? helper on Node??
    if (VmSettings.INSTRUMENTATION) {
      assert node.getSourceSection() != null || (node instanceof WrapperNode) : "Node needs source section, or needs to be wrapper";
      InstrumentationHandler.insertInstrumentationWrapper(node);
    }
  }

  private static void outputAllTruffleMethodsToIGV() {
    GraphPrintVisitor graphPrinter = new GraphPrintVisitor();

    List<MixinDefinition> classes = new ArrayList<MixinDefinition>(structuralProbe.getClasses());
    Collections.sort(classes, (final MixinDefinition a, final MixinDefinition b) -> a.getName().getString().compareTo(b.getName().getString()));

    for (MixinDefinition mixin : classes) {
      graphPrinter.beginGroup(mixin.getName().getString());

      for (Dispatchable disp : mixin.getInstanceDispatchables().values()) {
        if (disp instanceof SInvokable) {
          SInvokable i = (SInvokable) disp;
          graphPrinter.beginGraph(i.toString()).visit(i.getCallTarget().getRootNode());
        }
      }
      graphPrinter.endGroup();
    }

    graphPrinter.printToNetwork(true);
    graphPrinter.close();
  }

  public VM(final String[] args, final boolean avoidExitForTesting) throws IOException {
    vm = this;

    this.avoidExitForTesting = avoidExitForTesting;
    options = new VmOptions(args);
    objectSystem = new ObjectSystem(new SourcecodeCompiler(), structuralProbe);
    objectSystem.loadKernelAndPlatform(options.platformFile, options.kernelFile);

    if (options.showUsage) {
      VmOptions.printUsageAndExit();
    }
  }

  public VM(final String[] args) throws IOException {
    this(args, false);
  }

  public static void reportSyntaxElement(final Class<? extends Tags> type,
      final SourceSection source) {
    if (webDebugger != null) {
      webDebugger.reportSyntaxElement(type, source);
    }
  }

  public static void reportParsedRootNode(final RootNode rootNode) {
    if (webDebugger != null) {
      webDebugger.reportRootNodeAfterParsing(rootNode);
      outputAllTruffleMethodsToIGV();
    }
  }

  public static void reportLoadedSource(final Source source) {
{'fraction_non_alphanumeric': 0.09002237136465324, 'fraction_numerical': 0.0001789709172259508, 'mean_word_length': 4.817803227485684, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 12, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1949266', 'n_tokens_mistral': 3366, 'n_tokens_neox': 3314, 'n_words': 723}