JDK-8167408 : Invalid critical JNI function lookup
  • Type: Bug
  • Component: hotspot
  • Sub-Component: compiler
  • Affected Version: 9
  • Priority: P5
  • Status: Resolved
  • Resolution: Fixed
  • Submitted: 2016-10-10
  • Updated: 2019-09-13
  • Resolved: 2017-11-06
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 10
10 b33Fixed
Related Reports
Relates :  
Relates :  
Relates :  
Description
On 10/10/2016 10:34 AM, Ioannis Tsakpinis wrote:
> This patch fixes the lookup of critical JNI functions on Windows x86.
> 
> There are two problems with the argument size calculation in the
> lookup_critical_entry function:
> 
> 1) Critical natives do not have a JNIEnv parameter. Critical natives are
> always static, but do not have a jclass parameter. The current code assumes
> that both parameters exist and counts them against the total argument size.
> 
> 2) For each Java array parameter, the critical native gets an additional
> length parameter for that array. The current code does not count them.
> 
> On the 32-bit VM, the argument size is used to apply stdcall decorations to
> the function name. A wrong size is calculated with the current code, so the
> name used for the lookup is invalid (unless the function happens to have
> exactly two array parameters).
> 
> diff -r fec31089c2ef src/share/vm/prims/nativeLookup.cpp
> --- a/src/share/vm/prims/nativeLookup.cpp       Thu Oct 06 18:05:53 2016 -0700
> +++ b/src/share/vm/prims/nativeLookup.cpp       Sun Oct 09 22:44:54 2016 +0300
> @@ -293,10 +293,12 @@
>    char* critical_name = critical_jni_name(method);
> 
>    // Compute argument size
> -  int args_size = 1                             // JNIEnv
> -                + (method->is_static() ? 1 : 0) // class for static methods
> -                + method->size_of_parameters(); // actual parameters
> -
> +  int args_size = method->size_of_parameters(); // actual parameters
> +  for (SignatureStream ss(signature); !ss.at_return_type(); ss.next()) {
> +    if (ss.is_array()) {
> +        args_size += T_INT_size; // array length parameter
> +    }
> +  }
> 
>    // 1) Try JNI short style
>    entry = lookup_critical_style(method, critical_name, "",
> args_size, true);
> 
> In steps 3 and 4 the function lookup is done without a prefix/suffix, so a
> workaround is available. On msvc JNI functions can be exported without
> decorations, but it's not without pain: it requires pragmas or a .DEF file.
> 
> Regards,
> Ioannis
> 
Comments
Problem does not manifest as a regression or a failure (yet), deferring to 10.
12-10-2016

Hi Jamsheed, I'm assigning this to you (together with JDK-8167409, see detailed comment in that bug). Best regards, Zoltan
11-10-2016

ILW=invalid lookup that results in slightly reduced performance (not a regression, was there from the beginning),crypto native methods on solaris,no workaround=LMH=P5
11-10-2016

Thank you, David, for the link to JDK-7013347. It seems that the critical JNI calls have not much to do with JSR292, they are currently only used in the solaris implementation of some cryptographic functions. JavaCritical_com_oracle_security_ucrypto_NativeDigestMD_nativeInit; JavaCritical_com_oracle_security_ucrypto_NativeDigestMD_nativeUpdate; JavaCritical_com_oracle_security_ucrypto_NativeDigestMD_nativeDigest; JavaCritical_com_oracle_security_ucrypto_NativeDigestMD_nativeClone; JavaCritical_com_oracle_security_ucrypto_NativeDigestMD_nativeFree; JavaCritical_com_oracle_security_ucrypto_NativeDigest_nativeInit; JavaCritical_com_oracle_security_ucrypto_NativeDigest_nativeUpdate; JavaCritical_com_oracle_security_ucrypto_NativeDigest_nativeDigest; JavaCritical_com_oracle_security_ucrypto_NativeDigest_nativeFree; JavaCritical_com_oracle_security_ucrypto_NativeCipher_nativeInit; JavaCritical_com_oracle_security_ucrypto_NativeCipher_nativeUpdate; JavaCritical_com_oracle_security_ucrypto_NativeCipher_nativeFinal; JavaCritical_com_oracle_security_ucrypto_NativeKey_nativeFree; JavaCritical_com_oracle_security_ucrypto_NativeKey_00024RSAPrivate_nativeInit; JavaCritical_com_oracle_security_ucrypto_NativeKey_00024RSAPrivateCrt_nativeInit; JavaCritical_com_oracle_security_ucrypto_NativeKey_00024RSAPublic_nativeInit; JavaCritical_com_oracle_security_ucrypto_NativeRSASignature_nativeInit; JavaCritical_com_oracle_security_ucrypto_NativeRSASignature_nativeUpdate__JZ_3BII; JavaCritical_com_oracle_security_ucrypto_NativeRSASignature_nativeUpdate__JZJI; JavaCritical_com_oracle_security_ucrypto_NativeRSASignature_nativeFinal; JavaCritical_com_oracle_security_ucrypto_NativeRSACipher_nativeAtomic; All these functions have their non-critical equivalents: Java_com_oracle_security_ucrypto_NativeDigestMD_nativeInit; Java_com_oracle_security_ucrypto_NativeDigestMD_nativeUpdate; Java_com_oracle_security_ucrypto_NativeDigestMD_nativeDigest; Java_com_oracle_security_ucrypto_NativeDigestMD_nativeClone; Java_com_oracle_security_ucrypto_NativeDigestMD_nativeFree; Java_com_oracle_security_ucrypto_NativeDigest_nativeInit; Java_com_oracle_security_ucrypto_NativeDigest_nativeUpdate; Java_com_oracle_security_ucrypto_NativeDigest_nativeDigest; Java_com_oracle_security_ucrypto_NativeDigest_nativeFree; Java_com_oracle_security_ucrypto_NativeCipher_nativeInit; Java_com_oracle_security_ucrypto_NativeCipher_nativeUpdate; Java_com_oracle_security_ucrypto_NativeCipher_nativeFinal; Java_com_oracle_security_ucrypto_NativeKey_nativeFree; Java_com_oracle_security_ucrypto_NativeKey_00024RSAPrivate_nativeInit; Java_com_oracle_security_ucrypto_NativeKey_00024RSAPrivateCrt_nativeInit; Java_com_oracle_security_ucrypto_NativeKey_00024RSAPublic_nativeInit; Java_com_oracle_security_ucrypto_NativeRSASignature_nativeInit; Java_com_oracle_security_ucrypto_NativeRSASignature_nativeUpdate__JZ_3BII; Java_com_oracle_security_ucrypto_NativeRSASignature_nativeUpdate__JZJI; Java_com_oracle_security_ucrypto_NativeRSASignature_nativeFinal; Java_com_oracle_security_ucrypto_NativeRSACipher_nativeAtomic; If the critical lookup fails, the function is looked as a standard native function. (See SharedRuntime::generate_native_wrapper()).
11-10-2016

The code for critical JNI calls seems to have been added by the compiler team to optimize JSR292.
10-10-2016

Ioannis responds: The OS-specific bit comes in lookup_critical_style, which passes args_size to os::print_jni_name_prefix_on and os::print_jni_name_suffix_on. Afaict, these don't do anything except on Windows x86.
10-10-2016

See JDK-7013347 for where critical JNI functions were introduced. I don't see anything that would be Window specific here.
10-10-2016