LucidDB / luciddb

DEFUNCT: See README
https://github.com/LucidDB/luciddb
Apache License 2.0
53 stars 24 forks source link

[FRG-295] MDR code generation does not correctly handle more than 4 long or double attributes #577

Open dynamobi-build opened 12 years ago

dynamobi-build commented 12 years ago

[reporter="stephan", created="Tue, 25 Sep 2007 15:34:51 -0500 (GMT-05:00)"] The current version of Netbeans MDR libraries has a code generation bug.

If more than 5 attributes with type Long or Double and multiplicity 1 exist in a single class (including super classes), the code generation fails because the generated method _createInstance(Object[]) does not compensate for the fact that double and long primitives take up two JVM operand stack slots a piece. With exactly 5 such attributes, the code generation fails intermittently.

Need to take the following actions:

1) Short Term: modify net.sf.farrago.catalog.codegen.FactoryGen to detect the cases that causes errors and fail with a useful error message.
2) Long Term: resurrect a buildable version of MDR and fix the bug

dynamobi-build commented 12 years ago

[author="stephan", created="Tue, 25 Sep 2007 15:35:46 -0500 (GMT-05:00)"] A more detailed description of the problem.

-----Original Message-----
From: Stephan Zuercher
Sent: Tue 9/25/2007 11:14 AM
To: John Sichi
Subject: Re: createCatalogRepository
 
Okay, the reason switching to [0..1] helps is that it causes the
interfaces to use java.lang.Long vs. primitive long. A java.lang.Long
takes a single operand stack slot (it's just a reference like any
other), but primitive longs take two slots. This eats into the 6 slot
buffer and if you have enough of them in your class's hierarcy, you'll
get the VerifyError.

If I write out the byte code for FemCmdVerifyIndex's _createInstance,
assuming that super class attributes come before their child's
attributes and that attributes are ordered within a class, then I should
never see the error. However, if I scramble the order and the last
attribute is not a primitive type, then my class exceeds the max stack
by 1 slot. Basically each primitive type increases the number of
operand stack slots used by 1 (or 2 if a long or double). Each
non-primitive type increases the operand stack slots used by 1, but
temporarily uses a 2nd slot.

So, with up to 4 primitive longs or doubles there's no problem. With 5,
the error appears randomly. With 6 it should always appear.

In any event, switching my result attributes to Long[0..1] will take
care of the problem: the class will have only 3 primitive longs.

Will note this limitation on the wiki. Is there a good place to add a
check for this during catalog creation? May as well prevent the error
until we fix it for real.

Stephan

dynamobi-build commented 12 years ago

[author="stephan", created="Tue, 25 Sep 2007 15:36:56 -0500 (GMT-05:00)"] Work arounds:

1) Switch one or more long/double attributes to integer/float.
2) Switch multiplicity from 1 to 0..1 (causes a java.lang.Long or java.lang.Double to be used, reducing stack space requirements)
3) Anything that reduces the number of long/double attributes.

dynamobi-build commented 12 years ago

[author="jvs", created="Tue, 25 Sep 2007 15:46:53 -0500 (GMT-05:00)"] Oops...one problem with generateMetadataFactory is that it gets called after writeDTD, which is where the failure currently occurs when it does occur. So the developer will still get a bad error message, though that's better than no error message at all.

dynamobi-build commented 12 years ago

[author="stephan", created="Tue, 25 Sep 2007 21:23:49 -0500 (GMT-05:00)"] Since the VerifyError will appear with 6+ long/double attributes, I'll add the error message here to help anyone who runs into it.

     [java] /home/szuercher/open/farrago/build.xml:537: java.lang.VerifyError: (class: net/sf/farrago/fem/fennel/FemCmdVerifyIndexClass$Impl, method: _createInstance signature: ([Ljava/lang/Object;)Ljavax/jmi/reflect/RefObject;) Stack size too large

dynamobi-build commented 12 years ago

[author="stephan", created="Wed, 26 Sep 2007 11:01:27 -0500 (GMT-05:00)"] Change 9919 (on the //open/lu/dev_lcs branch) adds a test or the condition that causes the error, so the intermittent case won't slip through.

dynamobi-build commented 12 years ago

[author="stephan", created="Fri, 20 Jun 2008 13:09:18 -0500 (GMT-05:00)"] These limitations go away if Enki/Hibernate is in use -- it generates Java source code at build-time. So, if/when Farrago switches completely away from Netbeans (at least as the repository implementation) we can close this bug. Note that we could continue to use Netbeans XMI reader/writer implementations without issue.


Also, Enki is now handling the generation of the JMI interface classes (e.g. FemLocalSchema), so we can add a test for "too many longs or doubles" there and get ahead of the writeDTD error.

dynamobi-build commented 12 years ago

[author="stephan", created="Fri, 6 Feb 2009 13:05:35 -0500 (GMT-05:00)"] The Enki change to detect this condition was never made.


If it's still desirable to add it, it would go in JmiTemplateHandler's generateClassInstance method. Count long and double values with multiplicity.lower == 1 and throw GenerationError if you get to 5.