VerifyError: arbitrarily rejecting large method

Showing 1-5 of 5 messages
VerifyError: arbitrarily rejecting large method MarVel 10/13/10 9:42 AM
Hi,

I'm working on an android application for the analysis of measurements
(e.g, blood pressure) using a Bayesian network model (PEModelOR is the
class in my android application), which is embedded in a smart phone.
Since the measurements are to be taken at sequential times, the model
contains a number of variables referring to different time controls.
With the initial version with 2 controls the model run without a
problem but when I extended the model to 4 controls it crashed
producing the following error:

10-12 16:50:15.291: WARN/dalvikvm(4848): VFY: arbitrarily rejecting
large method (regs=134 count=17618)
10-12 16:50:15.291: WARN/dalvikvm(4848): VFY:  rejected Lcom/example/
pregmonit/PEModelOR;.<init> ()V
10-12 16:50:15.291: WARN/dalvikvm(4848): Verifier rejected class Lcom/
example/pregmonit/PEModelOR;
10-12 16:50:15.311: DEBUG/AndroidRuntime(4848): Shutting down VM
10-12 16:50:15.311: WARN/dalvikvm(4848): threadid=1: thread exiting
with uncaught exception (group=0x40027e08)
10-12 16:50:15.341: ERROR/AndroidRuntime(4848): FATAL EXCEPTION: main
10-12 16:50:15.341: ERROR/AndroidRuntime(4848): java.lang.VerifyError:
com.example.pregmonit.PEModelOR
10-12 16:50:15.341: ERROR/AndroidRuntime(4848):     at
com.example.pregmonit.EBayes.<init>(EBayes.java:20)
10-12 16:50:15.341: ERROR/AndroidRuntime(4848):     at
com.example.pregmonit.EBayes.android_main(EBayes.java:78)
10-12 16:50:15.341: ERROR/AndroidRuntime(4848):     at
com.example.pregmonit.Status.onCreate(Status.java:54)

I saw that in a recent discussion
http://groups.google.com/group/android-developers/browse_thread/thread/2126a73ba0cf7ade
Dirk has encountered the same problem but unfortunately I could not
see any solution to that.
The extended PEModelOR method runs without problems in Java but it
fails in the android application due to the dalvikvm verifier as far
as I understood. The PEModelOR method is a description of a Bayesian
Network in java and it simply contains definition of 62 variables and
62 probability distribution tables (in total 700 lines and the java
file is 41 KB); below is a sample of the code (note that BayesNet is a
class loaded via external jar):

import BayesianNetworks.*;
public class PEModelOR extends BayesNet {
        public PEModelOR() {
        name = "PEModelOR";
......
final DiscreteVariable DB =
new DiscreteVariable ("DB",
DiscreteVariable.CHANCE,
new String[] { "yes","no" });
.......
DiscreteFunction p62=
new DiscreteFunction(
new DiscreteVariable[] {DB},
new DiscreteVariable[] {FHDiab},
new double[] {0.0052, 0.2, 0.9948, 0.8 });
.......

Does the size/definition of PEModelOR cause the problem? I'm not sure
how I can split it as it needs to be loaded at once for creating the
network and running the model with available measurements. The thing
is that this is even not the final version of the model, where the
goal is to have 11 time controls, ending up with 112 variables and
probability tables, and 1245 lines.

Is there a way out or alternative of implementing PEModelOR so that it
does not fail at verification?
I will highly appreciate any help and suggestions on solving this
problem. Thanks a lot in advance.

Cheers, MarVel
Re: VerifyError: arbitrarily rejecting large method DanH 10/13/10 10:50 AM
From my knowledge of other Java verifiers/compilers, it's more the
complexity of the code rather than its absolute size that is likely to
be the problem.  Methods that branch into a lot of parallel paths (big
nested switch statements, eg) will cause problems, and things get
worse if there are a lot of nested exception handler ranges (try-
finally ranges are the worst).

In addition to somehow reducing the width of parallel branching (eg,
by placing inner switch statements in their own methods), if you can
reduce the number of "global" local variables (method local variables
that reach all branch paths) that's likely to help substantially.
> I saw that in a recent discussionhttp://groups.google.com/group/android-developers/browse_thread/threa...
Re: VerifyError: arbitrarily rejecting large method fadden 10/13/10 4:13 PM
On Oct 13, 9:42 am, MarVel <marina.velik...@gmail.com> wrote:
> 10-12 16:50:15.291: WARN/dalvikvm(4848): VFY: arbitrarily rejecting
> large method (regs=134 count=17618)
 ...
> I saw that in a recent discussionhttp://groups.google.com/group/android-developers/browse_thread/threa...
> Dirk has encountered the same problem but unfortunately I could not
> see any solution to that.

This test is going away in a future release.

The method has 17,618 instructions, and requires 134 registers.  Both
of these are on the "large" side.  If you can find a way to break the
method into pieces that should help.
Re: VerifyError: arbitrarily rejecting large method MarVel 11/4/10 3:51 AM
Thanks a lot for the help and suggestions, which definitely guided me
to the solution of my VerifyError problem.
I just want to share the solution in case someone else encounters the
same problem, which appeared to be very simple - I only needed to move
the variables' definition outside of the method, i.e.,

**********Original definition (when the VerifyError
occurred):**********

public class PEModelOR extends BayesNet {
        public PEModelOR() {
        name = "PEModelOR";
......
final DiscreteVariable DB =
new DiscreteVariable ("DB",
DiscreteVariable.CHANCE,
new String[] { "yes","no" });
..........

     /some functions calling the above variables/
   }
}

*********Solution:**********

public class PEModelOR extends BayesNet {

......
final DiscreteVariable DB =
new DiscreteVariable ("DB",
DiscreteVariable.CHANCE,
new String[] { "yes","no" });
..........

   public PEModelOR() {
        name = "PEModelOR";
     /some functions calling the above variables/
   }
}

In such a way, I was even able to extend my model, which now includes
112 variables and 112 functions, all defined before the method
PEModelOR().

Cheers, MarVel
Re: VerifyError: arbitrarily rejecting large method DanH 11/4/10 5:22 AM
Yep, the Dalvik compiler attempts to assign a "register" to every
local variable in the method.  It should be able to handle that many,
but apparently can't.  By making them instance variables you remove
the compiler's need/desire to "manage" them (and also make the method
a fair amount smaller).