0

I have the following JNI code:

JNIEXPORT jint JNICALL Java_demo_Test_callCritical
    (JNIEnv *env, jclass jobj_clazz)
{
  printf("I'm not critical\n");
  return 1;
}

JNIEXPORT jint JNICALL JavaCritical_demo_Test_callCritical ()
{
  printf ("I'm critical\n");
  return 1;
}

And Kotlin code:

package demo

class Test {
    companion object {
        @JvmStatic
        external fun callCritical(): Int
    }
}

If I run the program, it processes the Java method, not JavaCritical. I met all the conditions for running JavaCritical.

There is a similar question: How to get JavaCritical to really work on JNI , but I build the native part and run it on MacOS.

UPD: I built under jvmTarget 1.8, the version of kotlin 1.3.61, and ran on jvm 1.8.0_222 and 11.0.2

  • Please edit your question to make an [mcve]. How are you compiling and testing this? – Botje Jan 30 '20 at 16:21
  • Your Kotlin code has `testCritical` while your JNI code has `callCritical` and expects a `demo` package. And we're still missing the code that _calls_ `callCritical`. Please take the effort to show us an actual [mcve]. – Botje Jan 31 '20 at 08:35
  • @Botje Sorry, fixes added. But I can’t understand what kind of example is needed to call a function. The usual function call in main, but I think that you do not need to add this. – Pavel Gorgulov Jan 31 '20 at 12:48
  • Please show the output of `nm libXXX.dylib | grep callCritical`. Before we go deeper I want to make sure the symbol is correctly defined. – Botje Jan 31 '20 at 12:59
  • I got the following: `0000000000000f50 T _JavaCritical_demo_Test_callCritical 0000000000000f20 T _Java_demo_Test_callCritical` – Pavel Gorgulov Jan 31 '20 at 13:26

1 Answers1

0

This comment by @apangin is crucial:

Only JIT compiled methods call Critical Natives. While a method is interpreted, it will call standard implementation.

I arrived at much the same conclusion by reading the JVM code, but it was good to see that confirmed.

I was able to force the JavaCritical function to fire by passing -Xcomp to my java invocation, which forces JIT compilation on the first call to a method. This is a ridiculously terrible idea, so I hope your general use case involves a hot loop around your JavaCritical function.

Finally, there may not be much point to all this. This GitHub issue measured JavaCritical JNI invocations and found them to be only marginally faster.

tl;dr: Unless this is for research purposes, you are better off abandoning the search for JavaCritical and using "plain" JNI (which ought to be fast enough already).

Botje
  • 26,269
  • 3
  • 31
  • 41