Re: [drlvm] Calling native methods from Java code: implementation details
I thought moxie already had an implementation of fast native calls ? Perhaps you could look at that ? cheers, Robin Mikhail Fursov wrote: On 10/23/06, Pavel Afremov [EMAIL PROTECTED] wrote: Mikhail could you summarize all issues which should be clarified and possible solutions for these issues? Ok, I'm going to summarize our discussion. Correct me if I missed something. Problem 1A: How JIT will know if a Java method must be replaced with a direct native call. Solution: Check if the class implements special marker interface or have an annotation. The class must be loaded by bootstrap classloader. Problem 1B: How JIT will know which VM helper must be replaced with a fast-path Java version. Solution: Check if predefined VM property is set. Get the name of the class from the property. Initiate the resolution and initialization of the class with fast-path helper. Problem 2: How JIT will get the address of the native method to generate a direct call? Here we have 2 solutions: Solution 2.1: Every component must have C method to return address for a given Java method 'void* get_direct_address(Method_Handle)'. The name of the component is stored as annotation for the method. Solution 2.2: Every class with a method to be replaced with direct native call must have a JNI method: 'static native long get_address(int id). JIT asks VM to get the address for a given method handle. VM gets the id from the method annotations and calls the JNI method to derive the address. Problem 3: How JIT will know which calling convention to use? Solution 3: Use method's annotation again. The current status: Today we need only solution for 1B problem. I've implemented the first fast-path vmhelper and inlined it using the solution described above. The patch depends on JIRA1942 and JIRA1949. I'm going to commit the patch after these JIRAs are accepted. We have multiple solution for the problem 2. We can postpone the decision for a awhile. The problem is not critical for the vmhelper inlining task .
Re: [drlvm] Calling native methods from Java code: implementation details
On 10/23/06, Pavel Afremov [EMAIL PROTECTED] wrote: Mikhail could you summarize all issues which should be clarified and possible solutions for these issues? Ok, I'm going to summarize our discussion. Correct me if I missed something. Problem 1A: How JIT will know if a Java method must be replaced with a direct native call. Solution: Check if the class implements special marker interface or have an annotation. The class must be loaded by bootstrap classloader. Problem 1B: How JIT will know which VM helper must be replaced with a fast-path Java version. Solution: Check if predefined VM property is set. Get the name of the class from the property. Initiate the resolution and initialization of the class with fast-path helper. Problem 2: How JIT will get the address of the native method to generate a direct call? Here we have 2 solutions: Solution 2.1: Every component must have C method to return address for a given Java method 'void* get_direct_address(Method_Handle)'. The name of the component is stored as annotation for the method. Solution 2.2: Every class with a method to be replaced with direct native call must have a JNI method: 'static native long get_address(int id). JIT asks VM to get the address for a given method handle. VM gets the id from the method annotations and calls the JNI method to derive the address. Problem 3: How JIT will know which calling convention to use? Solution 3: Use method's annotation again. The current status: Today we need only solution for 1B problem. I've implemented the first fast-path vmhelper and inlined it using the solution described above. The patch depends on JIRA1942 and JIRA1949. I'm going to commit the patch after these JIRAs are accepted. We have multiple solution for the problem 2. We can postpone the decision for a awhile. The problem is not critical for the vmhelper inlining task . -- Mikhail Fursov
Re: [drlvm] Calling native methods from Java code: implementation details
Hi. On First question I think that alternative 1 is better. It's allow to avoid creating of special or magic registration subsystem which should provide addresses for magic native call. On the Second question I agree with Pavel P. Null should be OK. On Third question, I think no additional actions is required. All dll's or so's for DRL VM must be in jre/bin directory and classes jar's must be jre/lib directory. Both should be loaded by as the others in these directories now. It's the first part of third question. The second part or fourth question is How to understand that this class contains magic native functions?. I prefer answer by extends a special empty interface. It's can provide opportunity writing libraries with fast native calls in future. Also it's match with java security. DRL VM can control what component can use Magic and what not via SecurityManager. Mikhail could you summarize all issues which should be clarified and possible solutions for these issues? Thanks. Pavel Afremov. On 10/20/06, Pavel Pervov [EMAIL PROTECTED] wrote: Prerequisite: each component carries its own helpers (which means no allocation helper in VM Core, for example). Yes, simple JIT will call helper as regular JNI method. I missed several issues in my original message. First: how to get address of helper? Answer: Two choices: 1) each component must provide static native long getHelperAddress(int) in its helper class. JIT will make a call to this function as regular JNICALL (stdcall on Windows, cdecl on Linux). Function prototype can be typedef'ed as typedef (JNICALL*)(JNIEnv*, jint). The issue I see here is naming: each component has its own helpers class name. So, the name for native method to call will be package name_class name_getHelperAddress. 2) add regular (OPEN) interface function to each component which will provide such mapping (as it is now done by VM). Second: what should be passed as JNIEnv to getHelperAddress? Answer: NULL. Component should not use JNIEnv pointer in this call. Third: how to retrieve helpers class for a particular component? Answer: Two choices again: 1) component modifies boot class path on initialization and exports component type.helpers_class system property. Then VM loads this class and JIT uses this class' name to retrieve fast path helpers. 2) component exports component type.helpers_jar system property on initialization, then VM adds this JAR to boot class path, extracts the manifest from it, retrieve Helpers-Class attribute from the manifest, and exports it as component type.helpers_class. Then VM loads this class and JIT uses this class' name to retrieve fast path helpers. I, personally, prefer second choice here. Anything else?.. Pavel. On 10/20/06, Alex Astapchuk [EMAIL PROTECTED] wrote: Pavel Pervov : My alternative follows: 1) Each component which exports magics, provides JAR file with class implementing these magics. Class name is described in (e.g.) Main-Class attribute of JAR's manifest. 2) The class contains java fast path for helper, and a pair of native methods: one for fast-slow path, and one for slow-slow path. 3) Fast-slow path helper can have any (supported) calling convention. 4) Slow-slow path helper will be called through JNI - it is regular native method. ... way and generate call to slow_alloc in annotated calling convention. If JIT does not support magics at all, it'll call jni_alloc in usual way - as regular call to native Java method. Helpers are neither called as JNI methods nor they are called through the JNI. Or do you propose to make a code for the helpers as the JNI methods? How would the 'jni_alloc(Address class, int size);' look like in the C code? -- Thanks, Alex The example follows: -- package org.apache.harmony.vm.helpers; // Annotations follow here, which describe which method is which helper, // and which is fast-path, fast-slow path, slow-slow path class GCv6Helpers { // fast-path allocation here public static Address alloc(Address class, int size) { // ... } // annotation, describing calling convention for fast-slow path public static native Address slow_alloc(Address class, int size); public static native Address jni_alloc(Address class, int size); } Now, if JIT supports magics, it'll process GCv6Magics::alloc in a special way and generate call to slow_alloc in annotated calling convention. If JIT does not support magics at all, it'll call jni_alloc in usual way - as regular call to native Java method. Yes, my idea suggests to change helper retrieval interface for JIT, but we already started to make significant changes to architecture - let's just make them more generic. Regards, Pavel. P.S. IMHO, this approach combines strong sides of Mikhail's and Pavel's ideas, as it use standard mechanisms of resolution and search of methods in loaded classes.
Re: [drlvm] Calling native methods from Java code: implementation details
Pavel, I've found only one problem in your design. Why do we need 1) if every component must have 2) E.g. why not to implement get_address(int) method in C language too? AFAIU Pavel Afremov's design has no C-interface methods at all. -- Mikhail Fursov
Re: [drlvm] Calling native methods from Java code: implementation details
Yes, this thread is not about JNI. I'll start another thread related to JNI calls from VM components. BTW here is another solution how to find an address of the direct native method. May be it's not the best, but it does not requires any calls from JIT during the compilation (neither Java nor VM calls) class IHaveNatives { public static final long myNativeAddress = jni_getAddress(myNative) // call to be replaced with direct native call public static void myNative() {throws new RuntimeException(not implemented)}; // the way to obtain an address for a method private static native jni_getAddress(String directNativeCallName); } Solution: To find an address of the native call JIT can access to the final variable. On 10/20/06, Alex Astapchuk [EMAIL PROTECTED] wrote: Gregory, Gregory Shimansky: On Thursday 19 October 2006 09:21 Alex Astapchuk wrote: Mikhail Fursov wrote: On 10/19/06, Alex Astapchuk [EMAIL PROTECTED] wrote: Pavel, One more note. b) About call of java method during compilation time. Jit now make class loading during compilation. It means that Jit make call of java method. So I don't think that it's the other case. It is different. The JIT itself does not call Java code. All what JIT does is calling VM's resolve_{anything}. It's VM who may execute the Java code during the resolution. The JIT itself neither has a way to call an arbitrary Java method during the compilation, neither has an access to JNI functionality. Sounds reasonable. And this solution joins mine and Pavel's proposals: JIT calls a VM method to resolve native address for direct call. JIT does not I would also add that we can not use any Java-based resolution schemes at all. (Here I mean anything that implies execution of managed code during compilation in order to resolve the things). Doing so we would dig a hge grave for ourselves: we'll get a number of dead lock issues, as such a scheme will add a sporadic and random locks inside a normal Java control flow. Exactly the same issue as we had with mixing native and Java locks in the same control flow. I didn't read the beginning of this thread (it is huge!) so forgive my Well, ok, here is its content in short: in previous series of the thread we were talking about a very special native methods. It has nothing to do with regular Java or JNI methods. ignorance. Do you mean normal Java method resolution which is done for all methods native and Java, or do you mean some special native helper address resolution where you a priori know that method is native and normal Java resolution was successfully done for it already? I think in this case native helper address resolution would not perform any Java calls, it would be a simple lookup through native libraries loaded by Pavel's proposal was *to perform* the Java or JNI call. the class loader which was used to load the class which owns the method where you want to inline a helper. The helpers we are talking about may have nothing to do neither with ClassLoading machinery, nor with a libraries already loaded by Java. -- Thanks, Alex - Terms of use : http://incubator.apache.org/harmony/mailing.html To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED] -- Mikhail Fursov
Re: [drlvm] Calling native methods from Java code: implementation details
My alternative follows: 1) Each component which exports magics, provides JAR file with class implementing these magics. Class name is described in (e.g.) Main-Class attribute of JAR's manifest. 2) The class contains java fast path for helper, and a pair of native methods: one for fast-slow path, and one for slow-slow path. 3) Fast-slow path helper can have any (supported) calling convention. 4) Slow-slow path helper will be called through JNI - it is regular native method. The example follows: -- package org.apache.harmony.vm.helpers; // Annotations follow here, which describe which method is which helper, // and which is fast-path, fast-slow path, slow-slow path class GCv6Helpers { // fast-path allocation here public static Address alloc(Address class, int size) { // ... } // annotation, describing calling convention for fast-slow path public static native Address slow_alloc(Address class, int size); public static native Address jni_alloc(Address class, int size); } Now, if JIT supports magics, it'll process GCv6Magics::alloc in a special way and generate call to slow_alloc in annotated calling convention. If JIT does not support magics at all, it'll call jni_alloc in usual way - as regular call to native Java method. Yes, my idea suggests to change helper retrieval interface for JIT, but we already started to make significant changes to architecture - let's just make them more generic. Regards, Pavel. P.S. IMHO, this approach combines strong sides of Mikhail's and Pavel's ideas, as it use standard mechanisms of resolution and search of methods in loaded classes. On 10/20/06, Mikhail Fursov [EMAIL PROTECTED] wrote: Yes, this thread is not about JNI. I'll start another thread related to JNI calls from VM components. BTW here is another solution how to find an address of the direct native method. May be it's not the best, but it does not requires any calls from JIT during the compilation (neither Java nor VM calls) class IHaveNatives { public static final long myNativeAddress = jni_getAddress(myNative) // call to be replaced with direct native call public static void myNative() {throws new RuntimeException(not implemented)}; // the way to obtain an address for a method private static native jni_getAddress(String directNativeCallName); } Solution: To find an address of the native call JIT can access to the final variable. On 10/20/06, Alex Astapchuk [EMAIL PROTECTED] wrote: Gregory, Gregory Shimansky: On Thursday 19 October 2006 09:21 Alex Astapchuk wrote: Mikhail Fursov wrote: On 10/19/06, Alex Astapchuk [EMAIL PROTECTED] wrote: Pavel, One more note. b) About call of java method during compilation time. Jit now make class loading during compilation. It means that Jit make call of java method. So I don't think that it's the other case. It is different. The JIT itself does not call Java code. All what JIT does is calling VM's resolve_{anything}. It's VM who may execute the Java code during the resolution. The JIT itself neither has a way to call an arbitrary Java method during the compilation, neither has an access to JNI functionality. Sounds reasonable. And this solution joins mine and Pavel's proposals: JIT calls a VM method to resolve native address for direct call. JIT does not I would also add that we can not use any Java-based resolution schemes at all. (Here I mean anything that implies execution of managed code during compilation in order to resolve the things). Doing so we would dig a hge grave for ourselves: we'll get a number of dead lock issues, as such a scheme will add a sporadic and random locks inside a normal Java control flow. Exactly the same issue as we had with mixing native and Java locks in the same control flow. I didn't read the beginning of this thread (it is huge!) so forgive my Well, ok, here is its content in short: in previous series of the thread we were talking about a very special native methods. It has nothing to do with regular Java or JNI methods. ignorance. Do you mean normal Java method resolution which is done for all methods native and Java, or do you mean some special native helper address resolution where you a priori know that method is native and normal Java resolution was successfully done for it already? I think in this case native helper address resolution would not perform any Java calls, it would be a simple lookup through native libraries loaded by Pavel's proposal was *to perform* the Java or JNI call. the class loader which was used to load the class which owns the method where you want to inline a helper. The helpers we are talking about may have nothing to do neither with ClassLoading machinery, nor with a libraries already loaded by Java. -- Thanks, Alex - Terms of use :
Re: [drlvm] Calling native methods from Java code: implementation details
Pavel Pervov : My alternative follows: 1) Each component which exports magics, provides JAR file with class implementing these magics. Class name is described in (e.g.) Main-Class attribute of JAR's manifest. 2) The class contains java fast path for helper, and a pair of native methods: one for fast-slow path, and one for slow-slow path. 3) Fast-slow path helper can have any (supported) calling convention. 4) Slow-slow path helper will be called through JNI - it is regular native method. ... way and generate call to slow_alloc in annotated calling convention. If JIT does not support magics at all, it'll call jni_alloc in usual way - as regular call to native Java method. Helpers are neither called as JNI methods nor they are called through the JNI. Or do you propose to make a code for the helpers as the JNI methods? How would the 'jni_alloc(Address class, int size);' look like in the C code? -- Thanks, Alex The example follows: -- package org.apache.harmony.vm.helpers; // Annotations follow here, which describe which method is which helper, // and which is fast-path, fast-slow path, slow-slow path class GCv6Helpers { // fast-path allocation here public static Address alloc(Address class, int size) { // ... } // annotation, describing calling convention for fast-slow path public static native Address slow_alloc(Address class, int size); public static native Address jni_alloc(Address class, int size); } Now, if JIT supports magics, it'll process GCv6Magics::alloc in a special way and generate call to slow_alloc in annotated calling convention. If JIT does not support magics at all, it'll call jni_alloc in usual way - as regular call to native Java method. Yes, my idea suggests to change helper retrieval interface for JIT, but we already started to make significant changes to architecture - let's just make them more generic. Regards, Pavel. P.S. IMHO, this approach combines strong sides of Mikhail's and Pavel's ideas, as it use standard mechanisms of resolution and search of methods in loaded classes. On 10/20/06, Mikhail Fursov [EMAIL PROTECTED] wrote: Yes, this thread is not about JNI. I'll start another thread related to JNI calls from VM components. BTW here is another solution how to find an address of the direct native method. May be it's not the best, but it does not requires any calls from JIT during the compilation (neither Java nor VM calls) class IHaveNatives { public static final long myNativeAddress = jni_getAddress(myNative) // call to be replaced with direct native call public static void myNative() {throws new RuntimeException(not implemented)}; // the way to obtain an address for a method private static native jni_getAddress(String directNativeCallName); } Solution: To find an address of the native call JIT can access to the final variable. On 10/20/06, Alex Astapchuk [EMAIL PROTECTED] wrote: Gregory, Gregory Shimansky: On Thursday 19 October 2006 09:21 Alex Astapchuk wrote: Mikhail Fursov wrote: On 10/19/06, Alex Astapchuk [EMAIL PROTECTED] wrote: Pavel, One more note. b) About call of java method during compilation time. Jit now make class loading during compilation. It means that Jit make call of java method. So I don't think that it's the other case. It is different. The JIT itself does not call Java code. All what JIT does is calling VM's resolve_{anything}. It's VM who may execute the Java code during the resolution. The JIT itself neither has a way to call an arbitrary Java method during the compilation, neither has an access to JNI functionality. Sounds reasonable. And this solution joins mine and Pavel's proposals: JIT calls a VM method to resolve native address for direct call. JIT does not I would also add that we can not use any Java-based resolution schemes at all. (Here I mean anything that implies execution of managed code during compilation in order to resolve the things). Doing so we would dig a hge grave for ourselves: we'll get a number of dead lock issues, as such a scheme will add a sporadic and random locks inside a normal Java control flow. Exactly the same issue as we had with mixing native and Java locks in the same control flow. I didn't read the beginning of this thread (it is huge!) so forgive my Well, ok, here is its content in short: in previous series of the thread we were talking about a very special native methods. It has nothing to do with regular Java or JNI methods. ignorance. Do you mean normal Java method resolution which is done for all methods native and Java, or do you mean some special native helper address resolution where you a priori know that method is native and normal Java resolution was successfully done for it already? I think in this case native helper address resolution would not perform any Java calls, it would be a simple lookup
Re: [drlvm] Calling native methods from Java code: implementation details
Prerequisite: each component carries its own helpers (which means no allocation helper in VM Core, for example). Yes, simple JIT will call helper as regular JNI method. I missed several issues in my original message. First: how to get address of helper? Answer: Two choices: 1) each component must provide static native long getHelperAddress(int) in its helper class. JIT will make a call to this function as regular JNICALL (stdcall on Windows, cdecl on Linux). Function prototype can be typedef'ed as typedef (JNICALL*)(JNIEnv*, jint). The issue I see here is naming: each component has its own helpers class name. So, the name for native method to call will be package name_class name_getHelperAddress. 2) add regular (OPEN) interface function to each component which will provide such mapping (as it is now done by VM). Second: what should be passed as JNIEnv to getHelperAddress? Answer: NULL. Component should not use JNIEnv pointer in this call. Third: how to retrieve helpers class for a particular component? Answer: Two choices again: 1) component modifies boot class path on initialization and exports component type.helpers_class system property. Then VM loads this class and JIT uses this class' name to retrieve fast path helpers. 2) component exports component type.helpers_jar system property on initialization, then VM adds this JAR to boot class path, extracts the manifest from it, retrieve Helpers-Class attribute from the manifest, and exports it as component type.helpers_class. Then VM loads this class and JIT uses this class' name to retrieve fast path helpers. I, personally, prefer second choice here. Anything else?.. Pavel. On 10/20/06, Alex Astapchuk [EMAIL PROTECTED] wrote: Pavel Pervov : My alternative follows: 1) Each component which exports magics, provides JAR file with class implementing these magics. Class name is described in (e.g.) Main-Class attribute of JAR's manifest. 2) The class contains java fast path for helper, and a pair of native methods: one for fast-slow path, and one for slow-slow path. 3) Fast-slow path helper can have any (supported) calling convention. 4) Slow-slow path helper will be called through JNI - it is regular native method. ... way and generate call to slow_alloc in annotated calling convention. If JIT does not support magics at all, it'll call jni_alloc in usual way - as regular call to native Java method. Helpers are neither called as JNI methods nor they are called through the JNI. Or do you propose to make a code for the helpers as the JNI methods? How would the 'jni_alloc(Address class, int size);' look like in the C code? -- Thanks, Alex The example follows: -- package org.apache.harmony.vm.helpers; // Annotations follow here, which describe which method is which helper, // and which is fast-path, fast-slow path, slow-slow path class GCv6Helpers { // fast-path allocation here public static Address alloc(Address class, int size) { // ... } // annotation, describing calling convention for fast-slow path public static native Address slow_alloc(Address class, int size); public static native Address jni_alloc(Address class, int size); } Now, if JIT supports magics, it'll process GCv6Magics::alloc in a special way and generate call to slow_alloc in annotated calling convention. If JIT does not support magics at all, it'll call jni_alloc in usual way - as regular call to native Java method. Yes, my idea suggests to change helper retrieval interface for JIT, but we already started to make significant changes to architecture - let's just make them more generic. Regards, Pavel. P.S. IMHO, this approach combines strong sides of Mikhail's and Pavel's ideas, as it use standard mechanisms of resolution and search of methods in loaded classes. On 10/20/06, Mikhail Fursov [EMAIL PROTECTED] wrote: Yes, this thread is not about JNI. I'll start another thread related to JNI calls from VM components. BTW here is another solution how to find an address of the direct native method. May be it's not the best, but it does not requires any calls from JIT during the compilation (neither Java nor VM calls) class IHaveNatives { public static final long myNativeAddress = jni_getAddress(myNative) // call to be replaced with direct native call public static void myNative() {throws new RuntimeException(not implemented)}; // the way to obtain an address for a method private static native jni_getAddress(String directNativeCallName); } Solution: To find an address of the native call JIT can access to the final variable. On 10/20/06, Alex Astapchuk [EMAIL PROTECTED] wrote: Gregory, Gregory Shimansky: On Thursday 19 October 2006 09:21 Alex Astapchuk wrote: Mikhail Fursov wrote: On 10/19/06, Alex Astapchuk [EMAIL PROTECTED] wrote: Pavel, One more note. b) About call of java method during compilation time. Jit now
Re: [drlvm] Calling native methods from Java code: implementation details
On 10/19/06, Alex Astapchuk [EMAIL PROTECTED] wrote: Sounds reasonable. And this solution joins mine and Pavel's proposals: JIT calls a VM method to resolve native address for direct call. JIT does not I would also add that we can not use any Java-based resolution schemes at all. (Here I mean anything that implies execution of managed code during compilation in order to resolve the things). We already do. We resolve classes and it leads to the execution of user's classloader Java code. But JIT does not know about it: it just calls something like 'vm_resolve_class()' . The same could be done with native calls. JIT could ask VM (vm_resolve_native_addr()) and do not care which algorithm (Pavel'l or mine is used). In this case we make no workarounds in JIT. All workarounds and temporary solutions are fitted into the one method. In order to think anything meaningful, it would be nice to see something like a pseudo-code example. Something like a piece of Java code for the helper. Would you be so kind, please? Let me presume several things - are you talking about anything like the following? // // JIT side // ByteCodeTranslator::handleInvokeStatic() { MethodDesc md = getMethodToInvoke(); ClassDesc klass = md.getClass(); if (klass.implements(NativeCallProvider) /and what's here??/) { if (klass.implements(NativeCallProvider) vm_resolve_native_addr(md)!=NULL) { // So, the VM is smart enough to find all the needed only by the name. Right? Yes. Find a given static method with bootstrap classloader void* addr = vm_get_special_native_method_address(md.get_fully_qualified_name()) insert_a_native_call(addr); } else { proceed_as_usual_java_call(); } } The JIT side becomes simple, indeed. What about the 'helper writer's' side? What should be placed in the helper's Java code in order to make this special call? The helper writer must prepare his helper to work with a current VM. The body of the helper is not changed, the only thing is changed is how to report the address. Both variants require from a writer small amount of code. // // Java side // package org.apache.hy.drvm.gc.helpers; public class GCHelpers /*implements anything? */ { /** it's fast path - will be inlined by JIT. */ private static Address fast_alloc(Address classHandle, int size) { ... if (fast_path_succeeded) return allocated_address(); return perform_slow_path(classHandle, size); } /** it's slow path - implemented by gc.dll*/ // What's here? annotation? anything else? private static Address perform_slow_path(Address classHandle, int size); } Yes, annotation that the method is native. The address of the method could be retrieved by VM either using my or Pavel's solution All, I have a critical amount of changes. The first inlined helper is ready and I'm testing it with different workloads. The names of the slow-path helpers are hardcoded in JIT today - VM code is not affected before we find an agreement on the final solution. And the final solution should cover not only VM helpers but any native calls (or assert that we do not want to support anything except helpers). It's possible that my further work on the other helpers will open new problems that will affect the final design. So I'm going to put the patch into JIRA soon with workaround in JIT before we find the solution. Nobody minds? -- Mikhail Fursov
Re: [drlvm] Calling native methods from Java code: implementation details
On Thursday 19 October 2006 09:21 Alex Astapchuk wrote: Mikhail Fursov wrote: On 10/19/06, Alex Astapchuk [EMAIL PROTECTED] wrote: Pavel, One more note. b) About call of java method during compilation time. Jit now make class loading during compilation. It means that Jit make call of java method. So I don't think that it's the other case. It is different. The JIT itself does not call Java code. All what JIT does is calling VM's resolve_{anything}. It's VM who may execute the Java code during the resolution. The JIT itself neither has a way to call an arbitrary Java method during the compilation, neither has an access to JNI functionality. Sounds reasonable. And this solution joins mine and Pavel's proposals: JIT calls a VM method to resolve native address for direct call. JIT does not I would also add that we can not use any Java-based resolution schemes at all. (Here I mean anything that implies execution of managed code during compilation in order to resolve the things). Doing so we would dig a hge grave for ourselves: we'll get a number of dead lock issues, as such a scheme will add a sporadic and random locks inside a normal Java control flow. Exactly the same issue as we had with mixing native and Java locks in the same control flow. I didn't read the beginning of this thread (it is huge!) so forgive my ignorance. Do you mean normal Java method resolution which is done for all methods native and Java, or do you mean some special native helper address resolution where you a priori know that method is native and normal Java resolution was successfully done for it already? I think in this case native helper address resolution would not perform any Java calls, it would be a simple lookup through native libraries loaded by the class loader which was used to load the class which owns the method where you want to inline a helper. -- Gregory Shimansky, Intel Middleware Products Division - Terms of use : http://incubator.apache.org/harmony/mailing.html To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Re: [drlvm] Calling native methods from Java code: implementation details
Gregory, Gregory Shimansky: On Thursday 19 October 2006 09:21 Alex Astapchuk wrote: Mikhail Fursov wrote: On 10/19/06, Alex Astapchuk [EMAIL PROTECTED] wrote: Pavel, One more note. b) About call of java method during compilation time. Jit now make class loading during compilation. It means that Jit make call of java method. So I don't think that it's the other case. It is different. The JIT itself does not call Java code. All what JIT does is calling VM's resolve_{anything}. It's VM who may execute the Java code during the resolution. The JIT itself neither has a way to call an arbitrary Java method during the compilation, neither has an access to JNI functionality. Sounds reasonable. And this solution joins mine and Pavel's proposals: JIT calls a VM method to resolve native address for direct call. JIT does not I would also add that we can not use any Java-based resolution schemes at all. (Here I mean anything that implies execution of managed code during compilation in order to resolve the things). Doing so we would dig a hge grave for ourselves: we'll get a number of dead lock issues, as such a scheme will add a sporadic and random locks inside a normal Java control flow. Exactly the same issue as we had with mixing native and Java locks in the same control flow. I didn't read the beginning of this thread (it is huge!) so forgive my Well, ok, here is its content in short: in previous series of the thread we were talking about a very special native methods. It has nothing to do with regular Java or JNI methods. ignorance. Do you mean normal Java method resolution which is done for all methods native and Java, or do you mean some special native helper address resolution where you a priori know that method is native and normal Java resolution was successfully done for it already? I think in this case native helper address resolution would not perform any Java calls, it would be a simple lookup through native libraries loaded by Pavel's proposal was *to perform* the Java or JNI call. the class loader which was used to load the class which owns the method where you want to inline a helper. The helpers we are talking about may have nothing to do neither with ClassLoading machinery, nor with a libraries already loaded by Java. -- Thanks, Alex - Terms of use : http://incubator.apache.org/harmony/mailing.html To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Re: [drlvm] Calling native methods from Java code: implementation details
Pavel, I completely agree with Alex critics. But the thread is to discuss and to find the best solution that could be implemented fast. Sorry, some questions I have are the same as Alex's. On 10/18/06, Pavel Afremov [EMAIL PROTECTED] wrote: 1) The special interface MagicNativeCall should be created. The interface has only one method CallAddress getCallAddress(String methodName). All native methods of classes which implement this interface should be called by JIT via special magic way. a. Object instance? Where should I get it during the compilation? b. Why to use marker interface if we can use annotations to provide all knowledge we need in the same way (e.g. calling convention/if native/other knowledge that may be needed)? 2) If JIT find call of native method, it tries to find call address using getCallAddress method. If null is returned by the method, usual call of JNI method should be processed. In other case magic native call can be included instead JNI call. Result returned by getCallAddress can and should be cashed by JIT for performance reasons. a. Self-describing Java code (I mean getCallAddress()) - this is very good. b. Calling virtual method from the JIT during the compilation is not a good idea. 3) I propose for the firs time use fastcall calling convention. In future new additional method can be added MagicNativeCall interface. It can be named as getCallType for example. If it returns JNI – jit should use stdcall, if FastWay – fast call. Also we can add special Magic type of calling convention. In this type of call one can select Register and stack slot for every parameter and return value. a. The development is limited to support only basic CCs - I agree. All other calling convention could be discussed latter. b. Why to use abstract lists but not the named and typed parameters like in Java? -- Mikhail Fursov
Re: [drlvm] Calling native methods from Java code: implementation details
On 10/18/06, Xiao-Feng Li [EMAIL PROTECTED] wrote: Pavel's looks like more flexible, but I have a question with the special interface approach: is it possible that sometimes we want to call a library native method in fast way? If possible, shall we require all library classes that have the native method implement the special interface? The solution if my proposal is accepted: to call any native method from a native library user must 1) Create a header-like Java file with a static method stub and describe its parameters 2) Add the Java header to the protected by VM classes (e.g. load it with bootstrap classloader) 3) Create a library that will be loaded by component manager and will resolve the method by (void* getAddress(name)) request. I think this is reasonable amount of actions to add unsafe functionality into VM. Or, is it possible for the VM developer to override a library native method with a fast internal replacement that still keeps the semantics? In this situation, this method is not really implemented in the library class. Where will JIT find it? In my proposal: Yes. A component (VM,GC) can return an address not only for 'persistent' functions but of generated ones (like helpers we have today) And we probably don't want over-generality to the design of fast native method invocation. We'd better keep them internally to the VM at the moment until we see real need to open this contract interface to external library/application developers. So if you agree with this, the set of non-JNI native methods for JIT to handle are very limited -- they are actually just some JVM internal functions (plus some special cases for speedup). We probably want them more closed than open just like the inlined helpers. Completely agree. This functionality must be invisible for usual Java developers. Before we realize we need it we must hide the functionality from classlib developers too. -- Mikhail Fursov
Re: [drlvm] Calling native methods from Java code: implementation details
Mikhail, I think our opinions are pretty close about this topic now. Thanks, xiaofeng On 10/18/06, Mikhail Fursov [EMAIL PROTECTED] wrote: On 10/18/06, Xiao-Feng Li [EMAIL PROTECTED] wrote: Pavel's looks like more flexible, but I have a question with the special interface approach: is it possible that sometimes we want to call a library native method in fast way? If possible, shall we require all library classes that have the native method implement the special interface? The solution if my proposal is accepted: to call any native method from a native library user must 1) Create a header-like Java file with a static method stub and describe its parameters 2) Add the Java header to the protected by VM classes (e.g. load it with bootstrap classloader) 3) Create a library that will be loaded by component manager and will resolve the method by (void* getAddress(name)) request. I think this is reasonable amount of actions to add unsafe functionality into VM. Or, is it possible for the VM developer to override a library native method with a fast internal replacement that still keeps the semantics? In this situation, this method is not really implemented in the library class. Where will JIT find it? In my proposal: Yes. A component (VM,GC) can return an address not only for 'persistent' functions but of generated ones (like helpers we have today) And we probably don't want over-generality to the design of fast native method invocation. We'd better keep them internally to the VM at the moment until we see real need to open this contract interface to external library/application developers. So if you agree with this, the set of non-JNI native methods for JIT to handle are very limited -- they are actually just some JVM internal functions (plus some special cases for speedup). We probably want them more closed than open just like the inlined helpers. Completely agree. This functionality must be invisible for usual Java developers. Before we realize we need it we must hide the functionality from classlib developers too. -- Mikhail Fursov - Terms of use : http://incubator.apache.org/harmony/mailing.html To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Re: [drlvm] Calling native methods from Java code: implementation details
It's better to use standard JNI call, to call libraries from the side. It's provide creation of m2n and other required stuff. The other case if the library is ours and we know that there are methods which can be called via fast way. In this case we can do following For example there is class MyLibraryClass { int methodA(); void methodB(int); } Wrapper should be added . Class MyFastLibraryClass extends MyLibraryClass { CallAddress getCallAddress(String methodName); // which returns fast call addresses. } BR Pavel Afremov On 10/18/06, Xiao-Feng Li [EMAIL PROTECTED] wrote: Hi, I think Pavel and Mikhail's proposals are essentially the same. Pavel's looks like more flexible, but I have a question with the special interface approach: is it possible that sometimes we want to call a library native method in fast way? If possible, shall we require all library classes that have the native method implement the special interface? Or, is it possible for the VM developer to override a library native method with a fast internal replacement that still keeps the semantics? In this situation, this method is not really implemented in the library class. Where will JIT find it? And we probably don't want over-generality to the design of fast native method invocation. We'd better keep them internally to the VM at the moment until we see real need to open this contract interface to external library/application developers. So if you agree with this, the set of non-JNI native methods for JIT to handle are very limited -- they are actually just some JVM internal functions (plus some special cases for speedup). We probably want them more closed than open just like the inlined helpers. Thanks, xiaofeng On 10/18/06, Pavel Afremov [EMAIL PROTECTED] wrote: Mikhail proposal is OK. But I think that following solution is better 1) The special interface MagicNativeCall should be created. The interface has only one method CallAddress getCallAddress(String methodName). All native methods of classes which implement this interface should be called by JIT via special magic way. 2) If JIT find call of native method, it tries to find call address using getCallAddress method. If null is returned by the method, usual call of JNI method should be processed. In other case magic native call can be included instead JNI call. Result returned by getCallAddress can and should be cashed by JIT for performance reasons. 3) I propose for the firs time use fastcall calling convention. In future new additional method can be added MagicNativeCall interface. It can be named as getCallType for example. If it returns JNI – jit should use stdcall, if FastWay – fast call. Also we can add special Magic type of calling convention. In this type of call one can select Register and stack slot for every parameter and return value. It can looks like: ReturnValue methodName(InParameterList ) or void methodName(InParameterList, OutParameterList). ReturValue is an void or OutValue, InParameterList is an empty or separated by comma , list of the InValue, OutParameterList is an empty or separated by comma , list of the OutValue. The OutValue can by one of OutRegisterParametr## or OutStackParametr##, where ## number of register or call in the stack, which are possible on the current platform. The InValue can be one of InRegisterParametr## or InStackParametr##. Register## and Stack## is the short aliases for InRegisterParametr## and InStackParametr## correspondently. Result is the short alias for OutRegisterParametr00 (EAX on ia32). Generics can be used for type safety. Thanks. Pavel Afremov. On 10/17/06, Rana Dasgupta [EMAIL PROTECTED] wrote: Mikhail, All this looks reasonable to me. At least to go ahead. Regarding 2A, could the jit cache this information for re-use? Alternatively, the JIT can do all this at startup...by going thru the contract class of fastpath java methods and querying the component manager for the native addresses of the slow counterparts. Thanks, Rana On 10/17/06, Mikhail Fursov [EMAIL PROTECTED] wrote: All, Finally we have almost everything finished to post helper's fast-path inlining framework into JIRA. The issue is left is how to call native slow-path versions of the from Java code. We already discussed some of the aspects, but there was no detailed discussion with a final agreement what API we will use. Let's make a final decision so I can add the code into JIRA. I'm sending my vision of the solution. Correct me or advise another approach. Step 1: How JIT will know if a Java method must be replaced with a native helper call. Solution 1.A: Every Java method that must be replaced with native call must be a static method and must have special Native runtime method annotation. Step 2: How JIT will get the address of the native method to
Re: [drlvm] Calling native methods from Java code: implementation details
Hello. My answers is here: a) About resolving during compilation time If Jit compiles call of the method from the current class, it means that resolving has been already done, and not additional resolving is not required to understand is class implements magic interface or not. If Jit compiles call of the method from other class it should resolve that class to understand is it usual call or JNI, as I understand. So no additional work again. b) About call of java method during compilation time. Jit now make class loading during compilation. It means that Jit make call of java method. So I don't think that it's the other case. To provide work of getCallAddress without class initializing, additional requirements can be put forward. If Jit will implements lazy resolution in future, compilation of the method call and getCallAddress invoking will be put into lazy resolution stub. c) Use of special interface is right for security issues. It's not clear for me how provide security in Mikhail scheme. Thanks Pavel Afremov. On 10/18/06, Mikhail Fursov [EMAIL PROTECTED] wrote: Pavel, I completely agree with Alex critics. But the thread is to discuss and to find the best solution that could be implemented fast. Sorry, some questions I have are the same as Alex's. On 10/18/06, Pavel Afremov [EMAIL PROTECTED] wrote: 1) The special interface MagicNativeCall should be created. The interface has only one method CallAddress getCallAddress(String methodName). All native methods of classes which implement this interface should be called by JIT via special magic way. a. Object instance? Where should I get it during the compilation? b. Why to use marker interface if we can use annotations to provide all knowledge we need in the same way (e.g. calling convention/if native/other knowledge that may be needed)? 2) If JIT find call of native method, it tries to find call address using getCallAddress method. If null is returned by the method, usual call of JNI method should be processed. In other case magic native call can be included instead JNI call. Result returned by getCallAddress can and should be cashed by JIT for performance reasons. a. Self-describing Java code (I mean getCallAddress()) - this is very good. b. Calling virtual method from the JIT during the compilation is not a good idea. 3) I propose for the firs time use fastcall calling convention. In future new additional method can be added MagicNativeCall interface. It can be named as getCallType for example. If it returns JNI – jit should use stdcall, if FastWay – fast call. Also we can add special Magic type of calling convention. In this type of call one can select Register and stack slot for every parameter and return value. a. The development is limited to support only basic CCs - I agree. All other calling convention could be discussed latter. b. Why to use abstract lists but not the named and typed parameters like in Java? -- Mikhail Fursov
Re: [drlvm] Calling native methods from Java code: implementation details
On 10/18/06, Pavel Afremov [EMAIL PROTECTED] wrote: c) Use of special interface is right for security issues. It's not clear for me how provide security in Mikhail scheme. It's simple :). Allow direct native calls only from classes loaded by bootstrap classloader. -- Mikhail Fursov
Re: [drlvm] Calling native methods from Java code: implementation details
On 10/18/06, Pavel Afremov [EMAIL PROTECTED] wrote: a) About resolving during compilation time If Jit compiles call of the method from the current class, it means that resolving has been already done, and not additional resolving is not required to understand is class implements magic interface or not. If Jit compiles call of the method from other class it should resolve that class to understand is it usual call or JNI, as I understand. So no additional work again. Pavel, do I understand it correctly public static native is a marker of native method. If yes, it forces library writer to implement native-stubs for all of them. Other questions were 1) Where to get an instance to call the virtual getAddress() method? 2) Execution of Java method from JIT during compilation requires additional VM support, doesn't it? -- Mikhail Fursov
Re: [drlvm] Calling native methods from Java code: implementation details
On 10/17/06, Mikhail Fursov [EMAIL PROTECTED] wrote: On 10/18/06, Xiao-Feng Li [EMAIL PROTECTED] wrote: Pavel's looks like more flexible, but I have a question with the special interface approach: is it possible that sometimes we want to call a library native method in fast way? If possible, shall we require all library classes that have the native method implement the special interface? The solution if my proposal is accepted: to call any native method from a native library user must 1) Create a header-like Java file with a static method stub and describe its parameters 2) Add the Java header to the protected by VM classes (e.g. load it with bootstrap classloader) 3) Create a library that will be loaded by component manager and will resolve the method by (void* getAddress(name)) request. I think this is reasonable amount of actions to add unsafe functionality This sounds like a good plan to me. The purpose of this design is to make helper invocation fast. Very fast, if posible. Though there are other interesting uses of this mechanism that we are discovering, it may be a good idea to focus on the main reason first. I am assuming that some level of caching will occur since the slow helpers will not change dynamically during a VM running instance. As Pavel pointed out, we may also want to consider a default calling convention like __fastcall, or a custom convention, so that we don't have to annotate every time. Thanks, Rana into VM.
Re: [drlvm] Calling native methods from Java code: implementation details
Pavel, One more note. b) About call of java method during compilation time. Jit now make class loading during compilation. It means that Jit make call of java method. So I don't think that it's the other case. It is different. The JIT itself does not call Java code. All what JIT does is calling VM's resolve_{anything}. It's VM who may execute the Java code during the resolution. The JIT itself neither has a way to call an arbitrary Java method during the compilation, neither has an access to JNI functionality. -- Thanks, Alex Pavel Afremov ?: Hello. My answers is here: a) About resolving during compilation time If Jit compiles call of the method from the current class, it means that resolving has been already done, and not additional resolving is not required to understand is class implements magic interface or not. If Jit compiles call of the method from other class it should resolve that class to understand is it usual call or JNI, as I understand. So no additional work again. b) About call of java method during compilation time. Jit now make class loading during compilation. It means that Jit make call of java method. So I don't think that it's the other case. To provide work of getCallAddress without class initializing, additional requirements can be put forward. If Jit will implements lazy resolution in future, compilation of the method call and getCallAddress invoking will be put into lazy resolution stub. c) Use of special interface is right for security issues. It's not clear for me how provide security in Mikhail scheme. Thanks Pavel Afremov. On 10/18/06, Mikhail Fursov [EMAIL PROTECTED] wrote: Pavel, I completely agree with Alex critics. But the thread is to discuss and to find the best solution that could be implemented fast. Sorry, some questions I have are the same as Alex's. On 10/18/06, Pavel Afremov [EMAIL PROTECTED] wrote: 1) The special interface MagicNativeCall should be created. The interface has only one method CallAddress getCallAddress(String methodName). All native methods of classes which implement this interface should be called by JIT via special magic way. a. Object instance? Where should I get it during the compilation? b. Why to use marker interface if we can use annotations to provide all knowledge we need in the same way (e.g. calling convention/if native/other knowledge that may be needed)? 2) If JIT find call of native method, it tries to find call address using getCallAddress method. If null is returned by the method, usual call of JNI method should be processed. In other case magic native call can be included instead JNI call. Result returned by getCallAddress can and should be cashed by JIT for performance reasons. a. Self-describing Java code (I mean getCallAddress()) - this is very good. b. Calling virtual method from the JIT during the compilation is not a good idea. 3) I propose for the firs time use fastcall calling convention. In future new additional method can be added MagicNativeCall interface. It can be named as getCallType for example. If it returns JNI – jit should use stdcall, if FastWay – fast call. Also we can add special Magic type of calling convention. In this type of call one can select Register and stack slot for every parameter and return value. a. The development is limited to support only basic CCs - I agree. All other calling convention could be discussed latter. b. Why to use abstract lists but not the named and typed parameters like in Java? -- Mikhail Fursov - Terms of use : http://incubator.apache.org/harmony/mailing.html To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Re: [drlvm] Calling native methods from Java code: implementation details
On 10/19/06, Alex Astapchuk [EMAIL PROTECTED] wrote: Pavel, One more note. b) About call of java method during compilation time. Jit now make class loading during compilation. It means that Jit make call of java method. So I don't think that it's the other case. It is different. The JIT itself does not call Java code. All what JIT does is calling VM's resolve_{anything}. It's VM who may execute the Java code during the resolution. The JIT itself neither has a way to call an arbitrary Java method during the compilation, neither has an access to JNI functionality. Sounds reasonable. And this solution joins mine and Pavel's proposals: JIT calls a VM method to resolve native address for direct call. JIT does not care how the address is resolved in VM. Alex, Pavel, what do you think about this interface? -- Mikhail Fursov
Re: [drlvm] Calling native methods from Java code: implementation details
Mikhail Fursov wrote: On 10/19/06, Alex Astapchuk [EMAIL PROTECTED] wrote: Pavel, One more note. b) About call of java method during compilation time. Jit now make class loading during compilation. It means that Jit make call of java method. So I don't think that it's the other case. It is different. The JIT itself does not call Java code. All what JIT does is calling VM's resolve_{anything}. It's VM who may execute the Java code during the resolution. The JIT itself neither has a way to call an arbitrary Java method during the compilation, neither has an access to JNI functionality. Sounds reasonable. And this solution joins mine and Pavel's proposals: JIT calls a VM method to resolve native address for direct call. JIT does not I would also add that we can not use any Java-based resolution schemes at all. (Here I mean anything that implies execution of managed code during compilation in order to resolve the things). Doing so we would dig a hge grave for ourselves: we'll get a number of dead lock issues, as such a scheme will add a sporadic and random locks inside a normal Java control flow. Exactly the same issue as we had with mixing native and Java locks in the same control flow. care how the address is resolved in VM. Alex, Pavel, what do you think about this interface? In order to think anything meaningful, it would be nice to see something like a pseudo-code example. Something like a piece of Java code for the helper. Would you be so kind, please? Let me presume several things - are you talking about anything like the following? // // JIT side // ByteCodeTranslator::handleInvokeStatic() { MethodDesc md = getMethodToInvoke(); ClassDesc klass = md.getClass(); if (klass.implements(NativeCallProvider) /and what's here??/) { // So, the VM is smart enough to find all the needed only by the name. Right? void* addr = vm_get_special_native_method_address(md.get_fully_qualified_name()) insert_a_native_call(addr); } else { proceed_as_usual_java_call(); } } The JIT side becomes simple, indeed. What about the 'helper writer's' side? What should be placed in the helper's Java code in order to make this special call? // // Java side // package org.apache.hy.drvm.gc.helpers; public class GCHelpers /*implements anything? */ { /** it's fast path - will be inlined by JIT. */ private static Address fast_alloc(Address classHandle, int size) { ... if (fast_path_succeeded) return allocated_address(); return perform_slow_path(classHandle, size); } /** it's slow path - implemented by gc.dll*/ // What's here? annotation? anything else? private static Address perform_slow_path(Address classHandle, int size); } -- Thanks, Alex - Terms of use : http://incubator.apache.org/harmony/mailing.html To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Re: [drlvm] Calling native methods from Java code: implementation details
Mikhail, All this looks reasonable to me. At least to go ahead. Regarding 2A, could the jit cache this information for re-use? Alternatively, the JIT can do all this at startup...by going thru the contract class of fastpath java methods and querying the component manager for the native addresses of the slow counterparts. Thanks, Rana On 10/17/06, Mikhail Fursov [EMAIL PROTECTED] wrote: All, Finally we have almost everything finished to post helper's fast-path inlining framework into JIRA. The issue is left is how to call native slow-path versions of the from Java code. We already discussed some of the aspects, but there was no detailed discussion with a final agreement what API we will use. Let's make a final decision so I can add the code into JIRA. I'm sending my vision of the solution. Correct me or advise another approach. Step 1: How JIT will know if a Java method must be replaced with a native helper call. Solution 1.A: Every Java method that must be replaced with native call must be a static method and must have special Native runtime method annotation. Step 2: How JIT will get the address of the native method to generate a direct call? Solution 2.A: Every Java method that must be replaced with native call must have special Component annotation. JIT will use this annotation to ask Component Manager to access to the specified component by it's name and call void* getAddress(const char* methodName) component's method to get the address of a helper. That is every component that have native calls from Java must provide this interface. Step 3: How JIT will know which calling convention to use? Solution 3.A: Use method's annotation again. These were all of the problems with native calls. Now we need to agree if the solution proposed is OK or find another one. Please note, that this is just the first implementation. We can extend it with more features in the future. -- Mikhail Fursov
Re: [drlvm] Calling native methods from Java code: implementation details
Mikhail proposal is OK. But I think that following solution is better 1) The special interface MagicNativeCall should be created. The interface has only one method CallAddress getCallAddress(String methodName). All native methods of classes which implement this interface should be called by JIT via special magic way. 2) If JIT find call of native method, it tries to find call address using getCallAddress method. If null is returned by the method, usual call of JNI method should be processed. In other case magic native call can be included instead JNI call. Result returned by getCallAddress can and should be cashed by JIT for performance reasons. 3) I propose for the firs time use fastcall calling convention. In future new additional method can be added MagicNativeCall interface. It can be named as getCallType for example. If it returns JNI – jit should use stdcall, if FastWay – fast call. Also we can add special Magic type of calling convention. In this type of call one can select Register and stack slot for every parameter and return value. It can looks like: ReturnValue methodName(InParameterList ) or void methodName(InParameterList, OutParameterList). ReturValue is an void or OutValue, InParameterList is an empty or separated by comma , list of the InValue, OutParameterList is an empty or separated by comma , list of the OutValue. The OutValue can by one of OutRegisterParametr## or OutStackParametr##, where ## number of register or call in the stack, which are possible on the current platform. The InValue can be one of InRegisterParametr## or InStackParametr##. Register## and Stack## is the short aliases for InRegisterParametr## and InStackParametr## correspondently. Result is the short alias for OutRegisterParametr00 (EAX on ia32). Generics can be used for type safety. Thanks. Pavel Afremov. On 10/17/06, Rana Dasgupta [EMAIL PROTECTED] wrote: Mikhail, All this looks reasonable to me. At least to go ahead. Regarding 2A, could the jit cache this information for re-use? Alternatively, the JIT can do all this at startup...by going thru the contract class of fastpath java methods and querying the component manager for the native addresses of the slow counterparts. Thanks, Rana On 10/17/06, Mikhail Fursov [EMAIL PROTECTED] wrote: All, Finally we have almost everything finished to post helper's fast-path inlining framework into JIRA. The issue is left is how to call native slow-path versions of the from Java code. We already discussed some of the aspects, but there was no detailed discussion with a final agreement what API we will use. Let's make a final decision so I can add the code into JIRA. I'm sending my vision of the solution. Correct me or advise another approach. Step 1: How JIT will know if a Java method must be replaced with a native helper call. Solution 1.A: Every Java method that must be replaced with native call must be a static method and must have special Native runtime method annotation. Step 2: How JIT will get the address of the native method to generate a direct call? Solution 2.A: Every Java method that must be replaced with native call must have special Component annotation. JIT will use this annotation to ask Component Manager to access to the specified component by it's name and call void* getAddress(const char* methodName) component's method to get the address of a helper. That is every component that have native calls from Java must provide this interface. Step 3: How JIT will know which calling convention to use? Solution 3.A: Use method's annotation again. These were all of the problems with native calls. Now we need to agree if the solution proposed is OK or find another one. Please note, that this is just the first implementation. We can extend it with more features in the future. -- Mikhail Fursov
Re: [drlvm] Calling native methods from Java code: implementation details
Mihail, It may border on overengineering but I like Pavel's below approach. If you think its too hard to implement, my second choice would be your scheme. On 10/17/06, Pavel Afremov [EMAIL PROTECTED] wrote: Mikhail proposal is OK. But I think that following solution is better 1) The special interface MagicNativeCall should be created. The interface has only one method CallAddress getCallAddress(String methodName). All native methods of classes which implement this interface should be called by JIT via special magic way. 2) If JIT find call of native method, it tries to find call address using getCallAddress method. If null is returned by the method, usual call of JNI method should be processed. In other case magic native call can be included instead JNI call. Result returned by getCallAddress can and should be cashed by JIT for performance reasons. 3) I propose for the firs time use fastcall calling convention. In future new additional method can be added MagicNativeCall interface. It can be named as getCallType for example. If it returns JNI – jit should use stdcall, if FastWay – fast call. Also we can add special Magic type of calling convention. In this type of call one can select Register and stack slot for every parameter and return value. It can looks like: ReturnValue methodName(InParameterList ) or void methodName(InParameterList, OutParameterList). ReturValue is an void or OutValue, InParameterList is an empty or separated by comma , list of the InValue, OutParameterList is an empty or separated by comma , list of the OutValue. The OutValue can by one of OutRegisterParametr## or OutStackParametr##, where ## number of register or call in the stack, which are possible on the current platform. The InValue can be one of InRegisterParametr## or InStackParametr##. Register## and Stack## is the short aliases for InRegisterParametr## and InStackParametr## correspondently. Result is the short alias for OutRegisterParametr00 (EAX on ia32). Generics can be used for type safety. Thanks. Pavel Afremov. On 10/17/06, Rana Dasgupta [EMAIL PROTECTED] wrote: Mikhail, All this looks reasonable to me. At least to go ahead. Regarding 2A, could the jit cache this information for re-use? Alternatively, the JIT can do all this at startup...by going thru the contract class of fastpath java methods and querying the component manager for the native addresses of the slow counterparts. Thanks, Rana On 10/17/06, Mikhail Fursov [EMAIL PROTECTED] wrote: All, Finally we have almost everything finished to post helper's fast-path inlining framework into JIRA. The issue is left is how to call native slow-path versions of the from Java code. We already discussed some of the aspects, but there was no detailed discussion with a final agreement what API we will use. Let's make a final decision so I can add the code into JIRA. I'm sending my vision of the solution. Correct me or advise another approach. Step 1: How JIT will know if a Java method must be replaced with a native helper call. Solution 1.A: Every Java method that must be replaced with native call must be a static method and must have special Native runtime method annotation. Step 2: How JIT will get the address of the native method to generate a direct call? Solution 2.A: Every Java method that must be replaced with native call must have special Component annotation. JIT will use this annotation to ask Component Manager to access to the specified component by it's name and call void* getAddress(const char* methodName) component's method to get the address of a helper. That is every component that have native calls from Java must provide this interface. Step 3: How JIT will know which calling convention to use? Solution 3.A: Use method's annotation again. These were all of the problems with native calls. Now we need to agree if the solution proposed is OK or find another one. Please note, that this is just the first implementation. We can extend it with more features in the future. -- Mikhail Fursov -- Weldon Washburn Intel Middleware Products Division
Re: [drlvm] Calling native methods from Java code: implementation details
Hi, I think Pavel and Mikhail's proposals are essentially the same. Pavel's looks like more flexible, but I have a question with the special interface approach: is it possible that sometimes we want to call a library native method in fast way? If possible, shall we require all library classes that have the native method implement the special interface? Or, is it possible for the VM developer to override a library native method with a fast internal replacement that still keeps the semantics? In this situation, this method is not really implemented in the library class. Where will JIT find it? And we probably don't want over-generality to the design of fast native method invocation. We'd better keep them internally to the VM at the moment until we see real need to open this contract interface to external library/application developers. So if you agree with this, the set of non-JNI native methods for JIT to handle are very limited -- they are actually just some JVM internal functions (plus some special cases for speedup). We probably want them more closed than open just like the inlined helpers. Thanks, xiaofeng On 10/18/06, Pavel Afremov [EMAIL PROTECTED] wrote: Mikhail proposal is OK. But I think that following solution is better 1) The special interface MagicNativeCall should be created. The interface has only one method CallAddress getCallAddress(String methodName). All native methods of classes which implement this interface should be called by JIT via special magic way. 2) If JIT find call of native method, it tries to find call address using getCallAddress method. If null is returned by the method, usual call of JNI method should be processed. In other case magic native call can be included instead JNI call. Result returned by getCallAddress can and should be cashed by JIT for performance reasons. 3) I propose for the firs time use fastcall calling convention. In future new additional method can be added MagicNativeCall interface. It can be named as getCallType for example. If it returns JNI – jit should use stdcall, if FastWay – fast call. Also we can add special Magic type of calling convention. In this type of call one can select Register and stack slot for every parameter and return value. It can looks like: ReturnValue methodName(InParameterList ) or void methodName(InParameterList, OutParameterList). ReturValue is an void or OutValue, InParameterList is an empty or separated by comma , list of the InValue, OutParameterList is an empty or separated by comma , list of the OutValue. The OutValue can by one of OutRegisterParametr## or OutStackParametr##, where ## number of register or call in the stack, which are possible on the current platform. The InValue can be one of InRegisterParametr## or InStackParametr##. Register## and Stack## is the short aliases for InRegisterParametr## and InStackParametr## correspondently. Result is the short alias for OutRegisterParametr00 (EAX on ia32). Generics can be used for type safety. Thanks. Pavel Afremov. On 10/17/06, Rana Dasgupta [EMAIL PROTECTED] wrote: Mikhail, All this looks reasonable to me. At least to go ahead. Regarding 2A, could the jit cache this information for re-use? Alternatively, the JIT can do all this at startup...by going thru the contract class of fastpath java methods and querying the component manager for the native addresses of the slow counterparts. Thanks, Rana On 10/17/06, Mikhail Fursov [EMAIL PROTECTED] wrote: All, Finally we have almost everything finished to post helper's fast-path inlining framework into JIRA. The issue is left is how to call native slow-path versions of the from Java code. We already discussed some of the aspects, but there was no detailed discussion with a final agreement what API we will use. Let's make a final decision so I can add the code into JIRA. I'm sending my vision of the solution. Correct me or advise another approach. Step 1: How JIT will know if a Java method must be replaced with a native helper call. Solution 1.A: Every Java method that must be replaced with native call must be a static method and must have special Native runtime method annotation. Step 2: How JIT will get the address of the native method to generate a direct call? Solution 2.A: Every Java method that must be replaced with native call must have special Component annotation. JIT will use this annotation to ask Component Manager to access to the specified component by it's name and call void* getAddress(const char* methodName) component's method to get the address of a helper. That is every component that have native calls from Java must provide this interface. Step 3: How JIT will know which calling convention to use? Solution 3.A: Use method's annotation again. These were all of the problems with native calls. Now we need to agree if the solution proposed is OK or find another
Re: [drlvm] Calling native methods from Java code: implementation details
Pavel, Though the proposal look interesting, but some things are not clear. Could you please shed a bit of light on it? 1) The special interface MagicNativeCall should be created. The interface has only one method CallAddress getCallAddress(String methodName).. An interface method implies an instance of some class. 2) If JIT find call of native method, it tries to find call address using getCallAddress method. Are we still talking about *compilation* time? The JIT must know how to call the method *at the compile time*, long before the code is executed. What instance should the JIT use - again, at the compile time? And how? We can not use a lazy resolution scheme here, for both the performance and implemetation reasons: think about inlining of 'load_interface_vtable' helper. If its fast path fails, then it goes to the slow path. On the slow path the code must lazily resolve the slow path helper address, and to do this, it should call... surprise! surprise! load_interface_vtable helper. Recursion - see recursion :-) I don't see how the *runtime* things like interface/virtual methods may help at the *compile* time. I was thinking about something *really* static, what is known at the compile time, before the execution. Something like 'implements' or 'trows' clauses. Or annotations. -- Thanks, Alex Pavel Afremov wrote: Mikhail proposal is OK. But I think that following solution is better 1) The special interface MagicNativeCall should be created. The interface has only one method CallAddress getCallAddress(String methodName).. All native methods of classes which implement this interface should be called by JIT via special magic way. 2) If JIT find call of native method, it tries to find call address using getCallAddress method. If null is returned by the method, usual call of JNI method should be processed. In other case magic native call can be included instead JNI call. Result returned by getCallAddress can and should be cashed by JIT for performance reasons. 3) I propose for the firs time use fastcall calling convention. In future new additional method can be added MagicNativeCall interface. It can be named as getCallType for example. If it returns JNI – jit should use stdcall, if FastWay – fast call. Also we can add special Magic type of calling convention. In this type of call one can select Register and stack slot for every parameter and return value. It can looks like: ReturnValue methodName(InParameterList ) or void methodName(InParameterList, OutParameterList). ReturValue is an void or OutValue, InParameterList is an empty or separated by comma , list of the InValue, OutParameterList is an empty or separated by comma , list of the OutValue. The OutValue can by one of OutRegisterParametr## or OutStackParametr##, where ## number of register or call in the stack, which are possible on the current platform. The InValue can be one of InRegisterParametr## or InStackParametr##. Register## and Stack## is the short aliases for InRegisterParametr## and InStackParametr## correspondently. Result is the short alias for OutRegisterParametr00 (EAX on ia32). Generics can be used for type safety. Thanks. Pavel Afremov. On 10/17/06, Rana Dasgupta [EMAIL PROTECTED] wrote: Mikhail, All this looks reasonable to me. At least to go ahead. Regarding 2A, could the jit cache this information for re-use? Alternatively, the JIT can do all this at startup...by going thru the contract class of fastpath java methods and querying the component manager for the native addresses of the slow counterparts. Thanks, Rana On 10/17/06, Mikhail Fursov [EMAIL PROTECTED] wrote: All, Finally we have almost everything finished to post helper's fast-path inlining framework into JIRA. The issue is left is how to call native slow-path versions of the from Java code. We already discussed some of the aspects, but there was no detailed discussion with a final agreement what API we will use. Let's make a final decision so I can add the code into JIRA. I'm sending my vision of the solution. Correct me or advise another approach. Step 1: How JIT will know if a Java method must be replaced with a native helper call. Solution 1.A: Every Java method that must be replaced with native call must be a static method and must have special Native runtime method annotation. Step 2: How JIT will get the address of the native method to generate a direct call? Solution 2.A: Every Java method that must be replaced with native call must have special Component annotation. JIT will use this annotation to ask Component Manager to access to the specified component by it's name and call void* getAddress(const char* methodName) component's method to get the address of a helper. That is every component that have native calls from Java must provide this interface. Step 3: How JIT will know which calling convention to use? Solution