JDK-6741940 : Nonvolatile XMM registers not preserved across JNI calls
  • Type: Bug
  • Component: hotspot
  • Sub-Component: compiler
  • Affected Version: 6
  • Priority: P3
  • Status: Closed
  • Resolution: Fixed
  • OS: solaris_8
  • CPU: x86
  • Submitted: 2008-08-27
  • Updated: 2014-12-17
  • Resolved: 2011-04-24
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 7 Other
7Fixed hs21Fixed
Related Reports
Relates :  
Description
FULL PRODUCT VERSION :
java version "1.6.0_04"
Java(TM) SE Runtime Environment (build 1.6.0_04-b12)
Java HotSpot(TM) 64-Bit Server VM (build 10.0-b19, mixed mode)

FULL OS VERSION :
Microsoft Windows [Version 5.2.3790]

A DESCRIPTION OF THE PROBLEM :
See attached program.  Calls to the JNI entry point "CallVoidMethod" do not preserve the nonvolatile XMM registers, unless running with -Xint.  This is in violation of the Windows 64-bit ABI:
http://msdn.microsoft.com/en-us/library/ms794547.aspx

The Java method being invoked is doing an extensive amount of floating point arithmetic, so it appears that the Hotspot generated code may be at fault.

We cannot build for 64-bit Windows using Profile Guided Optimization (PGO) until this issue is resolved, since a PGO build relies on full compliance with the ABI specification.


THE PROBLEM WAS REPRODUCIBLE WITH -Xint FLAG: No

THE PROBLEM WAS REPRODUCIBLE WITH -server FLAG: Yes

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Start Visual Studio 2005 x64 Win64 Command Prompt

cl /Zi /Ic:\Progra~1\Java\jdk1.6.0\include /Ic:\Progra~1\Java\jdk1.6.0\include\win32 /EHsc c:\Progra~1\Java\jdk1.6.0\lib\jvm.lib JNI-test.cpp

set PATH=c:\Program Files\Java\jre1.6.0_04\bin\server;%path%

run JNI-test.exe under Visual Studio debugger
set breakpoint at call to CallVoidMethod
Monitor value of XMM registers before and after call.  After the 3rd or 4th call, the nonvolatile registers are changed.

EXPECTED VERSUS ACTUAL BEHAVIOR :
Nonvolatile XMM registers XMM6:XMM15 will show differences after JNI calls.  They should always be preserved.
ERROR MESSAGES/STACK TRACES THAT OCCUR :
There are no error messages.  The behavior must be observed using a debugger.


REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
#include <iostream>
#include <stdio.h>
#include <jni.h>

JNIEnv* create_vm() {
	JavaVM* jvm;
	JNIEnv* env;
	JavaVMInitArgs args;
	JavaVMOption options[1];

	args.version = JNI_VERSION_1_4;
	args.nOptions = 1;
	options[0].optionString = "-Djava.class.path=h:/gecks/g417269/patch";
	args.options = options;
	args.ignoreUnrecognized = JNI_FALSE;

	JNI_CreateJavaVM(&jvm, (void**)&env, &args);
	return env;
}

void invoke_class(JNIEnv* env) {
	jclass testFPClass;
	jmethodID initMethod;
	jmethodID testMethod;
	jobject testResult;

	testFPClass = env->FindClass("com/mathworks/bde/graphLayout/FadeLayout");
	initMethod = env->GetStaticMethodID(testFPClass, "init", "()Lcom/mathworks/bde/graphLayout/FadeLayout;");
	testResult = env->CallStaticObjectMethod(testFPClass, initMethod, NULL);
    jclass cls = env->GetObjectClass(testResult);
	testMethod = env->GetMethodID(cls, "fadeStep", "()V");
    for (int i = 0; i < 10; i++) {
	 env->CallVoidMethod(testResult, testMethod, NULL);
                      // at this point, several of the XMM6:XMM15 registers are
                     // modified
    }
}

int main(int argc, char **argv) {
	JNIEnv* env = create_vm();
	char temp = 0;
	//std::cin >> temp;
	invoke_class( env );
}

---------- END SOURCE ----------

CUSTOMER SUBMITTED WORKAROUND :
We have not found one.

Comments
EVALUATION http://hg.openjdk.java.net/jdk7/hotspot-comp/hotspot/rev/b1c22848507b
30-03-2011