Fri, 15 Jan 2010 11:53:33 -0800
6849984: Value methods for platform dependent math functions constant fold incorrectly
Reviewed-by: kvn, twisti
1.1 --- a/src/cpu/sparc/vm/interpreter_sparc.cpp Wed Jan 13 23:05:52 2010 -0800 1.2 +++ b/src/cpu/sparc/vm/interpreter_sparc.cpp Fri Jan 15 11:53:33 2010 -0800 1.3 @@ -1,5 +1,5 @@ 1.4 /* 1.5 - * Copyright 1997-2009 Sun Microsystems, Inc. All Rights Reserved. 1.6 + * Copyright 1997-2010 Sun Microsystems, Inc. All Rights Reserved. 1.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.8 * 1.9 * This code is free software; you can redistribute it and/or modify it 1.10 @@ -394,6 +394,11 @@ 1.11 } 1.12 1.13 1.14 +bool AbstractInterpreter::can_be_compiled(methodHandle m) { 1.15 + // No special entry points that preclude compilation 1.16 + return true; 1.17 +} 1.18 + 1.19 // This method tells the deoptimizer how big an interpreted frame must be: 1.20 int AbstractInterpreter::size_activation(methodOop method, 1.21 int tempcount,
2.1 --- a/src/cpu/sparc/vm/stubGenerator_sparc.cpp Wed Jan 13 23:05:52 2010 -0800 2.2 +++ b/src/cpu/sparc/vm/stubGenerator_sparc.cpp Fri Jan 15 11:53:33 2010 -0800 2.3 @@ -1,5 +1,5 @@ 2.4 /* 2.5 - * Copyright 1997-2009 Sun Microsystems, Inc. All Rights Reserved. 2.6 + * Copyright 1997-2010 Sun Microsystems, Inc. All Rights Reserved. 2.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 2.8 * 2.9 * This code is free software; you can redistribute it and/or modify it 2.10 @@ -2862,6 +2862,9 @@ 2.11 2.12 // arraycopy stubs used by compilers 2.13 generate_arraycopy_stubs(); 2.14 + 2.15 + // Don't initialize the platform math functions since sparc 2.16 + // doesn't have intrinsics for these operations. 2.17 } 2.18 2.19
3.1 --- a/src/cpu/x86/vm/stubGenerator_x86_32.cpp Wed Jan 13 23:05:52 2010 -0800 3.2 +++ b/src/cpu/x86/vm/stubGenerator_x86_32.cpp Fri Jan 15 11:53:33 2010 -0800 3.3 @@ -1,5 +1,5 @@ 3.4 /* 3.5 - * Copyright 1999-2009 Sun Microsystems, Inc. All Rights Reserved. 3.6 + * Copyright 1999-2010 Sun Microsystems, Inc. All Rights Reserved. 3.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 3.8 * 3.9 * This code is free software; you can redistribute it and/or modify it 3.10 @@ -2030,6 +2030,54 @@ 3.11 entry_checkcast_arraycopy); 3.12 } 3.13 3.14 + void generate_math_stubs() { 3.15 + { 3.16 + StubCodeMark mark(this, "StubRoutines", "log"); 3.17 + StubRoutines::_intrinsic_log = (double (*)(double)) __ pc(); 3.18 + 3.19 + __ fld_d(Address(rsp, 4)); 3.20 + __ flog(); 3.21 + __ ret(0); 3.22 + } 3.23 + { 3.24 + StubCodeMark mark(this, "StubRoutines", "log10"); 3.25 + StubRoutines::_intrinsic_log10 = (double (*)(double)) __ pc(); 3.26 + 3.27 + __ fld_d(Address(rsp, 4)); 3.28 + __ flog10(); 3.29 + __ ret(0); 3.30 + } 3.31 + { 3.32 + StubCodeMark mark(this, "StubRoutines", "sin"); 3.33 + StubRoutines::_intrinsic_sin = (double (*)(double)) __ pc(); 3.34 + 3.35 + __ fld_d(Address(rsp, 4)); 3.36 + __ trigfunc('s'); 3.37 + __ ret(0); 3.38 + } 3.39 + { 3.40 + StubCodeMark mark(this, "StubRoutines", "cos"); 3.41 + StubRoutines::_intrinsic_cos = (double (*)(double)) __ pc(); 3.42 + 3.43 + __ fld_d(Address(rsp, 4)); 3.44 + __ trigfunc('c'); 3.45 + __ ret(0); 3.46 + } 3.47 + { 3.48 + StubCodeMark mark(this, "StubRoutines", "tan"); 3.49 + StubRoutines::_intrinsic_tan = (double (*)(double)) __ pc(); 3.50 + 3.51 + __ fld_d(Address(rsp, 4)); 3.52 + __ trigfunc('t'); 3.53 + __ ret(0); 3.54 + } 3.55 + 3.56 + // The intrinsic version of these seem to return the same value as 3.57 + // the strict version. 3.58 + StubRoutines::_intrinsic_exp = SharedRuntime::dexp; 3.59 + StubRoutines::_intrinsic_pow = SharedRuntime::dpow; 3.60 + } 3.61 + 3.62 public: 3.63 // Information about frame layout at time of blocking runtime call. 3.64 // Note that we only have to preserve callee-saved registers since 3.65 @@ -2228,6 +2276,8 @@ 3.66 MethodHandles::generate_method_handle_stub(_masm, ek); 3.67 } 3.68 } 3.69 + 3.70 + generate_math_stubs(); 3.71 } 3.72 3.73
4.1 --- a/src/cpu/x86/vm/stubGenerator_x86_64.cpp Wed Jan 13 23:05:52 2010 -0800 4.2 +++ b/src/cpu/x86/vm/stubGenerator_x86_64.cpp Fri Jan 15 11:53:33 2010 -0800 4.3 @@ -1,5 +1,5 @@ 4.4 /* 4.5 - * Copyright 2003-2009 Sun Microsystems, Inc. All Rights Reserved. 4.6 + * Copyright 2003-2010 Sun Microsystems, Inc. All Rights Reserved. 4.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4.8 * 4.9 * This code is free software; you can redistribute it and/or modify it 4.10 @@ -2731,6 +2731,79 @@ 4.11 StubRoutines::_arrayof_oop_arraycopy = StubRoutines::_oop_arraycopy; 4.12 } 4.13 4.14 + void generate_math_stubs() { 4.15 + { 4.16 + StubCodeMark mark(this, "StubRoutines", "log"); 4.17 + StubRoutines::_intrinsic_log = (double (*)(double)) __ pc(); 4.18 + 4.19 + __ subq(rsp, 8); 4.20 + __ movdbl(Address(rsp, 0), xmm0); 4.21 + __ fld_d(Address(rsp, 0)); 4.22 + __ flog(); 4.23 + __ fstp_d(Address(rsp, 0)); 4.24 + __ movdbl(xmm0, Address(rsp, 0)); 4.25 + __ addq(rsp, 8); 4.26 + __ ret(0); 4.27 + } 4.28 + { 4.29 + StubCodeMark mark(this, "StubRoutines", "log10"); 4.30 + StubRoutines::_intrinsic_log10 = (double (*)(double)) __ pc(); 4.31 + 4.32 + __ subq(rsp, 8); 4.33 + __ movdbl(Address(rsp, 0), xmm0); 4.34 + __ fld_d(Address(rsp, 0)); 4.35 + __ flog10(); 4.36 + __ fstp_d(Address(rsp, 0)); 4.37 + __ movdbl(xmm0, Address(rsp, 0)); 4.38 + __ addq(rsp, 8); 4.39 + __ ret(0); 4.40 + } 4.41 + { 4.42 + StubCodeMark mark(this, "StubRoutines", "sin"); 4.43 + StubRoutines::_intrinsic_sin = (double (*)(double)) __ pc(); 4.44 + 4.45 + __ subq(rsp, 8); 4.46 + __ movdbl(Address(rsp, 0), xmm0); 4.47 + __ fld_d(Address(rsp, 0)); 4.48 + __ trigfunc('s'); 4.49 + __ fstp_d(Address(rsp, 0)); 4.50 + __ movdbl(xmm0, Address(rsp, 0)); 4.51 + __ addq(rsp, 8); 4.52 + __ ret(0); 4.53 + } 4.54 + { 4.55 + StubCodeMark mark(this, "StubRoutines", "cos"); 4.56 + StubRoutines::_intrinsic_cos = (double (*)(double)) __ pc(); 4.57 + 4.58 + __ subq(rsp, 8); 4.59 + __ movdbl(Address(rsp, 0), xmm0); 4.60 + __ fld_d(Address(rsp, 0)); 4.61 + __ trigfunc('c'); 4.62 + __ fstp_d(Address(rsp, 0)); 4.63 + __ movdbl(xmm0, Address(rsp, 0)); 4.64 + __ addq(rsp, 8); 4.65 + __ ret(0); 4.66 + } 4.67 + { 4.68 + StubCodeMark mark(this, "StubRoutines", "tan"); 4.69 + StubRoutines::_intrinsic_tan = (double (*)(double)) __ pc(); 4.70 + 4.71 + __ subq(rsp, 8); 4.72 + __ movdbl(Address(rsp, 0), xmm0); 4.73 + __ fld_d(Address(rsp, 0)); 4.74 + __ trigfunc('t'); 4.75 + __ fstp_d(Address(rsp, 0)); 4.76 + __ movdbl(xmm0, Address(rsp, 0)); 4.77 + __ addq(rsp, 8); 4.78 + __ ret(0); 4.79 + } 4.80 + 4.81 + // The intrinsic version of these seem to return the same value as 4.82 + // the strict version. 4.83 + StubRoutines::_intrinsic_exp = SharedRuntime::dexp; 4.84 + StubRoutines::_intrinsic_pow = SharedRuntime::dpow; 4.85 + } 4.86 + 4.87 #undef __ 4.88 #define __ masm-> 4.89 4.90 @@ -2945,6 +3018,8 @@ 4.91 MethodHandles::generate_method_handle_stub(_masm, ek); 4.92 } 4.93 } 4.94 + 4.95 + generate_math_stubs(); 4.96 } 4.97 4.98 public:
5.1 --- a/src/cpu/x86/vm/templateInterpreter_x86_32.cpp Wed Jan 13 23:05:52 2010 -0800 5.2 +++ b/src/cpu/x86/vm/templateInterpreter_x86_32.cpp Fri Jan 15 11:53:33 2010 -0800 5.3 @@ -1,5 +1,5 @@ 5.4 /* 5.5 - * Copyright 1997-2009 Sun Microsystems, Inc. All Rights Reserved. 5.6 + * Copyright 1997-2010 Sun Microsystems, Inc. All Rights Reserved. 5.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 5.8 * 5.9 * This code is free software; you can redistribute it and/or modify it 5.10 @@ -1431,6 +1431,23 @@ 5.11 5.12 } 5.13 5.14 +// These should never be compiled since the interpreter will prefer 5.15 +// the compiled version to the intrinsic version. 5.16 +bool AbstractInterpreter::can_be_compiled(methodHandle m) { 5.17 + switch (method_kind(m)) { 5.18 + case Interpreter::java_lang_math_sin : // fall thru 5.19 + case Interpreter::java_lang_math_cos : // fall thru 5.20 + case Interpreter::java_lang_math_tan : // fall thru 5.21 + case Interpreter::java_lang_math_abs : // fall thru 5.22 + case Interpreter::java_lang_math_log : // fall thru 5.23 + case Interpreter::java_lang_math_log10 : // fall thru 5.24 + case Interpreter::java_lang_math_sqrt : 5.25 + return false; 5.26 + default: 5.27 + return true; 5.28 + } 5.29 +} 5.30 + 5.31 // How much stack a method activation needs in words. 5.32 int AbstractInterpreter::size_top_interpreter_activation(methodOop method) { 5.33
6.1 --- a/src/cpu/x86/vm/templateInterpreter_x86_64.cpp Wed Jan 13 23:05:52 2010 -0800 6.2 +++ b/src/cpu/x86/vm/templateInterpreter_x86_64.cpp Fri Jan 15 11:53:33 2010 -0800 6.3 @@ -1,5 +1,5 @@ 6.4 /* 6.5 - * Copyright 2003-2009 Sun Microsystems, Inc. All Rights Reserved. 6.6 + * Copyright 2003-2010 Sun Microsystems, Inc. All Rights Reserved. 6.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 6.8 * 6.9 * This code is free software; you can redistribute it and/or modify it 6.10 @@ -1456,6 +1456,23 @@ 6.11 generate_normal_entry(synchronized); 6.12 } 6.13 6.14 +// These should never be compiled since the interpreter will prefer 6.15 +// the compiled version to the intrinsic version. 6.16 +bool AbstractInterpreter::can_be_compiled(methodHandle m) { 6.17 + switch (method_kind(m)) { 6.18 + case Interpreter::java_lang_math_sin : // fall thru 6.19 + case Interpreter::java_lang_math_cos : // fall thru 6.20 + case Interpreter::java_lang_math_tan : // fall thru 6.21 + case Interpreter::java_lang_math_abs : // fall thru 6.22 + case Interpreter::java_lang_math_log : // fall thru 6.23 + case Interpreter::java_lang_math_log10 : // fall thru 6.24 + case Interpreter::java_lang_math_sqrt : 6.25 + return false; 6.26 + default: 6.27 + return true; 6.28 + } 6.29 +} 6.30 + 6.31 // How much stack a method activation needs in words. 6.32 int AbstractInterpreter::size_top_interpreter_activation(methodOop method) { 6.33 const int entry_size = frame::interpreter_frame_monitor_size();
7.1 --- a/src/share/vm/interpreter/abstractInterpreter.hpp Wed Jan 13 23:05:52 2010 -0800 7.2 +++ b/src/share/vm/interpreter/abstractInterpreter.hpp Fri Jan 15 11:53:33 2010 -0800 7.3 @@ -1,5 +1,5 @@ 7.4 /* 7.5 - * Copyright 1997-2009 Sun Microsystems, Inc. All Rights Reserved. 7.6 + * Copyright 1997-2010 Sun Microsystems, Inc. All Rights Reserved. 7.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 7.8 * 7.9 * This code is free software; you can redistribute it and/or modify it 7.10 @@ -109,6 +109,8 @@ 7.11 7.12 static void print_method_kind(MethodKind kind) PRODUCT_RETURN; 7.13 7.14 + static bool can_be_compiled(methodHandle m); 7.15 + 7.16 // Runtime support 7.17 7.18 // length = invoke bytecode length (to advance to next bytecode)
8.1 --- a/src/share/vm/opto/subnode.cpp Wed Jan 13 23:05:52 2010 -0800 8.2 +++ b/src/share/vm/opto/subnode.cpp Fri Jan 15 11:53:33 2010 -0800 8.3 @@ -1,5 +1,5 @@ 8.4 /* 8.5 - * Copyright 1997-2009 Sun Microsystems, Inc. All Rights Reserved. 8.6 + * Copyright 1997-2010 Sun Microsystems, Inc. All Rights Reserved. 8.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 8.8 * 8.9 * This code is free software; you can redistribute it and/or modify it 8.10 @@ -1244,8 +1244,7 @@ 8.11 if( t1 == Type::TOP ) return Type::TOP; 8.12 if( t1->base() != Type::DoubleCon ) return Type::DOUBLE; 8.13 double d = t1->getd(); 8.14 - if( d < 0.0 ) return Type::DOUBLE; 8.15 - return TypeD::make( SharedRuntime::dcos( d ) ); 8.16 + return TypeD::make( StubRoutines::intrinsic_cos( d ) ); 8.17 } 8.18 8.19 //============================================================================= 8.20 @@ -1256,8 +1255,7 @@ 8.21 if( t1 == Type::TOP ) return Type::TOP; 8.22 if( t1->base() != Type::DoubleCon ) return Type::DOUBLE; 8.23 double d = t1->getd(); 8.24 - if( d < 0.0 ) return Type::DOUBLE; 8.25 - return TypeD::make( SharedRuntime::dsin( d ) ); 8.26 + return TypeD::make( StubRoutines::intrinsic_sin( d ) ); 8.27 } 8.28 8.29 //============================================================================= 8.30 @@ -1268,8 +1266,7 @@ 8.31 if( t1 == Type::TOP ) return Type::TOP; 8.32 if( t1->base() != Type::DoubleCon ) return Type::DOUBLE; 8.33 double d = t1->getd(); 8.34 - if( d < 0.0 ) return Type::DOUBLE; 8.35 - return TypeD::make( SharedRuntime::dtan( d ) ); 8.36 + return TypeD::make( StubRoutines::intrinsic_tan( d ) ); 8.37 } 8.38 8.39 //============================================================================= 8.40 @@ -1280,8 +1277,7 @@ 8.41 if( t1 == Type::TOP ) return Type::TOP; 8.42 if( t1->base() != Type::DoubleCon ) return Type::DOUBLE; 8.43 double d = t1->getd(); 8.44 - if( d < 0.0 ) return Type::DOUBLE; 8.45 - return TypeD::make( SharedRuntime::dlog( d ) ); 8.46 + return TypeD::make( StubRoutines::intrinsic_log( d ) ); 8.47 } 8.48 8.49 //============================================================================= 8.50 @@ -1292,8 +1288,7 @@ 8.51 if( t1 == Type::TOP ) return Type::TOP; 8.52 if( t1->base() != Type::DoubleCon ) return Type::DOUBLE; 8.53 double d = t1->getd(); 8.54 - if( d < 0.0 ) return Type::DOUBLE; 8.55 - return TypeD::make( SharedRuntime::dlog10( d ) ); 8.56 + return TypeD::make( StubRoutines::intrinsic_log10( d ) ); 8.57 } 8.58 8.59 //============================================================================= 8.60 @@ -1304,8 +1299,7 @@ 8.61 if( t1 == Type::TOP ) return Type::TOP; 8.62 if( t1->base() != Type::DoubleCon ) return Type::DOUBLE; 8.63 double d = t1->getd(); 8.64 - if( d < 0.0 ) return Type::DOUBLE; 8.65 - return TypeD::make( SharedRuntime::dexp( d ) ); 8.66 + return TypeD::make( StubRoutines::intrinsic_exp( d ) ); 8.67 } 8.68 8.69 8.70 @@ -1323,5 +1317,5 @@ 8.71 double d2 = t2->getd(); 8.72 if( d1 < 0.0 ) return Type::DOUBLE; 8.73 if( d2 < 0.0 ) return Type::DOUBLE; 8.74 - return TypeD::make( SharedRuntime::dpow( d1, d2 ) ); 8.75 + return TypeD::make( StubRoutines::intrinsic_pow( d1, d2 ) ); 8.76 }
9.1 --- a/src/share/vm/runtime/compilationPolicy.cpp Wed Jan 13 23:05:52 2010 -0800 9.2 +++ b/src/share/vm/runtime/compilationPolicy.cpp Fri Jan 15 11:53:33 2010 -0800 9.3 @@ -1,5 +1,5 @@ 9.4 /* 9.5 - * Copyright 2000-2007 Sun Microsystems, Inc. All Rights Reserved. 9.6 + * Copyright 2000-2010 Sun Microsystems, Inc. All Rights Reserved. 9.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 9.8 * 9.9 * This code is free software; you can redistribute it and/or modify it 9.10 @@ -74,6 +74,16 @@ 9.11 if (m->is_abstract()) return false; 9.12 if (DontCompileHugeMethods && m->code_size() > HugeMethodLimit) return false; 9.13 9.14 + // Math intrinsics should never be compiled as this can lead to 9.15 + // monotonicity problems because the interpreter will prefer the 9.16 + // compiled code to the intrinsic version. This can't happen in 9.17 + // production because the invocation counter can't be incremented 9.18 + // but we shouldn't expose the system to this problem in testing 9.19 + // modes. 9.20 + if (!AbstractInterpreter::can_be_compiled(m)) { 9.21 + return false; 9.22 + } 9.23 + 9.24 return !m->is_not_compilable(); 9.25 } 9.26
10.1 --- a/src/share/vm/runtime/stubRoutines.cpp Wed Jan 13 23:05:52 2010 -0800 10.2 +++ b/src/share/vm/runtime/stubRoutines.cpp Fri Jan 15 11:53:33 2010 -0800 10.3 @@ -1,5 +1,5 @@ 10.4 /* 10.5 - * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. 10.6 + * Copyright 1997-2010 Sun Microsystems, Inc. All Rights Reserved. 10.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 10.8 * 10.9 * This code is free software; you can redistribute it and/or modify it 10.10 @@ -97,6 +97,14 @@ 10.11 address StubRoutines::_unsafe_arraycopy = NULL; 10.12 address StubRoutines::_generic_arraycopy = NULL; 10.13 10.14 +double (* StubRoutines::_intrinsic_log )(double) = NULL; 10.15 +double (* StubRoutines::_intrinsic_log10 )(double) = NULL; 10.16 +double (* StubRoutines::_intrinsic_exp )(double) = NULL; 10.17 +double (* StubRoutines::_intrinsic_pow )(double, double) = NULL; 10.18 +double (* StubRoutines::_intrinsic_sin )(double) = NULL; 10.19 +double (* StubRoutines::_intrinsic_cos )(double) = NULL; 10.20 +double (* StubRoutines::_intrinsic_tan )(double) = NULL; 10.21 + 10.22 // Initialization 10.23 // 10.24 // Note: to break cycle with universe initialization, stubs are generated in two phases.
11.1 --- a/src/share/vm/runtime/stubRoutines.hpp Wed Jan 13 23:05:52 2010 -0800 11.2 +++ b/src/share/vm/runtime/stubRoutines.hpp Fri Jan 15 11:53:33 2010 -0800 11.3 @@ -1,5 +1,5 @@ 11.4 /* 11.5 - * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. 11.6 + * Copyright 1997-2010 Sun Microsystems, Inc. All Rights Reserved. 11.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 11.8 * 11.9 * This code is free software; you can redistribute it and/or modify it 11.10 @@ -148,6 +148,20 @@ 11.11 static address _unsafe_arraycopy; 11.12 static address _generic_arraycopy; 11.13 11.14 + // These are versions of the java.lang.Math methods which perform 11.15 + // the same operations as the intrinsic version. They are used for 11.16 + // constant folding in the compiler to ensure equivalence. If the 11.17 + // intrinsic version returns the same result as the strict version 11.18 + // then they can be set to the appropriate function from 11.19 + // SharedRuntime. 11.20 + static double (*_intrinsic_log)(double); 11.21 + static double (*_intrinsic_log10)(double); 11.22 + static double (*_intrinsic_exp)(double); 11.23 + static double (*_intrinsic_pow)(double, double); 11.24 + static double (*_intrinsic_sin)(double); 11.25 + static double (*_intrinsic_cos)(double); 11.26 + static double (*_intrinsic_tan)(double); 11.27 + 11.28 public: 11.29 // Initialization/Testing 11.30 static void initialize1(); // must happen before universe::genesis 11.31 @@ -245,6 +259,35 @@ 11.32 static address unsafe_arraycopy() { return _unsafe_arraycopy; } 11.33 static address generic_arraycopy() { return _generic_arraycopy; } 11.34 11.35 + static double intrinsic_log(double d) { 11.36 + assert(_intrinsic_log != NULL, "must be defined"); 11.37 + return _intrinsic_log(d); 11.38 + } 11.39 + static double intrinsic_log10(double d) { 11.40 + assert(_intrinsic_log != NULL, "must be defined"); 11.41 + return _intrinsic_log10(d); 11.42 + } 11.43 + static double intrinsic_exp(double d) { 11.44 + assert(_intrinsic_exp != NULL, "must be defined"); 11.45 + return _intrinsic_exp(d); 11.46 + } 11.47 + static double intrinsic_pow(double d, double d2) { 11.48 + assert(_intrinsic_pow != NULL, "must be defined"); 11.49 + return _intrinsic_pow(d, d2); 11.50 + } 11.51 + static double intrinsic_sin(double d) { 11.52 + assert(_intrinsic_sin != NULL, "must be defined"); 11.53 + return _intrinsic_sin(d); 11.54 + } 11.55 + static double intrinsic_cos(double d) { 11.56 + assert(_intrinsic_cos != NULL, "must be defined"); 11.57 + return _intrinsic_cos(d); 11.58 + } 11.59 + static double intrinsic_tan(double d) { 11.60 + assert(_intrinsic_tan != NULL, "must be defined"); 11.61 + return _intrinsic_tan(d); 11.62 + } 11.63 + 11.64 // 11.65 // Default versions of the above arraycopy functions for platforms which do 11.66 // not have specialized versions