Package

Source Code of CallsiteHook

import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.jruby.Ruby;
import org.jruby.RubyArray;
import org.jruby.RubyHash;
import org.jruby.runtime.Frame;
import org.jruby.runtime.ThreadContext;
import org.jruby.runtime.RubyEvent;
import org.jruby.runtime.builtin.IRubyObject;

public class CallsiteHook extends RcovHook {
 
  private static CallsiteHook callsiteHook;

  public static CallsiteHook getCallsiteHook() {
    if (callsiteHook == null) {
      callsiteHook = new CallsiteHook();
    }
    return callsiteHook;
  }
 
  private boolean active;
  private RubyHash defsites;
  private RubyHash callsites;
 
  private CallsiteHook() {
    super();
  }
 
  public boolean isActive() {
    return active;
  }
 
  public boolean isInterestedInEvent(RubyEvent event) {
    return event == RubyEvent.CALL || event == RubyEvent.C_CALL;
  }
 
  public RubyArray getCallsiteInfo(Ruby runtime) {
    RubyArray info = runtime.newArray();
    info.add(getCallsites(runtime));
    info.add(getDefsites(runtime));
    return info;
  }
 
  public void setActive(boolean active) {
    this.active = active;
  }
 
  public RubyHash resetDefsites() {
    defsites.clear();
    return defsites;
  }
 
  public void eventHandler(ThreadContext context, String event, String file, int line, String name, IRubyObject type) {
    RubyArray currentMethod = context.getRuntime().newArray();
    currentMethod.add(context.getFrameKlazz());
    currentMethod.add(context.getRuntime().newSymbol(name));
   
    RubyArray fileLoc = context.getRuntime().newArray();
    fileLoc.add(file);
    fileLoc.add(Long.valueOf(line));
    defsites = getDefsites(context.getRuntime());
   
    if (!context.isWithinTrace()) {
      context.setWithinTrace(true);
      defsites.put(currentMethod, fileLoc);
      callsites = getCallsites(context.getRuntime());
     
      if (!callsites.containsKey(currentMethod)) {
        callsites.put(currentMethod, RubyHash.newHash(context.getRuntime()));
      }
     
      RubyHash hash = (RubyHash) callsites.get(currentMethod);
      RubyArray callerArray = customBacktrace(context);
     
      if (!hash.containsKey(callerArray)) {
        hash.put(callerArray, Long.valueOf(0));
      }
     
      Long count = (Long) hash.get(callerArray);
      long itCount = count.longValue() + 1L;
      hash.put(callerArray, Long.valueOf(itCount));
      context.setWithinTrace(false);
    }
  }
 
  private RubyArray customBacktrace(ThreadContext context) {
    Frame[] frames = context.createBacktrace(1, false);
    RubyArray ary = context.getRuntime().newArray();
    ary.addAll(formatBacktrace(context.getRuntime(), frames[frames.length - 1]));
    return context.getRuntime().newArray((IRubyObject) ary);
  }
 
  /*
   * TODO: The logic in this method really needs to be wrapped in a backtrace
   * object or something. Then I could fix the file path issues that cause
   * test failures.
   * @param runtime
   * @param backtrace
   * @return
   */
  private RubyArray formatBacktrace(Ruby runtime, Frame backtrace) {
    RubyArray ary = runtime.newArray();
   
    if (backtrace == null) {
      ary.add(runtime.getNil());
      ary.add(runtime.getNil());
      ary.add("");
      ary.add(Long.valueOf(0));
    } else {
      ary.add(backtrace.getKlazz());
      ary.add((backtrace.getName() == null ? runtime.getNil() : runtime.newSymbol( backtrace.getName())));
      ary.add(backtrace.getFile());
      //Add 1 to compensate for the zero offset in the Frame elements.
      ary.add(backtrace.getLine() + 1);
    }
   
    return ary;
  }
 
  private RubyHash getCallsites(Ruby runtime) {
    if (this.callsites == null) {
      this.callsites = RubyHash.newHash(runtime);
    }
   
    return this.callsites;
  }
 
  private RubyHash getDefsites(Ruby runtime) {
    if (this.defsites == null) {
      this.defsites = RubyHash.newHash(runtime);
    }
   
    return this.defsites;
  }
}
TOP

Related Classes of CallsiteHook

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.