[
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