public DynamicMethod dup() { DefaultMethod newMethod = new DefaultMethod(getImplementationClass(), staticScope, body, name, argsNode, getVisibility(), position); newMethod.setIsBuiltin(this.builtin); newMethod.box = this.box; return newMethod; }
public ArgsNode getArgsNode() { return realMethod.getArgsNode(); }
static void log(DefaultMethod method, String name, String message, String... reason) { String className = method.getImplementationClass().getBaseName(); if (className == null) className = "<anon class>"; StringBuilder builder = new StringBuilder(message + ":" + className + "." + name + " at " + method.getPosition()); if (reason.length > 0) { builder.append(" because of: \""); for (int i = 0; i < reason.length; i++) { builder.append(reason[i]); } builder.append('"'); } LOG.info(builder.toString()); }
public void switchToJitted(Script jitCompiledScript, CallConfiguration jitCallConfig) { this.box.actualMethod = DynamicMethodFactory.newJittedMethod( getImplementationClass().getRuntime(), getImplementationClass(), staticScope, jitCompiledScript, name, jitCallConfig, getVisibility(), argsNode.getArity(), position, this); this.box.actualMethod.serialNumber = this.serialNumber; this.box.callCount = -1; getImplementationClass().invalidateCacheDescendants(); }
if (method.getImplementationClass().isSingleton()) { IRubyObject possibleRealClass = ((MetaClass) method.getImplementationClass()).getAttached(); if (possibleRealClass instanceof RubyModule) { excludeModuleName = "Meta:" + ((RubyModule) possibleRealClass).getName(); || config.getExcludedMethods().contains(excludeModuleName + "#" + methodName) || config.getExcludedMethods().contains(methodName))) { method.setCallCount(-1); log(method, methodName, "skipping method: " + excludeModuleName + "#" + methodName); return; String key = SexpMaker.create(methodName, method.getArgsNode(), method.getBodyNode()); JITClassGenerator generator = new JITClassGenerator(className, methodName, key, runtime, method, counts); jitCompiledScript.setRootScope(method.getStaticScope()); method.switchToJitted(jitCompiledScript, generator.callConfig()); return; } catch (Throwable t) {
public JITClassGenerator(String className, String methodName, String key, Ruby ruby, DefaultMethod method, JITCounts counts) { this.packageName = JITCompiler.RUBY_JIT_PREFIX; if (RubyInstanceConfig.JAVA_VERSION == Opcodes.V1_7 || Options.COMPILE_INVOKEDYNAMIC.load() == true) { // Some versions of Java 7 seems to have a bug that leaks definitions across cousin classloaders // so we force the class name to be unique to this runtime. // Also, invokedynamic forces us to make jitted code unique to each runtime, since the call sites cache // at class level rather than at our runtime level. This makes it impossible to share jitted code // across runtimes. digestString = key + Math.abs(ruby.hashCode()); } else { digestString = key; } this.className = packageName + "/" + className.replace('.', '/') + CLASS_METHOD_DELIMITER + JavaNameMangler.mangleMethodName(methodName) + "_" + digestString; this.name = this.className.replaceAll("/", "."); this.bodyNode = method.getBodyNode(); this.argsNode = method.getArgsNode(); this.methodName = methodName; filename = calculateFilename(argsNode, bodyNode); staticScope = method.getStaticScope(); asmCompiler = new StandardASMCompiler(this.className, filename); this.ruby = ruby; this.counts = counts; }
/** * Visit methods contained in the specified class using the given visitor. * * @param visitor the visitor to use * @param mod the module/class whose methods to visit */ private static void visitMethods(NodeVisitor visitor, RubyModule mod) { for (DynamicMethod method : mod.getNonIncludedClass().getMethods().values()) { DynamicMethod realMethod = method.getRealMethod(); List<Node> args, body; if (method instanceof DefaultMethod) { DefaultMethod defaultMethod = ((DefaultMethod) realMethod); args = defaultMethod.getArgsNode().childNodes(); body = defaultMethod.getBodyNode().childNodes(); } else if (method instanceof InterpretedMethod) { InterpretedMethod interpretedMethod = ((InterpretedMethod) realMethod); args = interpretedMethod.getArgsNode().childNodes(); body = interpretedMethod.getBodyNode().childNodes(); } else { return; } for (int i = 0; i < args.size(); i++) args.get(i).accept(visitor); for (int i = 0; i < body.size(); i++) body.get(i).accept(visitor); } }
@Override public MethodData getMethodData() { if (methodData == null){ methodData = new MethodData(name, getFile(), InstanceVariableFinder.findVariables(body)); } return methodData; }
public void tryJIT(DefaultMethod method, ThreadContext context, String className, String methodName) { if (!config.getCompileMode().shouldJIT()) return; if (method.incrementCallCount() < config.getJitThreshold()) return; jitThresholdReached(method, config, context, className, methodName); }
public static DynamicMethod newDefaultMethod( Ruby runtime, RubyModule container, String name, StaticScope scope, Node body, ArgsNode argsNode, Visibility visibility, ISourcePosition position) { if (runtime.getInstanceConfig().getCompileMode() == CompileMode.OFF) { if (RubyInstanceConfig.FULL_TRACE_ENABLED) { return new TraceableInterpretedMethod(container, scope, body, name, argsNode, visibility, position); } else { return new InterpretedMethod(container, scope, body, name, argsNode, visibility, position); } } else { return new DefaultMethod(container, scope, body, name, argsNode, visibility, position); } }
public static DynamicMethod unwrapMethod(DynamicMethod method, String[] realName) throws IndirectBindingException { // get the "real" method in a few ways while (method instanceof AliasMethod) { realName[0] = ((AliasMethod)method).getOldName(); // need to use original name, not aliased name method = method.getRealMethod(); } while (method instanceof WrapperMethod) method = method.getRealMethod(); // ProfilingDynamicMethod wraps any number of other types of methods but // we do not handle it in indy binding right now. Disable direct binding // and bind through DynamicMethod. if (method instanceof ProfilingDynamicMethod) { throw new IndirectBindingException("profiling active"); } if (method instanceof DefaultMethod) { DefaultMethod defaultMethod = (DefaultMethod) method; if (defaultMethod.getMethodForCaching() instanceof JittedMethod) { method = defaultMethod.getMethodForCaching(); } } return method; }
if (method.getImplementationClass().isSingleton()) { IRubyObject possibleRealClass = ((MetaClass) method.getImplementationClass()).getAttached(); if (possibleRealClass instanceof RubyModule) { excludeModuleName = "Meta:" + ((RubyModule) possibleRealClass).getName(); || config.getExcludedMethods().contains(excludeModuleName + "#" + methodName) || config.getExcludedMethods().contains(methodName))) { method.setCallCount(-1); log(method, methodName, "skipping method: " + excludeModuleName + "#" + methodName); return; String key = SexpMaker.sha1(methodName, method.getArgsNode(), method.getBodyNode()); JITClassGenerator generator = new JITClassGenerator(className, methodName, key, runtime, method, counts); jitCompiledScript.setRootScope(method.getStaticScope()); method.switchToJitted(jitCompiledScript, generator.callConfig()); return; } catch (Throwable t) {
public JITClassGenerator(String className, String methodName, String key, Ruby ruby, DefaultMethod method, JITCounts counts) { this.packageName = JITCompiler.RUBY_JIT_PREFIX; if (RubyInstanceConfig.JAVA_VERSION == Opcodes.V1_7 || Options.COMPILE_INVOKEDYNAMIC.load() == true) { // Some versions of Java 7 seems to have a bug that leaks definitions across cousin classloaders // so we force the class name to be unique to this runtime. // Also, invokedynamic forces us to make jitted code unique to each runtime, since the call sites cache // at class level rather than at our runtime level. This makes it impossible to share jitted code // across runtimes. digestString = getHashForString(key) + Math.abs(ruby.hashCode()); } else { digestString = getHashForString(key); } this.className = packageName + "/" + className.replace('.', '/') + CLASS_METHOD_DELIMITER + JavaNameMangler.mangleMethodName(methodName) + "_" + digestString; this.name = this.className.replaceAll("/", "."); this.bodyNode = method.getBodyNode(); this.argsNode = method.getArgsNode(); this.methodName = methodName; filename = calculateFilename(argsNode, bodyNode); staticScope = method.getStaticScope(); asmCompiler = new StandardASMCompiler(this.className, filename); this.ruby = ruby; this.counts = counts; }
public void switchToJitted(Script jitCompiledScript, CallConfiguration jitCallConfig) { this.box.actualMethod = DynamicMethodFactory.newJittedMethod( getImplementationClass().getRuntime(), getImplementationClass(), staticScope, jitCompiledScript, name, jitCallConfig, getVisibility(), argsNode.getArity(), position, this); this.box.actualMethod.serialNumber = this.serialNumber; this.box.callCount = -1; getImplementationClass().invalidateCacheDescendants(); }
/** * Visit methods contained in the specified class using the given visitor. * * @param visitor the visitor to use * @param mod the module/class whose methods to visit */ private static void visitMethods(NodeVisitor visitor, RubyModule mod) { for (DynamicMethod method : mod.getNonIncludedClass().getMethods().values()) { DynamicMethod realMethod = method.getRealMethod(); if (method instanceof DefaultMethod) { for (Node node : ((DefaultMethod) realMethod).getArgsNode().childNodes()) { node.accept(visitor); } for (Node node : ((DefaultMethod) realMethod).getBodyNode().childNodes()) { node.accept(visitor); } } else if (method instanceof InterpretedMethod) { for (Node node : ((InterpretedMethod) realMethod).getArgsNode().childNodes()) { node.accept(visitor); } for (Node node : ((InterpretedMethod) realMethod).getBodyNode().childNodes()) { node.accept(visitor); } } } }
@Override public MethodData getMethodData() { if (methodData == null){ methodData = new MethodData(name, getFile(), InstanceVariableFinder.findVariables(body)); } return methodData; }
public void tryJIT(DefaultMethod method, ThreadContext context, String className, String methodName) { if (!config.getCompileMode().shouldJIT()) return; if (method.incrementCallCount() < config.getJitThreshold()) return; jitThresholdReached(method, config, context, className, methodName); }
public static DynamicMethod newDefaultMethod( Ruby runtime, RubyModule container, String name, StaticScope scope, Node body, ArgsNode argsNode, Visibility visibility, ISourcePosition position) { if (runtime.getInstanceConfig().getCompileMode() == CompileMode.OFF) { if (RubyInstanceConfig.FULL_TRACE_ENABLED) { return new TraceableInterpretedMethod(container, scope, body, name, argsNode, visibility, position); } else { return new InterpretedMethod(container, scope, body, name, argsNode, visibility, position); } } else { return new DefaultMethod(container, scope, body, name, argsNode, visibility, position); } }
public static DynamicMethod unwrapMethod(DynamicMethod method, String[] realName) throws IndirectBindingException { // get the "real" method in a few ways while (method instanceof AliasMethod) { realName[0] = ((AliasMethod)method).getOldName(); // need to use original name, not aliased name method = method.getRealMethod(); } while (method instanceof WrapperMethod) method = method.getRealMethod(); // ProfilingDynamicMethod wraps any number of other types of methods but // we do not handle it in indy binding right now. Disable direct binding // and bind through DynamicMethod. if (method instanceof ProfilingDynamicMethod) { throw new IndirectBindingException("profiling active"); } if (method instanceof DefaultMethod) { DefaultMethod defaultMethod = (DefaultMethod) method; if (defaultMethod.getMethodForCaching() instanceof JittedMethod) { method = defaultMethod.getMethodForCaching(); } } return method; }
public DynamicMethod dup() { DefaultMethod newMethod = new DefaultMethod(getImplementationClass(), staticScope, body, name, argsNode, getVisibility(), position); newMethod.setIsBuiltin(this.builtin); newMethod.box = this.box; return newMethod; }