Thursday, June 11, 2009

Complex Number in Groovy

Here's a quick note of making Groovy to support complex numbers:

1. override number operations via metaclass:
Number.metaClass.plus = { n ->
  if(n instanceof Imaginary) {
    return new Complex(r:delegate, i:n.v)
  }
}

2. define class Complex to hold real, r, and imaginary, i, parts
class Complex {
  def r
  def i
  String toString() {
    "$r + ${i}i"
  }
}


3. create class Imaginary to be a wrapper class (I borrow this idea from Scala's implicit converter).
class Imaginary {
  def v
}


4. define i as a global closure. It would be in DefaultGroovyMethods, actually.
def i = { v ->
  new Imaginary(v:v)
}


Then when you write:
def b = 2 + i(2.4)
println b
println b.class


This prints "2 + 2.4i" and the type of b is class Complex.

Saturday, June 06, 2009

Fortress - Hello World

Here's my early experiment of running Fortress Hello world program, which is listed below (taken from the tutorial at MIT by the Fortress team):

component hello
export Executable

run() = println("Hello, World !")

end


I'm a bit surprised that its compilation time is "really" slow. I may be guessing that it's caused by type inference in the Fortress compiler. JVM 1.6.0_12 was used in the experiment. One of my quick conclusion is that Fortress is not suitable for scripting. But I think its compiled program will not be slow (as I mentioned that I am suspecting its type inference engine that makes scripting slow).

Here's 5 times of running:

chanwit@lb /cygdrive/c/fortress/fortress_3625
$ time `bin/fortress chanwit/hello.fss`
bash: Hello,: command not found

real    0m11.393s
user    0m0.244s
sys     0m0.199s

chanwit@lb /cygdrive/c/fortress/fortress_3625
$ time `bin/fortress chanwit/hello.fss`
bash: Hello,: command not found

real    0m11.486s
user    0m0.181s
sys     0m0.214s

chanwit@lb /cygdrive/c/fortress/fortress_3625
$ time `bin/fortress chanwit/hello.fss`
bash: Hello,: command not found

real    0m11.412s
user    0m0.213s
sys     0m0.215s

chanwit@lb /cygdrive/c/fortress/fortress_3625
$ time `bin/fortress chanwit/hello.fss`
bash: Hello,: command not found

real    0m11.377s
user    0m0.197s
sys     0m0.198s

chanwit@lb /cygdrive/c/fortress/fortress_3625
$ time `bin/fortress chanwit/hello.fss`
bash: Hello,: command not found

real    0m11.432s
user    0m0.229s
sys     0m0.198s


Friday, February 27, 2009

Hybrid call site model based on Groovy

I'm trying to model a class structure that support the following features:
  • callsite; separating call and execution semantics to
    • support before/after advice of AspectJ's pointcut-advice model (possible support around advice)
    • further support my typing concerns.
  • support statically resolved callsite (resolving is done at compile-time, but also changeable at runtime)
  • support dynamically resolved callsite (as done in Groovy, JRuby, etc.)
  • must be compatible with Java. i.e., Generated classes can be used as normal Java classes.
My below POC is based on Alex T. implementation. But instead of showing all kind of callsite, I show you here only statically resolved callsite. This callsite is surely fast (I hope it's gonna be at the same level of Java) because it's compile-time thing. The interesting point is that, I have a special class loader for these callsites, namely StaticCallSiteClassLoader. What does it do?  This class loader allows re-definition of these callsites.

What I have observed so far is that All of my callsite classes (_0_println, _1_ctor, _2_render and _3_index) have not been loaded when there is no "direct" reference to them. So they can be fully lazy loading using the StaticCallSiteClassLoader. (I've checked this with java --verbose)

How could these callsites are changed at runtime?
You may see the acallsite, an CallSite array that hold all callsites in the example class. It's intended to be public and can be accessed by, for example, a virtual meta-class.
So what's a virtual meta-class? It's kind of meta-class, but in this case, it's not for controlling behaviour of the class (because all dispatch are static). It's for changing behaviour of callsite by reassigning new callsites object to the callsite array.

Notic that I use WeakReference to hold a callsite class loader. This will be making the class loader GC-able. That's it, after deferenceing all old callsites out of the callsite array, the class loader can be unloaded. Therefore, all callsite class definition are gone as well. Then, we can create a new set of callsites for the current class. This technique would be flexible enough for:
  • changing a static call to be a dynamic call
  • changing a dynamic call back to a static call
  • installing a woven callsite with before, after advice (it features dynamic AOP)
  • inserting type advice, which can lead to bytecode inlining
  • design a hybrid type system to support both static and dynamic typing in the same system.
import java.lang.ref.WeakReference;

import runtime.CallSite;
import classloader.StaticCallSiteClassLoader;
import dm.Render;

public class TestController {

    /* synthetic */
    private static WeakReference<StaticCallSiteClassLoader> cl;

    /* synthetic normal callsite */
    public static class _0_println extends CallSite {...}

    /* synthetic constructor */
    public static class _1_ctor extends CallSite {...}

    /* synthetic inter-type declaration callsite. statically resolved */
    public static class _2_render extends CallSite {...}

    /* synthetic property callsite */
    public static class _3_index extends CallSite {...}

    /* synthetic */
    public static CallSite[] acallsite;

    static {
        cl = new WeakReference<StaticCallSiteClassLoader>(
                    new StaticCallSiteClassLoader(TestController.class)
        );
        acallsite = new CallSite[4];
        acallsite[0] = cl.get().get("_0_println");
        acallsite[1] = cl.get().get("_1_ctor");
        acallsite[2] = cl.get().get("_2_render");
        acallsite[3] = cl.get().get("_3_index");
    }

    public TestController(){
        super();
    }

    public int getIndex() {
        return 10;
    }

    public static void main(String[] args) {
        acallsite[0].callStatic("hello world");
        TestController t = (TestController)(acallsite[1].callConstructor());
        acallsite[2].call(t, "hello world");
        acallsite[0].callStatic(acallsite[3].callGetProperty(t, "index"));
    }

}


Wednesday, February 25, 2009

Using AspectJ to find a Grails' bug

It's because I've got a constraint resource (also time). I've found a Grails bug (4060) that is really hard to spot. There is no exception was thrown and I have no idea how to trace this bug because my knowledge about Spring is really limited. I also do not have any good IDE to help debug Grails well. (calling grails-debug and attaching it remotely to Eclipse won't help much in this situation).

After I enabled Grails log to understand some behaviour of Grails' spring package, I saw some point in the log that it's likely a bug, but the log message is inside Spring, not Grails. (Yep, I need a stack trace).

I then got an idea of using AspectJ to help inserting a conditional code to "dump" stack from that point. What I've used is an execution PCD and a call to Thread.dumpStack();

Here's steps:
  • Enable trace log in grails-app/Config.groovy
  • Find a message
  • Grep to locate the point that emits the message. I found it in Spring code, not Grails.
  • Instead of rebuild Spring, I wrote this AspectJ code:
    pointcut pc():
        execution(
           public Object DefaultSingletonBeanRegistry
               .getSingleton(String,ObjectFactory)
        );
       
    before(String name): pc() && args(name,..) {
        if(name.equals("localeResolver")) {
            Thread.dumpStack();
        }
    }

Note that my target Spring bean is localeResolver, so I put a condition here to dump the current stack to find which part of Grails code is doing with this bean at that time.
  • I then wove the above aspect into spring.jar
$ ajc -cp .:aspectjrt.jar:spring.jar
   -inpath spring.jar\ // I was going to weave spring.jar
   -outjar spring-2.5.6.jar\ // output would be spring-2.5.6.jar
   -showWeaveInfo\ // I wanted to see some weaving info
   -Xlint:ignore\ // ignore error when resolving some missing classes
   Dump.aj // the above aspect


And gotcha, I could really see the context around when this Spring bean is loaded, and reported to Grails JIRA (And Graeme, you did fix it really quickly - you're super cool!).

Thus, using AspectJ code + Thread.dumpStack() is kind of a conditional break point that can help you debugging Grails without an IDE.