Support for allocation of executable memory
Glavo
zjx001202 at gmail.com
Sun Nov 21 20:46:20 UTC 2021
You can generate MethodHandle from the MemoryAddress/MemorySegment using
CLinker::downcallHandle, and then call it.
Felix Cravic <themode at outlook.fr> 于2021年11月22日周一 上午4:36写道:
> I emphasize here again that Panama is different from JNI, There is no
> need to compile the native library.
> All we need is:
>
> 1. Through SymbolLookup::lookup, find the symbols of system API in
> the system library;
> 2. Through CLinker::downcallHandle, generate MethodHandle
> corresponding to the system API;
> 3. Call it.
>
> This is completely implemented in Java code, and there is no need to use
> native code, let alone compile native code.
>
> Indeed I guess that it works for the allocation phase, how would you run
> the code given an executable memory address?
> ------------------------------
> *De :* Glavo <zjx001202 at gmail.com>
> *Envoyé :* dimanche 21 novembre 2021 21:30
> *À :* Felix Cravic <themode at outlook.fr>
> *Cc :* panama-dev at openjdk.java.net <panama-dev at openjdk.java.net>
> *Objet :* Re: Support for allocation of executable memory
>
>
> Do you have any benchmark comparing JNI to the linker API? Last time I
> checked those were similar and the JEP mentions "similar performance". I am
> aware of how the API works, I am however still not convinced that it fixes
> my previous points.
>
>
> At this stage, the performance of Panama will not be higher than that of
> JNI, because its back end is still based on JNI, so it should have similar
> performance.
> At present, Panama is still some distance away from maturity, but it
> leaves more room for optimization for the JVM. Please wait patiently for it
> to focus on optimizing performance after it matures in function.
>
> Sure you can implement the Java side solely in Java, but you will
> obviously still need to compile the native library for multiple platforms &
> architectures.
>
>
> I emphasize here again that Panama is different from JNI, There is no
> need to compile the native library.
> All we need is:
>
> 1. Through SymbolLookup::lookup, find the symbols of system API in
> the system library;
> 2. Through CLinker::downcallHandle, generate MethodHandle
> corresponding to the system API;
> 3. Call it.
>
> This is completely implemented in Java code, and there is no need to use
> native code, let alone compile native code.
>
> Felix Cravic <themode at outlook.fr> 于2021年11月22日周一 上午3:58写道:
>
> Do you have any benchmark comparing JNI to the linker API? Last time I
> checked those were similar and the JEP mentions "similar performance". I am
> aware of how the API works, I am however still not convinced that it fixes
> my previous points.
>
> Sure you can implement the Java side solely in Java, but you will
> obviously still need to compile the native library for multiple platforms &
> architectures.
> ------------------------------
> *De :* Glavo <zjx001202 at gmail.com>
> *Envoyé :* dimanche 21 novembre 2021 20:51
> *À :* Felix Cravic <themode at outlook.fr>
> *Cc :* panama-dev at openjdk.java.net <panama-dev at openjdk.java.net>
> *Objet :* Re: Support for allocation of executable memory
>
> You're talking about the way JNI works, not the way Panama Foreign Linker
> API works. All the problems you mentioned do not apply to Panama.
> The Foreign Linker API does not require you to write any native code, let
> alone compile native code. You only need to write pure Java code to
> implement it.
>
> Reducing the cost of native calls is also one of Panama's goals. I believe
> that the cost of calling native wrappers implemented through the Foreign
> Linker API is low enough in common Java running environments.
>
> Forgive me for not being familiar with these system APIs, so I can't
> provide you with an example implementation of this function here.
> I just copy an example given by the official here. I believe it can make
> you understand how the Foreign Linker API works:
>
> // 1. Find foreign function on the C library path
> MethodHandle radixSort = CLinker.getInstance().downcallHandle(
> CLinker.systemLookup().lookup("radixsort"),
> ...);
> // 2. Allocate on-heap memory to store four strings
> String[] javaStrings = { "mouse", "cat", "dog", "car" };
> // 3. Allocate off-heap memory to store four pointers
> MemorySegment offHeap = MemorySegment.allocateNative(
> MemoryLayout.ofSequence(javaStrings.length,
> CLinker.C_POINTER),
> ...);
> // 4. Copy the strings from on-heap to off-heap
> for (int i = 0; i < javaStrings.length; i++) {
> // Allocate a string off-heap, then store a pointer to it
> MemorySegment cString = CLinker.toCString(javaStrings[i],
> newImplicitScope());
> MemoryAccess.setAddressAtIndex(offHeap, i, cString.address());
> }
> // 5. Sort the off-heap data by calling the foreign function
> radixSort.invoke(offHeap.address(), javaStrings.length,
> MemoryAddress.NULL, '\0');
> // 6. Copy the (reordered) strings from off-heap to on-heap
> for (int i = 0; i < javaStrings.length; i++) {
> MemoryAddress cStringPtr = MemoryAccess.getAddressAtIndex(offHeap, i);
> javaStrings[i] = CLinker.toJavaStringRestricted(cStringPtr);
> }
> assert Arrays.equals(javaStrings, new String[] {"car", "cat", "dog",
> "mouse"}); // true
>
>
> It is recommended that you read JEP 419 in its entirety first to
> understand Panama, or take a look at the description of Panama FFI in this
> document:
>
>
> https://github.com/openjdk/panama-foreign/blob/foreign-jextract/doc/panama_ffi.md
>
>
>
>
>
>
> Felix Cravic <themode at outlook.fr> 于2021年11月22日周一 上午3:21写道:
>
> If it needs to be implemented through JNI, you may be right.
>
> However, for Panama, although we still need to use different codes for
> different operating systems, all this can be implemented through pure java
> code.
>
> Additional dependencies are unnecessary because these functions should be
> part of the operating system. Because it only needs to be implemented in
> Java code, it is not necessary to compile on multiple platforms.
>
> You will be able to declare the native methods in Java, but the native
> library will need to be compiled for multiple platforms (and architecture)
>
> I don't understand why you should emphasize this. Does this bring any
> additional problems?
>
> JNI comes with overhead. Correct me if I am wrong, but I believe JIT
> compilers to work using an important number of stubs to allow
> de-optimization which would not work well with the said overhead (the
> alternative would be to move the work into the native code, but it doesn't
> really serve the original goal of being java-only)
>
> This implementation does improve the difficulty of user code maintenance,
> but this function itself is low-level, unsafe and platform related, and the
> code using it is often platform related.
> So I believe that when it is really needed, the problems caused by this
> part are relatively insignificant, so I use the word "only".
>
> Cannot disagree here. Though Java would currently not be suited for a
> project benefiting from such feature, which is a shame considering how
> little API change it requires (feel free to correct me). The closest
> alternative we have today is dynamic class loading, which is really good
> for most use-case but not all.
> ------------------------------
> *De :* Glavo <zjx001202 at gmail.com>
> *Envoyé :* dimanche 21 novembre 2021 20:04
> *À :* Felix Cravic <themode at outlook.fr>
> *Cc :* panama-dev at openjdk.java.net <panama-dev at openjdk.java.net>
> *Objet :* Re: Support for allocation of executable memory
>
> Sorry, in the last sentence of that email, I wanted to say "just" instead
> of "only".
>
> I am using Google translate to write email. Please forgive me for my
> problems in grammar and words.
>
> Glavo <zjx001202 at gmail.com> 于2021年11月22日周一 上午3:00写道:
>
> which would involve maintaining a native dependency and building it for
> every potential platform
>
>
> If it needs to be implemented through JNI, you may be right.
>
> However, for Panama, although we still need to use different codes for
> different operating systems, all this can be implemented through pure java
> code.
>
> Additional dependencies are unnecessary because these functions should be
> part of the operating system. Because it only needs to be implemented in
> Java code, it is not necessary to compile on multiple platforms.
>
> not to mention the fact that every execution will have to pass through
> JNI/Linker API
>
>
> I don't understand why you should emphasize this. Does this bring any
> additional problems?
>
> I however disagree with the "just"
>
> This implementation does improve the difficulty of user code maintenance,
> but this function itself is low-level, unsafe and platform related, and the
> code using it is often platform related.
> So I believe that when it is really needed, the problems caused by this
> part are relatively insignificant, so I use the word "only".
>
> Felix Cravic <themode at outlook.fr> 于2021年11月22日周一 上午2:41写道:
>
> I agree that there are reasons why it could not have its place in Panama,
> like OS limitations complicating the API design & it being another pretty
> unsafe feature.
> I however disagree with the "just", which would involve maintaining a
> native dependency and building it for every potential platform, not to
> mention the fact that every execution will have to pass through JNI/Linker
> API. By that point I doubt that Java would be the right tool for the job,
> or is it perhaps what you meant?
> ------------------------------
> *De :* Glavo <zjx001202 at gmail.com>
> *Envoyé :* dimanche 21 novembre 2021 19:19
> *À :* Felix Cravic <themode at outlook.fr>
> *Cc :* panama-dev at openjdk.java.net <panama-dev at openjdk.java.net>
> *Objet :* Re: Support for allocation of executable memory
>
> I don't think Panama should provide special support for it.
>
> To do this, you just need to create the binding of the relevant system API
> (e.g. `VirtualAlloc` and `VirtualProtect` on Windows, or `mmap` on Linux)
> with the foreign linker API and call it.
>
> Felix Cravic <themode at outlook.fr> 于2021年11月22日周一 上午1:01写道:
>
> Hello, I was wondering if there has ever been any discussion about
> supporting allocation of executable memory (and then its execution). The
> use cases I have in mind are emulation, very hot paths requiring
> specialized assembly (which could still fallback to jvm bytecode if
> unavailable), and a potential option to keep the whole application written
> in a JVM language.
>
> I doubt that such addition would drastically change the API, perhaps some
> concern about OS specific restrictions (e.g. write-xor-execute memory
> protection), and platform not supporting JIT compilation at all (IOS,
> potentially problematic for Graal & project Leyden)
>
> Discussion would be appreciated!
>
>
More information about the panama-dev
mailing list