More performance explorations
Ola Bini
ola.bini at gmail.com
Tue Jun 14 07:54:10 PDT 2011
Hi,
In the latest push to the github repository I've added the smallest
compilation I can get to exhibit the problem - it contains only one
invokedynamic ( it compiles a method that does 1 + 1 ).
You can run it specifically (and only) using:
$JAVA_HOME/bin/java
-Xbatch -XX:+PrintCompilation -cp
lib/seph.jar:build/classes/test:lib/release/asm-all-4.0.jar:$JUNIT4_JAR
org.junit.runner.JUnitCore seph.lang.code.Buster
This will print the ASM generated bytecode too, to simplify debugging a
bit. The compiled class ending in toplevel can be ignored - it's only
run once and will just create a new instance of the compiled
implementation of the inner abstraction.
Hope this helps.
Cheers
On 2011-06-14 01.22, John Rose wrote:
> On Jun 13, 2011, at 8:37 AM, Ola Bini wrote:
>
>> On 2011-06-13 10.14, Ola Bini wrote:
>>> I did a rebuild of MLVM+bsdport today, and I now see the missing
>>> class crash again on my Mac too (to clarify, this was gone from
>>> my Mac for a while, but came back. This means it's consistent
>>> with my JDK7 build on Linux).
>>
>> Oh my. I also did a rebuild of the JDK7 on Linux. Guess what? This
>> error is now gone from that source... So now the below problem only
>> happens on bsdport. *sigh*. So not very consistent then...
>
> I have reproduced this error on my mac. It happens on both 32- and
> 64-bit JVMs. It is insensitive to stack size (60k .. 40m).
>
> With -Xint the error does not occur. With -XX:+PrintCompilation,
> here are the last 10 compilations that occur before the error:
>
> 1574 111 ! seph.lang.bim.BaseBase::invoke (23 bytes)
> made not entrant 1574 113 b seph.lang.Runtime$2::isTrue (2
> bytes) 1574 114 b seph.lang.bim.NumberBase::minus (11
> bytes) 1575 115 b seph.lang.Number::minus (9 bytes) 1578
> 116 b gnu.math.Numeric::sub (7 bytes) 1582 114
> seph.lang.bim.NumberBase::minus (11 bytes) made not entrant 1587
> 117 b seph.lang.LexicalScope$One::assign (55 bytes) 1643
> 118 b seph$gen$abstraction$37$odd?::argument_0_0 (121
> bytes) 1647 119 b
> seph$gen$abstraction$38$even?::argument_0_0 (121 bytes) 1650 118
> seph$gen$abstraction$37$odd?::argument_0_0 (121 bytes) made not
> entrant
>
> Excluding compilation of odd? and even? makes the error go away: java
> ... -XX:CompileCommand='exclude,*'{odd,even}'*::*' ...
>
> The basic failure is here: Caused by: java.lang.NoClassDefFoundError:
> seph/lang/SephObject at
> java.lang.invoke.MethodHandle.invokeExact(MethodHandle.java) at
> seph$gen$abstraction$38$even?.argument_0_0(<eval>:7)
>
> It is evidently a class loader scoping problem, either in the 292
> implementation or in Seph itself.
>
> Here is a command line that exhibits the bug: $JAVA_HOME/bin/java
> -Xbatch -XX:+PrintCompilation -cp
> lib/seph.jar:build/classes/test:lib/release/asm-all-4.0.jar:$JUNIT4_JAR
> org.junit.runner.JUnitCore seph.lang.code.BasicSanityTest
>
> Moving seph.jar onto the BCP works around the bug:
> $JAVA_HOME/bin/java ... -Xbootclasspath/a:lib/seph.jar ...
>
> In other words, somebody (probably the code for argument_0_0) is
> looking on the BCP loader for the Seph runtime.
>
> Looking at the various dumps, I do not see what is the content of
> argument_0_0, but AbstractionCompiler.java indicates that it simply
> mentions SephObject as a type. If this type shows up on an
> invokedynamic (or MH.invokeExact), it will be lazily reified to
> SephObject.class as a part of a MethodType, on first execution. This
> is probably what causes the NCDF error we are seeing.
>
> The class containing argument_0_0 is apparently loaded here in
> AbstractionCompiler.java: abstractionClass =
> seph.lang.Runtime.LOADER.defineClass(className, classBytes);
>
> This defines the dynamically loaded code in a singular
> SephClassLoader. I have a question: Why doesn't the SephClassLoader
> delegate lookups to its parent? It seems to me that if code in that
> loader needs to reify SephObject, it must somehow access the parent
> of SephClassLoader. Is this really happening? I suggest putting
> tracing code into SephClassLoader to see whether it is being asked
> about SephObject just before the error happens.
>
> One thing that suggests it is 292's fault is the way -Xint hides the
> bug. It seems to me that if it is a class loader config problem,
> -Xint would make no difference. It is as if the interpreter is using
> one class loader while the compiled code is using a different one.
>
> This would be easier to debug if we could boil this failure down to a
> simpler case, with a single MH.invoke call whose signature mentions
> the non-global type (SephObject in this case). Something like this:
> class GeneratedC { ... invoke((LocalB)null) ... } java LocalA class
> LocalA { ... new
> MyClassLoader(LocalA.getClassLoader()).loadClass(...bytes for
> GeneratedC...)
>
> BTW, the -Xbatch command makes for a more deterministic interaction
> between the compile queue (which is concurrent) and the application.
>
> -- John
--
Ola Bini (http://olabini.com)
Ioke - JRuby - ThoughtWorks
"Yields falsehood when quined" yields falsehood when quined.
More information about the mlvm-dev
mailing list