Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
[aspectj-users] Comments on this SizeOf Aspect?

Hi All,

I have just written a SizeOf Aspect using the new pertypewithin option and i'm wondering whether anyone has any comments/suggestions on the design ...

The problem is to write a "sizeof" method for Java (as close to the C equivalent as possible). The idea I originally envisaged was to introduce a static int field into every class which could hold the classes "sizeof" value. The value itself being computed once during static initialisation of the class. This would give constant time access to the sizeof information, which would be more efficient than using, for example, a Map from Classes to Sizeof values.

While static introductions using wildcards are not possible in AspectJ (see README-11.html), the new pertypewithin appears to be the answer. The initial design looking like this:

public aspect SizeOf pertypewithin(*) {
    private int size = -1;

    // is this the right way to do this?
    after() : staticinitialization(*) {	
	size = computeSize(thisJoinPointStaticPart
                          .getSignature().getDeclaringType());
    }
public static int get(Object o) { Class c = o.getClass();
	SizeOf a = SizeOf.aspectOf(c);
	return a.size;
} }

For now, don't worry about how computeSize works (it uses reflection). Basically, the size value is computed on static initialisation of a type and then stored in a field for constant-time access from get(). So, for a given Object o, the user can use the method SizeOf.get(o) to estimate the size in bytes of the object.

One problem, of course, is that many classes (e.g. arrays, classes in the standard library) are not exposed to the weaver and, hence, are not matched by pertypewithin(*). To get around this, I use a "back up" cache for those types which have no aspect associated with them, giving the following:

public aspect SizeOf pertypewithin(*) {
    static private Map cache = Collections.synchronizedMap(new HashMap());
    private int size = -1;

    // is this the right way to do this?
    after() : staticinitialization(*) {	
	size = computeSize(thisJoinPointStaticPart
>                          .getSignature().getDeclaringType(),null);
    }
public static int get(Object o) { Class c = o.getClass();
	
	if(SizeOf.hasAspect(c)) {
	    SizeOf a = SizeOf.aspectOf(c);
	    return a.size;
	} else {
	    Integer r = (Integer) cache.get(c);
	    if(r != null) { return r; }
	    else {
		int x = computeSize(c,o);
		cache.put(c,x);
		return x;
} } }

In get(), I pass the actual Object into computeSize() as well, so that it can be used to determine the size of an array (for array types).

Anyway, I've attached the complete source, including a test harness as a tarball. The test testharness performs some simple measurements of the time taken for a static lookup versus a cache lookup. The results suggest a static lookup is about twice as fast (on my machine, at least).

So, finally, any comments on this design would be very much appreciated!! In particular, is there a better way to do this?

Cheers,

David J. Pearce

--
Lecturer in Computer Science,
School of Mathematics, Statistics and Computer Science,
Victoria University of Wellington,
PO Box 600,
Wellington,
New Zealand.

Office: Cotton 231
Telephone: +64 4 463 5833
URL: http://www.mcs.vuw.ac.nz/~djp

Attachment: sizeof-aspect.tgz
Description: application/compressed-tar


Back to the top