Re: Re: [newbie] access question
Chris Uzdavinis <[email protected]>
| Newsgroups | gmane.comp.java.objectweb.asm |
|---|---|
| Message-ID | <[email protected]> |
Hi, Thanks for your reply (as I was starting to doubt if I'd get one at all.) But would you mind helping me with my problem? Question: How do you generate code that down-casts an object to an arbitrary, user-provided type--even if that type is private? Currently, when I generate code that does a downcast to an arbitrary type, it works for public types, but gets a runtime exception if the type is private (since the generated code does not have access to the type.) If you could help me do this, I'd be very grateful. Thanks again, Chris PS, I appreciate the fact that you question the value of my optimization, as trying to out-do an optimizing compiler usually is one of those things that shows a certain naiveté. If the roles were reversed, I'd probably question you on it too. However, this is not wishful thinking, or some theoretical fantasy. I _already_ have a working implementation of the optimization I described that has significant, measurable benefit in both contrived benchmarks as well as in my real-world application. The problem with it is not "if it works", but "how to make it work with private types." On Sun, Nov 21, 2010 at 2:24 AM, Tronje Krop <[email protected]> wrote: > Why don't you want to let the JIT compiler decide whether to unrole > or not unrole your code? As I see it, this should happen authomatically > for some time: > > http://java.sun.com/products/hotspot/docs/whitepaper/Java_HotSpot_WP_Final_4_30_01.html > > If the size of the array is known and final on first execution it should > run as expected. > > Best regards > > Tronje > > [email protected] wrote: >> Hi, >> >> I'm fairly new to ASM, bytecode, and reflection in java. However, >> I've successfully written my first ASM project and am quite happy with >> it... except for one access-related problem that I'm not sure how to >> fix. >> >> The situation: >> >> interface Callback >> { >> void doSomething(); >> } >> >> class Impl1 implements Callback { ... } >> class Impl2 implements Callback { ... } >> >> Suppose I have an array of N Callback objects I want to invoke: >> >> final Callback[] cbs = { new Impl1(), new Impl1(), new Impl2(), new Impl2() >> }; >> ... >> >> // Works, but can be optimized >> for (Callback cb : cbs) >> { >> cb.doSomething(); >> } >> >> Due to the special case of the array being setup at program start, and >> never changing, there is an opportunity for optimization to unroll the >> loop and call doSomething() directly on the objects sequentially, also >> in a way that allows the JIT compiler to de-virtualize the calls. >> >> I've generated a class using ASM that does just this. The generated >> code is equivalent to this: >> >> class DelegateCallbacks implements Callback >> { >> private final Impl1 delegate0; >> private final Impl1 delegate1; >> private final Impl2 delegate2; >> private final Impl2 delegate3; >> >> public DelegateCallbacks(Object[] objects) { >> delegate0 = (Impl1) objects[0]; >> delegate1 = (Impl1) objects[1]; >> delegate2 = (Impl1) objects[2]; >> delegate3 = (Impl1) objects[3]; >> } >> >> @Override public void doSomething() { >> delegate0.doSomething(); >> delegate1.doSomething(); >> delegate2.doSomething(); >> delegate3.doSomething(); >> } >> } >> >> Now instead of writing the for loop, I just generate this optimized >> unrolled class and instantiate it with my array. >> >> >> >> The problem arises when the most derived type of the object happens to >> be private or protected, then my generated class receives a >> java.lang.reflect.InvocationTargetException when its constructor >> executes, presumably at the point at which I do the downcast from >> Object to initialize the member. >> >> Here is some of the code that helps generate my class constructor. >> I'm using a GeneratorAdapter to help write the constructor. >> >> ... >> final GeneratorAdapter ga = new GeneratorAdapter(Opcodes.ACC_PUBLIC, >> myMethod, null, null, cw); >> ... (stuff omitted) >> // downcast & initialize the member variable with delegate >> ga.checkCast(delegateType); >> ga.putField(myType, delegateExternalName, delegateType); >> >> ... >> >> for (int i = 0; i < numDelegates; ++i) >> { >> final Type delegateType = Type.getType(delegateDescriptor(i)); >> ga.newLabel(); >> ga.loadThis(); >> ga.loadArg(0); // push delegates array >> ga.push(i); // push index into delegates array >> ga.arrayLoad(delegateType); // get the current delegate object >> >> // initialize the member variable with delegate >> ga.checkCast(delegateType); >> ga.putField(classType, delegateExternalName(i), delegateType); >> } >> >> ga.returnValue(); >> ga.endMethod(); >> >> >> At the point where I call checkCast, it is there (I imagine) that the >> exception is originating. >> >> I think this problem has two parts for my understanding. >> >> 1) Java reflection makes it easy to change access for fields and >> methods since they extend the java.lang.reflect.AccessibleObject, >> but this is a *class*_ (not just a member/method of a class), and I >> don't know how to modify access to it. If it's not really simple, >> a pointer to documention on this would be most appreciated. >> >> 2) If it is possible to tweak the class access, do I have to do it in >> the generated code? If so, could anyone give me a hand on doing so >> in ASM? >> >> I'm wondering if I'm going to have to do something like this: >> >> ga.<emit code to remember old access to class of delegate type> >> ga.<emit code to make class of delegate accessible> >> ga.checkCast(delegateType); >> ga.putField(myType, delegateExternalName, delegateType); >> ga.<emit code to return access of delegate class back to what it was> >> >> >> Is this the right approach? I suppose the <emit> sections could possibly >> be implemented in regular java code, and I only have to generate ASM code >> to call those functions. >> >> But still, I'm kind of not sure how to proceed. >> >> Thanks! >> >> >> Chris >> > > -- > Tronje Krop <[email protected]> > > Encrypted eMail welcome! GPG/PGP-Key: 0x9AD43A05 > 68E5 A3D3 75A0 B096 AC75 62D5 8EEE 3D18 9AD4 3A05 > > No responsibility is taken for the correctness of the > previous information. Please delete if you receive this > mail unintentional. > > > -- > You receive this message as a subscriber of the [email protected] mailing list. > To unsubscribe: mailto:[email protected] > For general help: mailto:[email protected]?subject=help > OW2 mailing lists service home page: http://www.ow2.org/wws > >
message-footer.txt
(text/plain, 238 B)
-- You receive this message as a subscriber of the [email protected] mailing list. To unsubscribe: mailto:[email protected] For general help: mailto:[email protected]?subject=help OW2 mailing lists service home page: http://www.ow2.org/wws