--- old/src/cpu/sparc/vm/sharedRuntime_sparc.cpp Thu Feb 18 19:05:37 2010 +++ new/src/cpu/sparc/vm/sharedRuntime_sparc.cpp Thu Feb 18 19:05:37 2010 @@ -314,6 +314,13 @@ } // --------------------------------------------------------------------------- +// This method is used to read a float value from stack but sparc does not +// handle callee-save floats yet so this method should not be called. +StackValue* StackValue::create_float_stack_value(address value_addr) { + ShouldNotCallThis(); return NULL; +} + +// --------------------------------------------------------------------------- // Read the array of BasicTypes from a signature, and compute where the // arguments should go. Values in the VMRegPair regs array refer to 4-byte (VMRegImpl::stack_slot_size) // quantities. Values less than VMRegImpl::stack0 are registers, those above --- old/src/cpu/x86/vm/sharedRuntime_x86_32.cpp Thu Feb 18 19:05:37 2010 +++ new/src/cpu/x86/vm/sharedRuntime_x86_32.cpp Thu Feb 18 19:05:37 2010 @@ -319,6 +319,23 @@ } // --------------------------------------------------------------------------- +// This method is used to read a float value which could be saved on stack +// as double (see RegisterSaver::save_live_registers() above). +StackValue* StackValue::create_float_stack_value(address value_addr) { + union { intptr_t p; jfloat jf; } value; + value.p = (intptr_t) CONST64(0xDEADDEAFDEADDEAF); + if (UseSSE >=1) { + // XMM registers are used for float values and they are saved as float or + // as double without conversion. Read lowest 32 bit to get float value. + value.jf = *(jfloat*) value_addr; + } else { + // FPU stores with conversion to double. Convert it back to float. + value.jf = (jfloat) *(jdouble*) value_addr; + } + return new StackValue(value.p); // 64-bit high half is stack junk +} + +// --------------------------------------------------------------------------- // Read the array of BasicTypes from a signature, and compute where the // arguments should go. Values in the VMRegPair regs array refer to 4-byte // quantities. Values less than SharedInfo::stack0 are registers, those above --- old/src/cpu/x86/vm/sharedRuntime_x86_64.cpp Thu Feb 18 19:05:38 2010 +++ new/src/cpu/x86/vm/sharedRuntime_x86_64.cpp Thu Feb 18 19:05:38 2010 @@ -310,6 +310,18 @@ } // --------------------------------------------------------------------------- +// This method is used to read a float value which is saved on stack as double +// (see RegisterSaver::save_live_registers() above). +StackValue* StackValue::create_float_stack_value(address value_addr) { + union { intptr_t p; jfloat jf; } value; + value.p = (intptr_t) CONST64(0xDEADDEAFDEADDEAF); + // XMM registers are used for float values and they are saved as double + // without conversion. Read lowest 32 bit to get float value. + value.jf = *(jfloat*) value_addr; + return new StackValue(value.p); // 64-bit high half is stack junk +} + +// --------------------------------------------------------------------------- // Read the array of BasicTypes from a signature, and compute where the // arguments should go. Values in the VMRegPair regs array refer to 4-byte // quantities. Values less than VMRegImpl::stack0 are registers, those above --- old/src/share/vm/runtime/stackValue.cpp Thu Feb 18 19:05:39 2010 +++ new/src/share/vm/runtime/stackValue.cpp Thu Feb 18 19:05:39 2010 @@ -58,15 +58,9 @@ // switch( loc.type() ) { case Location::float_in_dbl: { // Holds a float in a double register? - // The callee has no clue whether the register holds a float, - // double or is unused. He always saves a double. Here we know - // a double was saved, but we only want a float back. Narrow the - // saved double to the float that the JVM wants. assert( loc.is_register(), "floats always saved to stack in 1 word" ); - union { intptr_t p; jfloat jf; } value; - value.p = (intptr_t) CONST64(0xDEADDEAFDEADDEAF); - value.jf = (jfloat) *(jdouble*) value_addr; - return new StackValue(value.p); // 64-bit high half is stack junk + // Call platform specific function defined in sharedRuntime_.cpp. + return create_float_stack_value(value_addr); } case Location::int_in_long: { // Holds an int in a long register? // The callee has no clue whether the register holds an int, --- old/src/share/vm/runtime/stackValue.hpp Thu Feb 18 19:05:39 2010 +++ new/src/share/vm/runtime/stackValue.hpp Thu Feb 18 19:05:39 2010 @@ -100,6 +100,9 @@ static StackValue* create_stack_value(const frame* fr, const RegisterMap* reg_map, ScopeValue* sv); static BasicLock* resolve_monitor_lock(const frame* fr, Location location); + // Platform specific function defined in sharedRuntime_.cpp. + static StackValue* create_float_stack_value(address value_addr); + #ifndef PRODUCT public: // Printing