Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: Re[2]: [aspectj-users] Once again aboutn non-this access

Hi Konstantin,

I'd like to step back to look at your requirements. I gather you are trying to implement lazy loading, i.e, to detect object instances that haven't been loaded so you can load them on demand. Is that right?

If so, then you need a mechanism that checks field accesses (and accesses to a member of a collection!) to see whether these objects are loaded or not. In general, this has to be a dynamic test (with the exception of types that are loaded by value such as primitives). Consider:

public class Tree {
    private Tree parent;
    private Collection children;
...
}

The persistence implementation should allow parent or any member of children to be lazily loaded. But both parent and the members of children are instances of Tree. So you really need a dynamic check for these accesses: the referred to instance might not be loaded, even though parent is a field on Tree and Tree is loaded. There are several approaches to implementing this kind of test (either proxies or dynamic tests), but describing the various options and how AspectJ can support them is too much detail for this email.

So I don't see how your original request will solve this problem. But implementing the request does raise some interesting points in their own right. So I'll also address the topics of optimization, a pointcut that expresses the test that you said you wanted, and how this might be enabled by future versions of the AspectJ language.

1. I would like to see more optimization of the this and target pointcut descriptors. There are several cases where the emitted bytecode performs runtime checks that can be proven to be true or false in all cases. 

I'd like to see is an optimization of this(Type) (or this(var) where var is of Type), which the compiler can always resolve to be true or false at compile-time. This results in code that may or may not be optimized away by the VM (JIT). I'd most like to see this optimization to improve the accuracy of the tools support (which currently identifies too many places as advised). I believe AspectJ 1.0.x did have this optimization.

There are several possible optimizations in emitted bytecode that it would be desirable for the AspectJ compiler to implement. But I think the team's current emphasis on making the compiler reliable, scalable, and fast is the right priority.

2. I personally don't think adding special case logic to say "access to a foreign field" is common enough to warrant a special case language extension, and as I will explain below, what you really want can't be expressed without a language extension.

From your clarification, you wanted to identify about access to fields from a different TYPE and not from a different instance. Translating into AspectJ (plus a logical quantification):

for all types T:
for any supertype S of T:
  pointcut externalGet(T t) : 
      this(t) && get(* *.*) && !get(* S.*);

If AspectJ had my proposed type pattern for a type or its supertypes (-), this
would reduce to:
for all types T:
  pointcut externalGet(T t) : 
      this(t) && get(* *.*) && !get(* T-.*);

An alternative version (that would also work for static fields) is:
for all types T:
  pointcut externalGet() : 
      // access to a field from any jp within type T or a parent type...
      (within(T-) || 
      // or from any ITD's defined on T or a parent type
       withincode(* T-.*(..)) || withincode(* T-.new(..))) && 
      get(* *.*) && !get(* T-.*);

For implementing object persistence, you probably don't care about static fields...

It _is_ feasible to write a special case of this pointcut for a single type in AspectJ (just plug in the appropriate value of T and expand to include T and ALL its supertypes). 

But AspectJ doesn't currently offer a way to quantify over types like this at compile-time. Unfortunately, I don't believe even the proposed pertype aspect would help here. 

I am hoping that when AspectJ supports generics, it will be possible to express this kind of pointcut, e.g.,
  pointcut <T> externalGet(T t) : 
      this(t) && get(* *.*) && !get(* T-.*);
  after <T> (T t) returning: externalGet(t) {
      t.dirty = true;
  }

I believe that advice for this pointcut could still be implemented as a method through type erasure (i.e., it wouldn't require macro expansion), though I don't have a fully developed proposal for how AspectJ should handle generics. (as an aside 

So hopefully AspectJ will grow into solving your stated design by 
1) defining generics support that will capture it
2) adopting my proposal for using T- for a type and all its supertypes
3) possibly optimizing the code for this() tests. But note that if we have #1 and #2, optimizing this isn't even necessary (using the within version of the pointcut will be optimized!)

Although I don't see how detecting foreign field access helps with persistence or remote object invocation.

Ron

Ron Bodkin
Chief Technology Officer
New Aspects of Software
m: (415) 509-2895

> ------------Original Message------------
> From: Konstantin Knizhnik <knizhnik@xxxxxxxxx>
> To: Wes Isberg <aspectj-users@xxxxxxxxxxx>
> Date: Sat, Jan-31-2004 10:20 AM
> Subject: Re[2]: [aspectj-users] Once again aboutn non-this access
> 
> Hello Wes,
> 
> 
> Thank you very much for your response.
> 
> WI> You can use within(), but it doesn't really help.
> 
> WI> A join point has a signature specifying only types, so
> WI> it seems like a dynamic test is needed.
> 
> With dynamic check such feature has completely no sense.
> The only reason of this my request is optimization of preprocessed
> code. In good OO programs instance variables are usually accessed only
> by self or derived classes. Access to foreign variables is not
> recommended (better to use setter/getter methods). In Smalltalk such
> access is not even possible! Now lets see what's happen if I want to
> implement persistence or remoting aspect. The main idea is
> transparently load target object. As far as Java is not
> Smalltalk nobody can prevent programmer from accessing instance
> variable of other objects. So I insert before access to the field
> code performing loading of the object. But for self instance variable
> this code is absolutely useless - self object is already loaded.
> And as far as access to self instance variable happens most frequently
> (in well designed program as I said it is 100%), been not able to
> distinguish self and not-self access cause significant performance and
> byte code size overhead. Concerning your example, I already mentioned
> in my previous mail that exact check (that != this) is not
> needed: I just want to avoid generation of extra code for normally
> accessed instance variables. It will cause completely no problems if value
> of target reference is equal to this.
> 
> Still wonder why nobody else request this feature before - size of
> code and will be significantly decreased and performance - increased
> (not extra method call for each field access). I think that is very
> important for production applications based on AspectJ.
> 
> WI> Assuming the join point signature were changed to include
> WI> an attribute for the invoking reference indicating
> WI> whether it was directly (but explicitly or implicitly)
> WI> via "this", consider
> 
> WI>     class Foo {
> WI>         int i;
> WI>         Bar o;
> WI>         int incBoth(Foo foo) {
> WI>            return (i++ + foo.i++); // foo:foo==this?
> WI>         }
> WI>         int incMe() {
> WI>            return incBoth(this);
> WI>         }
> WI>         int incMeAgain() {
> WI>            Foo me  = this;        // not a join point
> WI>            return incBoth(me);
> WI>         }
> WI>         public String toString() {
> WI>            Bar p = (o == null ? Bar.CONST : o);
> WI>            return p.toString();
> WI>         }
> WI>     }
> 
> WI> If it were supported, it would seem arbitary and
> WI> would hide the real semantics, which are dynamic.
> WI> So to me it looks impractical and more confusing than
> WI> helpful.
> 
> WI> Wes
> 
> WI> P.S. - As for whether this is the right place or whether
> WI> anyone replies to a message, that is all purely consensual.
> WI> No one is obliged to answer anyone's email.  There is
> WI> a general obligation on the part of the committers to
> WI> participate in discussions on aspectj-dev pertaining to
> WI> the *development* of the technology, but aspectj-users is
> WI> for users to communicate with each other.  If people
> WI> require immediate support when writing AspectJ code,
> WI> they can solicit professional support here or on
> WI> aspectj-dev.  (It's generally considered improper for
> WI> those offering support services to solicit people who
> WI> post to mailing lists unless the posters explicitly
> WI> request professional support.)  Also, emails on
> WI> questions that can't be resolved by considering the
> WI> documentation tend to spark more interest, as do emails
> WI> from posters who in the past have contributed correct
> WI> and well- written questions and answers.
> 
> WI> Konstantin Knizhnik wrote:
> 
> >> Hello,
> >> 
> >> Three days ago I have sent the question to this mailing list about
> >> possibility to distinguish access to this and foreign
> >> objects with AspectJ pointcuts. I received no replies to my message.
> >> I wonder if this mailing list is the right place for asking such
> >> questions? Its it really checked by Aspect-J developers?
> >> 
> >> I briefly repeat my message here. To be able to efficiently implement
> >> persistence and remoting aspects, it will be very useful to be able to
> >> distinguish access to self instance fields and access to fields of
> >> other objects (non-this access). In last case, such accesses should be
> >> wrapped with advice code which is responsible for object loading.
> >> But there is completely no need to insert such code for access to self
> >> instance variables. Right now I find only one way how to express
> >> correspondent pointcut in AspectJ: comparing result of this() and
> >> target(). But it is translated by AspectJ in runtime check! So it is
> >> in any case impossible to avoid AOP overhead for accessing self
> >> instance fields.
> >> 
> >> Actually what I want to know
> >> 1. Is such feature currently supported by Aspect-J?
> >> 2. If not - what is the reason:
> >> - nobody requested such feature before
> >> - technical problems with implementing this feature (it seems to me
> >> that there are completely no problems)
> >> - some ideological arguments against adding this feature
> >> - this feature will not be used by most of Aspect-J users
> >> - performance is not critical for most of Aspect-J users.
> >> 3. Also are there plans to implement it in 1.2 version of Aspect-J?
> >> 
> 
> WI> _______________________________________________
> WI> aspectj-users mailing list
> WI> aspectj-users@xxxxxxxxxxx
> WI> http://dev.eclipse.org/mailman/listinfo/aspectj-users
> 
> 
> 
> -- 
> Best regards,
>  Konstantin                            mailto:knizhnik@xxxxxxxxx
> 
> _______________________________________________
> aspectj-users mailing list
> aspectj-users@xxxxxxxxxxx
> http://dev.eclipse.org/mailman/listinfo/aspectj-users
> 
> 


Back to the top