United StatesChange Country, Oracle Worldwide Web Sites Communities I am a... I want to...
Bug ID: JDK-6741940 Nonvolatile XMM registers not preserved across JNI calls
JDK-6741940 : Nonvolatile XMM registers not preserved across JNI calls

Details
Type:
Bug
Submit Date:
2008-08-27
Status:
Closed
Updated Date:
2011-04-24
Project Name:
JDK
Resolved Date:
2011-04-24
Component:
hotspot
OS:
solaris_8
Sub-Component:
compiler
CPU:
x86
Priority:
P3
Resolution:
Fixed
Affected Versions:
6
Fixed Versions:
hs21 (b07)

Related Reports
Backport:

Sub Tasks

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
                                     
2011-03-30



Hardware and Software, Engineered to Work Together