LukasHeinzl
LukasHeinzl

Reputation: 51

JVM dynamic function calling

I am currently looking under the hood of the JVM, of the OpenJDK JVM to be speciffic. And I was wondering how the JVM calls native functions. I know that it loads them dynamically and saves them as void* but I can't seem to find the actual calling part.

For example:

jint Java_Test_add(jobject*, jint);

can be a native c function but so can:

jvoid Java_Test_main(jobject*);

So now I was wondering how the JVM can call these functions when only having the method signature as a string at runtime. As far as I know C does not support such dynamic calls. I hope someone can tell me how this works or how to approach such an problem.

Thanks in advance!

Upvotes: 1

Views: 461

Answers (3)

uraimo
uraimo

Reputation: 19821

Each language has its own set of procedure calling conventions (how a call to a subroutine is performed, what should be put in the stack or in registers, what must be done to return from a subroutine) and what happens in a case like this, calling from Java a native method written in C, is that the jvm will need to mimic the C calling convention to execute, outside from its normal context, the method Java_Test_add that you wrote.

The method signature will be used to get a reference to the C function location in memory (loaded from the static library you link when you compile your project) and the invoke_native instruction implementation (different for each jvm implementation) will take care of performing the call and handle the return (this can be done manually but as someone already said, there are libraries like libffi that implement various calling conventions).

So, you don't have to look at this from the point of view of the C language features, because yes, the language does not provide facilities of some easy syntactic sugar to perform this kind of "dynamic" calls at runtime, but this can still be implemented, eventually adding a bit of assembly to the mix.

Upvotes: 0

apangin
apangin

Reputation: 98350

C does not support such dynamic calls

Actually it does. Dynamic libraries are called dynamic, because they can be loaded at run-time, and their code can be linked by a symbolic name.

DLL (or shared library in Unix terminology) usually contains a symbol table used to map a symbolic name to an address of a function. OS provides API to resolve an address by a name, e.g. dlsym in POSIX or GetProcAddress on Windows.

JVM basically uses this API to find a function address on the first call of a native method. Then it remembers the resolved address, so that later invocations are done directly via this address.

The alternative way to bind a native method to a function address is to call RegisterNatives JNI function. A caller provides the direct pointer to a native function, not necessarily named according to standard JNI naming convention.

That's how native method linking works. The procedure of calling native method is described here.

Upvotes: 1

You can solve this in one of two basic ways:

  1. Write some platform and machine specific code that understands the calling conventions and sets it all up correctly. (See libffi for an example that's widely used under the hood)
  2. Write a heck of a lot of C functions that take vargs and dispatch them according to the type.

Upvotes: 0

Related Questions