mirror of
https://github.com/openjdk/jdk.git
synced 2026-03-05 21:50:20 +00:00
8154957: AArch64: Better byte behavior
The fix for 8132051 is needed for AArch64. Reviewed-by: roland
This commit is contained in:
parent
04ec692aca
commit
f2ba1fde33
@ -331,7 +331,7 @@ void LIRGenerator::do_StoreIndexed(StoreIndexed* x) {
|
||||
length.load_item();
|
||||
|
||||
}
|
||||
if (needs_store_check) {
|
||||
if (needs_store_check || x->check_boolean()) {
|
||||
value.load_item();
|
||||
} else {
|
||||
value.load_for_store(x->elt_type());
|
||||
@ -380,7 +380,8 @@ void LIRGenerator::do_StoreIndexed(StoreIndexed* x) {
|
||||
// Seems to be a precise
|
||||
post_barrier(LIR_OprFact::address(array_addr), value.result());
|
||||
} else {
|
||||
__ move(value.result(), array_addr, null_check_info);
|
||||
LIR_Opr result = maybe_mask_boolean(x, array.result(), value.result(), null_check_info);
|
||||
__ move(result, array_addr, null_check_info);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -40,7 +40,43 @@
|
||||
#include "runtime/thread.inline.hpp"
|
||||
|
||||
|
||||
// Implementation of InterpreterMacroAssembler
|
||||
void InterpreterMacroAssembler::narrow(Register result) {
|
||||
|
||||
// Get method->_constMethod->_result_type
|
||||
ldr(rscratch1, Address(rfp, frame::interpreter_frame_method_offset * wordSize));
|
||||
ldr(rscratch1, Address(rscratch1, Method::const_offset()));
|
||||
ldrb(rscratch1, Address(rscratch1, ConstMethod::result_type_offset()));
|
||||
|
||||
Label done, notBool, notByte, notChar;
|
||||
|
||||
// common case first
|
||||
cmpw(rscratch1, T_INT);
|
||||
br(Assembler::EQ, done);
|
||||
|
||||
// mask integer result to narrower return type.
|
||||
cmpw(rscratch1, T_BOOLEAN);
|
||||
br(Assembler::NE, notBool);
|
||||
andw(result, result, 0x1);
|
||||
b(done);
|
||||
|
||||
bind(notBool);
|
||||
cmpw(rscratch1, T_BYTE);
|
||||
br(Assembler::NE, notByte);
|
||||
sbfx(result, result, 0, 8);
|
||||
b(done);
|
||||
|
||||
bind(notByte);
|
||||
cmpw(rscratch1, T_CHAR);
|
||||
br(Assembler::NE, notChar);
|
||||
ubfx(result, result, 0, 16); // truncate upper 16 bits
|
||||
b(done);
|
||||
|
||||
bind(notChar);
|
||||
sbfx(result, result, 0, 16); // sign-extend short
|
||||
|
||||
// Nothing to do for T_INT
|
||||
bind(done);
|
||||
}
|
||||
|
||||
void InterpreterMacroAssembler::jump_to_entry(address entry) {
|
||||
assert(entry, "Entry must have been generated by now");
|
||||
@ -81,6 +117,7 @@ void InterpreterMacroAssembler::load_earlyret_value(TosState state) {
|
||||
verify_oop(r0, state); break;
|
||||
case ltos: ldr(r0, val_addr); break;
|
||||
case btos: // fall through
|
||||
case ztos: // fall through
|
||||
case ctos: // fall through
|
||||
case stos: // fall through
|
||||
case itos: ldrw(r0, val_addr); break;
|
||||
@ -314,6 +351,7 @@ void InterpreterMacroAssembler::pop(TosState state) {
|
||||
switch (state) {
|
||||
case atos: pop_ptr(); break;
|
||||
case btos:
|
||||
case ztos:
|
||||
case ctos:
|
||||
case stos:
|
||||
case itos: pop_i(); break;
|
||||
@ -331,6 +369,7 @@ void InterpreterMacroAssembler::push(TosState state) {
|
||||
switch (state) {
|
||||
case atos: push_ptr(); break;
|
||||
case btos:
|
||||
case ztos:
|
||||
case ctos:
|
||||
case stos:
|
||||
case itos: push_i(); break;
|
||||
|
||||
@ -245,6 +245,9 @@ class InterpreterMacroAssembler: public MacroAssembler {
|
||||
void update_mdp_by_constant(Register mdp_in, int constant);
|
||||
void update_mdp_for_ret(Register return_bci);
|
||||
|
||||
// narrow int return value
|
||||
void narrow(Register result);
|
||||
|
||||
void profile_taken_branch(Register mdp, Register bumped_count);
|
||||
void profile_not_taken_branch(Register mdp);
|
||||
void profile_call(Register mdp);
|
||||
|
||||
@ -1184,6 +1184,10 @@ public:
|
||||
Register result, Register cnt1,
|
||||
int elem_size, bool is_string);
|
||||
|
||||
void fill_words(Register base, Register cnt, Register value);
|
||||
void zero_words(Register base, Register cnt);
|
||||
void zero_words(Register base, u_int64_t cnt);
|
||||
|
||||
void byte_array_inflate(Register src, Register dst, Register len,
|
||||
FloatRegister vtmp1, FloatRegister vtmp2,
|
||||
FloatRegister vtmp3, Register tmp4);
|
||||
|
||||
@ -229,6 +229,7 @@ void TemplateTable::patch_bytecode(Bytecodes::Code bc, Register bc_reg,
|
||||
switch (bc) {
|
||||
case Bytecodes::_fast_aputfield:
|
||||
case Bytecodes::_fast_bputfield:
|
||||
case Bytecodes::_fast_zputfield:
|
||||
case Bytecodes::_fast_cputfield:
|
||||
case Bytecodes::_fast_dputfield:
|
||||
case Bytecodes::_fast_fputfield:
|
||||
@ -1082,6 +1083,17 @@ void TemplateTable::bastore()
|
||||
// r1: index
|
||||
// r3: array
|
||||
index_check(r3, r1); // prefer index in r1
|
||||
|
||||
// Need to check whether array is boolean or byte
|
||||
// since both types share the bastore bytecode.
|
||||
__ load_klass(r2, r3);
|
||||
__ ldrw(r2, Address(r2, Klass::layout_helper_offset()));
|
||||
int diffbit_index = exact_log2(Klass::layout_helper_boolean_diffbit());
|
||||
Label L_skip;
|
||||
__ tbz(r2, diffbit_index, L_skip);
|
||||
__ andw(r0, r0, 1); // if it is a T_BOOLEAN array, mask the stored value to 0/1
|
||||
__ bind(L_skip);
|
||||
|
||||
__ lea(rscratch1, Address(r3, r1, Address::uxtw(0)));
|
||||
__ strb(r0, Address(rscratch1,
|
||||
arrayOopDesc::base_offset_in_bytes(T_BYTE)));
|
||||
@ -2193,6 +2205,13 @@ void TemplateTable::_return(TosState state)
|
||||
if (_desc->bytecode() == Bytecodes::_return)
|
||||
__ membar(MacroAssembler::StoreStore);
|
||||
|
||||
// Narrow result if state is itos but result type is smaller.
|
||||
// Need to narrow in the return bytecode rather than in generate_return_entry
|
||||
// since compiled code callers expect the result to already be narrowed.
|
||||
if (state == itos) {
|
||||
__ narrow(r0);
|
||||
}
|
||||
|
||||
__ remove_activation(state);
|
||||
__ ret(lr);
|
||||
}
|
||||
@ -2386,7 +2405,7 @@ void TemplateTable::getfield_or_static(int byte_no, bool is_static, RewriteContr
|
||||
|
||||
const Address field(obj, off);
|
||||
|
||||
Label Done, notByte, notInt, notShort, notChar,
|
||||
Label Done, notByte, notBool, notInt, notShort, notChar,
|
||||
notLong, notFloat, notObj, notDouble;
|
||||
|
||||
// x86 uses a shift and mask or wings it with a shift plus assert
|
||||
@ -2409,6 +2428,20 @@ void TemplateTable::getfield_or_static(int byte_no, bool is_static, RewriteContr
|
||||
__ b(Done);
|
||||
|
||||
__ bind(notByte);
|
||||
__ cmp(flags, ztos);
|
||||
__ br(Assembler::NE, notBool);
|
||||
|
||||
// ztos (same code as btos)
|
||||
__ ldrsb(r0, field);
|
||||
__ push(ztos);
|
||||
// Rewrite bytecode to be faster
|
||||
if (!is_static) {
|
||||
// use btos rewriting, no truncating to t/f bit is needed for getfield.
|
||||
patch_bytecode(Bytecodes::_fast_bgetfield, bc, r1);
|
||||
}
|
||||
__ b(Done);
|
||||
|
||||
__ bind(notBool);
|
||||
__ cmp(flags, atos);
|
||||
__ br(Assembler::NE, notObj);
|
||||
// atos
|
||||
@ -2604,7 +2637,7 @@ void TemplateTable::putfield_or_static(int byte_no, bool is_static, RewriteContr
|
||||
// field address
|
||||
const Address field(obj, off);
|
||||
|
||||
Label notByte, notInt, notShort, notChar,
|
||||
Label notByte, notBool, notInt, notShort, notChar,
|
||||
notLong, notFloat, notObj, notDouble;
|
||||
|
||||
// x86 uses a shift and mask or wings it with a shift plus assert
|
||||
@ -2629,6 +2662,22 @@ void TemplateTable::putfield_or_static(int byte_no, bool is_static, RewriteContr
|
||||
}
|
||||
|
||||
__ bind(notByte);
|
||||
__ cmp(flags, ztos);
|
||||
__ br(Assembler::NE, notBool);
|
||||
|
||||
// ztos
|
||||
{
|
||||
__ pop(ztos);
|
||||
if (!is_static) pop_and_check_object(obj);
|
||||
__ andw(r0, r0, 0x1);
|
||||
__ strb(r0, field);
|
||||
if (!is_static) {
|
||||
patch_bytecode(Bytecodes::_fast_zputfield, bc, r1, true, byte_no);
|
||||
}
|
||||
__ b(Done);
|
||||
}
|
||||
|
||||
__ bind(notBool);
|
||||
__ cmp(flags, atos);
|
||||
__ br(Assembler::NE, notObj);
|
||||
|
||||
@ -2783,6 +2832,7 @@ void TemplateTable::jvmti_post_fast_field_mod()
|
||||
switch (bytecode()) { // load values into the jvalue object
|
||||
case Bytecodes::_fast_aputfield: __ push_ptr(r0); break;
|
||||
case Bytecodes::_fast_bputfield: // fall through
|
||||
case Bytecodes::_fast_zputfield: // fall through
|
||||
case Bytecodes::_fast_sputfield: // fall through
|
||||
case Bytecodes::_fast_cputfield: // fall through
|
||||
case Bytecodes::_fast_iputfield: __ push_i(r0); break;
|
||||
@ -2808,6 +2858,7 @@ void TemplateTable::jvmti_post_fast_field_mod()
|
||||
switch (bytecode()) { // restore tos values
|
||||
case Bytecodes::_fast_aputfield: __ pop_ptr(r0); break;
|
||||
case Bytecodes::_fast_bputfield: // fall through
|
||||
case Bytecodes::_fast_zputfield: // fall through
|
||||
case Bytecodes::_fast_sputfield: // fall through
|
||||
case Bytecodes::_fast_cputfield: // fall through
|
||||
case Bytecodes::_fast_iputfield: __ pop_i(r0); break;
|
||||
@ -2863,6 +2914,9 @@ void TemplateTable::fast_storefield(TosState state)
|
||||
case Bytecodes::_fast_iputfield:
|
||||
__ strw(r0, field);
|
||||
break;
|
||||
case Bytecodes::_fast_zputfield:
|
||||
__ andw(r0, r0, 0x1); // boolean is true if LSB is 1
|
||||
// fall through to bputfield
|
||||
case Bytecodes::_fast_bputfield:
|
||||
__ strb(r0, field);
|
||||
break;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user