Open mstoodle opened 5 years ago
@Leonardo2718 FYI this will help with enabling Tril on OpenJ9.
MethodBuilder I'm currently trying to get to compile and then be used inside jitHookAboutToRunMain
:
class TestTypeDictionary : public OMR::JitBuilder::TypeDictionary
{
public:
TestTypeDictionary()
: OMR::JitBuilder::TypeDictionary()
{
DEFINE_STRUCT(J9VMThread);
DEFINE_FIELD(J9VMThread, javaVM, Word);
CLOSE_STRUCT(J9VMThread);
}
};
class TestMethodBuilder : public OMR::JitBuilder::MethodBuilder
{
public:
TestMethodBuilder(TestTypeDictionary * d)
: OMR::JitBuilder::MethodBuilder(d)
{
DefineLine(LINETOSTR(__LINE__));
DefineFile(__FILE__);
DefineName("getJavaVMFromThread");
OMR::JitBuilder::IlType *pJ9JavaVM = d->PointerTo(Word);
DefineReturnType(pJ9JavaVM);
OMR::JitBuilder::IlType *j9VMThreadType = d->LookupStruct("J9VMThread");
OMR::JitBuilder::IlType *pJ9VMThreadType = d->PointerTo(j9VMThreadType);
DefineParameter("vmThread", pJ9VMThreadType);
}
bool buildIL()
{
Return(
LoadIndirect("J9VMThread", "javaVM",
Load("vmThread")));
return true;
}
};
Update: today I hacked my way to compiling a simpler test (the infamous Return(ConstInt64(3))
) while inside the OpenJ9 JIT. Still need to verify things are doing what I think they're doing, but it looks sort of reasonable.
Next step: get the Java API to work.
The MethodBuilder
I have tested so far:
class TestMethodBuilder : public OMR::JitBuilder::MethodBuilder
{
public:
TestMethodBuilder(TestTypeDictionary * d)
: OMR::JitBuilder::MethodBuilder(d)
{
DefineLine(LINETOSTR(__LINE__));
DefineFile(__FILE__);
DefineName("ReturnThree");
DefineReturnType(Int64);
}
bool buildIL()
{
Return(
ConstInt64(3));
return true;
}
};
Verbose output:
[ .. lots of other JIT compiled methods ... ]
+ (warm) /Users/mstoodle/git/openj9-openjdk-jdk11/build/macosx-x86_64-normal-server-release/vm/compiler/../compiler/control/HookedByTheJit.cpp:284:ReturnThree @ 0000000019002238-0000000019002258 MethodBuilder JitBuilder Q_SZ=5 Q_SZI=4 QW=26 sync compThread=0 CpuLoad=0%(0%avg) JvmCpu=283%
And the output that verified it worked, just for completeness :) :
Return3 MethodBuilder Passed! returned 3
I'll clean up my branch a bit and will then push, just for reference. It's got some ugly stuff in it we'll have to think harder about how to solve more properly.
Thanks for all the efforts here. I'm closely following the progress and appreciate the work. Getting JitBuilder working in OpenJ9 opens up a world of possibilities, including a Java API to generate JIT bodies on the fly, as well as a plethora of things we can do around testing the JIT.
I just pushed https://github.com/mstoodle/openj9/tree/explore_jitbuilder which contains the commits I used to get JitBuilder to compile inside the OpenJ9 JIT as well as to be able to invoke it from within the OpenJ9 JIT. I'm not filing it as a pull request because there are too many hacks, but if anyone wants to look through it, feedback welcome.
Note that it's very preliminary at the moment (not only due to hacks): only a subset of the JitBuilder API will work properly given the current state of things. More work will be needed to align the use of Symbols/SymbolReferences so things like Struct and Union can work, not to mention augmenting the J9 API with first class Java concepts like objects, classes, fields, and ability to construct try/catch blocks, etc.
Made some more progress on the way to being able to use JitBuilder from Java applications.
I managed to get the Java API client classes generated now, and successfully compiling with javac
. I still need to generate the native layer that connects the Java classes to the JitBuilder implementation classes, but that shouldn't be too bad since it's mostly a pass-through layer (a lot of the implementation versus client object stuff landed in the Java layer).
I have been working on a side project to enable the internal JVM as well as Java applications (under proper security permission) to be able to generate native code directly into the JIT code cache using the OMR JitBuilder API. That should include, at some point, the ability for the JIT to inject such code sequences (as IL) into Java method compiles (and vice versa).
There are a host of obstacles to making this work, not least that some fundamental structures aren’t really shared between the OpenJ9 JIT and the OMR compiler, but I’ve been trying to hack my way through just to see what all is needed.
Current status: From the
jitHookAboutToRunMain()
I created aTypeDictionary
and aMethodBuilder
object representing a function that returns the 64-bit constant '3'. I calledcompileMethodBuilder()
on that object, cast the returnedstartPC
to a function pointer, called the function and verified that I did get the 64-bit value 3 as its return value. Yay!I am now working through the Java language client bindings which would enable using JitBuilder directly in a Java application. I'm building on top of the C generator originally started by @Leonardo2718 and now in an OMR pull request thanks to @daytonallen ( https://github.com/eclipse/omr/pull/3859 ). As of now, I have Java classes being correctly generated for the full JitBuilder API (they can be compiled with javac without errors though there are warnings due to use of
Unsafe
). The next step is to generate the native layer underneath the Java classes that connect Java calls into the JitBuilder library and support the callbacks coming out of the native JitBuilder library.Issues encountered so far:
SystemSegmentProvider
in OpenJ9 is completely different than in OMR with a completely different constructor API. Much of the lower level memory allocation function is not consistent across OMR and OpenJ9, but it can be made consistent.FrontEnd
is handled differently between OMR and OpenJ9 (including where to findFrontEnd.hpp
codegen/ConcreteFE.hpp
OMRMethodBuilder
expects there to be a C functioncompileMethodBuilder()
J9::SymbolReferenceTable
needs an additional signature forfindOrCreateStaticMethodSymbol()
MethodBuilder
objectTR::ResolvedMethod
isn’t used in OpenJ9 but is used by OMR JitBuilderJ9Method
pointer that is actually aTR::MethodBuilder
pointer :/jitMethodTranslated()
at the end of the compilation