Skip to main content

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

Hi Wes!

(If you look at the implementation of pertypewithin, you might find a
map lookup, just like the cache implementation.)

This seems odd to me --- I can't see any advantage for pertypewithin using a map rather than direct introduction.

The instance variable is declared on an interface (declared on your Test)
and initialized on construction:

final aspect BSizeOf extends SizeOf {
    public int ISize.size = SizeOf.get(this); // reusing other implementation
    declare parents: Test implements ISize;
    declare error: !within(BSizeOf) && set(int ISizeOf.size) : "pseudo-final";
}

I had thought about this option but, given that I want to get size information for all types, it seems like the overhead would be too large.

Indeed, I'm not sure if your size computation handles a class that's not done initializing. In a cycle where classes A -> B -> A, B will complete
initialization before A does, but your calc would need the (uninitialized) A.
That's not really an AspectJ issue, but you bump into it when advising
staticinitialization(..).

Hmmm, the question is why does my sizeof calculation need A to compute the sizeof B? Certainly, it seems that if the dependence cycle you describe comes just from references then there is no problem as the size of a reference is known anyway (4 bytes). The only situation I can forsee is if B extends A. In which case, I wonder if the VM spec says anything about the order of evaluation for static initializers between classes and their super classes ?

Cheers,

Dave


------------Original Message------------
From: David Pearce <david.pearce@xxxxxxxxxxxxx>
To: aspectj-users@xxxxxxxxxxx
Date: Thu, Jan-19-2006 2:11 PM
Subject: [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
_______________________________________________
aspectj-users mailing list
aspectj-users@xxxxxxxxxxx
https://dev.eclipse.org/mailman/listinfo/aspectj-users




------------------------------------------------------------------------

_______________________________________________
aspectj-users mailing list
aspectj-users@xxxxxxxxxxx
https://dev.eclipse.org/mailman/listinfo/aspectj-users


--
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



Back to the top