8169711: CDS does not patch entry trampoline if intrinsic method is disabled

Always create interpreter method entries for intrinsified methods but replace them with vanilla entries if the intrinsic is disabled at runtime.

Reviewed-by: kvn, iklam
This commit is contained in:
Tobias Hartmann 2016-11-21 08:27:10 +01:00
parent d1f8287a49
commit 94e3514d8f
7 changed files with 132 additions and 43 deletions

View File

@ -203,6 +203,9 @@ address TemplateInterpreterGenerator::generate_math_entry(AbstractInterpreter::M
__ mov(sp, r13);
generate_transcendental_entry(kind, 2);
break;
case Interpreter::java_lang_math_fmaD :
case Interpreter::java_lang_math_fmaF :
return NULL;
default:
;
}

View File

@ -351,7 +351,7 @@ void VM_Version::initialize() {
FLAG_SET_DEFAULT(UseCRC32Intrinsics, true);
}
} else if (UseCRC32Intrinsics) {
warning("SPARC CRC32 intrinsics require VIS3 insructions support. Intriniscs will be disabled");
warning("SPARC CRC32 intrinsics require VIS3 instructions support. Intrinsics will be disabled");
FLAG_SET_DEFAULT(UseCRC32Intrinsics, false);
}

View File

@ -342,6 +342,9 @@ address TemplateInterpreterGenerator::generate_math_entry(AbstractInterpreter::M
// [ hi(arg) ]
//
if (kind == Interpreter::java_lang_math_fmaD) {
if (!UseFMA) {
return NULL; // Generate a vanilla entry
}
__ movdbl(xmm2, Address(rsp, 5 * wordSize));
__ movdbl(xmm1, Address(rsp, 3 * wordSize));
__ movdbl(xmm0, Address(rsp, 1 * wordSize));
@ -352,6 +355,9 @@ address TemplateInterpreterGenerator::generate_math_entry(AbstractInterpreter::M
return entry_point;
} else if (kind == Interpreter::java_lang_math_fmaF) {
if (!UseFMA) {
return NULL; // Generate a vanilla entry
}
__ movflt(xmm2, Address(rsp, 3 * wordSize));
__ movflt(xmm1, Address(rsp, 2 * wordSize));
__ movflt(xmm0, Address(rsp, 1 * wordSize));

View File

@ -370,11 +370,17 @@ address TemplateInterpreterGenerator::generate_math_entry(AbstractInterpreter::M
//
if (kind == Interpreter::java_lang_math_fmaD) {
if (!UseFMA) {
return NULL; // Generate a vanilla entry
}
__ movdbl(xmm0, Address(rsp, wordSize));
__ movdbl(xmm1, Address(rsp, 3 * wordSize));
__ movdbl(xmm2, Address(rsp, 5 * wordSize));
__ fmad(xmm0, xmm1, xmm2, xmm0);
} else if (kind == Interpreter::java_lang_math_fmaF) {
if (!UseFMA) {
return NULL; // Generate a vanilla entry
}
__ movflt(xmm0, Address(rsp, wordSize));
__ movflt(xmm1, Address(rsp, 2 * wordSize));
__ movflt(xmm2, Address(rsp, 3 * wordSize));

View File

@ -124,29 +124,19 @@ AbstractInterpreter::MethodKind AbstractInterpreter::method_kind(methodHandle m)
}
#ifndef CC_INTERP
if (UseCRC32Intrinsics && m->is_native()) {
switch (m->intrinsic_id()) {
// Use optimized stub code for CRC32 native methods.
switch (m->intrinsic_id()) {
case vmIntrinsics::_updateCRC32 : return java_util_zip_CRC32_update;
case vmIntrinsics::_updateBytesCRC32 : return java_util_zip_CRC32_updateBytes;
case vmIntrinsics::_updateByteBufferCRC32 : return java_util_zip_CRC32_updateByteBuffer;
}
}
if (UseCRC32CIntrinsics) {
case vmIntrinsics::_updateCRC32 : return java_util_zip_CRC32_update;
case vmIntrinsics::_updateBytesCRC32 : return java_util_zip_CRC32_updateBytes;
case vmIntrinsics::_updateByteBufferCRC32 : return java_util_zip_CRC32_updateByteBuffer;
// Use optimized stub code for CRC32C methods.
switch (m->intrinsic_id()) {
case vmIntrinsics::_updateBytesCRC32C : return java_util_zip_CRC32C_updateBytes;
case vmIntrinsics::_updateDirectByteBufferCRC32C : return java_util_zip_CRC32C_updateDirectByteBuffer;
}
case vmIntrinsics::_updateBytesCRC32C : return java_util_zip_CRC32C_updateBytes;
case vmIntrinsics::_updateDirectByteBufferCRC32C : return java_util_zip_CRC32C_updateDirectByteBuffer;
case vmIntrinsics::_intBitsToFloat: return java_lang_Float_intBitsToFloat;
case vmIntrinsics::_floatToRawIntBits: return java_lang_Float_floatToRawIntBits;
case vmIntrinsics::_longBitsToDouble: return java_lang_Double_longBitsToDouble;
case vmIntrinsics::_doubleToRawLongBits: return java_lang_Double_doubleToRawLongBits;
}
switch(m->intrinsic_id()) {
case vmIntrinsics::_intBitsToFloat: return java_lang_Float_intBitsToFloat;
case vmIntrinsics::_floatToRawIntBits: return java_lang_Float_floatToRawIntBits;
case vmIntrinsics::_longBitsToDouble: return java_lang_Double_longBitsToDouble;
case vmIntrinsics::_doubleToRawLongBits: return java_lang_Double_doubleToRawLongBits;
}
#endif // CC_INTERP
// Native method?
@ -189,18 +179,13 @@ AbstractInterpreter::MethodKind AbstractInterpreter::method_kind(methodHandle m)
case vmIntrinsics::_dlog10: return java_lang_math_log10;
case vmIntrinsics::_dpow : return java_lang_math_pow ;
case vmIntrinsics::_dexp : return java_lang_math_exp ;
case vmIntrinsics::_fmaD : return java_lang_math_fmaD ;
case vmIntrinsics::_fmaF : return java_lang_math_fmaF ;
case vmIntrinsics::_Reference_get:
return java_lang_ref_reference_get;
}
if (UseFMA) {
switch (m->intrinsic_id()) {
case vmIntrinsics::_fmaD: return java_lang_math_fmaD;
case vmIntrinsics::_fmaF: return java_lang_math_fmaF;
}
}
// Accessor method?
if (m->is_getter()) {
// TODO: We should have used ::is_accessor above, but fast accessors in Zero expect only getters.

View File

@ -239,10 +239,8 @@ void TemplateInterpreterGenerator::generate_all() {
method_entry(java_lang_math_log10)
method_entry(java_lang_math_exp )
method_entry(java_lang_math_pow )
if (UseFMA) {
method_entry(java_lang_math_fmaF)
method_entry(java_lang_math_fmaD)
}
method_entry(java_lang_math_fmaF )
method_entry(java_lang_math_fmaD )
method_entry(java_lang_ref_reference_get)
AbstractInterpreter::initialize_method_handle_entries();
@ -253,16 +251,11 @@ void TemplateInterpreterGenerator::generate_all() {
method_entry(native_synchronized)
Interpreter::_native_entry_end = Interpreter::code()->code_end();
if (UseCRC32Intrinsics) {
method_entry(java_util_zip_CRC32_update)
method_entry(java_util_zip_CRC32_updateBytes)
method_entry(java_util_zip_CRC32_updateByteBuffer)
}
if (UseCRC32CIntrinsics) {
method_entry(java_util_zip_CRC32C_updateBytes)
method_entry(java_util_zip_CRC32C_updateDirectByteBuffer)
}
method_entry(java_util_zip_CRC32_update)
method_entry(java_util_zip_CRC32_updateBytes)
method_entry(java_util_zip_CRC32_updateByteBuffer)
method_entry(java_util_zip_CRC32C_updateBytes)
method_entry(java_util_zip_CRC32C_updateDirectByteBuffer)
method_entry(java_lang_Float_intBitsToFloat);
method_entry(java_lang_Float_floatToRawIntBits);
@ -451,7 +444,7 @@ address TemplateInterpreterGenerator::generate_method_entry(
case Interpreter::java_lang_math_pow : // fall thru
case Interpreter::java_lang_math_exp : // fall thru
case Interpreter::java_lang_math_fmaD : // fall thru
case Interpreter::java_lang_math_fmaF : entry_point = generate_math_entry(kind); break;
case Interpreter::java_lang_math_fmaF : entry_point = generate_math_entry(kind); break;
case Interpreter::java_lang_ref_reference_get
: entry_point = generate_Reference_get_entry(); break;
case Interpreter::java_util_zip_CRC32_update

View File

@ -0,0 +1,96 @@
/*
* Copyright (c) 2016, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test InterpreterMethodEntries
* @bug 8169711
* @summary Test interpreter method entries for intrinsics with CDS (class data sharing)
* and different settings of the intrinsic flag during dump/use of the archive.
* @library /test/lib
* @modules java.base/jdk.internal.misc
* java.management
* @run main TestInterpreterMethodEntries
*/
import java.lang.Math;
import java.util.zip.CRC32;
import java.util.zip.CRC32C;
import jdk.test.lib.process.ProcessTools;
import jdk.test.lib.process.OutputAnalyzer;
public class TestInterpreterMethodEntries {
public static void main(String[] args) throws Exception {
if (args.length == 0) {
// Dump and use shared archive with different flag combinations
dumpAndUseSharedArchive("+", "-");
dumpAndUseSharedArchive("-", "+");
} else {
// Call intrinsified java.lang.Math::fma()
Math.fma(1.0, 2.0, 3.0);
byte[] buffer = new byte[256];
// Call intrinsified java.util.zip.CRC32::update()
CRC32 crc32 = new CRC32();
crc32.update(buffer, 0, 256);
// Call intrinsified java.util.zip.CRC32C::updateBytes(..)
CRC32C crc32c = new CRC32C();
crc32c.update(buffer, 0, 256);
}
}
private static void dumpAndUseSharedArchive(String dump, String use) throws Exception {
String dumpFMA = "-XX:" + dump + "UseFMA";
String dumpCRC32 = "-XX:" + dump + "UseCRC32Intrinsics";
String dumpCRC32C = "-XX:" + dump + "UseCRC32CIntrinsics";
String useFMA = "-XX:" + use + "UseFMA";
String useCRC32 = "-XX:" + use + "UseCRC32Intrinsics";
String useCRC32C = "-XX:" + use + "UseCRC32CIntrinsics";
// Dump shared archive
String filename = "./TestInterpreterMethodEntries" + dump + ".jsa";
ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
"-XX:+UnlockDiagnosticVMOptions",
"-XX:SharedArchiveFile=" + filename,
"-Xshare:dump",
dumpFMA, dumpCRC32, dumpCRC32C);
OutputAnalyzer output = new OutputAnalyzer(pb.start());
CDSTestUtils.checkDump(output);
// Use shared archive
pb = ProcessTools.createJavaProcessBuilder(
"-XX:+UnlockDiagnosticVMOptions",
"-XX:SharedArchiveFile=" + filename,
"-Xshare:on",
useFMA, useCRC32, useCRC32C,
"TestInterpreterMethodEntries", "run");
output = new OutputAnalyzer(pb.start());
if (CDSTestUtils.isUnableToMap(output)) {
System.out.println("Unable to map shared archive: test did not complete; assumed PASS");
return;
}
output.shouldHaveExitValue(0);
}
}