apangin / nalim Goto Github PK
View Code? Open in Web Editor NEWFast Java native interface based on JVMCI
License: GNU General Public License v2.0
Fast Java native interface based on JVMCI
License: GNU General Public License v2.0
f.e.
@code({(byte)0x48, (byte)0x31, (byte)0xC0, (byte)0xC3})
public static native long test();
Currently @Code
annotations do not implement any argument processing or any means of handling multiple architectures, unlike linked functions. This effectively forces all functions to go through a Java wrapper function at runtime to process arguments and select the appropriate implementation.
For example, even something as simple as querying CPUID output requires something like this:
@Code("4D01C8 4989D9 89D0 0FA2 418900 41895804 41894808 4189500C 4C89CB C3")
private static native void cpuid_amd64_win(int func, int[] out, long out_base_offset);
@Code("488D3C11 89F0 4889DE 0FA2 8907 895F04 894F08 89570C 4889F3 C3")
private static native void cpuid_amd64_linux(int func, int[] out, long out_base_offset);
private static final boolean is_windows = System.getProperty("os.name").toLowerCase().contains("windows");
public static void cpuid(int func, int[] out) {
if (is_windows) {
cpuid_amd64_win(func, out, UNSAFE.ARRAY_INT_BASE_OFFSET);
} else {
cpuid_amd64_linux(func, out, UNSAFE.ARRAY_INT_BASE_OFFSET);
}
}
Instead, it seems reasonable to allow specifying multiple possible bytecode sequences that the linker can select at runtime when parsing a class. This would make the feature much simpler to use.
@Code(
amd64_win = "4989D9 89D0 0FA2 418900 41895804 41894808 4189500C 4C89CB C3",
amd64_linux = "4889D7 89F0 4889DE 0FA2 8907 895F04 894F08 89570C 4889F3 C3"
)
public static native void cpuid(int func, int[] out);
Same code works with Java 20
Caused by: java.lang.ExceptionInInitializerError: Exception java.lang.IllegalArgumentException: nmethod entry barrier is missing [in thread "microbench.SimilarityBench.a_dotProductNalim-jmh-worker-5"]
at jdk.internal.vm.ci/jdk.vm.ci.hotspot.CompilerToVM.installCode0(Native Method)
at jdk.internal.vm.ci/jdk.vm.ci.hotspot.CompilerToVM.installCode(CompilerToVM.java:549)
at jdk.internal.vm.ci/jdk.vm.ci.hotspot.HotSpotCodeCacheProvider.installCode(HotSpotCodeCacheProvider.java:139)
at jdk.internal.vm.ci/jdk.vm.ci.code.CodeCacheProvider.setDefaultCode(CodeCacheProvider.java:67)
at one.nalim.Linker.installCode(Linker.java:174)
at one.nalim.Linker.linkMethod(Linker.java:121)
at one.nalim.Linker.linkMethod(Linker.java:93)
at one.nalim.Linker.linkClass(Linker.java:77)
at io.github.jbellis.jvector.vector.Jvector.<clinit>(Jvector.java:14)
... 12 more
I know that their JNI replacement isn't out yet, but including it in the bench seems reasonable. And may push them into providing a critical's replacement as well:)
First of all: Fantastic idea and library!
You write under "Limitations":
- Only primitive types and primitive arrays can be passed as arguments.
I wonder where this limitation is coming from, since when passing an arbitrary object, you will simply be given the actual object virtual address in the respective register of the calling convention.
When combined with sun.misc.Unsafe to find/validate the field offsets, you can actually do crazy stuff like using SSE/AVX to accelerate operations on float/double fields in your class, when they are consecutive.
So, when being careful here and first validating the field offsets that you expect and using native code via the @Code()
annotation, we can access and manipulate the object fields, can't we?
I've used your library to accelerate matrix multiplications from 10.5 ns. to just 4.0 ns. per operation for a class which uses 16 consecutive float fields: https://github.com/JOML-CI/joml-nalim
The entire agent and public API of nalim are licensed under GPLv2 and thus it is impossible for most organization to use it as a compile time dependency.
It'd be nice if we could separate nalim into two components:
nalim-api
- The public API licensed under more permissive license.
@Library
, @Link
, @Code
, etcnalim-agent
- All other stuff that must be licensed under GPLv2 due to JVMCI usage.
Linker
, Agent
, etc.A user who calls Linker.linkClass()
will still have the licensing problem, but the user can avoid it by specifying the list of the classes in the agent options instead of calling Linker.linkClass()
. (Please correct me if this still causes any licensing issues.)
We could also improve the nalim agent to link the classes automatically, most likely by 1) intercepting the class-loading process or 2) looking for a certain file in a JAR.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.