--- a/hotspot/src/cpu/x86/vm/c1_LIRGenerator_x86.cpp Mon Aug 31 08:31:45 2009 -0700
+++ b/hotspot/src/cpu/x86/vm/c1_LIRGenerator_x86.cpp Mon Aug 31 17:07:53 2009 -0700
@@ -827,8 +827,8 @@
case vmIntrinsics::_dsin: __ sin (calc_input, calc_result, tmp1, tmp2); break;
case vmIntrinsics::_dcos: __ cos (calc_input, calc_result, tmp1, tmp2); break;
case vmIntrinsics::_dtan: __ tan (calc_input, calc_result, tmp1, tmp2); break;
- case vmIntrinsics::_dlog: __ log (calc_input, calc_result, LIR_OprFact::illegalOpr); break;
- case vmIntrinsics::_dlog10: __ log10(calc_input, calc_result, LIR_OprFact::illegalOpr); break;
+ case vmIntrinsics::_dlog: __ log (calc_input, calc_result, tmp1); break;
+ case vmIntrinsics::_dlog10: __ log10(calc_input, calc_result, tmp1); break;
default: ShouldNotReachHere();
}
--- a/hotspot/src/cpu/x86/vm/c1_LinearScan_x86.cpp Mon Aug 31 08:31:45 2009 -0700
+++ b/hotspot/src/cpu/x86/vm/c1_LinearScan_x86.cpp Mon Aug 31 17:07:53 2009 -0700
@@ -764,8 +764,6 @@
break;
}
- case lir_log:
- case lir_log10:
case lir_abs:
case lir_sqrt: {
// Right argument appears to be unused
@@ -785,6 +783,30 @@
break;
}
+ case lir_log:
+ case lir_log10: {
+ // log and log10 needs one temporary fpu stack slot, so there is ontemporary
+ // registers stored in temp of the operation.
+ // the stack allocator must guarantee that the stack slots are really free,
+ // otherwise there might be a stack overflow.
+ assert(right->is_illegal(), "must be");
+ assert(left->is_fpu_register(), "must be");
+ assert(res->is_fpu_register(), "must be");
+ assert(op2->tmp_opr()->is_fpu_register(), "must be");
+
+ insert_free_if_dead(op2->tmp_opr());
+ insert_free_if_dead(res, left);
+ insert_exchange(left);
+ do_rename(left, res);
+
+ new_left = to_fpu_stack_top(res);
+ new_res = new_left;
+
+ op2->set_fpu_stack_size(sim()->stack_size());
+ assert(sim()->stack_size() <= 7, "at least one stack slot must be free");
+ break;
+ }
+
case lir_tan:
case lir_sin:
--- a/hotspot/src/share/vm/c1/c1_LIR.cpp Mon Aug 31 08:31:45 2009 -0700
+++ b/hotspot/src/share/vm/c1/c1_LIR.cpp Mon Aug 31 17:07:53 2009 -0700
@@ -567,8 +567,6 @@
case lir_rem:
case lir_sqrt:
case lir_abs:
- case lir_log:
- case lir_log10:
case lir_logic_and:
case lir_logic_or:
case lir_logic_xor:
@@ -644,13 +642,16 @@
case lir_tan:
case lir_sin:
- case lir_cos: {
+ case lir_cos:
+ case lir_log:
+ case lir_log10: {
assert(op->as_Op2() != NULL, "must be");
LIR_Op2* op2 = (LIR_Op2*)op;
- // sin and cos need two temporary fpu stack slots, so register
- // two temp operands. Register input operand as temp to
- // guarantee that they do not overlap
+ // On x86 tan/sin/cos need two temporary fpu stack slots and
+ // log/log10 need one so handle opr2 and tmp as temp inputs.
+ // Register input operand as temp to guarantee that it doesn't
+ // overlap with the input.
assert(op2->_info == NULL, "not used");
assert(op2->_opr1->is_valid(), "used");
do_input(op2->_opr1); do_temp(op2->_opr1);
--- a/hotspot/src/share/vm/c1/c1_LIR.hpp Mon Aug 31 08:31:45 2009 -0700
+++ b/hotspot/src/share/vm/c1/c1_LIR.hpp Mon Aug 31 17:07:53 2009 -0700
@@ -1840,8 +1840,8 @@
void abs (LIR_Opr from, LIR_Opr to, LIR_Opr tmp) { append(new LIR_Op2(lir_abs , from, tmp, to)); }
void sqrt(LIR_Opr from, LIR_Opr to, LIR_Opr tmp) { append(new LIR_Op2(lir_sqrt, from, tmp, to)); }
- void log (LIR_Opr from, LIR_Opr to, LIR_Opr tmp) { append(new LIR_Op2(lir_log, from, tmp, to)); }
- void log10 (LIR_Opr from, LIR_Opr to, LIR_Opr tmp) { append(new LIR_Op2(lir_log10, from, tmp, to)); }
+ void log (LIR_Opr from, LIR_Opr to, LIR_Opr tmp) { append(new LIR_Op2(lir_log, from, LIR_OprFact::illegalOpr, to, tmp)); }
+ void log10 (LIR_Opr from, LIR_Opr to, LIR_Opr tmp) { append(new LIR_Op2(lir_log10, from, LIR_OprFact::illegalOpr, to, tmp)); }
void sin (LIR_Opr from, LIR_Opr to, LIR_Opr tmp1, LIR_Opr tmp2) { append(new LIR_Op2(lir_sin , from, tmp1, to, tmp2)); }
void cos (LIR_Opr from, LIR_Opr to, LIR_Opr tmp1, LIR_Opr tmp2) { append(new LIR_Op2(lir_cos , from, tmp1, to, tmp2)); }
void tan (LIR_Opr from, LIR_Opr to, LIR_Opr tmp1, LIR_Opr tmp2) { append(new LIR_Op2(lir_tan , from, tmp1, to, tmp2)); }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/6855215/Test6855215.java Mon Aug 31 17:07:53 2009 -0700
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+/**
+ * @test
+ * @bug 6855215
+ * @summary Calculation error (NaN) after about 1500 calculations
+ *
+ * @run main/othervm -Xbatch -XX:UseSSE=0 Test6855215
+ */
+
+public class Test6855215 {
+ private double m;
+ private double b;
+
+ public static double log10(double x) {
+ return Math.log(x) / Math.log(10);
+ }
+
+ void calcMapping(double xmin, double xmax, double ymin, double ymax) {
+ m = (ymax - ymin) / (log10(xmax) - log10(xmin));
+ b = (log10(xmin) * ymax - log10(xmax) * ymin);
+ }
+
+ public static void main(String[] args) {
+ Test6855215 c = new Test6855215();
+ for (int i = 0; i < 30000; i++) {
+ c.calcMapping(91, 121, 177, 34);
+ if (c.m != c.m) {
+ throw new InternalError();
+ }
+ }
+ }
+}