Skip to main content

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

Hello Ron,

I was really surprised by the result of your test.
I even disassembled class file. And that is what I see here:

void localIsAdvised();
  Code:
   0:   aload_0
   1:   dup
   2:   getfield        #27; //Field x:I
   5:   iconst_1
   6:   iadd
   7:   putfield        #27; //Field x:I
   10:  return

void nonLocalIsAdvised();
  Code:
   0:   getstatic       #18; //Field associate:LDynamicTest;
   3:   dup
   4:   getfield        #27; //Field x:I
   7:   iconst_1
   8:   iadd
   9:   putfield        #27; //Field x:I
   12:  return

void notAdvised();
  Code:
   0:   aload_0
   1:   dup
   2:   getfield        #27; //Field x:I
   5:   iconst_1
   6:   iadd
   7:   putfield        #27; //Field x:I
   10:  return


So none of these methods was modified by AspectJ.
So you just test difference between access to this and non-this
object:) This is result of mistyping in pointcut settingField:
*isAdvised instead of *IsAdvised.
When this bug is fixed code looks likes this:

void localIsAdvised();
  Code:
   0:   aload_0
   1:   dup
   2:   astore_1
   3:   aload_0
   4:   aload_1
   5:   invokestatic    #110; //Method DynamicTest$CheckFieldAccess.ajc$if_0:(LDynamicTest;LDynamicTest;)Z
   8:   ifeq    19
   11:  invokestatic    #102; //Method DynamicTest$CheckFieldAccess.aspectOf:()LDynamicTest$CheckFieldAccess;
   14:  aload_0
   15:  aload_1
   16:  invokevirtual   #106; //Method DynamicTest$CheckFieldAccess.ajc$before$DynamicTest$CheckFieldAccess$543:(LDynamicTest;LDynamicTest;)V
   19:  aload_1
   20:  getfield        #27; //Field x:I
   23:  iconst_1
   24:  iadd
   25:  putfield        #27; //Field x:I
   28:  return

void nonLocalIsAdvised();
  Code:
   0:   getstatic       #18; //Field associate:LDynamicTest;
   3:   dup
   4:   astore_1
   5:   aload_0
   6:   aload_1
   7:   invokestatic    #110; //Method DynamicTest$CheckFieldAccess.ajc$if_0:(LDynamicTest;LDynamicTest;)Z
   10:  ifeq    21
   13:  invokestatic    #102; //Method DynamicTest$CheckFieldAccess.aspectOf:()LDynamicTest$CheckFieldAccess;
   16:  aload_0
   17:  aload_1
   18:  invokevirtual   #106; //Method DynamicTest$CheckFieldAccess.ajc$before$DynamicTest$CheckFieldAccess$543:(LDynamicTest;LDynamicTest;)V
   21:  aload_1
   22:  getfield        #27; //Field x:I
   25:  iconst_1
   26:  iadd
   27:  putfield        #27; //Field x:I
   30:  return

void notAdvised();
  Code:
   0:   aload_0
   1:   dup
   2:   getfield        #27; //Field x:I
   5:   iconst_1
   6:   iadd
   7:   putfield        #27; //Field x:I
   10:  return

You see difference in byte code size? Three times...
Yes, modern CPUs are very fast, memory is very cheap, JVM uses JIT
technology and so it is aslo very fast (but still 10 times slower than
optimized C code). But if the cleverest JVM will have to perform two
method calls instead of one, even at the fastest CPU performance will be two
times worse. Certainly in some cases this difference is not important:
0.001 seconds vs. 0.002 seconds. But there many applications where it is critical
(it is true even for Java applications, I even do not speak about system and realtime software).

Results with corrected test are the following (I reduce number of
iteration 10 times):

C:\Temp>java DynamicTest 100000000
not advised
Elapsed time is 2503
local advised
Elapsed time is 3134
non-local advised
Elapsed time is 4657

Also not so awful. But actually most time in your test is spent in
invocation of run() method. Lets change test a little bit and place
access to the field in the loop:

    void localIsAdvised(int count) {
        for (int i = 0; i < n; i++) {
            x++;
        }
    }

    void nonLocalIsAdvised(int count) {
        for (int i = 0; i < count; i++) {
            associate.x++;
        }
    }

    void notAdvised(int count) {
        for (int i = 0; i < count; i++) {
            x++;
        }
    }


C:\Temp>java DynamicTest 100000000
not advised
Elapsed time is 471
local advised
Elapsed time is 1212
non-local advised
Elapsed time is 2694

So now the difference in performance is more noticeable, right?
3-6 times! Do you still think that this optimization is not important?


Complete version of my patched example is below:

import java.util.Date;

public class DynamicTest {
    private int x;
    private static DynamicTest associate = new DynamicTest();
    private boolean isLoaded = true;

    void localIsAdvised(int count) {
        for (int i = 0; i < count; i++) {
            x++;
        }
    }

    void nonLocalIsAdvised(int count) {
        for (int i = 0; i < count; i++) {
            associate.x++;
        }
    }

    void notAdvised(int count) {
        for (int i = 0; i < count; i++) {
            x++;
        }
    }

    public static void main(String args[]) {
        int count = 10000;
        if (args.length == 1) {
            count = Integer.parseInt(args[0]);
        }

        DynamicTest t = new DynamicTest();
        t.testIt(count);
    }

    private void testIt(final int count) {
        System.out.println("not advised");
        repeat(count, new Runnable() { public void run() { notAdvised(count); } });
        System.out.println("local advised");
        repeat(count, new Runnable() { public void run() { localIsAdvised(count); } });
        System.out.println("non-local advised");
        repeat(count, new Runnable() { public void run() { nonLocalIsAdvised(count); } });
    }

    private void repeat(int count, Runnable r) {
        r.run();
    }

    private static aspect CheckFieldAccess {
        pointcut settingField(DynamicTest targ) : 
            withincode(* *IsAdvised(..)) && get(* DynamicTest.x) && target(targ);

        before(DynamicTest curr, DynamicTest targ) : settingField(targ) && this(curr) && if(curr!=targ) {
            targ.checkLoaded();
        }

        void DynamicTest.checkLoaded() {
            if (!isLoaded) {
                // slow operation
            }
        }
    }

    private static aspect Timing {
        void around() : execution(void DynamicTest.repeat(..)) {
            Date start = new Date();
            proceed();
            Date end = new Date();
            System.err.println("Elapsed time is "+(end.getTime() - start.getTime()));
        }
    }
}





Wednesday, February 4, 2004, 9:35:27 PM, you wrote:

RB> Hi Konstantin,

RB> I now understand why you want to detect foreign field access.
RB> So you really do need to check for whether this == target; the
RB> fact that the field is from the same type doesn't help you
RB> (because you could load one instance of a type but not another).

RB> One thing that's always good to keep in mind when discussing
RB> performance is that modern VM's are _really good_ at optimizing.
RB> In general, one should always ask whether AspectJ needs to perform
RB> an optimization or whether the VM should do it.

RB> With that in mind, I write a small test that measures performance for 3 cases:
RB> 1) a method that isn't ever advised 
RB> 2) a method that is advised with local access (where the
RB> pointcut excludes local access)
RB> 3) a method that is advised with foreign access (where the
RB> pointcut excludes local access)

RB> See the end of this email for the exact code I ran. Using JDK
RB> 1.4.2_01 on my Windows XP laptop here is an example run:

C:\devel\test\perf>>java DynamicTest 1000000000
RB> not advised
RB> Elapsed time is 21280
RB> local advised
RB> Elapsed time is 21281
RB> non-local advised
RB> Elapsed time is 27680

RB> So a modern VM already implements the optimization you want
RB> (in cases where the test result can be resolved statically - *).
RB> In other words, implementing an AspectJ optimization wouldn't
RB> actually improve performance! Now I can see benefits for
RB> implementing the optimization (e.g., more accuracy in identifying
RB> where advice runs for tools, smaller bytecode, and even better
RB> performance on old VMs). But I think for many uses the current
RB> AspectJ support would be helpful.

RB> A couple of other quick notes:
RB> - the getField() pointcut you described works for me. You can write:
RB> aspect Persistence {
RB>   public interface Persistent {}
RB>   declare parents: com.example..impl.* implements Persistent;

RB>   pointcut getField(): get(!transient !static Persistent+ *.*);
RB>   // ...
RB> }
RB> Are you having problems defining Persistent? You can define
RB> this as a marker interface and use declare parents to denote what
RB> classes are persistent. The only case where I can see this causing
RB> problems is if you would like to persist third party classes. Is
RB> this why you said this pointcut isn't accepted by AspectJ!?

RB> Test Code:

RB> DynamicTest.java:
RB> import java.util.Date;

RB> public class DynamicTest {
RB>     private int x;
RB>     private static DynamicTest associate = new DynamicTest();
RB>     private boolean isLoaded = true;

RB>     void localIsAdvised() {
RB>         x++;
RB>     }pointcut settingField
RB>     void nonLocalIsAdvised() {
RB>         associate.x++;
RB>     }

RB>     void notAdvised() {
RB>         x++;
RB>     }

RB>     public static void main(String args[]) {
RB> 	int count = 10000;
RB> 	if (args.length == 1) {
RB> 	    count = Integer.parseInt(args[0]);
RB> 	}

RB> 	DynamicTest t = new DynamicTest();
RB> 	t.testIt(count);
RB>     }

RB>     private void testIt(int count) {
RB> 	System.out.println("not advised");
RB> 	repeat(count, new Runnable() { public void run() { notAdvised(); } });
RB> 	System.out.println("local advised");
RB> 	repeat(count, new Runnable() { public void run() { localIsAdvised(); } });
RB> 	System.out.println("non-local advised");
RB> 	repeat(count, new Runnable() { public void run() { nonLocalIsAdvised(); } });
RB>     }

RB>     private void repeat(int count, Runnable r) {
RB>         for (int i=0; i<count; i++) {
RB> 	    r.run();
RB> 	}
RB>     }

RB>     private static aspect CheckFieldAccess {
RB> 	pointcut settingField(DynamicTest targ) : 
RB> 	    withincode(* *isAdvised()) && get(* DynamicTest.x) && target(targ);

RB> 	before(DynamicTest curr, DynamicTest targ) :
RB> settingField(targ) && this(curr) && if(curr!=targ) {
RB> 	    targ.checkLoaded();
RB> 	}

RB> 	void DynamicTest.checkLoaded() {
RB> 	    if (!isLoaded) {
RB> 		// slow operation
RB> 	    }
RB> 	}
RB>     }

RB>     private static aspect Timing {
RB> 	void around() : execution(void DynamicTest.repeat(..)) {
RB> 	    Date start = new Date();
RB> 	    proceed();
RB> 	    Date end = new Date();
RB> 	    System.err.println("Elapsed time is "+(end.getTime() - start.getTime()));
RB> 	}
RB>     }
RB> }


RB> Ron

RB> * - as Wes notes, you can't always statically determine whether this==target

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

>> ------------Original Message------------
>> From: Konstantin Knizhnik <knizhnik@xxxxxxxxx>
>> To: Ron Bodkin <aspectj-users@xxxxxxxxxxx>
>> Date: Tue, Feb-3-2004 7:35 AM
>> Subject: Re[4]: [aspectj-users] Once again aboutn non-this access
>> 
>> Hello Ron,
>> 
>> Monday, February 2, 2004, 3:42:08 AM, you wrote:
>> 
>> RB> Hi Konstantin,
>> 
>> RB> I'd like to step back to look at your requirements. I gather
>> RB> you are trying to implement lazy loading, i.e, to detect object
>> RB> instances that haven't been loaded so you can load them on demand.
>> RB> Is that right?
>> 
>> Yes, you are right: object will be loaded on demand.
>> 
>> RB> If so, then you need a mechanism that checks field accesses
>> RB> (and accesses to a member of a collection!) to see whether these
>> RB> objects are loaded or not. In general, this has to be a dynamic
>> RB> test (with the exception of types that are loaded by value such as
>> RB> primitives). Consider:
>> 
>> RB> public class Tree {
>> RB>     private Tree parent;
>> RB>     private Collection children;
>> RB> ...
>> RB> }
>> 
>> RB> The persistence implementation should allow parent or any
>> RB> member of children to be lazily loaded. But both parent and the
>> RB> members of children are instances of Tree. So you really need a
>> RB> dynamic check for these accesses: the referred to instance might
>> RB> not be loaded, even though parent is a field on Tree and Tree is
>> RB> loaded. There are several approaches to implementing this kind of
>> RB> test (either proxies or dynamic tests), but describing the various
>> RB> options and how AspectJ can support them is too much detail for
>> RB> this email.
>> 
>> 
>> Certainly dynamic check is always needed to check whether object is
>> loaded or not. There is only one case when I do not need to perform
>> this checking - and actually it is most commonly used case: access to
>> self instance variables. Because in any case object is already
>> loaded.
>> 
>> RB> So I don't see how your original request will solve this
>> RB> problem.
>> 
>> Ok, I will try to briefly explain how lazy object loading was
>> implemented for my GOODS database (using my own bytecode preprocessor)
>> and for Perst using JAssist. First of all some introduction:
>> 
>> 1. Each persistent object has object identifier (OID) - integer number
>> allowing to uniquely identify object within storage.
>> 2. When object is loaded, it is obvious how to assign values to
>> scalar and string components of the object. But there are two possible
>> ways of representing references to other persistent objects.
>> Since Java is safe language with static type checking,
>> reference field can refer only to the object which type is the same or
>> derived from the type of the field.
>> - So we can store OID of referenced
>>   object somewhere also and store null in reference field (in this case
>>   we trap access to the field and load it on demand).
>> - Or we can create stub object which type is the same as real type of
>>   referenced object which which fields are not loaded yet.
>> 
>> Both approaches has their advantages and disadvantages.
>> I prefer second approach.
>> 3. Persistent object has load() method which checks if object is
>> already loaded and id not - loads its fields (I want to remember that
>> we use second case)
>> 
>> 
>> Now how to implement transparent persistency with this model:
>> 1. At the beginning of each instance method we insert load() method.
>> So it will ensure that object is loaded.
>> If access to the fields of "foreign" (non-this) objects is not
>> allowed (it is assumed that setter/getter methods are used instead),
>> then this is all we need. We should not insert any extra code or do
>> extra checks - fields of this object can be always accessed without
>> any extra overhead.
>> 2. If access to foreign object fields is allowed, then before
>> each such access we should invoke load() method for target object.
>> 3. To be able to detect modified objects, before each assignment to the field
>> modify() method should be called (it is also possible to call it after
>> update).
>> 
>> Unfortunately (as I already told), it is not possible to implement
>> this scenario with AspectJ - it doesn't allow to distinguish this and
>> non-this access. Alternative solution is to be able tot detect access
>> to reference fields (so we insert load method for each access to
>> reference field). Number of invoked load() method with this approach
>> is the same as with my approach. But size of code is larger - because
>> in my apporach load() is inserted only in one place - in method body,
>> and in this approach - in each access to the method or field.
>> Also in this case check for null should be done before invocation of
>> laod() method.
>> 
>> But I also do not know how to implement this approach with AspectJ.
>> It requires definition of pointcut like this:
>> 
>> getField(): get(!transient !static Persistent+ *.*);
>> 
>> (it means access to all fields referencing persistent objects).
>> But such pointcut is not accepted by AspectJ.
>> 
>> 
>> All other approaches requires insertion of AspectJ code before (or
>> after) each field access. Since OO program used to access fields very
>> frequently (there are even recommendations to avoid use of local
>> variables because them makes refactoring more difficult), size of the
>> program is significantly increased after such preprocessing and speed
>> - significantly decreased. I think that AOP should be not just a toy
>> or facility for debugging and adding trace messages to your application,
>> but really powerful system, which can provide performance compatible (or
>> even better) than alternative solutions. In case of persistence or
>> remoting aspects alternative solution is to load object explicitly.
>> That is why I think that such optimization is absolutely needed.
>> 
>> 
>> 
>> RB> But implementing the request does raise some interesting
>> RB> points in their own right. So I'll also address the topics of
>> RB> optimization, a pointcut that expresses the test that you said you
>> RB> wanted, and how this might be enabled by future versions of the
>> RB> AspectJ language.
>> 
>> RB> 1. I would like to see more optimization of the this and
>> RB> target pointcut descriptors. There are several cases where the
>> RB> emitted bytecode performs runtime checks that can be proven to be
>> RB> true or false in all cases. 
>> 
>> RB> I'd like to see is an optimization of this(Type) (or
>> RB> this(var) where var is of Type), which the compiler can always
>> RB> resolve to be true or false at compile-time. This results in code
>> RB> that may or may not be optimized away by the VM (JIT). I'd most
>> RB> like to see this optimization to improve the accuracy of the tools
>> RB> support (which currently identifies too many places as advised). I
>> RB> believe AspectJ 1.0.x did have this optimization.
>> 
>> RB> There are several possible optimizations in emitted bytecode
>> RB> that it would be desirable for the AspectJ compiler to implement.
>> RB> But I think the team's current emphasis on making the compiler
>> RB> reliable, scalable, and fast is the right priority.
>> 
>> RB> 2. I personally don't think adding special case logic to say
>> RB> "access to a foreign field" is common enough to warrant a special
>> RB> case language extension, and as I will explain below, what you
>> RB> 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):
>> 
>> RB> for all types T:
>> RB> for any supertype S of T:
>> RB>   pointcut externalGet(T t) : 
>> RB>       this(t) && get(* *.*) && !get(* S.*);
>> 
>> RB> If AspectJ had my proposed type pattern for a type or its supertypes (-), this
>> RB> would reduce to:
>> RB> for all types T:
>> RB>   pointcut externalGet(T t) : 
>> RB>       this(t) && get(* *.*) && !get(* T-.*);
>> 
>> RB> An alternative version (that would also work for static fields) is:
>> RB> for all types T:
>> RB>   pointcut externalGet() : 
>> RB>       // access to a field from any jp within type T or a parent type...
>> RB>       (within(T-) || 
>> RB>       // or from any ITD's defined on T or a parent type
>> RB>        withincode(* T-.*(..)) || withincode(* T-.new(..))) && 
>> RB>       get(* *.*) && !get(* T-.*);
>> 
>> RB> For implementing object persistence, you probably don't care about static fields...
>> 
>> RB> It _is_ feasible to write a special case of this pointcut for
>> RB> a single type in AspectJ (just plug in the appropriate value of T
>> RB> and expand to include T and ALL its supertypes). 
>> 
>> RB> But AspectJ doesn't currently offer a way to quantify over
>> RB> types like this at compile-time. Unfortunately, I don't believe
>> RB> even the proposed pertype aspect would help here. 
>> 
>> RB> I am hoping that when AspectJ supports generics, it will be
>> RB> possible to express this kind of pointcut, e.g.,
>> RB>   pointcut <T> externalGet(T t) : 
>> RB>       this(t) && get(* *.*) && !get(* T-.*);
>> RB>   after <T> (T t) returning: externalGet(t) {
>> RB>       t.dirty = true;
>> RB>   }
>> 
>> RB> I believe that advice for this pointcut could still be
>> RB> implemented as a method through type erasure (i.e., it wouldn't
>> RB> require macro expansion), though I don't have a fully developed
>> RB> proposal for how AspectJ should handle generics. (as an aside 
>> 
>> RB> So hopefully AspectJ will grow into solving your stated design by
>> RB> 1) defining generics support that will capture it
>> RB> 2) adopting my proposal for using T- for a type and all its supertypes
>> RB> 3) possibly optimizing the code for this() tests. But note
>> RB> that if we have #1 and #2, optimizing this isn't even necessary
>> RB> (using the within version of the pointcut will be optimized!)
>> 
>> RB> Although I don't see how detecting foreign field access helps
>> RB> with persistence or remote object invocation.
>> 
>> RB> Ron
>> 
>> RB> Ron Bodkin
>> RB> Chief Technology Officer
>> RB> New Aspects of Software
>> RB> 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
>> >> 
>> >> 
>> RB> _______________________________________________
>> RB> aspectj-users mailing list
>> RB> aspectj-users@xxxxxxxxxxx
>> RB> 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
>> 
>> 
RB> _______________________________________________
RB> aspectj-users mailing list
RB> aspectj-users@xxxxxxxxxxx
RB> http://dev.eclipse.org/mailman/listinfo/aspectj-users



-- 
Best regards,
 Konstantin                            mailto:knizhnik@xxxxxxxxx



Back to the top