Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Language IDEs » Objectteams » Simple detail questions(Some detailed questions about implementation stuff)
Simple detail questions [message #1751087] Wed, 04 January 2017 11:52 Go to next message
Lars Schütze is currently offline Lars SchützeFriend
Messages: 43
Registered: March 2012
Location: Germany
Member

Hi,

I have browsed through the source code to get a glimpse of how things are implemented. Thereby I found some things that make me question myself.

I am working on the Neon branch maintenance/OTDT_2.5.x.

1) CreateDispatchCodeInCallAllBindingsAdapter::getBoxedArguments() -- line 74

instructions.add(new IntInsnNode(Opcodes.ALOAD, 2));

The ASM documentation says, that for IntInsnNode the Opcode must be either BIPUSH, SIPUSH or NEWARRAY, but ALOAD is used. Here ALOAD is used which loads a local variable reference. Is this a trick to shorten the byte code as I understand that the local variable will be directly casted into an int? This has been done a lot in the OT/J codebase. Even to load "this". And when I search for how people use this I always see they use VarInsnNode(Opcode.ALOAD, 0) (etc).

2) ObjectTeamsTransformer::transform() -- line 78 - 88

if (!weavingContext.isWeavable(sourceClassName) || loader == null) {
if (clazz != null) {
if (isWeavable(className) && clazz.needsWeaving()) {
// only print out for now, exceptions thrown by us are silently caught by TransformerManager.
new LinkageError("Classs "+className+" requires weaving, but is not weavable!").printStackTrace();
} else {
clazz.markAsUnweavable(); // mark in case we'll try to weave later
}
}
return null;
}

The error message says that the class needs weaving, but is not weave-able. Is this due to loader is null? Or, due isWeavable(className) returns false? In this case, a negation is missing (as not weaveable + needsWeaving contradicts).

3) Overall understanding.

The joinpointId is a global unique Id which identifies every possible join point for the advices.
The callinId is a per binding identifier unique inside a team. It identifies a specific binding to a methodId.

The (bound) methodId is a per Class (and its subclasses) unique Id identifying the class methods. As I see in the implementation it is a String of the class + method name + signature. Now, the joinpointIdentifier (which will be mapped to an integer at runtime) is the class name + method name + signature. So, for an AbstractBoundClass c, and a Method m: c.getMethodIdentifier(m) returns the same as m.getGlobalId(c).

By all these id definitions it could be I get some of them wrong?! So, I am asking what is the real difference between bound method id and join point identifier (the string). I see the load time compiler could already determine the joint point ids. So these do not need to be constructed at "runtime". At runtime these strings are often recomputed (as they are concatenated). I see that all this ID construction and bookkeeping is something crucial to runtime performance (and heap pressure).

4) Maven

The current provided Maven version does not work. I think there is a bug report about that because the compiler does not compile OTJ specific stuff.
How about to mavenize the whole build process, so one could actually work on using JMH to identify more problems? And even automate much more of the jar generation part. So for local testing a simple mvn install would suffice to use a new build local version in depending projects.

5) Some comments

The source level could be taken to Java 8 as Eclipse and JDT already require Java 8. The ASM library could be upgraded to ASM 5.2 (released 23rd Dec 16).

6) Compiler

Is there anything like compiler phases where one can hook in in order to add optimisations (e.g., on the AST)? I think it will currently just try to make the best Java code out of the OTJ code (which is already a good junk of work to do, no doubt).

Best regards,
Lars

[Updated on: Tue, 10 January 2017 14:17]

Report message to a moderator

Re: Simple detail questions [message #1751328 is a reply to message #1751087] Sun, 08 January 2017 22:12 Go to previous messageGo to next message
Stephan Herrmann is currently offline Stephan HerrmannFriend
Messages: 1636
Registered: July 2009
Senior Member
Sorry for the delay. To get started I will answer one item at a time Smile

Quote:
1) CreateDispatchCodeInCallAllBindingsAdapter::getBoxedArguments() -- line 74

instructions.add(new IntInsnNode(Opcodes.ALOAD, 2));

The ASM documentation says, that for IntInsnNode the Opcode must be either BIPUSH, SIPUSH or NEWARRAY, but ALOAD is used. Here ALOAD is used which loads a local variable reference. Is this a trick to shorten the byte code as I understand that the local variable will be directly casted into an int? This has been done a lot in the OT/J codebase. Even to load "this". And when I search for how people use this I always see they use VarInsnNode(Opcode.ALOAD, 0) (etc).


Thanks. This was a simple oversight, i.e., usage of an API without actually reading the contract. I fixed it in HEAD and running all our tests it seems it changed: nothing Razz
Commit is http://git.eclipse.org/c/objectteams/org.eclipse.objectteams.git/commit/?id=4d78510cea0020757257062711a087cfe3111346

Stephan
Re: Simple detail questions [message #1758454 is a reply to message #1751328] Tue, 28 March 2017 19:36 Go to previous messageGo to next message
Stephan Herrmann is currently offline Stephan HerrmannFriend
Messages: 1636
Registered: July 2009
Senior Member
Slowly catching up on pending questions:

Quote:
2) ObjectTeamsTransformer::transform() -- line 78 - 88

if (!weavingContext.isWeavable(sourceClassName) || loader == null) {
if (clazz != null) {
if (isWeavable(className) && clazz.needsWeaving()) {
// only print out for now, exceptions thrown by us are silently caught by TransformerManager.
new LinkageError("Classs "+className+" requires weaving, but is not weavable!").printStackTrace();
} else {
clazz.markAsUnweavable(); // mark in case we'll try to weave later
}
}
return null;
}

The error message says that the class needs weaving, but is not weave-able. Is this due to loader is null? Or, due isWeavable(className) returns false? In this case, a negation is missing (as not weaveable + needsWeaving contradicts).


Several factors to consider:


  1. weavingContext.isWeavable() excludes some primordial classes from packages like java.lang, org.objectteams, org.objectweb.asm, which technically fall outside the scope of weavable classes
  2. weavingContext.isWeavable() may also use a file specified via -Dot.weavable which defines "weavable regions" (useful for admitting runtime weaving for certain parts of an application only)
  3. ObjectTeamsTransformer.isWeavable() is identical to the first item, by rechecking we restrict any subsequent error reporting to classes that could in principal be woven.
  4. clazz.needsWeaving() expresses requests from the class, due to actual bindings (callin or callout with decapsulation) that require weaving of this class. Basic weaving is performed even if needsWeaving() answers false, because "baseness" of a class may be detected much later of it is loaded.


Now the LinkageError is raised when

  • Either the loader is null, or the class falls outside the weavable regions (ot.weavable),
  • And, the class is affected by (callin/callout) bindings


makes sense?
Stephan


Re: Simple detail questions [message #1758456 is a reply to message #1751087] Tue, 28 March 2017 20:07 Go to previous messageGo to next message
Stephan Herrmann is currently offline Stephan HerrmannFriend
Messages: 1636
Registered: July 2009
Senior Member
Some more in bulk:

Lars Schuetze wrote on Wed, 04 January 2017 12:52

3) Overall understanding.

The joinpointId is a global unique Id which identifies every possible join point for the advices.
The callinId is a per binding identifier unique inside a team. It identifies a specific binding to a methodId.


I understand the relevance, but I'll skip this one for now, since this is quite complex material. Only one hint: essential differences are the scopes in which these ids need to be unique. Some need to be globally unique, some are scoped to one inheritance hierarchy etc.

Quote:

4) Maven

The current provided Maven version does not work. I think there is a bug report about that because the compiler does not compile OTJ specific stuff.
How about to mavenize the whole build process, so one could actually work on using JMH to identify more problems? And even automate much more of the jar generation part. So for local testing a simple mvn install would suffice to use a new build local version in depending projects.


Some day, perhaps, but not today. In the past, creating the full production build for OTDT was a HUGE effort, moving it from University servers to Eclipse.org was a matter of several weeks. Moving it from manual invocation to Hudson still was a matter of some days. Things are getting smoother every cycle, but migrating to Maven for all of the build is a different story.

Besides, I'm known for triggering every d*** bug in Maven ;-p

So for now I'm quite happy with the PDE based build.

Quote:

5) Some comments

The source level could be taken to Java 8 as Eclipse and JDT already require Java 8. The ASM library could be upgraded to ASM 5.2 (released 23rd Dec 16).

Java 8, yes. ASM 5.2 needs to be available in Orbit before we can consume it (not sure if anyone has started the process).
Similarly, I was going to revive the traditional OTRE with BCEL 6, but didn't have the energy to bring that to orbit (plus: lack of stackmap generator doesn't make this a very inviting option).

Quote:

6) Compiler

Is there anything like compiler phases where one can hook in in order to add optimisations (e.g., on the AST)? I think it will currently just try to make the best Java code out of the OTJ code (which is already a good junk of work to do, no doubt).


When you look at the compiler code, you'll see a class Dependencies which restructures compilation vs. original JDT exactly for the purpose of adding additional compilation phases. See ITranslationStates for details. If you want to play with changing the AST, the main question would probably be: do you want to do this before or after resolving? After resolving you have more information at hand, but you are also responsible for leaving the AST in a fully resolved state, ie., when creating new nodes you have to manually attach bindings etc.

Stephan

PS: In the future don't feel shy to remind me of unanswered questions (Hint, this thread still contains one Smile ).
Re: Simple detail questions [message #1759191 is a reply to message #1758456] Fri, 07 April 2017 13:31 Go to previous message
Lars Schütze is currently offline Lars SchützeFriend
Messages: 43
Registered: March 2012
Location: Germany
Member

For objectteams.asm 5.1.0 is available with Orbit for Oxygen M5 and 5.2.0 with Orbit for Oxygen M6. The contact is named Evgeny Mandrikov.
I see you did not answered 3. But I'll take again a look in the diploma thesis of 2009 where the dynamic binding mechanism is described. I think the concept and its implementation will not differ that much. There I can work an overview out of this.

For 6 I need to take a look. Thanks for the pointer.

Thanks for your feedback anyway. I was checking the forum every there and then. Smile
Previous Topic:OTDT in Neon.3
Next Topic:Arriving: OTDT 2.6.0
Goto Forum:
  


Current Time: Wed Oct 24 00:24:26 GMT 2018

Powered by FUDForum. Page generated in 0.02483 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software

Back to the top