8303415: Add VM_Version::is_intrinsic_supported(id)
Reviewed-by: thartmann, dholmes
This commit is contained in:
parent
31680b2bcf
commit
ec1eb00ed3
src/hotspot
cpu
aarch64
arm
ppc
riscv
s390
x86
share
classfile
compiler
interpreter
abstractInterpreter.cppabstractInterpreter.hpptemplateInterpreterGenerator.cpptemplateInterpreterGenerator.hpp
zero
opto
runtime
test/hotspot/jtreg/compiler/floatingpoint
@ -146,8 +146,6 @@ address TemplateInterpreterGenerator::generate_math_entry(AbstractInterpreter::M
|
||||
// r19_sender_sp: sender sp
|
||||
// esp: args
|
||||
|
||||
if (!InlineIntrinsics) return NULL; // Generate a vanilla entry
|
||||
|
||||
// These don't need a safepoint check because they aren't virtually
|
||||
// callable. We won't enter these intrinsics from compiled code.
|
||||
// If in the future we added an intrinsic which was virtually callable
|
||||
@ -301,12 +299,7 @@ void TemplateInterpreterGenerator::generate_transcendental_entry(AbstractInterpr
|
||||
}
|
||||
|
||||
address TemplateInterpreterGenerator::generate_Float_float16ToFloat_entry() {
|
||||
// vmIntrinsics checks InlineIntrinsics flag, no need to check it here.
|
||||
if (!VM_Version::supports_float16() ||
|
||||
vmIntrinsics::is_disabled_by_flags(vmIntrinsics::_float16ToFloat) ||
|
||||
vmIntrinsics::is_disabled_by_flags(vmIntrinsics::_floatToFloat16)) {
|
||||
return nullptr;
|
||||
}
|
||||
assert(VM_Version::supports_float16(), "this intrinsic is not supported");
|
||||
// r19_sender_sp: sender sp
|
||||
// stack:
|
||||
// [ arg ] <-- esp
|
||||
@ -323,12 +316,7 @@ address TemplateInterpreterGenerator::generate_Float_float16ToFloat_entry() {
|
||||
}
|
||||
|
||||
address TemplateInterpreterGenerator::generate_Float_floatToFloat16_entry() {
|
||||
// vmIntrinsics checks InlineIntrinsics flag, no need to check it here.
|
||||
if (!VM_Version::supports_float16() ||
|
||||
vmIntrinsics::is_disabled_by_flags(vmIntrinsics::_float16ToFloat) ||
|
||||
vmIntrinsics::is_disabled_by_flags(vmIntrinsics::_floatToFloat16)) {
|
||||
return nullptr;
|
||||
}
|
||||
assert(VM_Version::supports_float16(), "this intrinsic is not supported");
|
||||
// r19_sender_sp: sender sp
|
||||
// stack:
|
||||
// [ arg ] <-- esp
|
||||
@ -963,48 +951,46 @@ address TemplateInterpreterGenerator::generate_Reference_get_entry(void) {
|
||||
* int java.util.zip.CRC32.update(int crc, int b)
|
||||
*/
|
||||
address TemplateInterpreterGenerator::generate_CRC32_update_entry() {
|
||||
if (UseCRC32Intrinsics) {
|
||||
address entry = __ pc();
|
||||
assert(UseCRC32Intrinsics, "this intrinsic is not supported");
|
||||
address entry = __ pc();
|
||||
|
||||
// rmethod: Method*
|
||||
// r19_sender_sp: senderSP must preserved for slow path
|
||||
// esp: args
|
||||
// rmethod: Method*
|
||||
// r19_sender_sp: senderSP must preserved for slow path
|
||||
// esp: args
|
||||
|
||||
Label slow_path;
|
||||
// If we need a safepoint check, generate full interpreter entry.
|
||||
__ safepoint_poll(slow_path, false /* at_return */, false /* acquire */, false /* in_nmethod */);
|
||||
Label slow_path;
|
||||
// If we need a safepoint check, generate full interpreter entry.
|
||||
__ safepoint_poll(slow_path, false /* at_return */, false /* acquire */, false /* in_nmethod */);
|
||||
|
||||
// We don't generate local frame and don't align stack because
|
||||
// we call stub code and there is no safepoint on this path.
|
||||
// We don't generate local frame and don't align stack because
|
||||
// we call stub code and there is no safepoint on this path.
|
||||
|
||||
// Load parameters
|
||||
const Register crc = c_rarg0; // crc
|
||||
const Register val = c_rarg1; // source java byte value
|
||||
const Register tbl = c_rarg2; // scratch
|
||||
// Load parameters
|
||||
const Register crc = c_rarg0; // crc
|
||||
const Register val = c_rarg1; // source java byte value
|
||||
const Register tbl = c_rarg2; // scratch
|
||||
|
||||
// Arguments are reversed on java expression stack
|
||||
__ ldrw(val, Address(esp, 0)); // byte value
|
||||
__ ldrw(crc, Address(esp, wordSize)); // Initial CRC
|
||||
// Arguments are reversed on java expression stack
|
||||
__ ldrw(val, Address(esp, 0)); // byte value
|
||||
__ ldrw(crc, Address(esp, wordSize)); // Initial CRC
|
||||
|
||||
uint64_t offset;
|
||||
__ adrp(tbl, ExternalAddress(StubRoutines::crc_table_addr()), offset);
|
||||
__ add(tbl, tbl, offset);
|
||||
uint64_t offset;
|
||||
__ adrp(tbl, ExternalAddress(StubRoutines::crc_table_addr()), offset);
|
||||
__ add(tbl, tbl, offset);
|
||||
|
||||
__ mvnw(crc, crc); // ~crc
|
||||
__ update_byte_crc32(crc, val, tbl);
|
||||
__ mvnw(crc, crc); // ~crc
|
||||
__ mvnw(crc, crc); // ~crc
|
||||
__ update_byte_crc32(crc, val, tbl);
|
||||
__ mvnw(crc, crc); // ~crc
|
||||
|
||||
// result in c_rarg0
|
||||
// result in c_rarg0
|
||||
|
||||
__ andr(sp, r19_sender_sp, -16);
|
||||
__ ret(lr);
|
||||
__ andr(sp, r19_sender_sp, -16);
|
||||
__ ret(lr);
|
||||
|
||||
// generate a vanilla native entry as the slow path
|
||||
__ bind(slow_path);
|
||||
__ jump_to_entry(Interpreter::entry_for_kind(Interpreter::native));
|
||||
return entry;
|
||||
}
|
||||
return NULL;
|
||||
// generate a vanilla native entry as the slow path
|
||||
__ bind(slow_path);
|
||||
__ jump_to_entry(Interpreter::entry_for_kind(Interpreter::native));
|
||||
return entry;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1013,53 +999,51 @@ address TemplateInterpreterGenerator::generate_CRC32_update_entry() {
|
||||
* int java.util.zip.CRC32.updateByteBuffer(int crc, long buf, int off, int len)
|
||||
*/
|
||||
address TemplateInterpreterGenerator::generate_CRC32_updateBytes_entry(AbstractInterpreter::MethodKind kind) {
|
||||
if (UseCRC32Intrinsics) {
|
||||
address entry = __ pc();
|
||||
assert(UseCRC32Intrinsics, "this intrinsic is not supported");
|
||||
address entry = __ pc();
|
||||
|
||||
// rmethod,: Method*
|
||||
// r19_sender_sp: senderSP must preserved for slow path
|
||||
// rmethod,: Method*
|
||||
// r19_sender_sp: senderSP must preserved for slow path
|
||||
|
||||
Label slow_path;
|
||||
// If we need a safepoint check, generate full interpreter entry.
|
||||
__ safepoint_poll(slow_path, false /* at_return */, false /* acquire */, false /* in_nmethod */);
|
||||
Label slow_path;
|
||||
// If we need a safepoint check, generate full interpreter entry.
|
||||
__ safepoint_poll(slow_path, false /* at_return */, false /* acquire */, false /* in_nmethod */);
|
||||
|
||||
// We don't generate local frame and don't align stack because
|
||||
// we call stub code and there is no safepoint on this path.
|
||||
// We don't generate local frame and don't align stack because
|
||||
// we call stub code and there is no safepoint on this path.
|
||||
|
||||
// Load parameters
|
||||
const Register crc = c_rarg0; // crc
|
||||
const Register buf = c_rarg1; // source java byte array address
|
||||
const Register len = c_rarg2; // length
|
||||
const Register off = len; // offset (never overlaps with 'len')
|
||||
// Load parameters
|
||||
const Register crc = c_rarg0; // crc
|
||||
const Register buf = c_rarg1; // source java byte array address
|
||||
const Register len = c_rarg2; // length
|
||||
const Register off = len; // offset (never overlaps with 'len')
|
||||
|
||||
// Arguments are reversed on java expression stack
|
||||
// Calculate address of start element
|
||||
if (kind == Interpreter::java_util_zip_CRC32_updateByteBuffer) {
|
||||
__ ldr(buf, Address(esp, 2*wordSize)); // long buf
|
||||
__ ldrw(off, Address(esp, wordSize)); // offset
|
||||
__ add(buf, buf, off); // + offset
|
||||
__ ldrw(crc, Address(esp, 4*wordSize)); // Initial CRC
|
||||
} else {
|
||||
__ ldr(buf, Address(esp, 2*wordSize)); // byte[] array
|
||||
__ add(buf, buf, arrayOopDesc::base_offset_in_bytes(T_BYTE)); // + header size
|
||||
__ ldrw(off, Address(esp, wordSize)); // offset
|
||||
__ add(buf, buf, off); // + offset
|
||||
__ ldrw(crc, Address(esp, 3*wordSize)); // Initial CRC
|
||||
}
|
||||
// Can now load 'len' since we're finished with 'off'
|
||||
__ ldrw(len, Address(esp, 0x0)); // Length
|
||||
|
||||
__ andr(sp, r19_sender_sp, -16); // Restore the caller's SP
|
||||
|
||||
// We are frameless so we can just jump to the stub.
|
||||
__ b(CAST_FROM_FN_PTR(address, StubRoutines::updateBytesCRC32()));
|
||||
|
||||
// generate a vanilla native entry as the slow path
|
||||
__ bind(slow_path);
|
||||
__ jump_to_entry(Interpreter::entry_for_kind(Interpreter::native));
|
||||
return entry;
|
||||
// Arguments are reversed on java expression stack
|
||||
// Calculate address of start element
|
||||
if (kind == Interpreter::java_util_zip_CRC32_updateByteBuffer) {
|
||||
__ ldr(buf, Address(esp, 2*wordSize)); // long buf
|
||||
__ ldrw(off, Address(esp, wordSize)); // offset
|
||||
__ add(buf, buf, off); // + offset
|
||||
__ ldrw(crc, Address(esp, 4*wordSize)); // Initial CRC
|
||||
} else {
|
||||
__ ldr(buf, Address(esp, 2*wordSize)); // byte[] array
|
||||
__ add(buf, buf, arrayOopDesc::base_offset_in_bytes(T_BYTE)); // + header size
|
||||
__ ldrw(off, Address(esp, wordSize)); // offset
|
||||
__ add(buf, buf, off); // + offset
|
||||
__ ldrw(crc, Address(esp, 3*wordSize)); // Initial CRC
|
||||
}
|
||||
return NULL;
|
||||
// Can now load 'len' since we're finished with 'off'
|
||||
__ ldrw(len, Address(esp, 0x0)); // Length
|
||||
|
||||
__ andr(sp, r19_sender_sp, -16); // Restore the caller's SP
|
||||
|
||||
// We are frameless so we can just jump to the stub.
|
||||
__ b(CAST_FROM_FN_PTR(address, StubRoutines::updateBytesCRC32()));
|
||||
|
||||
// generate a vanilla native entry as the slow path
|
||||
__ bind(slow_path);
|
||||
__ jump_to_entry(Interpreter::entry_for_kind(Interpreter::native));
|
||||
return entry;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1070,37 +1054,35 @@ address TemplateInterpreterGenerator::generate_CRC32_updateBytes_entry(AbstractI
|
||||
* CRC32C also uses an "end" variable instead of the length variable CRC32 uses
|
||||
*/
|
||||
address TemplateInterpreterGenerator::generate_CRC32C_updateBytes_entry(AbstractInterpreter::MethodKind kind) {
|
||||
if (UseCRC32CIntrinsics) {
|
||||
address entry = __ pc();
|
||||
assert(UseCRC32CIntrinsics, "this intrinsic is not supported");
|
||||
address entry = __ pc();
|
||||
|
||||
// Prepare jump to stub using parameters from the stack
|
||||
const Register crc = c_rarg0; // initial crc
|
||||
const Register buf = c_rarg1; // source java byte array address
|
||||
const Register len = c_rarg2; // len argument to the kernel
|
||||
// Prepare jump to stub using parameters from the stack
|
||||
const Register crc = c_rarg0; // initial crc
|
||||
const Register buf = c_rarg1; // source java byte array address
|
||||
const Register len = c_rarg2; // len argument to the kernel
|
||||
|
||||
const Register end = len; // index of last element to process
|
||||
const Register off = crc; // offset
|
||||
const Register end = len; // index of last element to process
|
||||
const Register off = crc; // offset
|
||||
|
||||
__ ldrw(end, Address(esp)); // int end
|
||||
__ ldrw(off, Address(esp, wordSize)); // int offset
|
||||
__ sub(len, end, off);
|
||||
__ ldr(buf, Address(esp, 2*wordSize)); // byte[] buf | long buf
|
||||
__ add(buf, buf, off); // + offset
|
||||
if (kind == Interpreter::java_util_zip_CRC32C_updateDirectByteBuffer) {
|
||||
__ ldrw(crc, Address(esp, 4*wordSize)); // long crc
|
||||
} else {
|
||||
__ add(buf, buf, arrayOopDesc::base_offset_in_bytes(T_BYTE)); // + header size
|
||||
__ ldrw(crc, Address(esp, 3*wordSize)); // long crc
|
||||
}
|
||||
|
||||
__ andr(sp, r19_sender_sp, -16); // Restore the caller's SP
|
||||
|
||||
// Jump to the stub.
|
||||
__ b(CAST_FROM_FN_PTR(address, StubRoutines::updateBytesCRC32C()));
|
||||
|
||||
return entry;
|
||||
__ ldrw(end, Address(esp)); // int end
|
||||
__ ldrw(off, Address(esp, wordSize)); // int offset
|
||||
__ sub(len, end, off);
|
||||
__ ldr(buf, Address(esp, 2*wordSize)); // byte[] buf | long buf
|
||||
__ add(buf, buf, off); // + offset
|
||||
if (kind == Interpreter::java_util_zip_CRC32C_updateDirectByteBuffer) {
|
||||
__ ldrw(crc, Address(esp, 4*wordSize)); // long crc
|
||||
} else {
|
||||
__ add(buf, buf, arrayOopDesc::base_offset_in_bytes(T_BYTE)); // + header size
|
||||
__ ldrw(crc, Address(esp, 3*wordSize)); // long crc
|
||||
}
|
||||
return NULL;
|
||||
|
||||
__ andr(sp, r19_sender_sp, -16); // Restore the caller's SP
|
||||
|
||||
// Jump to the stub.
|
||||
__ b(CAST_FROM_FN_PTR(address, StubRoutines::updateBytesCRC32C()));
|
||||
|
||||
return entry;
|
||||
}
|
||||
|
||||
void TemplateInterpreterGenerator::bang_stack_shadow_pages(bool native_call) {
|
||||
@ -1742,6 +1724,11 @@ address TemplateInterpreterGenerator::generate_currentThread() {
|
||||
return entry_point;
|
||||
}
|
||||
|
||||
// Not supported
|
||||
address TemplateInterpreterGenerator::generate_Float_intBitsToFloat_entry() { return nullptr; }
|
||||
address TemplateInterpreterGenerator::generate_Float_floatToRawIntBits_entry() { return nullptr; }
|
||||
address TemplateInterpreterGenerator::generate_Double_longBitsToDouble_entry() { return nullptr; }
|
||||
address TemplateInterpreterGenerator::generate_Double_doubleToRawLongBits_entry() { return nullptr; }
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Exceptions
|
||||
|
@ -122,8 +122,6 @@ address TemplateInterpreterGenerator::generate_abstract_entry(void) {
|
||||
}
|
||||
|
||||
address TemplateInterpreterGenerator::generate_math_entry(AbstractInterpreter::MethodKind kind) {
|
||||
if (!InlineIntrinsics) return nullptr; // Generate a vanilla entry
|
||||
|
||||
address entry_point = nullptr;
|
||||
Register continuation = LR;
|
||||
bool use_runtime_call = false;
|
||||
@ -780,9 +778,14 @@ address TemplateInterpreterGenerator::generate_Reference_get_entry(void) {
|
||||
}
|
||||
|
||||
// Not supported
|
||||
address TemplateInterpreterGenerator::generate_currentThread() { return nullptr; }
|
||||
address TemplateInterpreterGenerator::generate_CRC32_update_entry() { return nullptr; }
|
||||
address TemplateInterpreterGenerator::generate_CRC32_updateBytes_entry(AbstractInterpreter::MethodKind kind) { return nullptr; }
|
||||
address TemplateInterpreterGenerator::generate_CRC32C_updateBytes_entry(AbstractInterpreter::MethodKind kind) { return nullptr; }
|
||||
address TemplateInterpreterGenerator::generate_Float_intBitsToFloat_entry() { return nullptr; }
|
||||
address TemplateInterpreterGenerator::generate_Float_floatToRawIntBits_entry() { return nullptr; }
|
||||
address TemplateInterpreterGenerator::generate_Double_longBitsToDouble_entry() { return nullptr; }
|
||||
address TemplateInterpreterGenerator::generate_Double_doubleToRawLongBits_entry() { return nullptr; }
|
||||
address TemplateInterpreterGenerator::generate_Float_float16ToFloat_entry() { return nullptr; }
|
||||
address TemplateInterpreterGenerator::generate_Float_floatToFloat16_entry() { return nullptr; }
|
||||
|
||||
|
@ -1746,52 +1746,49 @@ address TemplateInterpreterGenerator::generate_normal_entry(bool synchronized) {
|
||||
* int java.util.zip.CRC32.update(int crc, int b)
|
||||
*/
|
||||
address TemplateInterpreterGenerator::generate_CRC32_update_entry() {
|
||||
if (UseCRC32Intrinsics) {
|
||||
address start = __ pc(); // Remember stub start address (is rtn value).
|
||||
Label slow_path;
|
||||
assert(UseCRC32Intrinsics, "this intrinsic is not supported");
|
||||
address start = __ pc(); // Remember stub start address (is rtn value).
|
||||
Label slow_path;
|
||||
|
||||
// Safepoint check
|
||||
const Register sync_state = R11_scratch1;
|
||||
__ safepoint_poll(slow_path, sync_state, false /* at_return */, false /* in_nmethod */);
|
||||
// Safepoint check
|
||||
const Register sync_state = R11_scratch1;
|
||||
__ safepoint_poll(slow_path, sync_state, false /* at_return */, false /* in_nmethod */);
|
||||
|
||||
// We don't generate local frame and don't align stack because
|
||||
// we not even call stub code (we generate the code inline)
|
||||
// and there is no safepoint on this path.
|
||||
// We don't generate local frame and don't align stack because
|
||||
// we not even call stub code (we generate the code inline)
|
||||
// and there is no safepoint on this path.
|
||||
|
||||
// Load java parameters.
|
||||
// R15_esp is callers operand stack pointer, i.e. it points to the parameters.
|
||||
const Register argP = R15_esp;
|
||||
const Register crc = R3_ARG1; // crc value
|
||||
const Register data = R4_ARG2;
|
||||
const Register table = R5_ARG3; // address of crc32 table
|
||||
// Load java parameters.
|
||||
// R15_esp is callers operand stack pointer, i.e. it points to the parameters.
|
||||
const Register argP = R15_esp;
|
||||
const Register crc = R3_ARG1; // crc value
|
||||
const Register data = R4_ARG2;
|
||||
const Register table = R5_ARG3; // address of crc32 table
|
||||
|
||||
BLOCK_COMMENT("CRC32_update {");
|
||||
BLOCK_COMMENT("CRC32_update {");
|
||||
|
||||
// Arguments are reversed on java expression stack
|
||||
// Arguments are reversed on java expression stack
|
||||
#ifdef VM_LITTLE_ENDIAN
|
||||
int data_offs = 0+1*wordSize; // (stack) address of byte value. Emitter expects address, not value.
|
||||
// Being passed as an int, the single byte is at offset +0.
|
||||
int data_offs = 0+1*wordSize; // (stack) address of byte value. Emitter expects address, not value.
|
||||
// Being passed as an int, the single byte is at offset +0.
|
||||
#else
|
||||
int data_offs = 3+1*wordSize; // (stack) address of byte value. Emitter expects address, not value.
|
||||
// Being passed from java as an int, the single byte is at offset +3.
|
||||
int data_offs = 3+1*wordSize; // (stack) address of byte value. Emitter expects address, not value.
|
||||
// Being passed from java as an int, the single byte is at offset +3.
|
||||
#endif
|
||||
__ lwz(crc, 2*wordSize, argP); // Current crc state, zero extend to 64 bit to have a clean register.
|
||||
__ lbz(data, data_offs, argP); // Byte from buffer, zero-extended.
|
||||
__ load_const_optimized(table, StubRoutines::crc_table_addr(), R0);
|
||||
__ kernel_crc32_singleByteReg(crc, data, table, true);
|
||||
__ lwz(crc, 2*wordSize, argP); // Current crc state, zero extend to 64 bit to have a clean register.
|
||||
__ lbz(data, data_offs, argP); // Byte from buffer, zero-extended.
|
||||
__ load_const_optimized(table, StubRoutines::crc_table_addr(), R0);
|
||||
__ kernel_crc32_singleByteReg(crc, data, table, true);
|
||||
|
||||
// Restore caller sp for c2i case (from compiled) and for resized sender frame (from interpreted).
|
||||
__ resize_frame_absolute(R21_sender_SP, R11_scratch1, R0);
|
||||
__ blr();
|
||||
// Restore caller sp for c2i case (from compiled) and for resized sender frame (from interpreted).
|
||||
__ resize_frame_absolute(R21_sender_SP, R11_scratch1, R0);
|
||||
__ blr();
|
||||
|
||||
// Generate a vanilla native entry as the slow path.
|
||||
BLOCK_COMMENT("} CRC32_update");
|
||||
BIND(slow_path);
|
||||
__ jump_to_entry(Interpreter::entry_for_kind(Interpreter::native), R11_scratch1);
|
||||
return start;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
// Generate a vanilla native entry as the slow path.
|
||||
BLOCK_COMMENT("} CRC32_update");
|
||||
BIND(slow_path);
|
||||
__ jump_to_entry(Interpreter::entry_for_kind(Interpreter::native), R11_scratch1);
|
||||
return start;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1800,69 +1797,66 @@ address TemplateInterpreterGenerator::generate_CRC32_update_entry() {
|
||||
* int java.util.zip.CRC32.updateByteBuffer(int crc, long* buf, int off, int len)
|
||||
*/
|
||||
address TemplateInterpreterGenerator::generate_CRC32_updateBytes_entry(AbstractInterpreter::MethodKind kind) {
|
||||
if (UseCRC32Intrinsics) {
|
||||
address start = __ pc(); // Remember stub start address (is rtn value).
|
||||
Label slow_path;
|
||||
assert(UseCRC32Intrinsics, "this intrinsic is not supported");
|
||||
address start = __ pc(); // Remember stub start address (is rtn value).
|
||||
Label slow_path;
|
||||
|
||||
// Safepoint check
|
||||
const Register sync_state = R11_scratch1;
|
||||
__ safepoint_poll(slow_path, sync_state, false /* at_return */, false /* in_nmethod */);
|
||||
// Safepoint check
|
||||
const Register sync_state = R11_scratch1;
|
||||
__ safepoint_poll(slow_path, sync_state, false /* at_return */, false /* in_nmethod */);
|
||||
|
||||
// We don't generate local frame and don't align stack because
|
||||
// we not even call stub code (we generate the code inline)
|
||||
// and there is no safepoint on this path.
|
||||
// We don't generate local frame and don't align stack because
|
||||
// we not even call stub code (we generate the code inline)
|
||||
// and there is no safepoint on this path.
|
||||
|
||||
// Load parameters.
|
||||
// Z_esp is callers operand stack pointer, i.e. it points to the parameters.
|
||||
const Register argP = R15_esp;
|
||||
const Register crc = R3_ARG1; // crc value
|
||||
const Register data = R4_ARG2; // address of java byte array
|
||||
const Register dataLen = R5_ARG3; // source data len
|
||||
const Register tmp = R11_scratch1;
|
||||
// Load parameters.
|
||||
// Z_esp is callers operand stack pointer, i.e. it points to the parameters.
|
||||
const Register argP = R15_esp;
|
||||
const Register crc = R3_ARG1; // crc value
|
||||
const Register data = R4_ARG2; // address of java byte array
|
||||
const Register dataLen = R5_ARG3; // source data len
|
||||
const Register tmp = R11_scratch1;
|
||||
|
||||
// Arguments are reversed on java expression stack.
|
||||
// Calculate address of start element.
|
||||
if (kind == Interpreter::java_util_zip_CRC32_updateByteBuffer) { // Used for "updateByteBuffer direct".
|
||||
BLOCK_COMMENT("CRC32_updateByteBuffer {");
|
||||
// crc @ (SP + 5W) (32bit)
|
||||
// buf @ (SP + 3W) (64bit ptr to long array)
|
||||
// off @ (SP + 2W) (32bit)
|
||||
// dataLen @ (SP + 1W) (32bit)
|
||||
// data = buf + off
|
||||
__ ld( data, 3*wordSize, argP); // start of byte buffer
|
||||
__ lwa( tmp, 2*wordSize, argP); // byte buffer offset
|
||||
__ lwa( dataLen, 1*wordSize, argP); // #bytes to process
|
||||
__ lwz( crc, 5*wordSize, argP); // current crc state
|
||||
__ add( data, data, tmp); // Add byte buffer offset.
|
||||
} else { // Used for "updateBytes update".
|
||||
BLOCK_COMMENT("CRC32_updateBytes {");
|
||||
// crc @ (SP + 4W) (32bit)
|
||||
// buf @ (SP + 3W) (64bit ptr to byte array)
|
||||
// off @ (SP + 2W) (32bit)
|
||||
// dataLen @ (SP + 1W) (32bit)
|
||||
// data = buf + off + base_offset
|
||||
__ ld( data, 3*wordSize, argP); // start of byte buffer
|
||||
__ lwa( tmp, 2*wordSize, argP); // byte buffer offset
|
||||
__ lwa( dataLen, 1*wordSize, argP); // #bytes to process
|
||||
__ add( data, data, tmp); // add byte buffer offset
|
||||
__ lwz( crc, 4*wordSize, argP); // current crc state
|
||||
__ addi(data, data, arrayOopDesc::base_offset_in_bytes(T_BYTE));
|
||||
}
|
||||
|
||||
__ crc32(crc, data, dataLen, R2, R6, R7, R8, R9, R10, R11, R12, false);
|
||||
|
||||
// Restore caller sp for c2i case (from compiled) and for resized sender frame (from interpreted).
|
||||
__ resize_frame_absolute(R21_sender_SP, R11_scratch1, R0);
|
||||
__ blr();
|
||||
|
||||
// Generate a vanilla native entry as the slow path.
|
||||
BLOCK_COMMENT("} CRC32_updateBytes(Buffer)");
|
||||
BIND(slow_path);
|
||||
__ jump_to_entry(Interpreter::entry_for_kind(Interpreter::native), R11_scratch1);
|
||||
return start;
|
||||
// Arguments are reversed on java expression stack.
|
||||
// Calculate address of start element.
|
||||
if (kind == Interpreter::java_util_zip_CRC32_updateByteBuffer) { // Used for "updateByteBuffer direct".
|
||||
BLOCK_COMMENT("CRC32_updateByteBuffer {");
|
||||
// crc @ (SP + 5W) (32bit)
|
||||
// buf @ (SP + 3W) (64bit ptr to long array)
|
||||
// off @ (SP + 2W) (32bit)
|
||||
// dataLen @ (SP + 1W) (32bit)
|
||||
// data = buf + off
|
||||
__ ld( data, 3*wordSize, argP); // start of byte buffer
|
||||
__ lwa( tmp, 2*wordSize, argP); // byte buffer offset
|
||||
__ lwa( dataLen, 1*wordSize, argP); // #bytes to process
|
||||
__ lwz( crc, 5*wordSize, argP); // current crc state
|
||||
__ add( data, data, tmp); // Add byte buffer offset.
|
||||
} else { // Used for "updateBytes update".
|
||||
BLOCK_COMMENT("CRC32_updateBytes {");
|
||||
// crc @ (SP + 4W) (32bit)
|
||||
// buf @ (SP + 3W) (64bit ptr to byte array)
|
||||
// off @ (SP + 2W) (32bit)
|
||||
// dataLen @ (SP + 1W) (32bit)
|
||||
// data = buf + off + base_offset
|
||||
__ ld( data, 3*wordSize, argP); // start of byte buffer
|
||||
__ lwa( tmp, 2*wordSize, argP); // byte buffer offset
|
||||
__ lwa( dataLen, 1*wordSize, argP); // #bytes to process
|
||||
__ add( data, data, tmp); // add byte buffer offset
|
||||
__ lwz( crc, 4*wordSize, argP); // current crc state
|
||||
__ addi(data, data, arrayOopDesc::base_offset_in_bytes(T_BYTE));
|
||||
}
|
||||
|
||||
return NULL;
|
||||
__ crc32(crc, data, dataLen, R2, R6, R7, R8, R9, R10, R11, R12, false);
|
||||
|
||||
// Restore caller sp for c2i case (from compiled) and for resized sender frame (from interpreted).
|
||||
__ resize_frame_absolute(R21_sender_SP, R11_scratch1, R0);
|
||||
__ blr();
|
||||
|
||||
// Generate a vanilla native entry as the slow path.
|
||||
BLOCK_COMMENT("} CRC32_updateBytes(Buffer)");
|
||||
BIND(slow_path);
|
||||
__ jump_to_entry(Interpreter::entry_for_kind(Interpreter::native), R11_scratch1);
|
||||
return start;
|
||||
}
|
||||
|
||||
|
||||
@ -1874,66 +1868,68 @@ address TemplateInterpreterGenerator::generate_CRC32_updateBytes_entry(AbstractI
|
||||
* CRC32C also uses an "end" variable instead of the length variable CRC32 uses
|
||||
**/
|
||||
address TemplateInterpreterGenerator::generate_CRC32C_updateBytes_entry(AbstractInterpreter::MethodKind kind) {
|
||||
if (UseCRC32CIntrinsics) {
|
||||
address start = __ pc(); // Remember stub start address (is rtn value).
|
||||
assert(UseCRC32CIntrinsics, "this intrinsic is not supported");
|
||||
address start = __ pc(); // Remember stub start address (is rtn value).
|
||||
|
||||
// We don't generate local frame and don't align stack because
|
||||
// we not even call stub code (we generate the code inline)
|
||||
// and there is no safepoint on this path.
|
||||
// We don't generate local frame and don't align stack because
|
||||
// we not even call stub code (we generate the code inline)
|
||||
// and there is no safepoint on this path.
|
||||
|
||||
// Load parameters.
|
||||
// Z_esp is callers operand stack pointer, i.e. it points to the parameters.
|
||||
const Register argP = R15_esp;
|
||||
const Register crc = R3_ARG1; // crc value
|
||||
const Register data = R4_ARG2; // address of java byte array
|
||||
const Register dataLen = R5_ARG3; // source data len
|
||||
const Register tmp = R11_scratch1;
|
||||
// Load parameters.
|
||||
// Z_esp is callers operand stack pointer, i.e. it points to the parameters.
|
||||
const Register argP = R15_esp;
|
||||
const Register crc = R3_ARG1; // crc value
|
||||
const Register data = R4_ARG2; // address of java byte array
|
||||
const Register dataLen = R5_ARG3; // source data len
|
||||
const Register tmp = R11_scratch1;
|
||||
|
||||
// Arguments are reversed on java expression stack.
|
||||
// Calculate address of start element.
|
||||
if (kind == Interpreter::java_util_zip_CRC32C_updateDirectByteBuffer) { // Used for "updateDirectByteBuffer".
|
||||
BLOCK_COMMENT("CRC32C_updateDirectByteBuffer {");
|
||||
// crc @ (SP + 5W) (32bit)
|
||||
// buf @ (SP + 3W) (64bit ptr to long array)
|
||||
// off @ (SP + 2W) (32bit)
|
||||
// dataLen @ (SP + 1W) (32bit)
|
||||
// data = buf + off
|
||||
__ ld( data, 3*wordSize, argP); // start of byte buffer
|
||||
__ lwa( tmp, 2*wordSize, argP); // byte buffer offset
|
||||
__ lwa( dataLen, 1*wordSize, argP); // #bytes to process
|
||||
__ lwz( crc, 5*wordSize, argP); // current crc state
|
||||
__ add( data, data, tmp); // Add byte buffer offset.
|
||||
__ sub( dataLen, dataLen, tmp); // (end_index - offset)
|
||||
} else { // Used for "updateBytes update".
|
||||
BLOCK_COMMENT("CRC32C_updateBytes {");
|
||||
// crc @ (SP + 4W) (32bit)
|
||||
// buf @ (SP + 3W) (64bit ptr to byte array)
|
||||
// off @ (SP + 2W) (32bit)
|
||||
// dataLen @ (SP + 1W) (32bit)
|
||||
// data = buf + off + base_offset
|
||||
__ ld( data, 3*wordSize, argP); // start of byte buffer
|
||||
__ lwa( tmp, 2*wordSize, argP); // byte buffer offset
|
||||
__ lwa( dataLen, 1*wordSize, argP); // #bytes to process
|
||||
__ add( data, data, tmp); // add byte buffer offset
|
||||
__ sub( dataLen, dataLen, tmp); // (end_index - offset)
|
||||
__ lwz( crc, 4*wordSize, argP); // current crc state
|
||||
__ addi(data, data, arrayOopDesc::base_offset_in_bytes(T_BYTE));
|
||||
}
|
||||
|
||||
__ crc32(crc, data, dataLen, R2, R6, R7, R8, R9, R10, R11, R12, true);
|
||||
|
||||
// Restore caller sp for c2i case (from compiled) and for resized sender frame (from interpreted).
|
||||
__ resize_frame_absolute(R21_sender_SP, R11_scratch1, R0);
|
||||
__ blr();
|
||||
|
||||
BLOCK_COMMENT("} CRC32C_update{Bytes|DirectByteBuffer}");
|
||||
return start;
|
||||
// Arguments are reversed on java expression stack.
|
||||
// Calculate address of start element.
|
||||
if (kind == Interpreter::java_util_zip_CRC32C_updateDirectByteBuffer) { // Used for "updateDirectByteBuffer".
|
||||
BLOCK_COMMENT("CRC32C_updateDirectByteBuffer {");
|
||||
// crc @ (SP + 5W) (32bit)
|
||||
// buf @ (SP + 3W) (64bit ptr to long array)
|
||||
// off @ (SP + 2W) (32bit)
|
||||
// dataLen @ (SP + 1W) (32bit)
|
||||
// data = buf + off
|
||||
__ ld( data, 3*wordSize, argP); // start of byte buffer
|
||||
__ lwa( tmp, 2*wordSize, argP); // byte buffer offset
|
||||
__ lwa( dataLen, 1*wordSize, argP); // #bytes to process
|
||||
__ lwz( crc, 5*wordSize, argP); // current crc state
|
||||
__ add( data, data, tmp); // Add byte buffer offset.
|
||||
__ sub( dataLen, dataLen, tmp); // (end_index - offset)
|
||||
} else { // Used for "updateBytes update".
|
||||
BLOCK_COMMENT("CRC32C_updateBytes {");
|
||||
// crc @ (SP + 4W) (32bit)
|
||||
// buf @ (SP + 3W) (64bit ptr to byte array)
|
||||
// off @ (SP + 2W) (32bit)
|
||||
// dataLen @ (SP + 1W) (32bit)
|
||||
// data = buf + off + base_offset
|
||||
__ ld( data, 3*wordSize, argP); // start of byte buffer
|
||||
__ lwa( tmp, 2*wordSize, argP); // byte buffer offset
|
||||
__ lwa( dataLen, 1*wordSize, argP); // #bytes to process
|
||||
__ add( data, data, tmp); // add byte buffer offset
|
||||
__ sub( dataLen, dataLen, tmp); // (end_index - offset)
|
||||
__ lwz( crc, 4*wordSize, argP); // current crc state
|
||||
__ addi(data, data, arrayOopDesc::base_offset_in_bytes(T_BYTE));
|
||||
}
|
||||
|
||||
return NULL;
|
||||
__ crc32(crc, data, dataLen, R2, R6, R7, R8, R9, R10, R11, R12, true);
|
||||
|
||||
// Restore caller sp for c2i case (from compiled) and for resized sender frame (from interpreted).
|
||||
__ resize_frame_absolute(R21_sender_SP, R11_scratch1, R0);
|
||||
__ blr();
|
||||
|
||||
BLOCK_COMMENT("} CRC32C_update{Bytes|DirectByteBuffer}");
|
||||
return start;
|
||||
}
|
||||
|
||||
// Not supported
|
||||
address TemplateInterpreterGenerator::generate_currentThread() { return nullptr; }
|
||||
address TemplateInterpreterGenerator::generate_Float_intBitsToFloat_entry() { return nullptr; }
|
||||
address TemplateInterpreterGenerator::generate_Float_floatToRawIntBits_entry() { return nullptr; }
|
||||
address TemplateInterpreterGenerator::generate_Double_longBitsToDouble_entry() { return nullptr; }
|
||||
address TemplateInterpreterGenerator::generate_Double_doubleToRawLongBits_entry() { return nullptr; }
|
||||
address TemplateInterpreterGenerator::generate_Float_float16ToFloat_entry() { return nullptr; }
|
||||
address TemplateInterpreterGenerator::generate_Float_floatToFloat16_entry() { return nullptr; }
|
||||
|
||||
|
@ -143,10 +143,6 @@ address TemplateInterpreterGenerator::generate_math_entry(AbstractInterpreter::M
|
||||
// x19_sender_sp: sender sp
|
||||
// esp: args
|
||||
|
||||
if (!InlineIntrinsics) {
|
||||
return NULL; // Generate a vanilla entry
|
||||
}
|
||||
|
||||
// These don't need a safepoint check because they aren't virtually
|
||||
// callable. We won't enter these intrinsics from compiled code.
|
||||
// If in the future we added an intrinsic which was virtually callable
|
||||
@ -301,10 +297,6 @@ address TemplateInterpreterGenerator::generate_math_entry(AbstractInterpreter::M
|
||||
return entry_point;
|
||||
}
|
||||
|
||||
// Not supported
|
||||
address TemplateInterpreterGenerator::generate_Float_float16ToFloat_entry() { return nullptr; }
|
||||
address TemplateInterpreterGenerator::generate_Float_floatToFloat16_entry() { return nullptr; }
|
||||
|
||||
// Abstract method entry
|
||||
// Attempt to execute abstract method. Throw exception
|
||||
address TemplateInterpreterGenerator::generate_abstract_entry(void) {
|
||||
@ -864,7 +856,7 @@ address TemplateInterpreterGenerator::generate_Reference_get_entry(void) {
|
||||
*/
|
||||
address TemplateInterpreterGenerator::generate_CRC32_update_entry() {
|
||||
// TODO: Unimplemented generate_CRC32_update_entry
|
||||
return 0;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -874,7 +866,7 @@ address TemplateInterpreterGenerator::generate_CRC32_update_entry() {
|
||||
*/
|
||||
address TemplateInterpreterGenerator::generate_CRC32_updateBytes_entry(AbstractInterpreter::MethodKind kind) {
|
||||
// TODO: Unimplemented generate_CRC32_updateBytes_entry
|
||||
return 0;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -886,9 +878,17 @@ address TemplateInterpreterGenerator::generate_CRC32_updateBytes_entry(AbstractI
|
||||
*/
|
||||
address TemplateInterpreterGenerator::generate_CRC32C_updateBytes_entry(AbstractInterpreter::MethodKind kind) {
|
||||
// TODO: Unimplemented generate_CRC32C_updateBytes_entry
|
||||
return 0;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Not supported
|
||||
address TemplateInterpreterGenerator::generate_Float_intBitsToFloat_entry() { return nullptr; }
|
||||
address TemplateInterpreterGenerator::generate_Float_floatToRawIntBits_entry() { return nullptr; }
|
||||
address TemplateInterpreterGenerator::generate_Double_longBitsToDouble_entry() { return nullptr; }
|
||||
address TemplateInterpreterGenerator::generate_Double_doubleToRawLongBits_entry() { return nullptr; }
|
||||
address TemplateInterpreterGenerator::generate_Float_float16ToFloat_entry() { return nullptr; }
|
||||
address TemplateInterpreterGenerator::generate_Float_floatToFloat16_entry() { return nullptr; }
|
||||
|
||||
void TemplateInterpreterGenerator::bang_stack_shadow_pages(bool native_call) {
|
||||
// See more discussion in stackOverflow.hpp.
|
||||
|
||||
|
@ -1801,50 +1801,46 @@ address TemplateInterpreterGenerator::generate_normal_entry(bool synchronized) {
|
||||
* int java.util.zip.CRC32.update(int crc, int b)
|
||||
*/
|
||||
address TemplateInterpreterGenerator::generate_CRC32_update_entry() {
|
||||
assert(UseCRC32Intrinsics, "this intrinsic is not supported");
|
||||
uint64_t entry_off = __ offset();
|
||||
Label slow_path;
|
||||
|
||||
if (UseCRC32Intrinsics) {
|
||||
uint64_t entry_off = __ offset();
|
||||
Label slow_path;
|
||||
// If we need a safepoint check, generate full interpreter entry.
|
||||
__ safepoint_poll(slow_path, Z_R1);
|
||||
|
||||
// If we need a safepoint check, generate full interpreter entry.
|
||||
__ safepoint_poll(slow_path, Z_R1);
|
||||
BLOCK_COMMENT("CRC32_update {");
|
||||
|
||||
BLOCK_COMMENT("CRC32_update {");
|
||||
// We don't generate local frame and don't align stack because
|
||||
// we not even call stub code (we generate the code inline)
|
||||
// and there is no safepoint on this path.
|
||||
|
||||
// We don't generate local frame and don't align stack because
|
||||
// we not even call stub code (we generate the code inline)
|
||||
// and there is no safepoint on this path.
|
||||
// Load java parameters.
|
||||
// Z_esp is callers operand stack pointer, i.e. it points to the parameters.
|
||||
const Register argP = Z_esp;
|
||||
const Register crc = Z_ARG1; // crc value
|
||||
const Register data = Z_ARG2; // address of java byte value (kernel_crc32 needs address)
|
||||
const Register dataLen = Z_ARG3; // source data len (1 byte). Not used because calling the single-byte emitter.
|
||||
const Register table = Z_ARG4; // address of crc32 table
|
||||
|
||||
// Load java parameters.
|
||||
// Z_esp is callers operand stack pointer, i.e. it points to the parameters.
|
||||
const Register argP = Z_esp;
|
||||
const Register crc = Z_ARG1; // crc value
|
||||
const Register data = Z_ARG2; // address of java byte value (kernel_crc32 needs address)
|
||||
const Register dataLen = Z_ARG3; // source data len (1 byte). Not used because calling the single-byte emitter.
|
||||
const Register table = Z_ARG4; // address of crc32 table
|
||||
|
||||
// Arguments are reversed on java expression stack.
|
||||
__ z_la(data, 3+1*wordSize, argP); // byte value (stack address).
|
||||
// Arguments are reversed on java expression stack.
|
||||
__ z_la(data, 3+1*wordSize, argP); // byte value (stack address).
|
||||
// Being passed as an int, the single byte is at offset +3.
|
||||
__ z_llgf(crc, 2 * wordSize, argP); // Current crc state, zero extend to 64 bit to have a clean register.
|
||||
__ z_llgf(crc, 2 * wordSize, argP); // Current crc state, zero extend to 64 bit to have a clean register.
|
||||
|
||||
StubRoutines::zarch::generate_load_crc_table_addr(_masm, table);
|
||||
__ kernel_crc32_singleByte(crc, data, dataLen, table, Z_R1, true);
|
||||
StubRoutines::zarch::generate_load_crc_table_addr(_masm, table);
|
||||
__ kernel_crc32_singleByte(crc, data, dataLen, table, Z_R1, true);
|
||||
|
||||
// Restore caller sp for c2i case.
|
||||
__ resize_frame_absolute(Z_R10, Z_R0, true); // Cut the stack back to where the caller started.
|
||||
// Restore caller sp for c2i case.
|
||||
__ resize_frame_absolute(Z_R10, Z_R0, true); // Cut the stack back to where the caller started.
|
||||
|
||||
__ z_br(Z_R14);
|
||||
__ z_br(Z_R14);
|
||||
|
||||
BLOCK_COMMENT("} CRC32_update");
|
||||
BLOCK_COMMENT("} CRC32_update");
|
||||
|
||||
// Use a previously generated vanilla native entry as the slow path.
|
||||
BIND(slow_path);
|
||||
__ jump_to_entry(Interpreter::entry_for_kind(Interpreter::native), Z_R1);
|
||||
return __ addr_at(entry_off);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
// Use a previously generated vanilla native entry as the slow path.
|
||||
BIND(slow_path);
|
||||
__ jump_to_entry(Interpreter::entry_for_kind(Interpreter::native), Z_R1);
|
||||
return __ addr_at(entry_off);
|
||||
}
|
||||
|
||||
|
||||
@ -1854,77 +1850,73 @@ address TemplateInterpreterGenerator::generate_CRC32_update_entry() {
|
||||
* int java.util.zip.CRC32.updateByteBuffer(int crc, long* buf, int off, int len)
|
||||
*/
|
||||
address TemplateInterpreterGenerator::generate_CRC32_updateBytes_entry(AbstractInterpreter::MethodKind kind) {
|
||||
assert(UseCRC32Intrinsics, "this intrinsic is not supported");
|
||||
uint64_t entry_off = __ offset();
|
||||
Label slow_path;
|
||||
|
||||
if (UseCRC32Intrinsics) {
|
||||
uint64_t entry_off = __ offset();
|
||||
Label slow_path;
|
||||
// If we need a safepoint check, generate full interpreter entry.
|
||||
__ safepoint_poll(slow_path, Z_R1);
|
||||
|
||||
// If we need a safepoint check, generate full interpreter entry.
|
||||
__ safepoint_poll(slow_path, Z_R1);
|
||||
// We don't generate local frame and don't align stack because
|
||||
// we call stub code and there is no safepoint on this path.
|
||||
|
||||
// We don't generate local frame and don't align stack because
|
||||
// we call stub code and there is no safepoint on this path.
|
||||
// Load parameters.
|
||||
// Z_esp is callers operand stack pointer, i.e. it points to the parameters.
|
||||
const Register argP = Z_esp;
|
||||
const Register crc = Z_ARG1; // crc value
|
||||
const Register data = Z_ARG2; // address of java byte array
|
||||
const Register dataLen = Z_ARG3; // source data len
|
||||
const Register table = Z_ARG4; // address of crc32 table
|
||||
const Register t0 = Z_R10; // work reg for kernel* emitters
|
||||
const Register t1 = Z_R11; // work reg for kernel* emitters
|
||||
const Register t2 = Z_R12; // work reg for kernel* emitters
|
||||
const Register t3 = Z_R13; // work reg for kernel* emitters
|
||||
|
||||
// Load parameters.
|
||||
// Z_esp is callers operand stack pointer, i.e. it points to the parameters.
|
||||
const Register argP = Z_esp;
|
||||
const Register crc = Z_ARG1; // crc value
|
||||
const Register data = Z_ARG2; // address of java byte array
|
||||
const Register dataLen = Z_ARG3; // source data len
|
||||
const Register table = Z_ARG4; // address of crc32 table
|
||||
const Register t0 = Z_R10; // work reg for kernel* emitters
|
||||
const Register t1 = Z_R11; // work reg for kernel* emitters
|
||||
const Register t2 = Z_R12; // work reg for kernel* emitters
|
||||
const Register t3 = Z_R13; // work reg for kernel* emitters
|
||||
|
||||
// Arguments are reversed on java expression stack.
|
||||
// Calculate address of start element.
|
||||
if (kind == Interpreter::java_util_zip_CRC32_updateByteBuffer) { // Used for "updateByteBuffer direct".
|
||||
// crc @ (SP + 5W) (32bit)
|
||||
// buf @ (SP + 3W) (64bit ptr to long array)
|
||||
// off @ (SP + 2W) (32bit)
|
||||
// dataLen @ (SP + 1W) (32bit)
|
||||
// data = buf + off
|
||||
BLOCK_COMMENT("CRC32_updateByteBuffer {");
|
||||
__ z_llgf(crc, 5*wordSize, argP); // current crc state
|
||||
__ z_lg(data, 3*wordSize, argP); // start of byte buffer
|
||||
__ z_agf(data, 2*wordSize, argP); // Add byte buffer offset.
|
||||
__ z_lgf(dataLen, 1*wordSize, argP); // #bytes to process
|
||||
} else { // Used for "updateBytes update".
|
||||
// crc @ (SP + 4W) (32bit)
|
||||
// buf @ (SP + 3W) (64bit ptr to byte array)
|
||||
// off @ (SP + 2W) (32bit)
|
||||
// dataLen @ (SP + 1W) (32bit)
|
||||
// data = buf + off + base_offset
|
||||
BLOCK_COMMENT("CRC32_updateBytes {");
|
||||
__ z_llgf(crc, 4*wordSize, argP); // current crc state
|
||||
__ z_lg(data, 3*wordSize, argP); // start of byte buffer
|
||||
__ z_agf(data, 2*wordSize, argP); // Add byte buffer offset.
|
||||
__ z_lgf(dataLen, 1*wordSize, argP); // #bytes to process
|
||||
__ z_aghi(data, arrayOopDesc::base_offset_in_bytes(T_BYTE));
|
||||
}
|
||||
|
||||
StubRoutines::zarch::generate_load_crc_table_addr(_masm, table);
|
||||
|
||||
__ resize_frame(-(6*8), Z_R0, true); // Resize frame to provide add'l space to spill 5 registers.
|
||||
__ z_stmg(t0, t3, 1*8, Z_SP); // Spill regs 10..13 to make them available as work registers.
|
||||
__ kernel_crc32_1word(crc, data, dataLen, table, t0, t1, t2, t3, true);
|
||||
__ z_lmg(t0, t3, 1*8, Z_SP); // Spill regs 10..13 back from stack.
|
||||
|
||||
// Restore caller sp for c2i case.
|
||||
__ resize_frame_absolute(Z_R10, Z_R0, true); // Cut the stack back to where the caller started.
|
||||
|
||||
__ z_br(Z_R14);
|
||||
|
||||
BLOCK_COMMENT("} CRC32_update{Bytes|ByteBuffer}");
|
||||
|
||||
// Use a previously generated vanilla native entry as the slow path.
|
||||
BIND(slow_path);
|
||||
__ jump_to_entry(Interpreter::entry_for_kind(Interpreter::native), Z_R1);
|
||||
return __ addr_at(entry_off);
|
||||
// Arguments are reversed on java expression stack.
|
||||
// Calculate address of start element.
|
||||
if (kind == Interpreter::java_util_zip_CRC32_updateByteBuffer) { // Used for "updateByteBuffer direct".
|
||||
// crc @ (SP + 5W) (32bit)
|
||||
// buf @ (SP + 3W) (64bit ptr to long array)
|
||||
// off @ (SP + 2W) (32bit)
|
||||
// dataLen @ (SP + 1W) (32bit)
|
||||
// data = buf + off
|
||||
BLOCK_COMMENT("CRC32_updateByteBuffer {");
|
||||
__ z_llgf(crc, 5*wordSize, argP); // current crc state
|
||||
__ z_lg(data, 3*wordSize, argP); // start of byte buffer
|
||||
__ z_agf(data, 2*wordSize, argP); // Add byte buffer offset.
|
||||
__ z_lgf(dataLen, 1*wordSize, argP); // #bytes to process
|
||||
} else { // Used for "updateBytes update".
|
||||
// crc @ (SP + 4W) (32bit)
|
||||
// buf @ (SP + 3W) (64bit ptr to byte array)
|
||||
// off @ (SP + 2W) (32bit)
|
||||
// dataLen @ (SP + 1W) (32bit)
|
||||
// data = buf + off + base_offset
|
||||
BLOCK_COMMENT("CRC32_updateBytes {");
|
||||
__ z_llgf(crc, 4*wordSize, argP); // current crc state
|
||||
__ z_lg(data, 3*wordSize, argP); // start of byte buffer
|
||||
__ z_agf(data, 2*wordSize, argP); // Add byte buffer offset.
|
||||
__ z_lgf(dataLen, 1*wordSize, argP); // #bytes to process
|
||||
__ z_aghi(data, arrayOopDesc::base_offset_in_bytes(T_BYTE));
|
||||
}
|
||||
|
||||
return NULL;
|
||||
StubRoutines::zarch::generate_load_crc_table_addr(_masm, table);
|
||||
|
||||
__ resize_frame(-(6*8), Z_R0, true); // Resize frame to provide add'l space to spill 5 registers.
|
||||
__ z_stmg(t0, t3, 1*8, Z_SP); // Spill regs 10..13 to make them available as work registers.
|
||||
__ kernel_crc32_1word(crc, data, dataLen, table, t0, t1, t2, t3, true);
|
||||
__ z_lmg(t0, t3, 1*8, Z_SP); // Spill regs 10..13 back from stack.
|
||||
|
||||
// Restore caller sp for c2i case.
|
||||
__ resize_frame_absolute(Z_R10, Z_R0, true); // Cut the stack back to where the caller started.
|
||||
|
||||
__ z_br(Z_R14);
|
||||
|
||||
BLOCK_COMMENT("} CRC32_update{Bytes|ByteBuffer}");
|
||||
|
||||
// Use a previously generated vanilla native entry as the slow path.
|
||||
BIND(slow_path);
|
||||
__ jump_to_entry(Interpreter::entry_for_kind(Interpreter::native), Z_R1);
|
||||
return __ addr_at(entry_off);
|
||||
}
|
||||
|
||||
|
||||
@ -1936,74 +1928,75 @@ address TemplateInterpreterGenerator::generate_CRC32_updateBytes_entry(AbstractI
|
||||
* CRC32C also uses an "end" variable instead of the length variable CRC32 uses
|
||||
*/
|
||||
address TemplateInterpreterGenerator::generate_CRC32C_updateBytes_entry(AbstractInterpreter::MethodKind kind) {
|
||||
assert(UseCRC32CIntrinsics, "this intrinsic is not supported");
|
||||
uint64_t entry_off = __ offset();
|
||||
|
||||
if (UseCRC32CIntrinsics) {
|
||||
uint64_t entry_off = __ offset();
|
||||
// We don't generate local frame and don't align stack because
|
||||
// we call stub code and there is no safepoint on this path.
|
||||
|
||||
// We don't generate local frame and don't align stack because
|
||||
// we call stub code and there is no safepoint on this path.
|
||||
// Load parameters.
|
||||
// Z_esp is callers operand stack pointer, i.e. it points to the parameters.
|
||||
const Register argP = Z_esp;
|
||||
const Register crc = Z_ARG1; // crc value
|
||||
const Register data = Z_ARG2; // address of java byte array
|
||||
const Register dataLen = Z_ARG3; // source data len
|
||||
const Register table = Z_ARG4; // address of crc32 table
|
||||
const Register t0 = Z_R10; // work reg for kernel* emitters
|
||||
const Register t1 = Z_R11; // work reg for kernel* emitters
|
||||
const Register t2 = Z_R12; // work reg for kernel* emitters
|
||||
const Register t3 = Z_R13; // work reg for kernel* emitters
|
||||
|
||||
// Load parameters.
|
||||
// Z_esp is callers operand stack pointer, i.e. it points to the parameters.
|
||||
const Register argP = Z_esp;
|
||||
const Register crc = Z_ARG1; // crc value
|
||||
const Register data = Z_ARG2; // address of java byte array
|
||||
const Register dataLen = Z_ARG3; // source data len
|
||||
const Register table = Z_ARG4; // address of crc32 table
|
||||
const Register t0 = Z_R10; // work reg for kernel* emitters
|
||||
const Register t1 = Z_R11; // work reg for kernel* emitters
|
||||
const Register t2 = Z_R12; // work reg for kernel* emitters
|
||||
const Register t3 = Z_R13; // work reg for kernel* emitters
|
||||
|
||||
// Arguments are reversed on java expression stack.
|
||||
// Calculate address of start element.
|
||||
if (kind == Interpreter::java_util_zip_CRC32C_updateDirectByteBuffer) { // Used for "updateByteBuffer direct".
|
||||
// crc @ (SP + 5W) (32bit)
|
||||
// buf @ (SP + 3W) (64bit ptr to long array)
|
||||
// off @ (SP + 2W) (32bit)
|
||||
// dataLen @ (SP + 1W) (32bit)
|
||||
// data = buf + off
|
||||
BLOCK_COMMENT("CRC32C_updateDirectByteBuffer {");
|
||||
__ z_llgf(crc, 5*wordSize, argP); // current crc state
|
||||
__ z_lg(data, 3*wordSize, argP); // start of byte buffer
|
||||
__ z_agf(data, 2*wordSize, argP); // Add byte buffer offset.
|
||||
__ z_lgf(dataLen, 1*wordSize, argP); // #bytes to process, calculated as
|
||||
__ z_sgf(dataLen, Address(argP, 2*wordSize)); // (end_index - offset)
|
||||
} else { // Used for "updateBytes update".
|
||||
// crc @ (SP + 4W) (32bit)
|
||||
// buf @ (SP + 3W) (64bit ptr to byte array)
|
||||
// off @ (SP + 2W) (32bit)
|
||||
// dataLen @ (SP + 1W) (32bit)
|
||||
// data = buf + off + base_offset
|
||||
BLOCK_COMMENT("CRC32C_updateBytes {");
|
||||
__ z_llgf(crc, 4*wordSize, argP); // current crc state
|
||||
__ z_lg(data, 3*wordSize, argP); // start of byte buffer
|
||||
__ z_agf(data, 2*wordSize, argP); // Add byte buffer offset.
|
||||
__ z_lgf(dataLen, 1*wordSize, argP); // #bytes to process, calculated as
|
||||
__ z_sgf(dataLen, Address(argP, 2*wordSize)); // (end_index - offset)
|
||||
__ z_aghi(data, arrayOopDesc::base_offset_in_bytes(T_BYTE));
|
||||
}
|
||||
|
||||
StubRoutines::zarch::generate_load_crc32c_table_addr(_masm, table);
|
||||
|
||||
__ resize_frame(-(6*8), Z_R0, true); // Resize frame to provide add'l space to spill 5 registers.
|
||||
__ z_stmg(t0, t3, 1*8, Z_SP); // Spill regs 10..13 to make them available as work registers.
|
||||
__ kernel_crc32_1word(crc, data, dataLen, table, t0, t1, t2, t3, false);
|
||||
__ z_lmg(t0, t3, 1*8, Z_SP); // Spill regs 10..13 back from stack.
|
||||
|
||||
// Restore caller sp for c2i case.
|
||||
__ resize_frame_absolute(Z_R10, Z_R0, true); // Cut the stack back to where the caller started.
|
||||
|
||||
__ z_br(Z_R14);
|
||||
|
||||
BLOCK_COMMENT("} CRC32C_update{Bytes|DirectByteBuffer}");
|
||||
return __ addr_at(entry_off);
|
||||
// Arguments are reversed on java expression stack.
|
||||
// Calculate address of start element.
|
||||
if (kind == Interpreter::java_util_zip_CRC32C_updateDirectByteBuffer) { // Used for "updateByteBuffer direct".
|
||||
// crc @ (SP + 5W) (32bit)
|
||||
// buf @ (SP + 3W) (64bit ptr to long array)
|
||||
// off @ (SP + 2W) (32bit)
|
||||
// dataLen @ (SP + 1W) (32bit)
|
||||
// data = buf + off
|
||||
BLOCK_COMMENT("CRC32C_updateDirectByteBuffer {");
|
||||
__ z_llgf(crc, 5*wordSize, argP); // current crc state
|
||||
__ z_lg(data, 3*wordSize, argP); // start of byte buffer
|
||||
__ z_agf(data, 2*wordSize, argP); // Add byte buffer offset.
|
||||
__ z_lgf(dataLen, 1*wordSize, argP); // #bytes to process, calculated as
|
||||
__ z_sgf(dataLen, Address(argP, 2*wordSize)); // (end_index - offset)
|
||||
} else { // Used for "updateBytes update".
|
||||
// crc @ (SP + 4W) (32bit)
|
||||
// buf @ (SP + 3W) (64bit ptr to byte array)
|
||||
// off @ (SP + 2W) (32bit)
|
||||
// dataLen @ (SP + 1W) (32bit)
|
||||
// data = buf + off + base_offset
|
||||
BLOCK_COMMENT("CRC32C_updateBytes {");
|
||||
__ z_llgf(crc, 4*wordSize, argP); // current crc state
|
||||
__ z_lg(data, 3*wordSize, argP); // start of byte buffer
|
||||
__ z_agf(data, 2*wordSize, argP); // Add byte buffer offset.
|
||||
__ z_lgf(dataLen, 1*wordSize, argP); // #bytes to process, calculated as
|
||||
__ z_sgf(dataLen, Address(argP, 2*wordSize)); // (end_index - offset)
|
||||
__ z_aghi(data, arrayOopDesc::base_offset_in_bytes(T_BYTE));
|
||||
}
|
||||
|
||||
return NULL;
|
||||
StubRoutines::zarch::generate_load_crc32c_table_addr(_masm, table);
|
||||
|
||||
__ resize_frame(-(6*8), Z_R0, true); // Resize frame to provide add'l space to spill 5 registers.
|
||||
__ z_stmg(t0, t3, 1*8, Z_SP); // Spill regs 10..13 to make them available as work registers.
|
||||
__ kernel_crc32_1word(crc, data, dataLen, table, t0, t1, t2, t3, false);
|
||||
__ z_lmg(t0, t3, 1*8, Z_SP); // Spill regs 10..13 back from stack.
|
||||
|
||||
// Restore caller sp for c2i case.
|
||||
__ resize_frame_absolute(Z_R10, Z_R0, true); // Cut the stack back to where the caller started.
|
||||
|
||||
__ z_br(Z_R14);
|
||||
|
||||
BLOCK_COMMENT("} CRC32C_update{Bytes|DirectByteBuffer}");
|
||||
return __ addr_at(entry_off);
|
||||
}
|
||||
|
||||
// Not supported
|
||||
address TemplateInterpreterGenerator::generate_currentThread() { return nullptr; }
|
||||
address TemplateInterpreterGenerator::generate_Float_intBitsToFloat_entry() { return nullptr; }
|
||||
address TemplateInterpreterGenerator::generate_Float_floatToRawIntBits_entry() { return nullptr; }
|
||||
address TemplateInterpreterGenerator::generate_Double_longBitsToDouble_entry() { return nullptr; }
|
||||
address TemplateInterpreterGenerator::generate_Double_doubleToRawLongBits_entry() { return nullptr; }
|
||||
address TemplateInterpreterGenerator::generate_Float_float16ToFloat_entry() { return nullptr; }
|
||||
address TemplateInterpreterGenerator::generate_Float_floatToFloat16_entry() { return nullptr; }
|
||||
|
||||
|
@ -53,48 +53,46 @@ address TemplateInterpreterGenerator::generate_slow_signature_handler() {
|
||||
* int java.util.zip.CRC32.update(int crc, int b)
|
||||
*/
|
||||
address TemplateInterpreterGenerator::generate_CRC32_update_entry() {
|
||||
if (UseCRC32Intrinsics) {
|
||||
address entry = __ pc();
|
||||
assert(UseCRC32Intrinsics, "this intrinsic is not supported");
|
||||
address entry = __ pc();
|
||||
|
||||
// rbx: Method*
|
||||
// rsi: senderSP must preserved for slow path, set SP to it on fast path
|
||||
// rdx: scratch
|
||||
// rdi: scratch
|
||||
// rbx: Method*
|
||||
// rsi: senderSP must preserved for slow path, set SP to it on fast path
|
||||
// rdx: scratch
|
||||
// rdi: scratch
|
||||
|
||||
Label slow_path;
|
||||
// If we need a safepoint check, generate full interpreter entry.
|
||||
__ get_thread(rdi);
|
||||
__ safepoint_poll(slow_path, rdi, false /* at_return */, false /* in_nmethod */);
|
||||
Label slow_path;
|
||||
// If we need a safepoint check, generate full interpreter entry.
|
||||
__ get_thread(rdi);
|
||||
__ safepoint_poll(slow_path, rdi, false /* at_return */, false /* in_nmethod */);
|
||||
|
||||
// We don't generate local frame and don't align stack because
|
||||
// we call stub code and there is no safepoint on this path.
|
||||
// We don't generate local frame and don't align stack because
|
||||
// we call stub code and there is no safepoint on this path.
|
||||
|
||||
// Load parameters
|
||||
const Register crc = rax; // crc
|
||||
const Register val = rdx; // source java byte value
|
||||
const Register tbl = rdi; // scratch
|
||||
// Load parameters
|
||||
const Register crc = rax; // crc
|
||||
const Register val = rdx; // source java byte value
|
||||
const Register tbl = rdi; // scratch
|
||||
|
||||
// Arguments are reversed on java expression stack
|
||||
__ movl(val, Address(rsp, wordSize)); // byte value
|
||||
__ movl(crc, Address(rsp, 2*wordSize)); // Initial CRC
|
||||
// Arguments are reversed on java expression stack
|
||||
__ movl(val, Address(rsp, wordSize)); // byte value
|
||||
__ movl(crc, Address(rsp, 2*wordSize)); // Initial CRC
|
||||
|
||||
__ lea(tbl, ExternalAddress(StubRoutines::crc_table_addr()));
|
||||
__ notl(crc); // ~crc
|
||||
__ update_byte_crc32(crc, val, tbl);
|
||||
__ notl(crc); // ~crc
|
||||
// result in rax
|
||||
__ lea(tbl, ExternalAddress(StubRoutines::crc_table_addr()));
|
||||
__ notl(crc); // ~crc
|
||||
__ update_byte_crc32(crc, val, tbl);
|
||||
__ notl(crc); // ~crc
|
||||
// result in rax
|
||||
|
||||
// _areturn
|
||||
__ pop(rdi); // get return address
|
||||
__ mov(rsp, rsi); // set sp to sender sp
|
||||
__ jmp(rdi);
|
||||
// _areturn
|
||||
__ pop(rdi); // get return address
|
||||
__ mov(rsp, rsi); // set sp to sender sp
|
||||
__ jmp(rdi);
|
||||
|
||||
// generate a vanilla native entry as the slow path
|
||||
__ bind(slow_path);
|
||||
__ jump_to_entry(Interpreter::entry_for_kind(Interpreter::native));
|
||||
return entry;
|
||||
}
|
||||
return NULL;
|
||||
// generate a vanilla native entry as the slow path
|
||||
__ bind(slow_path);
|
||||
__ jump_to_entry(Interpreter::entry_for_kind(Interpreter::native));
|
||||
return entry;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -103,62 +101,60 @@ address TemplateInterpreterGenerator::generate_CRC32_update_entry() {
|
||||
* int java.util.zip.CRC32.updateByteBuffer(int crc, long buf, int off, int len)
|
||||
*/
|
||||
address TemplateInterpreterGenerator::generate_CRC32_updateBytes_entry(AbstractInterpreter::MethodKind kind) {
|
||||
if (UseCRC32Intrinsics) {
|
||||
address entry = __ pc();
|
||||
assert(UseCRC32Intrinsics, "this intrinsic is not supported");
|
||||
address entry = __ pc();
|
||||
|
||||
// rbx,: Method*
|
||||
// rsi: senderSP must preserved for slow path, set SP to it on fast path
|
||||
// rdx: scratch
|
||||
// rdi: scratch
|
||||
// rbx,: Method*
|
||||
// rsi: senderSP must preserved for slow path, set SP to it on fast path
|
||||
// rdx: scratch
|
||||
// rdi: scratch
|
||||
|
||||
Label slow_path;
|
||||
// If we need a safepoint check, generate full interpreter entry.
|
||||
__ get_thread(rdi);
|
||||
__ safepoint_poll(slow_path, rdi, false /* at_return */, false /* in_nmethod */);
|
||||
Label slow_path;
|
||||
// If we need a safepoint check, generate full interpreter entry.
|
||||
__ get_thread(rdi);
|
||||
__ safepoint_poll(slow_path, rdi, false /* at_return */, false /* in_nmethod */);
|
||||
|
||||
// We don't generate local frame and don't align stack because
|
||||
// we call stub code and there is no safepoint on this path.
|
||||
// We don't generate local frame and don't align stack because
|
||||
// we call stub code and there is no safepoint on this path.
|
||||
|
||||
// Load parameters
|
||||
const Register crc = rax; // crc
|
||||
const Register buf = rdx; // source java byte array address
|
||||
const Register len = rdi; // length
|
||||
// Load parameters
|
||||
const Register crc = rax; // crc
|
||||
const Register buf = rdx; // source java byte array address
|
||||
const Register len = rdi; // length
|
||||
|
||||
// value x86_32
|
||||
// interp. arg ptr ESP + 4
|
||||
// int java.util.zip.CRC32.updateBytes(int crc, byte[] b, int off, int len)
|
||||
// 3 2 1 0
|
||||
// int java.util.zip.CRC32.updateByteBuffer(int crc, long buf, int off, int len)
|
||||
// 4 2,3 1 0
|
||||
// value x86_32
|
||||
// interp. arg ptr ESP + 4
|
||||
// int java.util.zip.CRC32.updateBytes(int crc, byte[] b, int off, int len)
|
||||
// 3 2 1 0
|
||||
// int java.util.zip.CRC32.updateByteBuffer(int crc, long buf, int off, int len)
|
||||
// 4 2,3 1 0
|
||||
|
||||
// Arguments are reversed on java expression stack
|
||||
__ movl(len, Address(rsp, 4 + 0)); // Length
|
||||
// Calculate address of start element
|
||||
if (kind == Interpreter::java_util_zip_CRC32_updateByteBuffer) {
|
||||
__ movptr(buf, Address(rsp, 4 + 2 * wordSize)); // long buf
|
||||
__ addptr(buf, Address(rsp, 4 + 1 * wordSize)); // + offset
|
||||
__ movl(crc, Address(rsp, 4 + 4 * wordSize)); // Initial CRC
|
||||
} else {
|
||||
__ movptr(buf, Address(rsp, 4 + 2 * wordSize)); // byte[] array
|
||||
__ addptr(buf, arrayOopDesc::base_offset_in_bytes(T_BYTE)); // + header size
|
||||
__ addptr(buf, Address(rsp, 4 + 1 * wordSize)); // + offset
|
||||
__ movl(crc, Address(rsp, 4 + 3 * wordSize)); // Initial CRC
|
||||
}
|
||||
|
||||
__ super_call_VM_leaf(CAST_FROM_FN_PTR(address, StubRoutines::updateBytesCRC32()), crc, buf, len);
|
||||
// result in rax
|
||||
|
||||
// _areturn
|
||||
__ pop(rdi); // get return address
|
||||
__ mov(rsp, rsi); // set sp to sender sp
|
||||
__ jmp(rdi);
|
||||
|
||||
// generate a vanilla native entry as the slow path
|
||||
__ bind(slow_path);
|
||||
__ jump_to_entry(Interpreter::entry_for_kind(Interpreter::native));
|
||||
return entry;
|
||||
// Arguments are reversed on java expression stack
|
||||
__ movl(len, Address(rsp, 4 + 0)); // Length
|
||||
// Calculate address of start element
|
||||
if (kind == Interpreter::java_util_zip_CRC32_updateByteBuffer) {
|
||||
__ movptr(buf, Address(rsp, 4 + 2 * wordSize)); // long buf
|
||||
__ addptr(buf, Address(rsp, 4 + 1 * wordSize)); // + offset
|
||||
__ movl(crc, Address(rsp, 4 + 4 * wordSize)); // Initial CRC
|
||||
} else {
|
||||
__ movptr(buf, Address(rsp, 4 + 2 * wordSize)); // byte[] array
|
||||
__ addptr(buf, arrayOopDesc::base_offset_in_bytes(T_BYTE)); // + header size
|
||||
__ addptr(buf, Address(rsp, 4 + 1 * wordSize)); // + offset
|
||||
__ movl(crc, Address(rsp, 4 + 3 * wordSize)); // Initial CRC
|
||||
}
|
||||
return NULL;
|
||||
|
||||
__ super_call_VM_leaf(CAST_FROM_FN_PTR(address, StubRoutines::updateBytesCRC32()), crc, buf, len);
|
||||
// result in rax
|
||||
|
||||
// _areturn
|
||||
__ pop(rdi); // get return address
|
||||
__ mov(rsp, rsi); // set sp to sender sp
|
||||
__ jmp(rdi);
|
||||
|
||||
// generate a vanilla native entry as the slow path
|
||||
__ bind(slow_path);
|
||||
__ jump_to_entry(Interpreter::entry_for_kind(Interpreter::native));
|
||||
return entry;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -167,45 +163,43 @@ address TemplateInterpreterGenerator::generate_CRC32_updateBytes_entry(AbstractI
|
||||
* int java.util.zip.CRC32C.updateByteBuffer(int crc, long address, int off, int end)
|
||||
*/
|
||||
address TemplateInterpreterGenerator::generate_CRC32C_updateBytes_entry(AbstractInterpreter::MethodKind kind) {
|
||||
if (UseCRC32CIntrinsics) {
|
||||
address entry = __ pc();
|
||||
// Load parameters
|
||||
const Register crc = rax; // crc
|
||||
const Register buf = rcx; // source java byte array address
|
||||
const Register len = rdx; // length
|
||||
const Register end = len;
|
||||
assert(UseCRC32CIntrinsics, "this intrinsic is not supported");
|
||||
address entry = __ pc();
|
||||
// Load parameters
|
||||
const Register crc = rax; // crc
|
||||
const Register buf = rcx; // source java byte array address
|
||||
const Register len = rdx; // length
|
||||
const Register end = len;
|
||||
|
||||
// value x86_32
|
||||
// interp. arg ptr ESP + 4
|
||||
// int java.util.zip.CRC32.updateBytes(int crc, byte[] b, int off, int end)
|
||||
// 3 2 1 0
|
||||
// int java.util.zip.CRC32.updateByteBuffer(int crc, long address, int off, int end)
|
||||
// 4 2,3 1 0
|
||||
// value x86_32
|
||||
// interp. arg ptr ESP + 4
|
||||
// int java.util.zip.CRC32.updateBytes(int crc, byte[] b, int off, int end)
|
||||
// 3 2 1 0
|
||||
// int java.util.zip.CRC32.updateByteBuffer(int crc, long address, int off, int end)
|
||||
// 4 2,3 1 0
|
||||
|
||||
// Arguments are reversed on java expression stack
|
||||
__ movl(end, Address(rsp, 4 + 0)); // end
|
||||
__ subl(len, Address(rsp, 4 + 1 * wordSize)); // end - offset == length
|
||||
// Calculate address of start element
|
||||
if (kind == Interpreter::java_util_zip_CRC32C_updateDirectByteBuffer) {
|
||||
__ movptr(buf, Address(rsp, 4 + 2 * wordSize)); // long address
|
||||
__ addptr(buf, Address(rsp, 4 + 1 * wordSize)); // + offset
|
||||
__ movl(crc, Address(rsp, 4 + 4 * wordSize)); // Initial CRC
|
||||
} else {
|
||||
__ movptr(buf, Address(rsp, 4 + 2 * wordSize)); // byte[] array
|
||||
__ addptr(buf, arrayOopDesc::base_offset_in_bytes(T_BYTE)); // + header size
|
||||
__ addptr(buf, Address(rsp, 4 + 1 * wordSize)); // + offset
|
||||
__ movl(crc, Address(rsp, 4 + 3 * wordSize)); // Initial CRC
|
||||
}
|
||||
__ super_call_VM_leaf(CAST_FROM_FN_PTR(address, StubRoutines::updateBytesCRC32C()), crc, buf, len);
|
||||
// result in rax
|
||||
// _areturn
|
||||
__ pop(rdi); // get return address
|
||||
__ mov(rsp, rsi); // set sp to sender sp
|
||||
__ jmp(rdi);
|
||||
|
||||
return entry;
|
||||
// Arguments are reversed on java expression stack
|
||||
__ movl(end, Address(rsp, 4 + 0)); // end
|
||||
__ subl(len, Address(rsp, 4 + 1 * wordSize)); // end - offset == length
|
||||
// Calculate address of start element
|
||||
if (kind == Interpreter::java_util_zip_CRC32C_updateDirectByteBuffer) {
|
||||
__ movptr(buf, Address(rsp, 4 + 2 * wordSize)); // long address
|
||||
__ addptr(buf, Address(rsp, 4 + 1 * wordSize)); // + offset
|
||||
__ movl(crc, Address(rsp, 4 + 4 * wordSize)); // Initial CRC
|
||||
} else {
|
||||
__ movptr(buf, Address(rsp, 4 + 2 * wordSize)); // byte[] array
|
||||
__ addptr(buf, arrayOopDesc::base_offset_in_bytes(T_BYTE)); // + header size
|
||||
__ addptr(buf, Address(rsp, 4 + 1 * wordSize)); // + offset
|
||||
__ movl(crc, Address(rsp, 4 + 3 * wordSize)); // Initial CRC
|
||||
}
|
||||
return NULL;
|
||||
__ super_call_VM_leaf(CAST_FROM_FN_PTR(address, StubRoutines::updateBytesCRC32C()), crc, buf, len);
|
||||
// result in rax
|
||||
// _areturn
|
||||
__ pop(rdi); // get return address
|
||||
__ mov(rsp, rsi); // set sp to sender sp
|
||||
__ jmp(rdi);
|
||||
|
||||
return entry;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -319,12 +313,7 @@ address TemplateInterpreterGenerator::generate_Double_doubleToRawLongBits_entry(
|
||||
* java.lang.Float.float16ToFloat(short floatBinary16)
|
||||
*/
|
||||
address TemplateInterpreterGenerator::generate_Float_float16ToFloat_entry() {
|
||||
// vmIntrinsics checks InlineIntrinsics flag, no need to check it here.
|
||||
if (!VM_Version::supports_float16() ||
|
||||
vmIntrinsics::is_disabled_by_flags(vmIntrinsics::_float16ToFloat) ||
|
||||
vmIntrinsics::is_disabled_by_flags(vmIntrinsics::_floatToFloat16)) {
|
||||
return nullptr; // Generate a vanilla entry
|
||||
}
|
||||
assert(VM_Version::supports_float16(), "this intrinsic is not supported");
|
||||
address entry = __ pc();
|
||||
|
||||
// rsi: the sender's SP
|
||||
@ -345,12 +334,7 @@ address TemplateInterpreterGenerator::generate_Float_float16ToFloat_entry() {
|
||||
* java.lang.Float.floatToFloat16(float value)
|
||||
*/
|
||||
address TemplateInterpreterGenerator::generate_Float_floatToFloat16_entry() {
|
||||
// vmIntrinsics checks InlineIntrinsics flag, no need to check it here.
|
||||
if (!VM_Version::supports_float16() ||
|
||||
vmIntrinsics::is_disabled_by_flags(vmIntrinsics::_floatToFloat16) ||
|
||||
vmIntrinsics::is_disabled_by_flags(vmIntrinsics::_float16ToFloat)) {
|
||||
return nullptr; // Generate a vanilla entry
|
||||
}
|
||||
assert(VM_Version::supports_float16(), "this intrinsic is not supported");
|
||||
address entry = __ pc();
|
||||
|
||||
// rsi: the sender's SP
|
||||
@ -372,8 +356,6 @@ address TemplateInterpreterGenerator::generate_math_entry(AbstractInterpreter::M
|
||||
// rcx: scratrch
|
||||
// rsi: sender sp
|
||||
|
||||
if (!InlineIntrinsics) return NULL; // Generate a vanilla entry
|
||||
|
||||
address entry_point = __ pc();
|
||||
|
||||
// These don't need a safepoint check because they aren't virtually
|
||||
@ -518,3 +500,7 @@ address TemplateInterpreterGenerator::generate_math_entry(AbstractInterpreter::M
|
||||
|
||||
return entry_point;
|
||||
}
|
||||
|
||||
// Not supported
|
||||
address TemplateInterpreterGenerator::generate_currentThread() { return nullptr; }
|
||||
|
||||
|
@ -182,46 +182,44 @@ address TemplateInterpreterGenerator::generate_slow_signature_handler() {
|
||||
* int java.util.zip.CRC32.update(int crc, int b)
|
||||
*/
|
||||
address TemplateInterpreterGenerator::generate_CRC32_update_entry() {
|
||||
if (UseCRC32Intrinsics) {
|
||||
address entry = __ pc();
|
||||
assert(UseCRC32Intrinsics, "this intrinsic is not supported");
|
||||
address entry = __ pc();
|
||||
|
||||
// rbx,: Method*
|
||||
// r13: senderSP must preserved for slow path, set SP to it on fast path
|
||||
// c_rarg0: scratch (rdi on non-Win64, rcx on Win64)
|
||||
// c_rarg1: scratch (rsi on non-Win64, rdx on Win64)
|
||||
// rbx,: Method*
|
||||
// r13: senderSP must preserved for slow path, set SP to it on fast path
|
||||
// c_rarg0: scratch (rdi on non-Win64, rcx on Win64)
|
||||
// c_rarg1: scratch (rsi on non-Win64, rdx on Win64)
|
||||
|
||||
Label slow_path;
|
||||
__ safepoint_poll(slow_path, r15_thread, true /* at_return */, false /* in_nmethod */);
|
||||
Label slow_path;
|
||||
__ safepoint_poll(slow_path, r15_thread, true /* at_return */, false /* in_nmethod */);
|
||||
|
||||
// We don't generate local frame and don't align stack because
|
||||
// we call stub code and there is no safepoint on this path.
|
||||
// We don't generate local frame and don't align stack because
|
||||
// we call stub code and there is no safepoint on this path.
|
||||
|
||||
// Load parameters
|
||||
const Register crc = rax; // crc
|
||||
const Register val = c_rarg0; // source java byte value
|
||||
const Register tbl = c_rarg1; // scratch
|
||||
// Load parameters
|
||||
const Register crc = rax; // crc
|
||||
const Register val = c_rarg0; // source java byte value
|
||||
const Register tbl = c_rarg1; // scratch
|
||||
|
||||
// Arguments are reversed on java expression stack
|
||||
__ movl(val, Address(rsp, wordSize)); // byte value
|
||||
__ movl(crc, Address(rsp, 2*wordSize)); // Initial CRC
|
||||
// Arguments are reversed on java expression stack
|
||||
__ movl(val, Address(rsp, wordSize)); // byte value
|
||||
__ movl(crc, Address(rsp, 2*wordSize)); // Initial CRC
|
||||
|
||||
__ lea(tbl, ExternalAddress(StubRoutines::crc_table_addr()));
|
||||
__ notl(crc); // ~crc
|
||||
__ update_byte_crc32(crc, val, tbl);
|
||||
__ notl(crc); // ~crc
|
||||
// result in rax
|
||||
__ lea(tbl, ExternalAddress(StubRoutines::crc_table_addr()));
|
||||
__ notl(crc); // ~crc
|
||||
__ update_byte_crc32(crc, val, tbl);
|
||||
__ notl(crc); // ~crc
|
||||
// result in rax
|
||||
|
||||
// _areturn
|
||||
__ pop(rdi); // get return address
|
||||
__ mov(rsp, r13); // set sp to sender sp
|
||||
__ jmp(rdi);
|
||||
// _areturn
|
||||
__ pop(rdi); // get return address
|
||||
__ mov(rsp, r13); // set sp to sender sp
|
||||
__ jmp(rdi);
|
||||
|
||||
// generate a vanilla native entry as the slow path
|
||||
__ bind(slow_path);
|
||||
__ jump_to_entry(Interpreter::entry_for_kind(Interpreter::native));
|
||||
return entry;
|
||||
}
|
||||
return NULL;
|
||||
// generate a vanilla native entry as the slow path
|
||||
__ bind(slow_path);
|
||||
__ jump_to_entry(Interpreter::entry_for_kind(Interpreter::native));
|
||||
return entry;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -230,55 +228,53 @@ address TemplateInterpreterGenerator::generate_CRC32_update_entry() {
|
||||
* int java.util.zip.CRC32.updateByteBuffer(int crc, long buf, int off, int len)
|
||||
*/
|
||||
address TemplateInterpreterGenerator::generate_CRC32_updateBytes_entry(AbstractInterpreter::MethodKind kind) {
|
||||
if (UseCRC32Intrinsics) {
|
||||
address entry = __ pc();
|
||||
assert(UseCRC32Intrinsics, "this intrinsic is not supported");
|
||||
address entry = __ pc();
|
||||
|
||||
// rbx,: Method*
|
||||
// r13: senderSP must preserved for slow path, set SP to it on fast path
|
||||
// rbx,: Method*
|
||||
// r13: senderSP must preserved for slow path, set SP to it on fast path
|
||||
|
||||
Label slow_path;
|
||||
__ safepoint_poll(slow_path, r15_thread, false /* at_return */, false /* in_nmethod */);
|
||||
Label slow_path;
|
||||
__ safepoint_poll(slow_path, r15_thread, false /* at_return */, false /* in_nmethod */);
|
||||
|
||||
// We don't generate local frame and don't align stack because
|
||||
// we call stub code and there is no safepoint on this path.
|
||||
// We don't generate local frame and don't align stack because
|
||||
// we call stub code and there is no safepoint on this path.
|
||||
|
||||
// Load parameters
|
||||
const Register crc = c_rarg0; // crc
|
||||
const Register buf = c_rarg1; // source java byte array address
|
||||
const Register len = c_rarg2; // length
|
||||
const Register off = len; // offset (never overlaps with 'len')
|
||||
// Load parameters
|
||||
const Register crc = c_rarg0; // crc
|
||||
const Register buf = c_rarg1; // source java byte array address
|
||||
const Register len = c_rarg2; // length
|
||||
const Register off = len; // offset (never overlaps with 'len')
|
||||
|
||||
// Arguments are reversed on java expression stack
|
||||
// Calculate address of start element
|
||||
if (kind == Interpreter::java_util_zip_CRC32_updateByteBuffer) {
|
||||
__ movptr(buf, Address(rsp, 3*wordSize)); // long buf
|
||||
__ movl2ptr(off, Address(rsp, 2*wordSize)); // offset
|
||||
__ addq(buf, off); // + offset
|
||||
__ movl(crc, Address(rsp, 5*wordSize)); // Initial CRC
|
||||
} else {
|
||||
__ movptr(buf, Address(rsp, 3*wordSize)); // byte[] array
|
||||
__ addptr(buf, arrayOopDesc::base_offset_in_bytes(T_BYTE)); // + header size
|
||||
__ movl2ptr(off, Address(rsp, 2*wordSize)); // offset
|
||||
__ addq(buf, off); // + offset
|
||||
__ movl(crc, Address(rsp, 4*wordSize)); // Initial CRC
|
||||
}
|
||||
// Can now load 'len' since we're finished with 'off'
|
||||
__ movl(len, Address(rsp, wordSize)); // Length
|
||||
|
||||
__ super_call_VM_leaf(CAST_FROM_FN_PTR(address, StubRoutines::updateBytesCRC32()), crc, buf, len);
|
||||
// result in rax
|
||||
|
||||
// _areturn
|
||||
__ pop(rdi); // get return address
|
||||
__ mov(rsp, r13); // set sp to sender sp
|
||||
__ jmp(rdi);
|
||||
|
||||
// generate a vanilla native entry as the slow path
|
||||
__ bind(slow_path);
|
||||
__ jump_to_entry(Interpreter::entry_for_kind(Interpreter::native));
|
||||
return entry;
|
||||
// Arguments are reversed on java expression stack
|
||||
// Calculate address of start element
|
||||
if (kind == Interpreter::java_util_zip_CRC32_updateByteBuffer) {
|
||||
__ movptr(buf, Address(rsp, 3*wordSize)); // long buf
|
||||
__ movl2ptr(off, Address(rsp, 2*wordSize)); // offset
|
||||
__ addq(buf, off); // + offset
|
||||
__ movl(crc, Address(rsp, 5*wordSize)); // Initial CRC
|
||||
} else {
|
||||
__ movptr(buf, Address(rsp, 3*wordSize)); // byte[] array
|
||||
__ addptr(buf, arrayOopDesc::base_offset_in_bytes(T_BYTE)); // + header size
|
||||
__ movl2ptr(off, Address(rsp, 2*wordSize)); // offset
|
||||
__ addq(buf, off); // + offset
|
||||
__ movl(crc, Address(rsp, 4*wordSize)); // Initial CRC
|
||||
}
|
||||
return NULL;
|
||||
// Can now load 'len' since we're finished with 'off'
|
||||
__ movl(len, Address(rsp, wordSize)); // Length
|
||||
|
||||
__ super_call_VM_leaf(CAST_FROM_FN_PTR(address, StubRoutines::updateBytesCRC32()), crc, buf, len);
|
||||
// result in rax
|
||||
|
||||
// _areturn
|
||||
__ pop(rdi); // get return address
|
||||
__ mov(rsp, r13); // set sp to sender sp
|
||||
__ jmp(rdi);
|
||||
|
||||
// generate a vanilla native entry as the slow path
|
||||
__ bind(slow_path);
|
||||
__ jump_to_entry(Interpreter::entry_for_kind(Interpreter::native));
|
||||
return entry;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -287,49 +283,46 @@ address TemplateInterpreterGenerator::generate_CRC32_updateBytes_entry(AbstractI
|
||||
* int java.util.zip.CRC32C.updateDirectByteBuffer(int crc, long address, int off, int end)
|
||||
*/
|
||||
address TemplateInterpreterGenerator::generate_CRC32C_updateBytes_entry(AbstractInterpreter::MethodKind kind) {
|
||||
if (UseCRC32CIntrinsics) {
|
||||
address entry = __ pc();
|
||||
// Load parameters
|
||||
const Register crc = c_rarg0; // crc
|
||||
const Register buf = c_rarg1; // source java byte array address
|
||||
const Register len = c_rarg2;
|
||||
const Register off = c_rarg3; // offset
|
||||
const Register end = len;
|
||||
assert(UseCRC32CIntrinsics, "this intrinsic is not supported");
|
||||
address entry = __ pc();
|
||||
// Load parameters
|
||||
const Register crc = c_rarg0; // crc
|
||||
const Register buf = c_rarg1; // source java byte array address
|
||||
const Register len = c_rarg2;
|
||||
const Register off = c_rarg3; // offset
|
||||
const Register end = len;
|
||||
|
||||
// Arguments are reversed on java expression stack
|
||||
// Calculate address of start element
|
||||
if (kind == Interpreter::java_util_zip_CRC32C_updateDirectByteBuffer) {
|
||||
__ movptr(buf, Address(rsp, 3 * wordSize)); // long address
|
||||
__ movl2ptr(off, Address(rsp, 2 * wordSize)); // offset
|
||||
__ addq(buf, off); // + offset
|
||||
__ movl(crc, Address(rsp, 5 * wordSize)); // Initial CRC
|
||||
// Note on 5 * wordSize vs. 4 * wordSize:
|
||||
// * int java.util.zip.CRC32C.updateByteBuffer(int crc, long address, int off, int end)
|
||||
// 4 2,3 1 0
|
||||
// end starts at SP + 8
|
||||
// The Java(R) Virtual Machine Specification Java SE 7 Edition
|
||||
// 4.10.2.3. Values of Types long and double
|
||||
// "When calculating operand stack length, values of type long and double have length two."
|
||||
} else {
|
||||
__ movptr(buf, Address(rsp, 3 * wordSize)); // byte[] array
|
||||
__ addptr(buf, arrayOopDesc::base_offset_in_bytes(T_BYTE)); // + header size
|
||||
__ movl2ptr(off, Address(rsp, 2 * wordSize)); // offset
|
||||
__ addq(buf, off); // + offset
|
||||
__ movl(crc, Address(rsp, 4 * wordSize)); // Initial CRC
|
||||
}
|
||||
__ movl(end, Address(rsp, wordSize)); // end
|
||||
__ subl(end, off); // end - off
|
||||
__ super_call_VM_leaf(CAST_FROM_FN_PTR(address, StubRoutines::updateBytesCRC32C()), crc, buf, len);
|
||||
// result in rax
|
||||
// _areturn
|
||||
__ pop(rdi); // get return address
|
||||
__ mov(rsp, r13); // set sp to sender sp
|
||||
__ jmp(rdi);
|
||||
|
||||
return entry;
|
||||
// Arguments are reversed on java expression stack
|
||||
// Calculate address of start element
|
||||
if (kind == Interpreter::java_util_zip_CRC32C_updateDirectByteBuffer) {
|
||||
__ movptr(buf, Address(rsp, 3 * wordSize)); // long address
|
||||
__ movl2ptr(off, Address(rsp, 2 * wordSize)); // offset
|
||||
__ addq(buf, off); // + offset
|
||||
__ movl(crc, Address(rsp, 5 * wordSize)); // Initial CRC
|
||||
// Note on 5 * wordSize vs. 4 * wordSize:
|
||||
// * int java.util.zip.CRC32C.updateByteBuffer(int crc, long address, int off, int end)
|
||||
// 4 2,3 1 0
|
||||
// end starts at SP + 8
|
||||
// The Java(R) Virtual Machine Specification Java SE 7 Edition
|
||||
// 4.10.2.3. Values of Types long and double
|
||||
// "When calculating operand stack length, values of type long and double have length two."
|
||||
} else {
|
||||
__ movptr(buf, Address(rsp, 3 * wordSize)); // byte[] array
|
||||
__ addptr(buf, arrayOopDesc::base_offset_in_bytes(T_BYTE)); // + header size
|
||||
__ movl2ptr(off, Address(rsp, 2 * wordSize)); // offset
|
||||
__ addq(buf, off); // + offset
|
||||
__ movl(crc, Address(rsp, 4 * wordSize)); // Initial CRC
|
||||
}
|
||||
__ movl(end, Address(rsp, wordSize)); // end
|
||||
__ subl(end, off); // end - off
|
||||
__ super_call_VM_leaf(CAST_FROM_FN_PTR(address, StubRoutines::updateBytesCRC32C()), crc, buf, len);
|
||||
// result in rax
|
||||
// _areturn
|
||||
__ pop(rdi); // get return address
|
||||
__ mov(rsp, r13); // set sp to sender sp
|
||||
__ jmp(rdi);
|
||||
|
||||
return NULL;
|
||||
return entry;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -337,12 +330,7 @@ address TemplateInterpreterGenerator::generate_CRC32C_updateBytes_entry(Abstract
|
||||
* java.lang.Float.float16ToFloat(short floatBinary16)
|
||||
*/
|
||||
address TemplateInterpreterGenerator::generate_Float_float16ToFloat_entry() {
|
||||
// vmIntrinsics checks InlineIntrinsics flag, no need to check it here.
|
||||
if (!VM_Version::supports_float16() ||
|
||||
vmIntrinsics::is_disabled_by_flags(vmIntrinsics::_float16ToFloat) ||
|
||||
vmIntrinsics::is_disabled_by_flags(vmIntrinsics::_floatToFloat16)) {
|
||||
return nullptr; // Generate a vanilla entry
|
||||
}
|
||||
assert(VM_Version::supports_float16(), "this intrinsic is not supported");
|
||||
address entry = __ pc();
|
||||
|
||||
// r13: the sender's SP
|
||||
@ -364,12 +352,7 @@ address TemplateInterpreterGenerator::generate_Float_float16ToFloat_entry() {
|
||||
* java.lang.Float.floatToFloat16(float value)
|
||||
*/
|
||||
address TemplateInterpreterGenerator::generate_Float_floatToFloat16_entry() {
|
||||
// vmIntrinsics checks InlineIntrinsics flag, no need to check it here.
|
||||
if (!VM_Version::supports_float16() ||
|
||||
vmIntrinsics::is_disabled_by_flags(vmIntrinsics::_floatToFloat16) ||
|
||||
vmIntrinsics::is_disabled_by_flags(vmIntrinsics::_float16ToFloat)) {
|
||||
return nullptr; // Generate a vanilla entry
|
||||
}
|
||||
assert(VM_Version::supports_float16(), "this intrinsic is not supported");
|
||||
address entry = __ pc();
|
||||
|
||||
// r13: the sender's SP
|
||||
@ -396,8 +379,6 @@ address TemplateInterpreterGenerator::generate_math_entry(AbstractInterpreter::M
|
||||
// rcx: scratrch
|
||||
// r13: sender sp
|
||||
|
||||
if (!InlineIntrinsics) return NULL; // Generate a vanilla entry
|
||||
|
||||
address entry_point = __ pc();
|
||||
|
||||
// These don't need a safepoint check because they aren't virtually
|
||||
@ -514,3 +495,9 @@ address TemplateInterpreterGenerator::generate_currentThread() {
|
||||
return entry_point;
|
||||
}
|
||||
|
||||
// Not supported
|
||||
address TemplateInterpreterGenerator::generate_Float_intBitsToFloat_entry() { return nullptr; }
|
||||
address TemplateInterpreterGenerator::generate_Float_floatToRawIntBits_entry() { return nullptr; }
|
||||
address TemplateInterpreterGenerator::generate_Double_longBitsToDouble_entry() { return nullptr; }
|
||||
address TemplateInterpreterGenerator::generate_Double_doubleToRawLongBits_entry() { return nullptr; }
|
||||
|
||||
|
@ -25,6 +25,7 @@
|
||||
#include "precompiled.hpp"
|
||||
#include "asm/macroAssembler.hpp"
|
||||
#include "asm/macroAssembler.inline.hpp"
|
||||
#include "classfile/vmIntrinsics.hpp"
|
||||
#include "code/codeBlob.hpp"
|
||||
#include "compiler/compilerDefinitions.inline.hpp"
|
||||
#include "jvm.h"
|
||||
@ -3220,3 +3221,19 @@ intx VM_Version::allocate_prefetch_distance(bool use_watermark_prefetch) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool VM_Version::is_intrinsic_supported(vmIntrinsicID id) {
|
||||
assert(id != vmIntrinsics::_none, "must be a VM intrinsic");
|
||||
switch (id) {
|
||||
case vmIntrinsics::_floatToFloat16:
|
||||
case vmIntrinsics::_float16ToFloat:
|
||||
if (!supports_float16()) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -764,6 +764,9 @@ public:
|
||||
return supports_f16c() || supports_avx512vl();
|
||||
}
|
||||
|
||||
// Check intrinsic support
|
||||
static bool is_intrinsic_supported(vmIntrinsicID id);
|
||||
|
||||
// there are several insns to force cache line sync to memory which
|
||||
// we can use to ensure mapped non-volatile memory is up to date with
|
||||
// pending in-cache changes.
|
||||
|
@ -28,6 +28,7 @@
|
||||
#include "compiler/compilerDirectives.hpp"
|
||||
#include "jvm_constants.h"
|
||||
#include "jvm_io.h"
|
||||
#include "runtime/vm_version.hpp"
|
||||
#include "utilities/xmlstream.hpp"
|
||||
|
||||
// These are flag-matching functions:
|
||||
@ -649,9 +650,8 @@ vmIntrinsics::ID vmIntrinsics::find_id(const char* name) {
|
||||
return _none;
|
||||
}
|
||||
|
||||
bool vmIntrinsics::is_disabled_by_flags(const methodHandle& method) {
|
||||
vmIntrinsics::ID id = method->intrinsic_id();
|
||||
return is_disabled_by_flags(id);
|
||||
bool vmIntrinsics::is_intrinsic_available(vmIntrinsics::ID id) {
|
||||
return VM_Version::is_intrinsic_supported(id) && !is_disabled_by_flags(id);
|
||||
}
|
||||
|
||||
bool vmIntrinsics::is_disabled_by_flags(vmIntrinsics::ID id) {
|
||||
|
@ -1524,10 +1524,7 @@ public:
|
||||
// the corresponding coarse-grained control(2) disables it.
|
||||
static bool is_disabled_by_flags(vmIntrinsics::ID id);
|
||||
|
||||
static bool is_disabled_by_flags(const methodHandle& method);
|
||||
static bool is_intrinsic_available(vmIntrinsics::ID id) {
|
||||
return !is_disabled_by_flags(id);
|
||||
}
|
||||
static bool is_intrinsic_available(vmIntrinsics::ID id);
|
||||
};
|
||||
|
||||
#undef VM_INTRINSIC_ENUM
|
||||
|
@ -126,9 +126,11 @@ class AbstractCompiler : public CHeapObj<mtCompiler> {
|
||||
// for more details.
|
||||
|
||||
bool is_intrinsic_available(const methodHandle& method, DirectiveSet* directive) {
|
||||
vmIntrinsics::ID id = method->intrinsic_id();
|
||||
assert(id != vmIntrinsics::_none, "must be a VM intrinsic");
|
||||
return is_intrinsic_supported(method) &&
|
||||
!directive->is_intrinsic_disabled(method) &&
|
||||
!vmIntrinsics::is_disabled_by_flags(method);
|
||||
vmIntrinsics::is_intrinsic_available(id) &&
|
||||
!directive->is_intrinsic_disabled(id);
|
||||
}
|
||||
|
||||
// Determines if an intrinsic is supported by the compiler, that is,
|
||||
|
@ -549,8 +549,7 @@ void DirectiveSet::print_inline(outputStream* st) {
|
||||
}
|
||||
}
|
||||
|
||||
bool DirectiveSet::is_intrinsic_disabled(const methodHandle& method) {
|
||||
vmIntrinsics::ID id = method->intrinsic_id();
|
||||
bool DirectiveSet::is_intrinsic_disabled(vmIntrinsics::ID id) {
|
||||
assert(id > vmIntrinsics::_none && id < vmIntrinsics::ID_LIMIT, "invalid intrinsic_id!");
|
||||
|
||||
TriBool b = _intrinsic_control_words[vmIntrinsics::as_int(id)];
|
||||
|
@ -126,7 +126,7 @@ public:
|
||||
bool is_exclusive_copy() { return _directive == nullptr; }
|
||||
bool matches_inline(const methodHandle& method, int inline_action);
|
||||
static DirectiveSet* clone(DirectiveSet const* src);
|
||||
bool is_intrinsic_disabled(const methodHandle& method);
|
||||
bool is_intrinsic_disabled(vmIntrinsicID id);
|
||||
static ccstrlist canonicalize_control_intrinsic(ccstrlist option_value);
|
||||
void finalize(outputStream* st);
|
||||
bool is_c1(CompilerDirectives* directive) const;
|
||||
|
@ -87,8 +87,6 @@ StubQueue* AbstractInterpreter::_code = nu
|
||||
bool AbstractInterpreter::_notice_safepoints = false;
|
||||
address AbstractInterpreter::_rethrow_exception_entry = nullptr;
|
||||
|
||||
address AbstractInterpreter::_native_entry_begin = nullptr;
|
||||
address AbstractInterpreter::_native_entry_end = nullptr;
|
||||
address AbstractInterpreter::_slow_signature_handler;
|
||||
address AbstractInterpreter::_entry_table [AbstractInterpreter::number_of_method_entries];
|
||||
address AbstractInterpreter::_native_abi_to_tosca [AbstractInterpreter::number_of_result_handlers];
|
||||
@ -135,9 +133,7 @@ AbstractInterpreter::MethodKind AbstractInterpreter::method_kind(const methodHan
|
||||
case vmIntrinsics::_doubleToRawLongBits: return java_lang_Double_doubleToRawLongBits;
|
||||
case vmIntrinsics::_float16ToFloat: return java_lang_Float_float16ToFloat;
|
||||
case vmIntrinsics::_floatToFloat16: return java_lang_Float_floatToFloat16;
|
||||
#if defined(AMD64) || defined(AARCH64) || defined(RISCV64)
|
||||
case vmIntrinsics::_currentThread: return java_lang_Thread_currentThread;
|
||||
#endif
|
||||
#endif // ZERO
|
||||
case vmIntrinsics::_dsin: return java_lang_math_sin;
|
||||
case vmIntrinsics::_dcos: return java_lang_math_cos;
|
||||
@ -150,7 +146,7 @@ AbstractInterpreter::MethodKind AbstractInterpreter::method_kind(const methodHan
|
||||
case vmIntrinsics::_fmaD: return java_lang_math_fmaD;
|
||||
case vmIntrinsics::_fmaF: return java_lang_math_fmaF;
|
||||
case vmIntrinsics::_dsqrt: return java_lang_math_sqrt;
|
||||
case vmIntrinsics::_dsqrt_strict: return java_lang_math_sqrt;
|
||||
case vmIntrinsics::_dsqrt_strict: return java_lang_math_sqrt_strict;
|
||||
case vmIntrinsics::_Reference_get: return java_lang_ref_reference_get;
|
||||
case vmIntrinsics::_Object_init:
|
||||
if (RegisterFinalizersAtInit && m->code_size() == 1) {
|
||||
@ -197,7 +193,53 @@ AbstractInterpreter::MethodKind AbstractInterpreter::method_kind(const methodHan
|
||||
return zerolocals;
|
||||
}
|
||||
|
||||
void AbstractInterpreter::set_entry_for_kind(AbstractInterpreter::MethodKind kind, address entry) {
|
||||
vmIntrinsics::ID AbstractInterpreter::method_intrinsic(MethodKind kind) {
|
||||
switch (kind) {
|
||||
case java_lang_math_sin : return vmIntrinsics::_dsin;
|
||||
case java_lang_math_cos : return vmIntrinsics::_dcos;
|
||||
case java_lang_math_tan : return vmIntrinsics::_dtan;
|
||||
case java_lang_math_abs : return vmIntrinsics::_dabs;
|
||||
case java_lang_math_log : return vmIntrinsics::_dlog;
|
||||
case java_lang_math_log10 : return vmIntrinsics::_dlog10;
|
||||
case java_lang_math_sqrt : return vmIntrinsics::_dsqrt;
|
||||
case java_lang_math_sqrt_strict : return vmIntrinsics::_dsqrt_strict;
|
||||
case java_lang_math_pow : return vmIntrinsics::_dpow;
|
||||
case java_lang_math_exp : return vmIntrinsics::_dexp;
|
||||
case java_lang_math_fmaD : return vmIntrinsics::_fmaD;
|
||||
case java_lang_math_fmaF : return vmIntrinsics::_fmaF;
|
||||
case java_lang_ref_reference_get: return vmIntrinsics::_Reference_get;
|
||||
case java_util_zip_CRC32_update : return vmIntrinsics::_updateCRC32;
|
||||
case java_util_zip_CRC32_updateBytes
|
||||
: return vmIntrinsics::_updateBytesCRC32;
|
||||
case java_util_zip_CRC32_updateByteBuffer
|
||||
: return vmIntrinsics::_updateByteBufferCRC32;
|
||||
case java_util_zip_CRC32C_updateBytes
|
||||
: return vmIntrinsics::_updateBytesCRC32C;
|
||||
case java_util_zip_CRC32C_updateDirectByteBuffer
|
||||
: return vmIntrinsics::_updateDirectByteBufferCRC32C;
|
||||
case java_lang_Thread_currentThread
|
||||
: return vmIntrinsics::_currentThread;
|
||||
case java_lang_Float_intBitsToFloat
|
||||
: return vmIntrinsics::_intBitsToFloat;
|
||||
case java_lang_Float_floatToRawIntBits
|
||||
: return vmIntrinsics::_floatToRawIntBits;
|
||||
case java_lang_Double_longBitsToDouble
|
||||
: return vmIntrinsics::_longBitsToDouble;
|
||||
case java_lang_Double_doubleToRawLongBits
|
||||
: return vmIntrinsics::_doubleToRawLongBits;
|
||||
case java_lang_Float_float16ToFloat
|
||||
: return vmIntrinsics::_float16ToFloat;
|
||||
case java_lang_Float_floatToFloat16
|
||||
: return vmIntrinsics::_floatToFloat16;
|
||||
|
||||
default:
|
||||
fatal("unexpected method intrinsic kind: %d", kind);
|
||||
break;
|
||||
}
|
||||
return vmIntrinsics::_none;
|
||||
}
|
||||
|
||||
void AbstractInterpreter::set_entry_for_kind(MethodKind kind, address entry) {
|
||||
assert(kind >= method_handle_invoke_FIRST &&
|
||||
kind <= method_handle_invoke_LAST, "late initialization only for MH entry points");
|
||||
assert(_entry_table[kind] == _entry_table[abstract], "previous value must be AME entry");
|
||||
@ -268,16 +310,27 @@ void AbstractInterpreter::print_method_kind(MethodKind kind) {
|
||||
case java_lang_math_cos : tty->print("java_lang_math_cos" ); break;
|
||||
case java_lang_math_tan : tty->print("java_lang_math_tan" ); break;
|
||||
case java_lang_math_abs : tty->print("java_lang_math_abs" ); break;
|
||||
case java_lang_math_sqrt : tty->print("java_lang_math_sqrt" ); break;
|
||||
case java_lang_math_log : tty->print("java_lang_math_log" ); break;
|
||||
case java_lang_math_log10 : tty->print("java_lang_math_log10" ); break;
|
||||
case java_lang_math_pow : tty->print("java_lang_math_pow" ); break;
|
||||
case java_lang_math_exp : tty->print("java_lang_math_exp" ); break;
|
||||
case java_lang_math_fmaD : tty->print("java_lang_math_fmaD" ); break;
|
||||
case java_lang_math_fmaF : tty->print("java_lang_math_fmaF" ); break;
|
||||
case java_lang_math_sqrt : tty->print("java_lang_math_sqrt" ); break;
|
||||
case java_lang_math_sqrt_strict : tty->print("java_lang_math_sqrt_strict"); break;
|
||||
case java_util_zip_CRC32_update : tty->print("java_util_zip_CRC32_update"); break;
|
||||
case java_util_zip_CRC32_updateBytes : tty->print("java_util_zip_CRC32_updateBytes"); break;
|
||||
case java_util_zip_CRC32_updateByteBuffer : tty->print("java_util_zip_CRC32_updateByteBuffer"); break;
|
||||
case java_util_zip_CRC32C_updateBytes : tty->print("java_util_zip_CRC32C_updateBytes"); break;
|
||||
case java_util_zip_CRC32C_updateDirectByteBuffer: tty->print("java_util_zip_CRC32C_updateDirectByteByffer"); break;
|
||||
case java_lang_ref_reference_get : tty->print("java_lang_ref_reference_get"); break;
|
||||
case java_lang_Thread_currentThread : tty->print("java_lang_Thread_currentThread"); break;
|
||||
case java_lang_Float_intBitsToFloat : tty->print("java_lang_Float_intBitsToFloat"); break;
|
||||
case java_lang_Float_floatToRawIntBits : tty->print("java_lang_Float_floatToRawIntBits"); break;
|
||||
case java_lang_Double_longBitsToDouble : tty->print("java_lang_Double_longBitsToDouble"); break;
|
||||
case java_lang_Double_doubleToRawLongBits : tty->print("java_lang_Double_doubleToRawLongBits"); break;
|
||||
case java_lang_Float_float16ToFloat : tty->print("java_lang_Float_float16ToFloat"); break;
|
||||
case java_lang_Float_floatToFloat16 : tty->print("java_lang_Float_floatToFloat16"); break;
|
||||
default:
|
||||
if (kind >= method_handle_invoke_FIRST &&
|
||||
kind <= method_handle_invoke_LAST) {
|
||||
|
@ -74,6 +74,7 @@ class AbstractInterpreter: AllStatic {
|
||||
java_lang_math_tan, // implementation of java.lang.Math.tan (x)
|
||||
java_lang_math_abs, // implementation of java.lang.Math.abs (x)
|
||||
java_lang_math_sqrt, // implementation of java.lang.Math.sqrt (x)
|
||||
java_lang_math_sqrt_strict, // implementation of java.lang.StrictMath.sqrt(x)
|
||||
java_lang_math_log, // implementation of java.lang.Math.log (x)
|
||||
java_lang_math_log10, // implementation of java.lang.Math.log10 (x)
|
||||
java_lang_math_pow, // implementation of java.lang.Math.pow (x,y)
|
||||
@ -105,6 +106,9 @@ class AbstractInterpreter: AllStatic {
|
||||
return vmIntrinsics::_none;
|
||||
}
|
||||
|
||||
// Conversion from the above enum to vmIntrinsics::ID
|
||||
static vmIntrinsics::ID method_intrinsic(MethodKind kind);
|
||||
|
||||
enum SomeConstants {
|
||||
number_of_result_handlers = 10 // number of result handlers for native calls
|
||||
};
|
||||
@ -114,9 +118,6 @@ class AbstractInterpreter: AllStatic {
|
||||
|
||||
static bool _notice_safepoints; // true if safepoints are activated
|
||||
|
||||
static address _native_entry_begin; // Region for native entry code
|
||||
static address _native_entry_end;
|
||||
|
||||
// method entry points
|
||||
static address _entry_table[number_of_method_entries]; // entry points for a given method
|
||||
static address _native_abi_to_tosca[number_of_result_handlers]; // for native method result handlers
|
||||
@ -223,7 +224,6 @@ class AbstractInterpreter: AllStatic {
|
||||
static address slow_signature_handler() { return _slow_signature_handler; }
|
||||
static address result_handler(BasicType type) { return _native_abi_to_tosca[BasicType_as_index(type)]; }
|
||||
static int BasicType_as_index(BasicType type); // computes index into result_handler_by_index table
|
||||
static bool in_native_entry(address pc) { return _native_entry_begin <= pc && pc < _native_entry_end; }
|
||||
// Debugging/printing
|
||||
static void print(); // prints the interpreter code
|
||||
|
||||
|
@ -177,9 +177,9 @@ void TemplateInterpreterGenerator::generate_all() {
|
||||
|
||||
|
||||
|
||||
#define method_entry(kind) \
|
||||
{ CodeletMark cm(_masm, "method entry point (kind = " #kind ")"); \
|
||||
Interpreter::_entry_table[Interpreter::kind] = generate_method_entry(Interpreter::kind); \
|
||||
#define method_entry(kind) \
|
||||
{ CodeletMark cm(_masm, "method entry point (kind = " #kind ")"); \
|
||||
Interpreter::_entry_table[Interpreter::kind] = generate_method_entry(Interpreter::kind, false); \
|
||||
}
|
||||
|
||||
// all non-native method kinds
|
||||
@ -194,6 +194,7 @@ void TemplateInterpreterGenerator::generate_all() {
|
||||
method_entry(java_lang_math_tan )
|
||||
method_entry(java_lang_math_abs )
|
||||
method_entry(java_lang_math_sqrt )
|
||||
method_entry(java_lang_math_sqrt_strict)
|
||||
method_entry(java_lang_math_log )
|
||||
method_entry(java_lang_math_log10)
|
||||
method_entry(java_lang_math_exp )
|
||||
@ -201,33 +202,41 @@ void TemplateInterpreterGenerator::generate_all() {
|
||||
method_entry(java_lang_math_fmaF )
|
||||
method_entry(java_lang_math_fmaD )
|
||||
method_entry(java_lang_ref_reference_get)
|
||||
#if defined(AMD64) || defined(AARCH64) || defined(RISCV64)
|
||||
method_entry(java_lang_Thread_currentThread)
|
||||
#endif
|
||||
AbstractInterpreter::initialize_method_handle_entries();
|
||||
|
||||
// all native method kinds (must be one contiguous block)
|
||||
Interpreter::_native_entry_begin = Interpreter::code()->code_end();
|
||||
method_entry(native)
|
||||
method_entry(native_synchronized)
|
||||
Interpreter::_native_entry_end = Interpreter::code()->code_end();
|
||||
|
||||
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);
|
||||
method_entry(java_lang_Double_longBitsToDouble);
|
||||
method_entry(java_lang_Double_doubleToRawLongBits);
|
||||
|
||||
method_entry(java_lang_Float_float16ToFloat);
|
||||
method_entry(java_lang_Float_floatToFloat16);
|
||||
|
||||
#undef method_entry
|
||||
|
||||
// all native method kinds
|
||||
#define native_method_entry(kind) \
|
||||
{ CodeletMark cm(_masm, "native method entry point (kind = " #kind ")"); \
|
||||
Interpreter::_entry_table[Interpreter::kind] = generate_method_entry(Interpreter::kind, true); \
|
||||
}
|
||||
|
||||
native_method_entry(native)
|
||||
native_method_entry(native_synchronized)
|
||||
|
||||
// Entries to intrinsics for native methods should follow
|
||||
// entries for `native` methods to use the same address in case
|
||||
// intrinsic is disabled.
|
||||
native_method_entry(java_lang_Thread_currentThread)
|
||||
|
||||
native_method_entry(java_util_zip_CRC32_update)
|
||||
native_method_entry(java_util_zip_CRC32_updateBytes)
|
||||
native_method_entry(java_util_zip_CRC32_updateByteBuffer)
|
||||
|
||||
native_method_entry(java_lang_Float_intBitsToFloat)
|
||||
native_method_entry(java_lang_Float_floatToRawIntBits)
|
||||
native_method_entry(java_lang_Double_longBitsToDouble)
|
||||
native_method_entry(java_lang_Double_doubleToRawLongBits)
|
||||
|
||||
#undef native_method_entry
|
||||
|
||||
// Bytecodes
|
||||
set_entry_points_for_all_bytes();
|
||||
|
||||
@ -397,74 +406,22 @@ void TemplateInterpreterGenerator::generate_and_dispatch(Template* t, TosState t
|
||||
|
||||
// Generate method entries
|
||||
address TemplateInterpreterGenerator::generate_method_entry(
|
||||
AbstractInterpreter::MethodKind kind) {
|
||||
AbstractInterpreter::MethodKind kind, bool native) {
|
||||
// determine code generation flags
|
||||
bool native = false;
|
||||
bool synchronized = false;
|
||||
address entry_point = nullptr;
|
||||
|
||||
switch (kind) {
|
||||
case Interpreter::zerolocals : break;
|
||||
case Interpreter::zerolocals_synchronized: synchronized = true; break;
|
||||
case Interpreter::native : native = true; break;
|
||||
case Interpreter::native_synchronized : native = true; synchronized = true; break;
|
||||
case Interpreter::zerolocals : break;
|
||||
case Interpreter::zerolocals_synchronized: synchronized = true; break;
|
||||
case Interpreter::native : break;
|
||||
case Interpreter::native_synchronized : synchronized = true; break;
|
||||
case Interpreter::empty : break;
|
||||
case Interpreter::getter : break;
|
||||
case Interpreter::setter : break;
|
||||
case Interpreter::abstract : entry_point = generate_abstract_entry(); break;
|
||||
|
||||
case Interpreter::java_lang_math_sin : // fall thru
|
||||
case Interpreter::java_lang_math_cos : // fall thru
|
||||
case Interpreter::java_lang_math_tan : // fall thru
|
||||
case Interpreter::java_lang_math_abs : // fall thru
|
||||
case Interpreter::java_lang_math_log : // fall thru
|
||||
case Interpreter::java_lang_math_log10 : // fall thru
|
||||
case Interpreter::java_lang_math_sqrt : // fall thru
|
||||
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_ref_reference_get
|
||||
: entry_point = generate_Reference_get_entry(); break;
|
||||
case Interpreter::java_util_zip_CRC32_update
|
||||
: native = true; entry_point = generate_CRC32_update_entry(); break;
|
||||
case Interpreter::java_util_zip_CRC32_updateBytes
|
||||
: // fall thru
|
||||
case Interpreter::java_util_zip_CRC32_updateByteBuffer
|
||||
: native = true; entry_point = generate_CRC32_updateBytes_entry(kind); break;
|
||||
case Interpreter::java_util_zip_CRC32C_updateBytes
|
||||
: // fall thru
|
||||
case Interpreter::java_util_zip_CRC32C_updateDirectByteBuffer
|
||||
: entry_point = generate_CRC32C_updateBytes_entry(kind); break;
|
||||
#if defined(AMD64) || defined(AARCH64) || defined(RISCV64)
|
||||
case Interpreter::java_lang_Thread_currentThread
|
||||
: entry_point = generate_currentThread(); break;
|
||||
#endif
|
||||
case Interpreter::java_lang_Float_float16ToFloat
|
||||
: entry_point = generate_Float_float16ToFloat_entry(); break;
|
||||
case Interpreter::java_lang_Float_floatToFloat16
|
||||
: entry_point = generate_Float_floatToFloat16_entry(); break;
|
||||
#ifdef IA32
|
||||
// On x86_32 platforms, a special entry is generated for the following four methods.
|
||||
// On other platforms the normal entry is used to enter these methods.
|
||||
case Interpreter::java_lang_Float_intBitsToFloat
|
||||
: native = true; entry_point = generate_Float_intBitsToFloat_entry(); break;
|
||||
case Interpreter::java_lang_Float_floatToRawIntBits
|
||||
: native = true; entry_point = generate_Float_floatToRawIntBits_entry(); break;
|
||||
case Interpreter::java_lang_Double_longBitsToDouble
|
||||
: native = true; entry_point = generate_Double_longBitsToDouble_entry(); break;
|
||||
case Interpreter::java_lang_Double_doubleToRawLongBits
|
||||
: native = true; entry_point = generate_Double_doubleToRawLongBits_entry(); break;
|
||||
#else
|
||||
case Interpreter::java_lang_Float_intBitsToFloat:
|
||||
case Interpreter::java_lang_Float_floatToRawIntBits:
|
||||
case Interpreter::java_lang_Double_longBitsToDouble:
|
||||
case Interpreter::java_lang_Double_doubleToRawLongBits:
|
||||
native = true;
|
||||
break;
|
||||
#endif // !IA32
|
||||
default:
|
||||
fatal("unexpected method kind: %d", kind);
|
||||
entry_point = generate_intrinsic_entry(kind); // process the rest
|
||||
break;
|
||||
}
|
||||
|
||||
@ -487,3 +444,62 @@ address TemplateInterpreterGenerator::generate_method_entry(
|
||||
|
||||
return entry_point;
|
||||
}
|
||||
|
||||
// Generate intrinsic method entries
|
||||
address TemplateInterpreterGenerator::generate_intrinsic_entry(AbstractInterpreter::MethodKind kind) {
|
||||
if (!InlineIntrinsics || !vmIntrinsics::is_intrinsic_available(AbstractInterpreter::method_intrinsic(kind))) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
address entry_point = nullptr;
|
||||
|
||||
switch (kind) {
|
||||
case Interpreter::java_lang_math_sin : // fall thru
|
||||
case Interpreter::java_lang_math_cos : // fall thru
|
||||
case Interpreter::java_lang_math_tan : // fall thru
|
||||
case Interpreter::java_lang_math_abs : // fall thru
|
||||
case Interpreter::java_lang_math_log : // fall thru
|
||||
case Interpreter::java_lang_math_log10 : // fall thru
|
||||
case Interpreter::java_lang_math_sqrt : // fall thru
|
||||
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_sqrt_strict
|
||||
: entry_point = generate_math_entry(Interpreter::java_lang_math_sqrt); break;
|
||||
case Interpreter::java_lang_ref_reference_get
|
||||
: entry_point = generate_Reference_get_entry(); break;
|
||||
case Interpreter::java_util_zip_CRC32_update
|
||||
: entry_point = generate_CRC32_update_entry(); break;
|
||||
case Interpreter::java_util_zip_CRC32_updateBytes
|
||||
: // fall thru
|
||||
case Interpreter::java_util_zip_CRC32_updateByteBuffer
|
||||
: entry_point = generate_CRC32_updateBytes_entry(kind); break;
|
||||
case Interpreter::java_util_zip_CRC32C_updateBytes
|
||||
: // fall thru
|
||||
case Interpreter::java_util_zip_CRC32C_updateDirectByteBuffer
|
||||
: entry_point = generate_CRC32C_updateBytes_entry(kind); break;
|
||||
case Interpreter::java_lang_Thread_currentThread
|
||||
: entry_point = generate_currentThread(); break;
|
||||
case Interpreter::java_lang_Float_float16ToFloat
|
||||
: entry_point = generate_Float_float16ToFloat_entry(); break;
|
||||
case Interpreter::java_lang_Float_floatToFloat16
|
||||
: entry_point = generate_Float_floatToFloat16_entry(); break;
|
||||
|
||||
// On x86_32 platforms, a special entry is generated for the following four methods.
|
||||
// On other platforms the native entry is used to enter these methods.
|
||||
case Interpreter::java_lang_Float_intBitsToFloat
|
||||
: entry_point = generate_Float_intBitsToFloat_entry(); break;
|
||||
case Interpreter::java_lang_Float_floatToRawIntBits
|
||||
: entry_point = generate_Float_floatToRawIntBits_entry(); break;
|
||||
case Interpreter::java_lang_Double_longBitsToDouble
|
||||
: entry_point = generate_Double_longBitsToDouble_entry(); break;
|
||||
case Interpreter::java_lang_Double_doubleToRawLongBits
|
||||
: entry_point = generate_Double_doubleToRawLongBits_entry(); break;
|
||||
default:
|
||||
fatal("unexpected intrinsic method kind: %d", kind);
|
||||
break;
|
||||
}
|
||||
return entry_point;
|
||||
}
|
||||
|
||||
|
@ -84,7 +84,10 @@ class TemplateInterpreterGenerator: public AbstractInterpreterGenerator {
|
||||
void generate_all();
|
||||
|
||||
// entry point generator
|
||||
address generate_method_entry(AbstractInterpreter::MethodKind kind);
|
||||
address generate_method_entry(AbstractInterpreter::MethodKind kind, bool native);
|
||||
|
||||
// generate intrinsic method entries
|
||||
address generate_intrinsic_entry(AbstractInterpreter::MethodKind kind);
|
||||
|
||||
address generate_normal_entry(bool synchronized);
|
||||
address generate_native_entry(bool synchronized);
|
||||
@ -94,15 +97,11 @@ class TemplateInterpreterGenerator: public AbstractInterpreterGenerator {
|
||||
address generate_CRC32_update_entry();
|
||||
address generate_CRC32_updateBytes_entry(AbstractInterpreter::MethodKind kind);
|
||||
address generate_CRC32C_updateBytes_entry(AbstractInterpreter::MethodKind kind);
|
||||
#if defined(AMD64) || defined(AARCH64) || defined(RISCV64)
|
||||
address generate_currentThread();
|
||||
#endif
|
||||
#ifdef IA32
|
||||
address generate_Float_intBitsToFloat_entry();
|
||||
address generate_Float_floatToRawIntBits_entry();
|
||||
address generate_Double_longBitsToDouble_entry();
|
||||
address generate_Double_doubleToRawLongBits_entry();
|
||||
#endif // IA32
|
||||
address generate_Float_float16ToFloat_entry();
|
||||
address generate_Float_floatToFloat16_entry();
|
||||
|
||||
|
@ -66,10 +66,8 @@ void ZeroInterpreterGenerator::generate_all() {
|
||||
|
||||
AbstractInterpreter::initialize_method_handle_entries();
|
||||
|
||||
Interpreter::_native_entry_begin = Interpreter::code()->code_end();
|
||||
method_entry(native);
|
||||
method_entry(native_synchronized);
|
||||
Interpreter::_native_entry_end = Interpreter::code()->code_end();
|
||||
}
|
||||
|
||||
#undef method_entry
|
||||
|
@ -180,7 +180,7 @@ void C2Compiler::print_timers() {
|
||||
Compile::print_timers();
|
||||
}
|
||||
|
||||
bool C2Compiler::is_intrinsic_supported(const methodHandle& method, bool is_virtual) {
|
||||
bool C2Compiler::is_intrinsic_supported(const methodHandle& method) {
|
||||
vmIntrinsics::ID id = method->intrinsic_id();
|
||||
assert(id != vmIntrinsics::_none, "must be a VM intrinsic");
|
||||
|
||||
@ -188,20 +188,6 @@ bool C2Compiler::is_intrinsic_supported(const methodHandle& method, bool is_virt
|
||||
return false;
|
||||
}
|
||||
|
||||
// Only Object.hashCode and Object.clone intrinsics implement also a virtual
|
||||
// dispatch because calling both methods is expensive but both methods are
|
||||
// frequently overridden. All other intrinsics implement only a non-virtual
|
||||
// dispatch.
|
||||
if (is_virtual) {
|
||||
switch (id) {
|
||||
case vmIntrinsics::_hashCode:
|
||||
case vmIntrinsics::_clone:
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
switch (id) {
|
||||
case vmIntrinsics::_compressStringC:
|
||||
case vmIntrinsics::_compressStringB:
|
||||
|
@ -61,13 +61,7 @@ public:
|
||||
// possible for only a limited set of available intrinsics whereas
|
||||
// a non-virtual dispatch is possible for all available intrinsics.)
|
||||
// Return false otherwise.
|
||||
virtual bool is_intrinsic_supported(const methodHandle& method) {
|
||||
return is_intrinsic_supported(method, false);
|
||||
}
|
||||
|
||||
// Check if the compiler supports an intrinsic for 'method' given the
|
||||
// the dispatch mode specified by the 'is_virtual' parameter.
|
||||
bool is_intrinsic_supported(const methodHandle& method, bool is_virtual);
|
||||
virtual bool is_intrinsic_supported(const methodHandle& method);
|
||||
|
||||
// Initial size of the code buffer (may be increased at runtime)
|
||||
static int initial_code_buffer_size(int const_size = initial_const_capacity);
|
||||
|
@ -77,10 +77,10 @@ CallGenerator* Compile::make_vm_intrinsic(ciMethod* m, bool is_virtual) {
|
||||
// methods access VM-internal data.
|
||||
VM_ENTRY_MARK;
|
||||
methodHandle mh(THREAD, m->get_Method());
|
||||
is_available = compiler != nullptr && compiler->is_intrinsic_supported(mh, is_virtual) &&
|
||||
!C->directive()->is_intrinsic_disabled(mh) &&
|
||||
!vmIntrinsics::is_disabled_by_flags(mh);
|
||||
|
||||
is_available = compiler != nullptr && compiler->is_intrinsic_available(mh, C->directive());
|
||||
if (is_available && is_virtual) {
|
||||
is_available = vmIntrinsics::does_virtual_dispatch(id);
|
||||
}
|
||||
}
|
||||
|
||||
if (is_available) {
|
||||
|
@ -42,6 +42,7 @@ typedef enum {
|
||||
} VirtualizationType;
|
||||
|
||||
class outputStream;
|
||||
enum class vmIntrinsicID;
|
||||
|
||||
// Abstract_VM_Version provides information about the VM.
|
||||
|
||||
@ -181,6 +182,10 @@ class Abstract_VM_Version: AllStatic {
|
||||
|
||||
// Does platform support float16 instructions?
|
||||
static bool supports_float16() { return false; }
|
||||
|
||||
// Does this CPU support this intrinsic?
|
||||
static bool is_intrinsic_supported(vmIntrinsicID id) { return true; }
|
||||
|
||||
static bool print_matching_lines_from_file(const char* filename, outputStream* st, const char* keywords_to_match[]);
|
||||
|
||||
protected:
|
||||
|
@ -1194,7 +1194,7 @@ const int ObjectAlignmentInBytes = 8;
|
||||
"Trace frequency based inlining") \
|
||||
\
|
||||
develop_pd(bool, InlineIntrinsics, \
|
||||
"Inline intrinsics that can be statically resolved") \
|
||||
"Use intrinsics in Interpreter that can be statically resolved") \
|
||||
\
|
||||
product_pd(bool, ProfileInterpreter, \
|
||||
"Profile at the bytecode level during interpretation") \
|
||||
|
@ -83,8 +83,9 @@ public class NaNTest {
|
||||
// signaling NaNs.
|
||||
if (Platform.isX86()) {
|
||||
int sse = WHITE_BOX.getIntVMFlag("UseSSE").intValue();
|
||||
expectStableFloats = (sse >= 1);
|
||||
expectStableDoubles = (sse >= 2);
|
||||
boolean stubsPresent = WHITE_BOX.getBooleanVMFlag("InlineIntrinsics");
|
||||
expectStableFloats = (sse >= 1) && stubsPresent;
|
||||
expectStableDoubles = (sse >= 2) && stubsPresent;
|
||||
}
|
||||
|
||||
if (expectStableFloats) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user