Sunday, April 15, 2007

Groovy and AOP Metaclass

I've recently found John McClean's last year article about AspectJ-like AOP model implemented in Groovy. In its comments, his readers posted that he should have a custom MetaClass to support his approach. I'm sure he probably did it because he's going to talk about AOP in Groovy at Grails Exchange conference this May. However based on his implementation, I've done the similar MetaClass as well, as I need some kind of AOP facility to support my research.

Probably after the Grails Exchange event, I can see his AOP code somewhere.

Here's my implementation:

package org.plaop;

import groovy.lang.DelegatingMetaClass

public class AOPSupportMetaClass extends DelegatingMetaClass {

def after = [:]
def before = [:]
def around = [:]

public AOPSupportMetaClass(MetaClass delegate) {
super(delegate);
initialize();
}

public Object getProperty(Object object, String prop) {
if(prop == 'around') return this.around else
if(prop == 'before') return this.before else
if(prop == 'after') return this.after else
return super.getProperty(object, prop)
}

public Object invokeMethod(Object arg0, String name, Object[] args) {
if(before[name]!=null) {
before[name](inv)
}

def inv = new InvocationContext(methodName: name, args: args, called: arg0)
inv.proceed = { arglist ->
super.invokeMethod(arg0, name, arglist)
}

def result = null
if(around[name]!=null) {
result = around[name](inv)
} else {
result = super.invokeMethod(arg0, name, args)
}

inv.proceed = null

if(after[name]!=null) {
after[name](inv)
}
return result
}
}



This is how to use it:

void testBasicAround() {
def mcr = InvokerHelper.getInstance().metaRegistry
AOPSupportMetaClass amc = new AOPSupportMetaClass(
mcr.getMetaClass(TestObject.class))
mcr.setMetaClass(TestObject.class, amc)

def t = new TestObject()
t.around['save'] = { inv ->
inv.args[0] = inv.args[0] + '.'
inv.proceed(inv.args)
}
t.save('test')
}


The big bug here is that this MetaClass hasn't yet supported per class weaving model. But it's not that hard to implement. John's article really realised me the power of Groovy MOP from AOP perspective.

Sunday, April 08, 2007

Invariant Dynamic Calls

Basically, dynamically typed languages, Groovy in this context, dispatch calls by firstly choosing appropriate methods, then invoking them. The choosing process is obviously expensive. Several techniques, such as method caching, are currently implemented in Groovy to speed things up. However, choosing methods through reflection won't allow JIT to optimise method bodies for callers. With caching, the shortest steps for Groovy are still:

calling an invokeX method -> looking up cache -> calling the cached chosen method,

and you can not further optimise the invocation beyond this point.

The only way to do this is to simply replace that call by the chosen method call.
It's basic and everyone on the groovy-dev list knows about this (I supposed). Anyway, there're a lot arguments in the list that we should preserve the "dynamicity" of Groovy. I agree with those arguments, so we should leave Groovy core as it is, but we can really do somethings at the application level, in production phase.

During unit testing, developers may find sets of "invariant dynamic calls" of their applications. I roughly define an invariant dynamic call as a call that has only one chosen method. Trivial examples for this kind of call in Grails framework are Domain class' .save() and .delete(). If we assume that our test suites cover the application enough, so we can basically conclude that each dynamic call identified by the test suites is an invariant dynamic call, if there is only one chosen method for it. Then, we just simply replace these calls with static signatures, in class files or even by on-the-fly transformation, to gain performance back.

My current technique to analyse calls at bytecode-level is, firstly scanning for ScriptBytecodeAdapter.invoke*, then reverse looking for LDC "methodName" and other arguments that will be stored onto the stack.

Beyond Java 6
I dont exactly know when INVOKEDYNAMIC will arrive, but with this instruction replacing invariant dynamic calls will be much easier by
1. changing INVOKEDYNAMIC to appropriate kind of invoke, say INVOKEVIRTUAL, INVOKESPACIAL, INVOKESTATIC or INVOKEINTERFACE.
2. changing type descriptors to the correct classes.

I haven't followed the spec of INVOKEDYNAMIC at the moment, it's time to have a quick read again.

Saturday, March 31, 2007

OpenLaszlo 4.0.0

OpenLaszlo 4 released a few days ago. I was impressed with its CSS support, although it's a pull (not push - like HTML's CSS) style. Anyway I've found some bugs that prevented me from compiling an LZX program for the DHTML runtime. Hopefully, these bugs will be get fixed soon.

Another thing is that styles, which are working well in Flash runtimes, doesn't work for the DHTML runtime as well. However, these bugs don't stop me from using this great software !!!

Saturday, March 24, 2007

Get OpenJDK Hotspot Compiled !

I'm very newbie on hacking JVM and I'm very happy to get OpenJDK Hotspot B10 compiled on Ubuntu 6.10. Compilation time is 1 hour and 5 mins. Actually, what I'm wanting to do from now on is to add some modification into its interpreter mode. Everything's just started.

Some configuration
- OpenJDK Hotspot VM 7-EA-B10 (21 Mar 07)
- Importing JDK 1.6_01
- Ubuntu 6.10
- GCC 4.1.2 (Ubuntu 4.1.1-13ubuntu5)
- Linux 2.6.17-11