8190285: s390: Some java boolean checks are not correct
Reviewed-by: lucy, coleenp
--- a/src/hotspot/cpu/s390/c1_LIRGenerator_s390.cpp Sun Oct 29 18:13:18 2017 -0700
+++ b/src/hotspot/cpu/s390/c1_LIRGenerator_s390.cpp Mon Oct 30 17:14:39 2017 +0100
@@ -277,7 +277,7 @@
length.set_instruction(x->length());
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());
@@ -327,11 +327,14 @@
// Needs GC write barriers.
pre_barrier(LIR_OprFact::address(array_addr), LIR_OprFact::illegalOpr /* pre_val */,
true /* do_load */, false /* patch */, NULL);
- __ move(value.result(), array_addr, null_check_info);
- // Seems to be a precise.
+ }
+
+ LIR_Opr result = maybe_mask_boolean(x, array.result(), value.result(), null_check_info);
+ __ move(result, array_addr, null_check_info);
+
+ if (obj_store) {
+ // Precise card mark
post_barrier(LIR_OprFact::address(array_addr), value.result());
- } else {
- __ move(value.result(), array_addr, null_check_info);
}
}
--- a/src/hotspot/cpu/s390/interp_masm_s390.cpp Sun Oct 29 18:13:18 2017 -0700
+++ b/src/hotspot/cpu/s390/interp_masm_s390.cpp Mon Oct 30 17:14:39 2017 +0100
@@ -843,6 +843,38 @@
verify_oop(Z_tos, state);
}
+void InterpreterMacroAssembler::narrow(Register result, Register ret_type) {
+ get_method(ret_type);
+ z_lg(ret_type, Address(ret_type, in_bytes(Method::const_offset())));
+ z_lb(ret_type, Address(ret_type, in_bytes(ConstMethod::result_type_offset())));
+
+ Label notBool, notByte, notChar, done;
+
+ // common case first
+ compareU32_and_branch(ret_type, T_INT, bcondEqual, done);
+
+ compareU32_and_branch(ret_type, T_BOOLEAN, bcondNotEqual, notBool);
+ z_nilf(result, 0x1);
+ z_bru(done);
+
+ bind(notBool);
+ compareU32_and_branch(ret_type, T_BYTE, bcondNotEqual, notByte);
+ z_lbr(result, result);
+ z_bru(done);
+
+ bind(notByte);
+ compareU32_and_branch(ret_type, T_CHAR, bcondNotEqual, notChar);
+ z_nilf(result, 0xffff);
+ z_bru(done);
+
+ bind(notChar);
+ // compareU32_and_branch(ret_type, T_SHORT, bcondNotEqual, notShort);
+ z_lhr(result, result);
+
+ // Nothing to do for T_INT
+ bind(done);
+}
+
// remove activation
//
// Unlock the receiver if this is a synchronized method.
--- a/src/hotspot/cpu/s390/interp_masm_s390.hpp Sun Oct 29 18:13:18 2017 -0700
+++ b/src/hotspot/cpu/s390/interp_masm_s390.hpp Mon Oct 30 17:14:39 2017 +0100
@@ -86,6 +86,8 @@
void dispatch_next_noverify_oop(TosState state, int step = 0);
void dispatch_via(TosState state, address* table);
+ void narrow(Register result, Register ret_type);
+
// Jump to an invoked target.
void prepare_to_jump_from_interpreted(Register method);
void jump_from_interpreted(Register method, Register temp);
--- a/src/hotspot/cpu/s390/templateInterpreterGenerator_s390.cpp Sun Oct 29 18:13:18 2017 -0700
+++ b/src/hotspot/cpu/s390/templateInterpreterGenerator_s390.cpp Mon Oct 30 17:14:39 2017 +0100
@@ -2377,6 +2377,12 @@
__ store_const(Address(RjvmtiState, JvmtiThreadState::earlyret_state_offset()),
JvmtiThreadState::earlyret_inactive, 4, 4, Z_R0_scratch);
+ if (state == itos) {
+ // 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.
+ __ narrow(Z_tos, Z_tmp_1); /* fall through */
+ }
__ remove_activation(state,
Z_tmp_1, // retaddr
false, // throw_monitor_exception
--- a/src/hotspot/cpu/s390/templateTable_s390.cpp Sun Oct 29 18:13:18 2017 -0700
+++ b/src/hotspot/cpu/s390/templateTable_s390.cpp Mon Oct 30 17:14:39 2017 +0100
@@ -1174,8 +1174,20 @@
__ pop_i(Z_ARG3);
__ pop_ptr(Z_tmp_2);
// Z_tos : value
- // Z_ARG3 : index
+ // Z_ARG3 : index
// Z_tmp_2 : array
+
+ // Need to check whether array is boolean or byte
+ // since both types share the bastore bytecode.
+ __ load_klass(Z_tmp_1, Z_tmp_2);
+ __ z_llgf(Z_tmp_1, Address(Z_tmp_1, Klass::layout_helper_offset()));
+ __ z_tmll(Z_tmp_1, Klass::layout_helper_boolean_diffbit());
+ Label L_skip;
+ __ z_bfalse(L_skip);
+ // if it is a T_BOOLEAN array, mask the stored value to 0/1
+ __ z_nilf(Z_tos, 0x1);
+ __ bind(L_skip);
+
// No index shift necessary - pass 0.
index_check(Z_tmp_2, Z_ARG3, 0); // Prefer index in Z_ARG3.
__ z_stc(Z_tos,
@@ -2321,6 +2333,13 @@
__ bind(skip_register_finalizer);
}
+ if (state == itos) {
+ // 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.
+ __ narrow(Z_tos, Z_tmp_1); /* fall through */
+ }
+
__ remove_activation(state, Z_R14);
__ z_br(Z_R14);
}