BackEnd Service Provider.
Gary Frost
frost.gary at gmail.com
Tue Apr 21 10:30:42 UTC 2020
I don't want to flog this horse excessively, but please humour me one more
time.
Even after defining a module I can't offer my own service provider for
org.graalvm.compiler.hotspot.HotSpotBackendFactory
I really think we need a way for folks to experiment with Graal backends
without having to build there own JDK/JVM.
I created a module to be able to map my service provider
src/org.grfstuff.compiler/
├── module-info.java
└── org
└── grfstuff
└── compiler
└── GrfStuffHotSpotBackendFactory.java
Where my module-info.java is this.
--8<--
module org.grfstuff.compiler {
requires jdk.internal.vm.compiler;
provides org.graalvm.compiler.hotspot.HotSpotBackendFactory with
org.grfstuff.compiler.GrfStuffHotSpotBackendFactory;
}
-->8--
My implementation is just enough code so I can see an instance of my
backend get loaded.
--8<--
package org.grfstuff.compiler;
import org.graalvm.compiler.hotspot.HotSpotBackendFactory;
import org.graalvm.compiler.serviceprovider.ServiceProvider;
import org.graalvm.compiler.hotspot.amd64.AMD64HotSpotBackendFactory;
@ServiceProvider(HotSpotBackendFactory.class)
public class GrfStuffHotSpotBackendFactory extends
AMD64HotSpotBackendFactory {
public GrfStuffHotSpotBackendFactory(){
System.out.println("GrfStuffHotSpotFactory");
}
public String toString() {
return "GRFSTUFF_AMD64";
}
}
-->8--
I can build my module using appropriate --add-exports 'jiggery pokery ' :)
javac -g \
-d build \
--add-exports
jdk.internal.vm.compiler/org.graalvm.compiler.hotspot=org.grfstuff.compiler\
--add-exports
jdk.internal.vm.compiler/org.graalvm.compiler.serviceprovider=org.grfstuff.compiler\
--add-exports
jdk.internal.vm.compiler/org.graalvm.compiler.hotspot.amd64=org.grfstuff.compiler\
--module-source-path src\
--module org.grfstuff.compiler\
$(shell find src/org.grfstuff.compiler -name *.java)
But at runtime (my app is a compute intensive voilajones face detection
algorithm)
java \
-XX:+UnlockExperimentalVMOptions -XX:+UseJVMCICompiler
-XX:-TieredCompilation\
-XX:CompileCommand=compileonly,org/grfstuff/violajones/ViolaJones.compute\
-XX:CompileCommand=compileonly,org/grfstuff/violajones/ViolaJOnes.run\
-p build -m org.grfstuff.compiler\
-classpath build/org.grfstuff.violajones\
org.grfstuff.violajones.ViolaJones
I get this error
Error occurred during initialization of boot layer
java.lang.module.ResolutionException: Module org.grfstuff.compiler does not
read a module that exports org.graalvm.compiler.hotspot
It would appear that whilst add-exports is enough at compile time to
persuade the compiler that all is well. At runtime the service loader
execution path does not honour the add-exports requests to the service
layer.
In the end my temporary solution was to add this stanza
to org.graalvm.compiler.hotspot.CompilerConfigurationFactory.DefaultBackendMap's
constructor.
--8<--
String backendFactoryClassName =
System.getProperty("graal.backend.factory"); //
org.grfstuff.compiler.GrfStuffHotSpotBackendFactory
if (backendFactoryClassName != null){
try {
Class<? extends HotSpotBackendFactory> factoryClass =
(Class<? extends HotSpotBackendFactory>)
Class.forName(backendFactoryClassName);
HotSpotBackendFactory factory =
factoryClass.getDeclaredConstructor().newInstance();
Class<? extends Architecture> arch =
factory.getArchitecture();
HotSpotBackendFactory oldEntry = backends.put(arch,
factory);
}catch(Exception e){
}
}else {
//existing code
}
-->8--
Then I can build a jdk13 image and run using a combination of --add-modules
along with
-Dgraal.backend.factory=org.grfstuff.compiler.GrfStuffHotSpotBackendFactory
Whilst this works for me. I am quite sure if our common goal is to get
users to 'adopt/play-with' Graal, we can't expect them to build a dedicated
OpenJDK image.
I think it is an oversite to offer a ServiceProvider extension mechanism
(HotSpotBackendFactory) only for the module system to forbid anyone from
using it.
It would be great if we could offer a simpler mechanism (without resorting
to --patch-module which does not seem to be supported by IntelliJ).
We already have some protection by forcing -XX:+UnlockExperimentalVMOptions
-XX:+UseJVMCICompiler maybe we can just open this up a little more behind
these current flags.
Gary
On Mon, Apr 20, 2020 at 1:52 PM Doug Simon <doug.simon at oracle.com> wrote:
> Hi Gary,
>
> On 20 Apr 2020, at 14:44, Gary Frost <frost.gary at gmail.com> wrote:
>
> Yeah I started created a module, but it seems for my module to compile I
> need jdk.internal.vm.ci
> <https://urldefense.com/v3/__http://jdk.internal.vm.ci__;!!GqivPVa7Brio!IQVX1iggkDspLlkVBXNQ7IulcpTkED_VhK6SjF2apyR4-XW-E7oZHqeQPPY4GJB0$>
> module to export org.graalvm.compiler.hotspot.HotSpotBackendFactory to my
> named module. Which seems wrong.
>
>
> Actually, that’s by design. Only standard JDK API can be exported
> unqualified from the JDK. Neither Graal nor JVMCI is public API and so
> --add-exports is needed for compilation.
>
>
> I wanted to avoid using GraalVM. I figured I should be able to do what I
> want, using stock/released JDK13 and -XX:+UnlockExperimentalVMOptions
> -XX:+UseJVMCICompiler
>
>
> You can - you just need --add-exports (and maybe some other options) to
> “open up” the classes you’re trying to hook into.
>
> I can 'get around it' by pulling the source for
> org.graalvm.compiler.hotspot.CompilerConfigurationFactory locally. Hacking
> this one file (to load my Factory) then building using
> using --patch-module
> jdk.internal.vm.compiler=src/jdk.internal.vm.compiler/java, but this is
> clearly hacky. I should not have to use --patch-module here.
>
> Alas using --patch-module renders IntelliJ next to useless (it ignores
> patch-module) as pointed out by John Rose and myself here.
> https://youtrack.jetbrains.com/issue/IDEA-224342
> <https://urldefense.com/v3/__https://youtrack.jetbrains.com/issue/IDEA-224342__;!!GqivPVa7Brio!IQVX1iggkDspLlkVBXNQ7IulcpTkED_VhK6SjF2apyR4-XW-E7oZHqeQPKLKl6Nu$>
>
> Maybe the intent was that the JDK versions of Graal, were just to 'use
> Graal', not to allow developers to add there own features.
>
> Maybe that is the distiction between GraalVM and Graal enabled JDK.
>
>
> No, both of these don’t not offer open extension points. You need to force
> it open on the command as mentioned above. We can’t have just any old app
> code getting their hands on the compiler ;-)
>
> -Doug
>
> On Mon, Apr 20, 2020 at 11:54 AM Doug Simon <doug.simon at oracle.com> wrote:
>
>> Hi Gary,
>>
>> Have you tried creating a module for your service? I think that’s
>> required as of JDK 9.
>>
>> I suggest opening a PR on https://github.com/oracle/graal
>> <https://urldefense.com/v3/__https://github.com/oracle/graal__;!!GqivPVa7Brio!IQVX1iggkDspLlkVBXNQ7IulcpTkED_VhK6SjF2apyR4-XW-E7oZHqeQPMQSQQsk$>
>> so we can have a more concrete discussion.
>>
>> -Doug
>>
>> > On 20 Apr 2020, at 11:17, Gary Frost <frost.gary at gmail.com> wrote:
>> >
>> > I feel I am missing something obvious ;)
>> >
>> > I am working (well playing actually) with Graal and JDK13 and have
>> built my
>> > own implementation of
>> org.graalvm.compiler.hotspot.HotSpotBackendFactory to
>> > inject some custom code into generated x86. Very cool.
>> >
>> > If I hack the org.graalvm.compiler.hotspot.CompilerConfigurationFactory
>> > class (from JDK13 source) I can instantiate my factory directly, and I
>> see
>> > my modified code.
>> >
>> > But of course I want to able to build against and use use my factory
>> using
>> > a clean opendjdk JDK13 binary distribution.
>> >
>> > It looks like the
>> > class org.graalvm.compiler.hotspot.CompilerConfigurationFactory is
>> setup to
>> > allow me to offer my factory as a 'service provider' which the
>> > CompilerConfigurationFactory accesses via this call
>> > GraalServices.load(HotSpotBackendFactory.class)
>> > but nothing I try works.
>> >
>> > It looks like I need to provide a module-info.java class, but of course
>> I
>> > only want my one service to override the default.
>> >
>> > Any suggestions/help oir pointers to docs would be appreciated.
>> >
>> > Gary
>>
>>
>
More information about the graal-dev
mailing list