db-derby-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Daniel John Debrunner (JIRA)" <derby-...@db.apache.org>
Subject [jira] Commented: (DERBY-739) Reduce generated code required to access a parameter's value
Date Thu, 01 Dec 2005 22:36:31 GMT
    [ http://issues.apache.org/jira/browse/DERBY-739?page=comments#action_12359091 ] 

Daniel John Debrunner commented on DERBY-739:

Not sure exactly what you are asking, but I'll tell you what I did.

Given the information you had provided, I assumed the query was generating a method that was
too big for the class file format in some way.
[this could be a wrong assumption, maybe it's really a bug in the jump offset calculation]

De-compiled the class with javap, which comes with a JDK. Javap decompiles the class into
bytecode, not Java source code. I think this tends to be ok because Derby's query nodes are
basically writing at the byte code level. If you try to convert a generated class back into
Java source there's a good chance it will fail. Javap also seems to not require other classes
in the class path, it just takes the class contents and dumps it.

javap -private -c -classpath . org.apache.derby.exe.ac601a400fx0107xe7aaxc957x0000001ac9880

You can also use the JVM as you did to get some idea of the verifier error.
java -verify -classpath ".;../classes" org.apache.derby.exe.ac601a400fx0107xe7aaxc957x0000001ac9880

While looking at the class I saw some code I didn't understand and thus I investigated. This
was the multiple calls to setStorableDataValue() that were passing "java.lang.Integer". It
seemed strange to me that type information was being passed as a runtime value.

After finding the source for setStorableDataValue (using Eclipse),  I then searched for *generated*
callers of  setStorableDataValue. Since these will not appear in Eclipse's Java method references
search, I always search for the method name in double quotes. "setStorableDataValue". This
is how the method name is usually passed into the byte code compiler by the query nodes, ie
a String in Java code. This took me to the only caller, ParameterNode, and from there I could
see when & why it was being called.

Then seeing there were 360+ parameters in the SQL statement I thought let's see how a parameter
is accessed in the generated code, because every byte saving there is going to be multipled
by 360+. So that lead to this task.

A similar exercise could be taken for column reference, since there are also 360 of those.
Any way to make the corresponding node generate less code will be multipled 360 times, and
then for AND and OR nodes and any other nodes repeated in the query.

These tend to be simple fixes, as they are small contained improvements, and thus have a small
pay-back. E.g. fixing parameter node and column reference node might allow this specific query
to succeed, but the underlying problem would still be there , and a similar query with a couple
more of the repeated lines may fail. The good thing is that these small fixes are good in
themselves, even if they are not solving the more generic problem.

I actually thought I would start looking at seeing how the compilation system could generic
the code for '(ITEMID=? AND VERSIONID=?)' once and re-use for all the repeated uses. But I
got distracted by the low-hanging fruit.

I'm still thinking about how to be able to compile similar blocks once and re-use them, not
sure if it would be best at the language level, or handle it at the byte code level. 

> Reduce generated code required to access a parameter's value
> ------------------------------------------------------------
>          Key: DERBY-739
>          URL: http://issues.apache.org/jira/browse/DERBY-739
>      Project: Derby
>         Type: Sub-task
>     Reporter: Daniel John Debrunner
>     Assignee: Kathey Marsden
>     Priority: Minor

> When accessing a parameter the generated code is:
> this.pvs.getParameter(23);
> A slightly shorter form would be
> this.getParameter(23);
> if a getParameter() method was added to BaseActivation that simply did:
>  protected final DataValueDescriptor getParameter(int n) { return pvs.getParameter(n);
> ------------------------------
> An interesting separate idea, to reduce the number of constant pool entries would be
to have multiple getParameter() methods, that took values from 0-5 to construct the actual
parameter number.
> getParameter(3) -- >  3 parameter (0 based)
> getParameter(2, 1) --> 13 parameter (2*6 + 1)
> getParameter(5, 1, 4) --> 190 parameter (5*36 + 1*6+ 4)
> above the limit of three args, revert to getParameter(n)
> This should probably be a separate issue and probably would increease code size which
would not help DERBY-732 , it's a tradeoff between constant pool entries and code size.

This message is automatically generated by JIRA.
If you think it was sent incorrectly contact one of the administrators:
For more information on JIRA, see:

View raw message