Mercurial > hg > icedtea7-forest > hotspot
changeset 6451:71fdc2163e4e
8154413: AArch64: Better byte behaviour
Summary: Add support for 8132051 on AArch64
Reviewed-by: adinn
author | aph |
---|---|
date | Mon, 18 Apr 2016 07:12:53 +0100 |
parents | 18f9f032164c |
children | b6971126dc0f |
files | src/cpu/aarch64/vm/c1_LIRGenerator_aarch64.cpp src/cpu/aarch64/vm/interp_masm_aarch64.cpp src/cpu/aarch64/vm/interp_masm_aarch64.hpp src/cpu/aarch64/vm/templateTable_aarch64.cpp |
diffstat | 4 files changed, 103 insertions(+), 5 deletions(-) [+] |
line wrap: on
line diff
--- a/src/cpu/aarch64/vm/c1_LIRGenerator_aarch64.cpp Wed Jan 27 15:01:46 2016 +0100 +++ b/src/cpu/aarch64/vm/c1_LIRGenerator_aarch64.cpp Mon Apr 18 07:12:53 2016 +0100 @@ -339,7 +339,7 @@ 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()); @@ -388,7 +388,8 @@ // 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); } }
--- a/src/cpu/aarch64/vm/interp_masm_aarch64.cpp Wed Jan 27 15:01:46 2016 +0100 +++ b/src/cpu/aarch64/vm/interp_masm_aarch64.cpp Mon Apr 18 07:12:53 2016 +0100 @@ -52,7 +52,43 @@ #endif -// 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, methodOopDesc::const_offset())); + ldrb(rscratch1, Address(rscratch1, constMethodOopDesc::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); +} #ifndef CC_INTERP @@ -90,6 +126,7 @@ 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; @@ -293,6 +330,7 @@ switch (state) { case atos: pop_ptr(); break; case btos: + case ztos: case ctos: case stos: case itos: pop_i(); break; @@ -310,6 +348,7 @@ switch (state) { case atos: push_ptr(); break; case btos: + case ztos: case ctos: case stos: case itos: push_i(); break;
--- a/src/cpu/aarch64/vm/interp_masm_aarch64.hpp Wed Jan 27 15:01:46 2016 +0100 +++ b/src/cpu/aarch64/vm/interp_masm_aarch64.hpp Mon Apr 18 07:12:53 2016 +0100 @@ -244,6 +244,9 @@ 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);
--- a/src/cpu/aarch64/vm/templateTable_aarch64.cpp Wed Jan 27 15:01:46 2016 +0100 +++ b/src/cpu/aarch64/vm/templateTable_aarch64.cpp Mon Apr 18 07:12:53 2016 +0100 @@ -232,6 +232,7 @@ 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: @@ -1108,6 +1109,18 @@ // 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 = Klass::layout_helper_boolean_diffbit(); + __ andw(rscratch1, r2, diffbit); + Label L_skip; + __ cbzw(rscratch1, 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))); @@ -2204,6 +2217,13 @@ 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); } @@ -2443,7 +2463,7 @@ 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 @@ -2463,6 +2483,20 @@ __ 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 @@ -2655,7 +2689,7 @@ // 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 @@ -2677,6 +2711,22 @@ } __ 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); @@ -2827,6 +2877,7 @@ 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; @@ -2852,6 +2903,7 @@ 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; @@ -2907,6 +2959,9 @@ 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;