[ 
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:
   http://issues.apache.org/jira/secure/Administrators.jspa
-
For more information on JIRA, see:
   http://www.atlassian.com/software/jira

Reply via email to