# HG changeset patch # User kevinw # Date 1462275667 -3600 # Node ID 320a3e1b732525788e12f6fafd3306af9610a07f # Parent fe4bbf70da7e0172caf9ca774bf331d454509bc2 8132051: Better byte behavior Summary: Contains introduction of interp_masm_x86.{c,h}pp from 8026251 Reviewed-by: coleenp, roland diff -r fe4bbf70da7e -r 320a3e1b7325 src/cpu/sparc/vm/c1_LIRGenerator_sparc.cpp --- a/src/cpu/sparc/vm/c1_LIRGenerator_sparc.cpp Tue May 03 12:13:18 2016 +0100 +++ b/src/cpu/sparc/vm/c1_LIRGenerator_sparc.cpp Tue May 03 12:41:07 2016 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -346,7 +346,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()); @@ -391,7 +391,8 @@ 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); + 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()); diff -r fe4bbf70da7e -r 320a3e1b7325 src/cpu/sparc/vm/cppInterpreter_sparc.cpp --- a/src/cpu/sparc/vm/cppInterpreter_sparc.cpp Tue May 03 12:13:18 2016 +0100 +++ b/src/cpu/sparc/vm/cppInterpreter_sparc.cpp Tue May 03 12:41:07 2016 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -533,6 +533,9 @@ __ cmp(G1_scratch, btos); __ br(Assembler::equal, true, Assembler::pt, xreturn_path); __ delayed()->ldsb(Otos_i, G3_scratch, Otos_i); + __ cmp(G1_scratch, ztos); + __ br(Assembler::equal, true, Assembler::pt, xreturn_path); + __ delayed()->ldsb(Otos_i, G3_scratch, Otos_i); __ should_not_reach_here(); #endif __ ldsb(Otos_i, G3_scratch, Otos_i); diff -r fe4bbf70da7e -r 320a3e1b7325 src/cpu/sparc/vm/interp_masm_sparc.cpp --- a/src/cpu/sparc/vm/interp_masm_sparc.cpp Tue May 03 12:13:18 2016 +0100 +++ b/src/cpu/sparc/vm/interp_masm_sparc.cpp Tue May 03 12:41:07 2016 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -215,6 +215,7 @@ case atos: ld_ptr(oop_addr, Otos_l); st_ptr(G0, oop_addr); break; case btos: // fall through + case ztos: // fall through case ctos: // fall through case stos: // fall through case itos: ld(val_addr, Otos_l1); break; @@ -463,9 +464,10 @@ interp_verify_oop(Otos_i, state, __FILE__, __LINE__); switch (state) { case atos: push_ptr(); break; - case btos: push_i(); break; - case ctos: - case stos: push_i(); break; + case btos: // fall through + case ztos: // fall through + case ctos: // fall through + case stos: // fall through case itos: push_i(); break; case ltos: push_l(); break; case ftos: push_f(); break; @@ -479,9 +481,10 @@ void InterpreterMacroAssembler::pop(TosState state) { switch (state) { case atos: pop_ptr(); break; - case btos: pop_i(); break; - case ctos: - case stos: pop_i(); break; + case btos: // fall through + case ztos: // fall through + case ctos: // fall through + case stos: // fall through case itos: pop_i(); break; case ltos: pop_l(); break; case ftos: pop_f(); break; @@ -1087,6 +1090,49 @@ interp_verify_oop(Otos_i, state, __FILE__, __LINE__); } +void InterpreterMacroAssembler::narrow(Register result) { + + ld_ptr(Address(Lmethod, methodOopDesc::const_offset()), G3_scratch); + ldub(G3_scratch, in_bytes(constMethodOopDesc::result_type_offset()), G3_scratch); + + Label notBool, notByte, notChar, done; + + // common case first + cmp(G3_scratch, T_INT); + br(Assembler::equal, true, pn, done); + delayed()->nop(); + + cmp(G3_scratch, T_BOOLEAN); + br(Assembler::notEqual, true, pn, notBool); + delayed()->cmp(G3_scratch, T_BYTE); + and3(result, 1, result); + ba(done); + delayed()->nop(); + + bind(notBool); + // cmp(G3_scratch, T_BYTE); + br(Assembler::notEqual, true, pn, notByte); + delayed()->cmp(G3_scratch, T_CHAR); + sll(result, 24, result); + sra(result, 24, result); + ba(done); + delayed()->nop(); + + bind(notByte); + // cmp(G3_scratch, T_CHAR); + sll(result, 16, result); + br(Assembler::notEqual, true, pn, done); + delayed()->sra(result, 16, result); + // sll(result, 16, result); + srl(result, 16, result); + + // bind(notChar); + // must be short, instructions already executed in delay slot + // sll(result, 16, result); + // sra(result, 16, result); + + bind(done); +} // remove activation // @@ -1123,6 +1169,7 @@ case ltos: mov(Otos_l2, Otos_l2->after_save()); // fall through // O1 -> I1 #endif case btos: // fall through + case ztos: // fall through case ctos: case stos: // fall through case atos: // fall through diff -r fe4bbf70da7e -r 320a3e1b7325 src/cpu/sparc/vm/interp_masm_sparc.hpp --- a/src/cpu/sparc/vm/interp_masm_sparc.hpp Tue May 03 12:13:18 2016 +0100 +++ b/src/cpu/sparc/vm/interp_masm_sparc.hpp Tue May 03 12:41:07 2016 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -105,6 +105,8 @@ void dispatch_via (TosState state, address* table); + void narrow(Register result); + // Removes the current activation (incl. unlocking of monitors). // Additionally this code is used for earlyReturn in which case we // want to skip throwing an exception and installing an exception. diff -r fe4bbf70da7e -r 320a3e1b7325 src/cpu/sparc/vm/templateInterpreter_sparc.cpp --- a/src/cpu/sparc/vm/templateInterpreter_sparc.cpp Tue May 03 12:13:18 2016 +0100 +++ b/src/cpu/sparc/vm/templateInterpreter_sparc.cpp Tue May 03 12:41:07 2016 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -711,6 +711,9 @@ __ cmp(G1_scratch, btos); __ br(Assembler::equal, true, Assembler::pt, xreturn_path); __ delayed()->ldsb(Otos_i, G3_scratch, Otos_i); + __ cmp(G1_scratch, ztos); + __ br(Assembler::equal, true, Assembler::pt, xreturn_path); + __ delayed()->ldsb(Otos_i, G3_scratch, Otos_i); __ should_not_reach_here(); #endif __ ldsb(Otos_i, G3_scratch, Otos_i); diff -r fe4bbf70da7e -r 320a3e1b7325 src/cpu/sparc/vm/templateTable_sparc.cpp --- a/src/cpu/sparc/vm/templateTable_sparc.cpp Tue May 03 12:13:18 2016 +0100 +++ b/src/cpu/sparc/vm/templateTable_sparc.cpp Tue May 03 12:41:07 2016 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -159,6 +159,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: @@ -928,8 +929,20 @@ transition(itos, vtos); __ pop_i(O2); // index // Otos_i: val + // O2: index // O3: array __ index_check(O3, O2, 0, G3_scratch, O2); + // Need to check whether array is boolean or byte + // since both types share the bastore bytecode. + __ load_klass(O3, G4_scratch); + __ ld(G4_scratch, in_bytes(Klass::layout_helper_offset()), G4_scratch); + __ set(Klass::layout_helper_boolean_diffbit(), G3_scratch); + __ andcc(G3_scratch, G4_scratch, G0); + Label L_skip; + __ br(Assembler::zero, false, Assembler::pn, L_skip); + __ delayed()->nop(); + __ and3(Otos_i, 1, Otos_i); // if it is a T_BOOLEAN array, mask the stored value to 0/1 + __ bind(L_skip); __ stb(Otos_i, O2, arrayOopDesc::base_offset_in_bytes(T_BYTE)); } @@ -2043,6 +2056,12 @@ __ bind(skip_register_finalizer); } + // 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(Otos_i); + } __ remove_activation(state, /* throw_monitor_exception */ true); // The caller's SP was adjusted upon method entry to accomodate @@ -2279,7 +2298,7 @@ Label checkVolatile; // compute field type - Label notByte, notInt, notShort, notChar, notLong, notFloat, notObj; + Label notByte, notBool, notInt, notShort, notChar, notLong, notFloat, notObj; __ srl(Rflags, ConstantPoolCacheEntry::tosBits, Rflags); // Make sure we don't need to mask Rflags for tosBits after the above shift ConstantPoolCacheEntry::verify_tosBits(); @@ -2334,7 +2353,7 @@ // cmp(Rflags, btos); __ br(Assembler::notEqual, false, Assembler::pt, notByte); - __ delayed() ->cmp(Rflags, ctos); + __ delayed() ->cmp(Rflags, ztos); // btos __ ldsb(Rclass, Roffset, Otos_i); @@ -2347,6 +2366,22 @@ __ bind(notByte); + // cmp(Rflags, ztos); + __ br(Assembler::notEqual, false, Assembler::pt, notBool); + __ delayed() ->cmp(Rflags, ctos); + + // ztos + __ ldsb(Rclass, Roffset, Otos_i); + __ push(itos); + if (!is_static) { + // use btos rewriting, no truncating to t/f bit is needed for getfield. + patch_bytecode(Bytecodes::_fast_bgetfield, G3_scratch, G4_scratch); + } + __ ba(checkVolatile); + __ delayed()->tst(Lscratch); + + __ bind(notBool); + // cmp(Rflags, ctos); __ br(Assembler::notEqual, false, Assembler::pt, notChar); __ delayed() ->cmp(Rflags, stos); @@ -2508,6 +2543,7 @@ switch (bytecode()) { // save tos values before call_VM() clobbers them case Bytecodes::_fast_aputfield: __ push_ptr(Otos_i); 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(Otos_i); break; @@ -2525,6 +2561,7 @@ switch (bytecode()) { // restore tos values case Bytecodes::_fast_aputfield: __ pop_ptr(Otos_i); 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(Otos_i); break; @@ -2640,7 +2677,7 @@ ConstantPoolCacheEntry::verify_tosBits(); // compute field type - Label notInt, notShort, notChar, notObj, notByte, notLong, notFloat; + Label notInt, notShort, notChar, notObj, notByte, notBool, notLong, notFloat; if (is_static) { // putstatic with object type most likely, check that first @@ -2708,7 +2745,7 @@ // cmp(Rflags, btos); __ br(Assembler::notEqual, false, Assembler::pt, notByte); - __ delayed()->cmp(Rflags, ltos); + __ delayed()->cmp(Rflags, ztos); // btos { @@ -2723,6 +2760,25 @@ } __ bind(notByte); + + // cmp(Rflags, btos); + __ br(Assembler::notEqual, false, Assembler::pt, notBool); + __ delayed()->cmp(Rflags, ltos); + + // ztos + { + __ pop_i(); + if (!is_static) pop_and_check_object(Rclass); + __ and3(Otos_i, 1, Otos_i); + __ stb(Otos_i, Rclass, Roffset); + if (!is_static) { + patch_bytecode(Bytecodes::_fast_zputfield, G3_scratch, G4_scratch, true, byte_no); + } + __ ba(checkVolatile); + __ delayed()->tst(Lscratch); + } + + __ bind(notBool); // cmp(Rflags, ltos); __ br(Assembler::notEqual, false, Assembler::pt, notLong); __ delayed()->cmp(Rflags, ctos); @@ -2846,6 +2902,7 @@ pop_and_check_object(Rclass); switch (bytecode()) { + case Bytecodes::_fast_zputfield: __ and3(Otos_i, 1, Otos_i); // fall through to bputfield case Bytecodes::_fast_bputfield: __ stb(Otos_i, Rclass, Roffset); break; case Bytecodes::_fast_cputfield: /* fall through */ case Bytecodes::_fast_sputfield: __ sth(Otos_i, Rclass, Roffset); break; diff -r fe4bbf70da7e -r 320a3e1b7325 src/cpu/x86/vm/bytecodeInterpreter_x86.cpp --- a/src/cpu/x86/vm/bytecodeInterpreter_x86.cpp Tue May 03 12:13:18 2016 +0100 +++ b/src/cpu/x86/vm/bytecodeInterpreter_x86.cpp Tue May 03 12:41:07 2016 +0100 @@ -40,11 +40,8 @@ #include "runtime/synchronizer.hpp" #include "runtime/vframeArray.hpp" #include "utilities/debug.hpp" -#ifdef TARGET_ARCH_MODEL_x86_32 -# include "interp_masm_x86_32.hpp" -#endif -#ifdef TARGET_ARCH_MODEL_x86_64 -# include "interp_masm_x86_64.hpp" +#ifdef TARGET_ARCH_x86 +# include "interp_masm_x86.hpp" #endif #ifdef CC_INTERP diff -r fe4bbf70da7e -r 320a3e1b7325 src/cpu/x86/vm/c1_LIRGenerator_x86.cpp --- a/src/cpu/x86/vm/c1_LIRGenerator_x86.cpp Tue May 03 12:13:18 2016 +0100 +++ b/src/cpu/x86/vm/c1_LIRGenerator_x86.cpp Tue May 03 12:41:07 2016 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -285,7 +285,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()); @@ -333,7 +333,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); } } diff -r fe4bbf70da7e -r 320a3e1b7325 src/cpu/x86/vm/cppInterpreter_x86.cpp --- a/src/cpu/x86/vm/cppInterpreter_x86.cpp Tue May 03 12:13:18 2016 +0100 +++ b/src/cpu/x86/vm/cppInterpreter_x86.cpp Tue May 03 12:41:07 2016 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -862,7 +862,7 @@ rdx, Address::times_ptr, constantPoolCacheOopDesc::base_offset() + ConstantPoolCacheEntry::flags_offset())); - Label notByte, notShort, notChar; + Label notByte, notBool, notShort, notChar; const Address field_address (rax, rcx, Address::times_1); // Need to differentiate between igetfield, agetfield, bgetfield etc. @@ -881,6 +881,11 @@ __ bind(notObj); #endif // _LP64 + __ cmpl(rdx, ztos); + __ jcc(Assembler::notEqual, notBool); + __ load_signed_byte(rax, field_address); + __ jmp(xreturn_path); + __ cmpl(rdx, btos); __ jcc(Assembler::notEqual, notByte); __ load_signed_byte(rax, field_address); diff -r fe4bbf70da7e -r 320a3e1b7325 src/cpu/x86/vm/interp_masm_x86.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/cpu/x86/vm/interp_masm_x86.cpp Tue May 03 12:41:07 2016 +0100 @@ -0,0 +1,76 @@ +/* + * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#include "precompiled.hpp" +#include "interp_masm_x86.hpp" +#include "interpreter/interpreter.hpp" + + +// 8u does not have InterpreterMacroAssembler::load_earlyret_value here + +void InterpreterMacroAssembler::narrow(Register result) { + + // Get method->_constMethod->_result_type + movptr(rcx, Address(rbp, frame::interpreter_frame_method_offset * wordSize)); + movptr(rcx, Address(rcx, methodOopDesc::const_offset())); + load_unsigned_byte(rcx, Address(rcx, constMethodOopDesc::result_type_offset())); + + Label done, notBool, notByte, notChar; + + // common case first + cmpl(rcx, T_INT); + jcc(Assembler::equal, done); + + // mask integer result to narrower return type. + cmpl(rcx, T_BOOLEAN); + jcc(Assembler::notEqual, notBool); + andl(result, 0x1); + jmp(done); + + bind(notBool); + cmpl(rcx, T_BYTE); + jcc(Assembler::notEqual, notByte); + LP64_ONLY(movsbl(result, result);) + NOT_LP64(shll(result, 24);) // truncate upper 24 bits + NOT_LP64(sarl(result, 24);) // and sign-extend byte + jmp(done); + + bind(notByte); + cmpl(rcx, T_CHAR); + jcc(Assembler::notEqual, notChar); + LP64_ONLY(movzwl(result, result);) + NOT_LP64(andl(result, 0xFFFF);) // truncate upper 16 bits + jmp(done); + + bind(notChar); + // cmpl(rcx, T_SHORT); // all that's left + // jcc(Assembler::notEqual, done); + LP64_ONLY(movswl(result, result);) + NOT_LP64(shll(result, 16);) // truncate upper 16 bits + NOT_LP64(sarl(result, 16);) // and sign-extend short + + // Nothing to do for T_INT + bind(done); +} + diff -r fe4bbf70da7e -r 320a3e1b7325 src/cpu/x86/vm/interp_masm_x86.hpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/cpu/x86/vm/interp_masm_x86.hpp Tue May 03 12:41:07 2016 +0100 @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#ifndef CPU_X86_VM_INTERP_MASM_X86_HPP +#define CPU_X86_VM_INTERP_MASM_X86_HPP + +#include "assembler_x86.inline.hpp" +#include "interpreter/invocationCounter.hpp" + +// This file specializes the assember with interpreter-specific macros + + +class InterpreterMacroAssembler: public MacroAssembler { + +#ifdef TARGET_ARCH_MODEL_x86_32 +# include "interp_masm_x86_32.hpp" +#endif +#ifdef TARGET_ARCH_MODEL_x86_64 +# include "interp_masm_x86_64.hpp" +#endif + + public: + // narrow int return value + void narrow(Register result); + +}; + +#endif // CPU_X86_VM_INTERP_MASM_X86_HPP diff -r fe4bbf70da7e -r 320a3e1b7325 src/cpu/x86/vm/interp_masm_x86_32.cpp --- a/src/cpu/x86/vm/interp_masm_x86_32.cpp Tue May 03 12:13:18 2016 +0100 +++ b/src/cpu/x86/vm/interp_masm_x86_32.cpp Tue May 03 12:41:07 2016 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,7 @@ */ #include "precompiled.hpp" -#include "interp_masm_x86_32.hpp" +#include "interp_masm_x86.hpp" #include "interpreter/interpreter.hpp" #include "interpreter/interpreterRuntime.hpp" #include "oops/arrayOop.hpp" @@ -162,6 +162,7 @@ case ltos: movl(rdx, val_addr1); // fall through case btos: // fall through + case ztos: // fall through case ctos: // fall through case stos: // fall through case itos: movl(rax, val_addr); break; @@ -336,6 +337,7 @@ switch (state) { case atos: pop_ptr(rax); break; case btos: // fall through + case ztos: // fall through case ctos: // fall through case stos: // fall through case itos: pop_i(rax); break; @@ -379,6 +381,7 @@ switch (state) { case atos: push_ptr(rax); break; case btos: // fall through + case ztos: // fall through case ctos: // fall through case stos: // fall through case itos: push_i(rax); break; diff -r fe4bbf70da7e -r 320a3e1b7325 src/cpu/x86/vm/interp_masm_x86_32.hpp --- a/src/cpu/x86/vm/interp_masm_x86_32.hpp Tue May 03 12:13:18 2016 +0100 +++ b/src/cpu/x86/vm/interp_masm_x86_32.hpp Tue May 03 12:41:07 2016 +0100 @@ -22,16 +22,6 @@ * */ -#ifndef CPU_X86_VM_INTERP_MASM_X86_32_HPP -#define CPU_X86_VM_INTERP_MASM_X86_32_HPP - -#include "assembler_x86.inline.hpp" -#include "interpreter/invocationCounter.hpp" - -// This file specializes the assember with interpreter-specific macros - - -class InterpreterMacroAssembler: public MacroAssembler { #ifndef CC_INTERP protected: // Interpreter specific version of call_VM_base @@ -226,7 +216,3 @@ // support for jvmti void notify_method_entry(); void notify_method_exit(TosState state, NotifyMethodExitMode mode); - -}; - -#endif // CPU_X86_VM_INTERP_MASM_X86_32_HPP diff -r fe4bbf70da7e -r 320a3e1b7325 src/cpu/x86/vm/interp_masm_x86_64.cpp --- a/src/cpu/x86/vm/interp_masm_x86_64.cpp Tue May 03 12:13:18 2016 +0100 +++ b/src/cpu/x86/vm/interp_masm_x86_64.cpp Tue May 03 12:41:07 2016 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,7 @@ */ #include "precompiled.hpp" -#include "interp_masm_x86_64.hpp" +#include "interp_masm_x86.hpp" #include "interpreter/interpreter.hpp" #include "interpreter/interpreterRuntime.hpp" #include "oops/arrayOop.hpp" @@ -160,6 +160,7 @@ verify_oop(rax, state); break; case ltos: movptr(rax, val_addr); break; case btos: // fall through + case ztos: // fall through case ctos: // fall through case stos: // fall through case itos: movl(rax, val_addr); break; @@ -361,6 +362,7 @@ switch (state) { case atos: pop_ptr(); break; case btos: + case ztos: case ctos: case stos: case itos: pop_i(); break; @@ -378,6 +380,7 @@ switch (state) { case atos: push_ptr(); break; case btos: + case ztos: case ctos: case stos: case itos: push_i(); break; diff -r fe4bbf70da7e -r 320a3e1b7325 src/cpu/x86/vm/interp_masm_x86_64.hpp --- a/src/cpu/x86/vm/interp_masm_x86_64.hpp Tue May 03 12:13:18 2016 +0100 +++ b/src/cpu/x86/vm/interp_masm_x86_64.hpp Tue May 03 12:41:07 2016 +0100 @@ -22,16 +22,6 @@ * */ -#ifndef CPU_X86_VM_INTERP_MASM_X86_64_HPP -#define CPU_X86_VM_INTERP_MASM_X86_64_HPP - -#include "assembler_x86.inline.hpp" -#include "interpreter/invocationCounter.hpp" - -// This file specializes the assember with interpreter-specific macros - - -class InterpreterMacroAssembler: public MacroAssembler { #ifndef CC_INTERP protected: // Interpreter specific version of call_VM_base @@ -239,6 +229,3 @@ // support for jvmti/dtrace void notify_method_entry(); void notify_method_exit(TosState state, NotifyMethodExitMode mode); -}; - -#endif // CPU_X86_VM_INTERP_MASM_X86_64_HPP diff -r fe4bbf70da7e -r 320a3e1b7325 src/cpu/x86/vm/register_definitions_x86.cpp --- a/src/cpu/x86/vm/register_definitions_x86.cpp Tue May 03 12:13:18 2016 +0100 +++ b/src/cpu/x86/vm/register_definitions_x86.cpp Tue May 03 12:41:07 2016 +0100 @@ -26,11 +26,8 @@ #include "asm/assembler.hpp" #include "asm/register.hpp" #include "register_x86.hpp" -#ifdef TARGET_ARCH_MODEL_x86_32 -# include "interp_masm_x86_32.hpp" -#endif -#ifdef TARGET_ARCH_MODEL_x86_64 -# include "interp_masm_x86_64.hpp" +#ifdef TARGET_ARCH_x86 +# include "interp_masm_x86.hpp" #endif REGISTER_DEFINITION(Register, noreg); diff -r fe4bbf70da7e -r 320a3e1b7325 src/cpu/x86/vm/templateInterpreter_x86_32.cpp --- a/src/cpu/x86/vm/templateInterpreter_x86_32.cpp Tue May 03 12:13:18 2016 +0100 +++ b/src/cpu/x86/vm/templateInterpreter_x86_32.cpp Tue May 03 12:41:07 2016 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -702,7 +702,7 @@ rdx, Address::times_ptr, constantPoolCacheOopDesc::base_offset() + ConstantPoolCacheEntry::flags_offset())); - Label notByte, notShort, notChar; + Label notByte, notBool, notShort, notChar; const Address field_address (rax, rcx, Address::times_1); // Need to differentiate between igetfield, agetfield, bgetfield etc. @@ -717,6 +717,12 @@ __ jmp(xreturn_path); __ bind(notByte); + __ cmpl(rdx, ztos); + __ jcc(Assembler::notEqual, notBool); + __ load_signed_byte(rax, field_address); + __ jmp(xreturn_path); + + __ bind(notBool); __ cmpl(rdx, stos); __ jcc(Assembler::notEqual, notShort); __ load_signed_short(rax, field_address); diff -r fe4bbf70da7e -r 320a3e1b7325 src/cpu/x86/vm/templateInterpreter_x86_64.cpp --- a/src/cpu/x86/vm/templateInterpreter_x86_64.cpp Tue May 03 12:13:18 2016 +0100 +++ b/src/cpu/x86/vm/templateInterpreter_x86_64.cpp Tue May 03 12:41:07 2016 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -675,7 +675,7 @@ constantPoolCacheOopDesc::base_offset() + ConstantPoolCacheEntry::flags_offset())); - Label notObj, notInt, notByte, notShort; + Label notObj, notInt, notByte, notBool, notShort; const Address field_address(rax, rcx, Address::times_1); // Need to differentiate between igetfield, agetfield, bgetfield etc. @@ -706,6 +706,13 @@ __ jmp(xreturn_path); __ bind(notByte); + __ cmpl(rdx, ztos); + __ jcc(Assembler::notEqual, notBool); + // ztos + __ load_signed_byte(rax, field_address); + __ jmp(xreturn_path); + + __ bind(notBool); __ cmpl(rdx, stos); __ jcc(Assembler::notEqual, notShort); // stos diff -r fe4bbf70da7e -r 320a3e1b7325 src/cpu/x86/vm/templateTable_x86_32.cpp --- a/src/cpu/x86/vm/templateTable_x86_32.cpp Tue May 03 12:13:18 2016 +0100 +++ b/src/cpu/x86/vm/templateTable_x86_32.cpp Tue May 03 12:41:07 2016 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -211,6 +211,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: @@ -1018,11 +1019,21 @@ void TemplateTable::bastore() { transition(itos, vtos); __ pop_i(rbx); - // rax,: value + // rax: value + // rbx: index // rdx: array - index_check(rdx, rbx); // prefer index in rbx, - // rbx,: index - __ movb(Address(rdx, rbx, Address::times_1, arrayOopDesc::base_offset_in_bytes(T_BYTE)), rax); + index_check(rdx, rbx); // prefer index in rbx + // Need to check whether array is boolean or byte + // since both types share the bastore bytecode. + __ load_klass(rcx, rdx); + __ movl(rcx, Address(rcx, Klass::layout_helper_offset())); + int diffbit = Klass::layout_helper_boolean_diffbit(); + __ testl(rcx, diffbit); + Label L_skip; + __ jccb(Assembler::zero, L_skip); + __ andl(rax, 1); // if it is a T_BOOLEAN array, mask the stored value to 0/1 + __ bind(L_skip); + __ movb(Address(rdx, rbx, Address::times_1, arrayOopDesc::base_offset_in_bytes(T_BYTE)), rax); } @@ -2043,7 +2054,14 @@ __ bind(skip_register_finalizer); } + // 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(rax); + } __ remove_activation(state, rsi); + __ jmp(rsi); } @@ -2258,7 +2276,7 @@ const Address lo(obj, off, Address::times_1, 0*wordSize); const Address hi(obj, off, Address::times_1, 1*wordSize); - Label Done, notByte, notInt, notShort, notChar, notLong, notFloat, notObj, notDouble; + Label Done, notByte, notBool, notInt, notShort, notChar, notLong, notFloat, notObj, notDouble; __ shrl(flags, ConstantPoolCacheEntry::tosBits); assert(btos == 0, "change code, btos != 0"); @@ -2275,6 +2293,22 @@ __ jmp(Done); __ bind(notByte); + + __ cmpl(flags, ztos); + __ jcc(Assembler::notEqual, notBool); + + // ztos (same code as btos) + __ load_signed_byte(rax, lo); + __ 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, rcx, rbx); + } + __ jmp(Done); + + __ bind(notBool); + // itos __ cmpl(flags, itos ); __ jcc(Assembler::notEqual, notInt); @@ -2474,7 +2508,7 @@ const Address lo(obj, off, Address::times_1, 0*wordSize); const Address hi(obj, off, Address::times_1, 1*wordSize); - Label notByte, notInt, notShort, notChar, notLong, notFloat, notObj, notDouble; + Label notByte, notBool, notInt, notShort, notChar, notLong, notFloat, notObj, notDouble; __ shrl(flags, ConstantPoolCacheEntry::tosBits); assert(btos == 0, "change code, btos != 0"); @@ -2493,6 +2527,22 @@ } __ bind(notByte); + __ cmpl(flags, ztos); + __ jcc(Assembler::notEqual, notBool); + + // ztos + { + __ pop(ztos); + if (!is_static) pop_and_check_object(obj); + __ andl(rax, 0x1); + __ movb(lo, rax); + if (!is_static) { + patch_bytecode(Bytecodes::_fast_zputfield, rcx, rbx, true, byte_no); + } + __ jmp(Done); + } + + __ bind(notBool); __ cmpl(flags, itos); __ jcc(Assembler::notEqual, notInt); @@ -2664,6 +2714,7 @@ switch (bytecode()) { // load values into the jvalue object case Bytecodes::_fast_aputfield: __ push_ptr(rax); 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(rax); break; @@ -2686,6 +2737,7 @@ switch (bytecode()) { // restore tos values case Bytecodes::_fast_aputfield: __ pop_ptr(rax); 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(rax); break; @@ -2736,6 +2788,8 @@ // access field switch (bytecode()) { + case Bytecodes::_fast_zputfield: __ andl(rax, 0x1); // boolean is true if LSB is 1 + // fall through to bputfield case Bytecodes::_fast_bputfield: __ movb(lo, rax); break; case Bytecodes::_fast_sputfield: // fall through case Bytecodes::_fast_cputfield: __ movw(lo, rax); break; @@ -2770,6 +2824,8 @@ // access field switch (bytecode()) { + case Bytecodes::_fast_zputfield: __ andl(rax, 0x1); // boolean is true if LSB is 1 + // fall through to bputfield case Bytecodes::_fast_bputfield: __ movb(lo, rax); break; case Bytecodes::_fast_sputfield: // fall through case Bytecodes::_fast_cputfield: __ movw(lo, rax); break; diff -r fe4bbf70da7e -r 320a3e1b7325 src/cpu/x86/vm/templateTable_x86_64.cpp --- a/src/cpu/x86/vm/templateTable_x86_64.cpp Tue May 03 12:13:18 2016 +0100 +++ b/src/cpu/x86/vm/templateTable_x86_64.cpp Tue May 03 12:41:07 2016 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -212,6 +212,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: @@ -1045,6 +1046,16 @@ // ebx: index // rdx: array index_check(rdx, rbx); // prefer index in ebx + // Need to check whether array is boolean or byte + // since both types share the bastore bytecode. + __ load_klass(rcx, rdx); + __ movl(rcx, Address(rcx, Klass::layout_helper_offset())); + int diffbit = Klass::layout_helper_boolean_diffbit(); + __ testl(rcx, diffbit); + Label L_skip; + __ jccb(Assembler::zero, L_skip); + __ andl(rax, 1); // if it is a T_BOOLEAN array, mask the stored value to 0/1 + __ bind(L_skip); __ movb(Address(rdx, rbx, Address::times_1, arrayOopDesc::base_offset_in_bytes(T_BYTE)), @@ -2076,7 +2087,14 @@ __ bind(skip_register_finalizer); } + // 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(rax); + } __ remove_activation(state, r13); + __ jmp(r13); } @@ -2314,7 +2332,7 @@ const Address field(obj, off, Address::times_1); - Label Done, notByte, notInt, notShort, notChar, + Label Done, notByte, notBool, notInt, notShort, notChar, notLong, notFloat, notObj, notDouble; __ shrl(flags, ConstantPoolCacheEntry::tosBits); @@ -2332,6 +2350,20 @@ __ jmp(Done); __ bind(notByte); + __ cmpl(flags, ztos); + __ jcc(Assembler::notEqual, notBool); + + // ztos (same code as btos) + __ load_signed_byte(rax, 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, rbx); + } + __ jmp(Done); + + __ bind(notBool); __ cmpl(flags, atos); __ jcc(Assembler::notEqual, notObj); // atos @@ -2522,7 +2554,7 @@ // field address const Address field(obj, off, Address::times_1); - Label notByte, notInt, notShort, notChar, + Label notByte, notBool, notInt, notShort, notChar, notLong, notFloat, notObj, notDouble; __ shrl(flags, ConstantPoolCacheEntry::tosBits); @@ -2543,6 +2575,22 @@ } __ bind(notByte); + __ cmpl(flags, ztos); + __ jcc(Assembler::notEqual, notBool); + + // ztos + { + __ pop(ztos); + if (!is_static) pop_and_check_object(obj); + __ andl(rax, 0x1); + __ movb(field, rax); + if (!is_static) { + patch_bytecode(Bytecodes::_fast_zputfield, bc, rbx, true, byte_no); + } + __ jmp(Done); + } + + __ bind(notBool); __ cmpl(flags, atos); __ jcc(Assembler::notEqual, notObj); @@ -2691,6 +2739,7 @@ switch (bytecode()) { // load values into the jvalue object case Bytecodes::_fast_aputfield: __ push_ptr(rax); 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(rax); break; @@ -2716,6 +2765,7 @@ switch (bytecode()) { // restore tos values case Bytecodes::_fast_aputfield: __ pop_ptr(rax); 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(rax); break; @@ -2771,6 +2821,9 @@ case Bytecodes::_fast_iputfield: __ movl(field, rax); break; + case Bytecodes::_fast_zputfield: + __ andl(rax, 0x1); // boolean is true if LSB is 1 + // fall through to bputfield case Bytecodes::_fast_bputfield: __ movb(field, rax); break; diff -r fe4bbf70da7e -r 320a3e1b7325 src/cpu/x86/vm/vtableStubs_x86_32.cpp --- a/src/cpu/x86/vm/vtableStubs_x86_32.cpp Tue May 03 12:13:18 2016 +0100 +++ b/src/cpu/x86/vm/vtableStubs_x86_32.cpp Tue May 03 12:41:07 2016 +0100 @@ -26,7 +26,7 @@ #include "asm/assembler.hpp" #include "assembler_x86.inline.hpp" #include "code/vtableStubs.hpp" -#include "interp_masm_x86_32.hpp" +#include "interp_masm_x86.hpp" #include "memory/resourceArea.hpp" #include "oops/instanceKlass.hpp" #include "oops/klassVtable.hpp" diff -r fe4bbf70da7e -r 320a3e1b7325 src/cpu/x86/vm/vtableStubs_x86_64.cpp --- a/src/cpu/x86/vm/vtableStubs_x86_64.cpp Tue May 03 12:13:18 2016 +0100 +++ b/src/cpu/x86/vm/vtableStubs_x86_64.cpp Tue May 03 12:41:07 2016 +0100 @@ -26,7 +26,7 @@ #include "asm/assembler.hpp" #include "assembler_x86.inline.hpp" #include "code/vtableStubs.hpp" -#include "interp_masm_x86_64.hpp" +#include "interp_masm_x86.hpp" #include "memory/resourceArea.hpp" #include "oops/instanceKlass.hpp" #include "oops/klassVtable.hpp" diff -r fe4bbf70da7e -r 320a3e1b7325 src/cpu/zero/vm/cppInterpreter_zero.cpp --- a/src/cpu/zero/vm/cppInterpreter_zero.cpp Tue May 03 12:13:18 2016 +0100 +++ b/src/cpu/zero/vm/cppInterpreter_zero.cpp Tue May 03 12:41:07 2016 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved. * Copyright 2007, 2008, 2009, 2010, 2011, 2012 Red Hat, Inc. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -79,6 +79,29 @@ return 0; } +intptr_t narrow(BasicType type, intptr_t result) { + // mask integer result to narrower return type. + switch (type) { + case T_BOOLEAN: + return result&1; + case T_BYTE: + return (intptr_t)(jbyte)result; + case T_CHAR: + return (intptr_t)(uintptr_t)(jchar)result; + case T_SHORT: + return (intptr_t)(jshort)result; + case T_OBJECT: // nothing to do fall through + case T_LONG: + case T_INT: + case T_FLOAT: + case T_DOUBLE: + case T_VOID: + return result; + default : ShouldNotReachHere(); + } +} + + void CppInterpreter::main_loop(int recurse, TRAPS) { JavaThread *thread = (JavaThread *) THREAD; ZeroStack *stack = thread->zero_stack(); @@ -211,8 +234,14 @@ stack->set_sp(stack->sp() + method->max_locals()); // Push our result - for (int i = 0; i < result_slots; i++) - stack->push(result[-i]); + for (int i = 0; i < result_slots; i++) { + // Adjust result to smaller + intptr_t res = result[-i]; + if (result_slots == 1) { + res = narrow(result_type_of(method), res); + } + stack->push(res); + } } int CppInterpreter::native_entry(methodOop method, intptr_t UNUSED, TRAPS) { @@ -539,6 +568,7 @@ break; case btos: + case ztos: SET_LOCALS_INT(object->byte_field_acquire(entry->f2()), 0); break; @@ -577,6 +607,7 @@ break; case btos: + case ztos: SET_LOCALS_INT(object->byte_field(entry->f2()), 0); break; diff -r fe4bbf70da7e -r 320a3e1b7325 src/share/vm/c1/c1_Canonicalizer.cpp --- a/src/share/vm/c1/c1_Canonicalizer.cpp Tue May 03 12:13:18 2016 +0100 +++ b/src/share/vm/c1/c1_Canonicalizer.cpp Tue May 03 12:41:07 2016 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -260,7 +260,8 @@ // limit this optimization to current block if (value != NULL && in_current_block(conv)) { set_canonical(new StoreIndexed(x->array(), x->index(), x->length(), - x->elt_type(), value, x->state_before())); + x->elt_type(), value, x->state_before(), + x->check_boolean())); return; } } diff -r fe4bbf70da7e -r 320a3e1b7325 src/share/vm/c1/c1_GraphBuilder.cpp --- a/src/share/vm/c1/c1_GraphBuilder.cpp Tue May 03 12:13:18 2016 +0100 +++ b/src/share/vm/c1/c1_GraphBuilder.cpp Tue May 03 12:41:07 2016 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -971,7 +971,19 @@ (array->as_NewArray() && array->as_NewArray()->length() && array->as_NewArray()->length()->type()->is_constant())) { length = append(new ArrayLength(array, state_before)); } - StoreIndexed* result = new StoreIndexed(array, index, length, type, value, state_before); + ciType* array_type = array->declared_type(); + bool check_boolean = false; + if (array_type != NULL) { + if (array_type->is_loaded() && + array_type->as_array_klass()->element_type()->basic_type() == T_BOOLEAN) { + assert(type == T_BYTE, "boolean store uses bastore"); + Value mask = append(new Constant(new IntConstant(1))); + value = append(new LogicOp(Bytecodes::_iand, value, mask)); + } + } else if (type == T_BYTE) { + check_boolean = true; + } + StoreIndexed* result = new StoreIndexed(array, index, length, type, value, state_before, check_boolean); append(result); _memory->store_value(value); @@ -1424,6 +1436,36 @@ need_mem_bar = true; } + BasicType bt = method()->return_type()->basic_type(); + switch (bt) { + case T_BYTE: + { + Value shift = append(new Constant(new IntConstant(24))); + x = append(new ShiftOp(Bytecodes::_ishl, x, shift)); + x = append(new ShiftOp(Bytecodes::_ishr, x, shift)); + break; + } + case T_SHORT: + { + Value shift = append(new Constant(new IntConstant(16))); + x = append(new ShiftOp(Bytecodes::_ishl, x, shift)); + x = append(new ShiftOp(Bytecodes::_ishr, x, shift)); + break; + } + case T_CHAR: + { + Value mask = append(new Constant(new IntConstant(0xFFFF))); + x = append(new LogicOp(Bytecodes::_iand, x, mask)); + break; + } + case T_BOOLEAN: + { + Value mask = append(new Constant(new IntConstant(1))); + x = append(new LogicOp(Bytecodes::_iand, x, mask)); + break; + } + } + // Check to see whether we are inlining. If so, Return // instructions become Gotos to the continuation point. if (continuation() != NULL) { @@ -1557,6 +1599,10 @@ if (state_before == NULL) { state_before = copy_state_for_exception(); } + if (field->type()->basic_type() == T_BOOLEAN) { + Value mask = append(new Constant(new IntConstant(1))); + val = append(new LogicOp(Bytecodes::_iand, val, mask)); + } append(new StoreField(append(obj), offset, field, val, true, state_before, needs_patching)); } break; @@ -1581,6 +1627,10 @@ if (state_before == NULL) { state_before = copy_state_for_exception(); } + if (field->type()->basic_type() == T_BOOLEAN) { + Value mask = append(new Constant(new IntConstant(1))); + val = append(new LogicOp(Bytecodes::_iand, val, mask)); + } StoreField* store = new StoreField(apop(), offset, field, val, false, state_before, needs_patching); if (!needs_patching) store = _memory->store(store); if (store != NULL) { @@ -3925,7 +3975,12 @@ #ifndef _LP64 offset = append(new Convert(Bytecodes::_l2i, offset, as_ValueType(T_INT))); #endif - Instruction* op = append(new UnsafePutObject(t, args->at(1), offset, args->at(3), is_volatile)); + Value val = args->at(3); + if (t == T_BOOLEAN) { + Value mask = append(new Constant(new IntConstant(1))); + val = append(new LogicOp(Bytecodes::_iand, val, mask)); + } + Instruction* op = append(new UnsafePutObject(t, args->at(1), offset, val, is_volatile)); compilation()->set_has_unsafe_access(true); kill_all(); } diff -r fe4bbf70da7e -r 320a3e1b7325 src/share/vm/c1/c1_Instruction.hpp --- a/src/share/vm/c1/c1_Instruction.hpp Tue May 03 12:13:18 2016 +0100 +++ b/src/share/vm/c1/c1_Instruction.hpp Tue May 03 12:41:07 2016 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -890,11 +890,13 @@ ciMethod* _profiled_method; int _profiled_bci; + bool _check_boolean; + public: // creation - StoreIndexed(Value array, Value index, Value length, BasicType elt_type, Value value, ValueStack* state_before) + StoreIndexed(Value array, Value index, Value length, BasicType elt_type, Value value, ValueStack* state_before, bool check_boolean) : AccessIndexed(array, index, length, elt_type, state_before) - , _value(value), _profiled_method(NULL), _profiled_bci(0) + , _value(value), _profiled_method(NULL), _profiled_bci(0), _check_boolean(check_boolean) { set_flag(NeedsWriteBarrierFlag, (as_ValueType(elt_type)->is_object())); set_flag(NeedsStoreCheckFlag, (as_ValueType(elt_type)->is_object())); @@ -906,6 +908,7 @@ Value value() const { return _value; } bool needs_write_barrier() const { return check_flag(NeedsWriteBarrierFlag); } bool needs_store_check() const { return check_flag(NeedsStoreCheckFlag); } + bool check_boolean() const { return _check_boolean; } // Helpers for methodDataOop profiling void set_should_profile(bool value) { set_flag(ProfileMDOFlag, value); } void set_profiled_method(ciMethod* method) { _profiled_method = method; } diff -r fe4bbf70da7e -r 320a3e1b7325 src/share/vm/c1/c1_LIRGenerator.cpp --- a/src/share/vm/c1/c1_LIRGenerator.cpp Tue May 03 12:13:18 2016 +0100 +++ b/src/share/vm/c1/c1_LIRGenerator.cpp Tue May 03 12:41:07 2016 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -3188,3 +3188,26 @@ } } +LIR_Opr LIRGenerator::maybe_mask_boolean(StoreIndexed* x, LIR_Opr array, LIR_Opr value, CodeEmitInfo*& null_check_info) { + if (x->check_boolean()) { + LIR_Opr value_fixed = rlock_byte(T_BYTE); + if (TwoOperandLIRForm) { + __ move(value, value_fixed); + __ logical_and(value_fixed, LIR_OprFact::intConst(1), value_fixed); + } else { + __ logical_and(value, LIR_OprFact::intConst(1), value_fixed); + } + LIR_Opr klass = new_register(T_OBJECT); + __ move(new LIR_Address(array, oopDesc::klass_offset_in_bytes(), T_OBJECT), klass, null_check_info); + null_check_info = NULL; + LIR_Opr layout = new_register(T_INT); + __ move(new LIR_Address(klass, in_bytes(Klass::layout_helper_offset()), T_INT), layout); + int diffbit = Klass::layout_helper_boolean_diffbit(); + __ logical_and(layout, LIR_OprFact::intConst(diffbit), layout); + __ cmp(lir_cond_notEqual, layout, LIR_OprFact::intConst(0)); + __ cmove(lir_cond_notEqual, value_fixed, value, value_fixed, T_BYTE); + value = value_fixed; + } + return value; +} + diff -r fe4bbf70da7e -r 320a3e1b7325 src/share/vm/c1/c1_LIRGenerator.hpp --- a/src/share/vm/c1/c1_LIRGenerator.hpp Tue May 03 12:13:18 2016 +0100 +++ b/src/share/vm/c1/c1_LIRGenerator.hpp Tue May 03 12:41:07 2016 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -425,6 +425,7 @@ SwitchRangeArray* create_lookup_ranges(TableSwitch* x); SwitchRangeArray* create_lookup_ranges(LookupSwitch* x); void do_SwitchRanges(SwitchRangeArray* x, LIR_Opr value, BlockBegin* default_sux); + LIR_Opr maybe_mask_boolean(StoreIndexed* x, LIR_Opr array, LIR_Opr value, CodeEmitInfo*& null_check_info); public: Compilation* compilation() const { return _compilation; } diff -r fe4bbf70da7e -r 320a3e1b7325 src/share/vm/classfile/classFileParser.cpp --- a/src/share/vm/classfile/classFileParser.cpp Tue May 03 12:13:18 2016 +0100 +++ b/src/share/vm/classfile/classFileParser.cpp Tue May 03 12:41:07 2016 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -1975,11 +1975,9 @@ m->set_name_index(name_index); m->set_signature_index(signature_index); m->set_generic_signature_index(generic_signature_index); -#ifdef CC_INTERP - // hmm is there a gc issue here?? + ResultTypeFinder rtf(cp->symbol_at(signature_index)); - m->set_result_index(rtf.type()); -#endif + m->constMethod()->set_result_type(rtf.type()); if (args_size >= 0) { m->set_size_of_parameters(args_size); diff -r fe4bbf70da7e -r 320a3e1b7325 src/share/vm/interpreter/abstractInterpreter.hpp --- a/src/share/vm/interpreter/abstractInterpreter.hpp Tue May 03 12:13:18 2016 +0100 +++ b/src/share/vm/interpreter/abstractInterpreter.hpp Tue May 03 12:41:07 2016 +0100 @@ -29,11 +29,8 @@ #include "interpreter/bytecodes.hpp" #include "runtime/vmThread.hpp" #include "utilities/top.hpp" -#ifdef TARGET_ARCH_MODEL_x86_32 -# include "interp_masm_x86_32.hpp" -#endif -#ifdef TARGET_ARCH_MODEL_x86_64 -# include "interp_masm_x86_64.hpp" +#ifdef TARGET_ARCH_x86 +# include "interp_masm_x86.hpp" #endif #ifdef TARGET_ARCH_MODEL_sparc # include "interp_masm_sparc.hpp" diff -r fe4bbf70da7e -r 320a3e1b7325 src/share/vm/interpreter/bytecodeInterpreter.cpp --- a/src/share/vm/interpreter/bytecodeInterpreter.cpp Tue May 03 12:13:18 2016 +0100 +++ b/src/share/vm/interpreter/bytecodeInterpreter.cpp Tue May 03 12:41:07 2016 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -1643,8 +1643,19 @@ OrderAccess::release_store(&BYTE_MAP_BASE[(uintptr_t)elem_loc >> CardTableModRefBS::card_shift], 0); UPDATE_PC_AND_TOS_AND_CONTINUE(1, -3); } - CASE(_bastore): - ARRAY_STOREFROM32(T_BYTE, jbyte, "%d", STACK_INT, 0); + CASE(_bastore): { + ARRAY_INTRO(-3); + int item = STACK_INT(-1); + // if it is a T_BOOLEAN array, mask the stored value to 0/1 + if (arrObj->klass() == Universe::boolArrayKlassObj()) { + item &= 1; + } else { + assert(arrObj->klass() == Universe::byteArrayKlassObj(), + "should be byte array otherwise"); + } + ((typeArrayOop)arrObj)->byte_at_put(index, item); + UPDATE_PC_AND_TOS_AND_CONTINUE(1, -3); + } CASE(_castore): ARRAY_STOREFROM32(T_CHAR, jchar, "%d", STACK_INT, 0); CASE(_sastore): @@ -1795,7 +1806,7 @@ } else if (tos_type == ltos) { SET_STACK_LONG(obj->long_field_acquire(field_offset), 0); MORE_STACK(1); - } else if (tos_type == btos) { + } else if (tos_type == btos || tos_type == ztos) { SET_STACK_INT(obj->byte_field_acquire(field_offset), -1); } else if (tos_type == ctos) { SET_STACK_INT(obj->char_field_acquire(field_offset), -1); @@ -1816,7 +1827,7 @@ } else if (tos_type == ltos) { SET_STACK_LONG(obj->long_field(field_offset), 0); MORE_STACK(1); - } else if (tos_type == btos) { + } else if (tos_type == btos || tos_type == ztos) { SET_STACK_INT(obj->byte_field(field_offset), -1); } else if (tos_type == ctos) { SET_STACK_INT(obj->char_field(field_offset), -1); @@ -1905,6 +1916,9 @@ OrderAccess::release_store(&BYTE_MAP_BASE[(uintptr_t)obj >> CardTableModRefBS::card_shift], 0); } else if (tos_type == btos) { obj->release_byte_field_put(field_offset, STACK_INT(-1)); + } else if (tos_type == ztos) { + int bool_field = STACK_INT(-1); // only store LSB + obj->release_byte_field_put(field_offset, (bool_field & 1)); } else if (tos_type == ltos) { obj->release_long_field_put(field_offset, STACK_LONG(-1)); } else if (tos_type == ctos) { @@ -1926,6 +1940,9 @@ OrderAccess::release_store(&BYTE_MAP_BASE[(uintptr_t)obj >> CardTableModRefBS::card_shift], 0); } else if (tos_type == btos) { obj->byte_field_put(field_offset, STACK_INT(-1)); + } else if (tos_type == ztos) { + int bool_field = STACK_INT(-1); // only store LSB + obj->byte_field_put(field_offset, (bool_field & 1)); } else if (tos_type == ltos) { obj->long_field_put(field_offset, STACK_LONG(-1)); } else if (tos_type == ctos) { diff -r fe4bbf70da7e -r 320a3e1b7325 src/share/vm/interpreter/bytecodes.cpp --- a/src/share/vm/interpreter/bytecodes.cpp Tue May 03 12:13:18 2016 +0100 +++ b/src/share/vm/interpreter/bytecodes.cpp Tue May 03 12:41:07 2016 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -510,6 +510,7 @@ def(_fast_aputfield , "fast_aputfield" , "bJJ" , NULL , T_OBJECT , 0, true , _putfield ); def(_fast_bputfield , "fast_bputfield" , "bJJ" , NULL , T_INT , 0, true , _putfield ); + def(_fast_zputfield , "fast_zputfield" , "bJJ" , NULL , T_INT , 0, true , _putfield ); def(_fast_cputfield , "fast_cputfield" , "bJJ" , NULL , T_CHAR , 0, true , _putfield ); def(_fast_dputfield , "fast_dputfield" , "bJJ" , NULL , T_DOUBLE , 0, true , _putfield ); def(_fast_fputfield , "fast_fputfield" , "bJJ" , NULL , T_FLOAT , 0, true , _putfield ); diff -r fe4bbf70da7e -r 320a3e1b7325 src/share/vm/interpreter/bytecodes.hpp --- a/src/share/vm/interpreter/bytecodes.hpp Tue May 03 12:13:18 2016 +0100 +++ b/src/share/vm/interpreter/bytecodes.hpp Tue May 03 12:41:07 2016 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -256,6 +256,7 @@ _fast_aputfield , _fast_bputfield , + _fast_zputfield , _fast_cputfield , _fast_dputfield , _fast_fputfield , diff -r fe4bbf70da7e -r 320a3e1b7325 src/share/vm/interpreter/interpreterRuntime.cpp --- a/src/share/vm/interpreter/interpreterRuntime.cpp Tue May 03 12:13:18 2016 +0100 +++ b/src/share/vm/interpreter/interpreterRuntime.cpp Tue May 03 12:41:07 2016 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -1035,7 +1035,8 @@ char sig_type = '\0'; switch(cp_entry->flag_state()) { - case btos: sig_type = 'Z'; break; + case btos: sig_type = 'B'; break; + case ztos: sig_type = 'Z'; break; case ctos: sig_type = 'C'; break; case stos: sig_type = 'S'; break; case itos: sig_type = 'I'; break; diff -r fe4bbf70da7e -r 320a3e1b7325 src/share/vm/interpreter/templateInterpreter.cpp --- a/src/share/vm/interpreter/templateInterpreter.cpp Tue May 03 12:13:18 2016 +0100 +++ b/src/share/vm/interpreter/templateInterpreter.cpp Tue May 03 12:41:07 2016 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -61,8 +61,9 @@ // Implementation of EntryPoint EntryPoint::EntryPoint() { - assert(number_of_states == 9, "check the code below"); + assert(number_of_states == 10, "check the code below"); _entry[btos] = NULL; + _entry[ztos] = NULL; _entry[ctos] = NULL; _entry[stos] = NULL; _entry[atos] = NULL; @@ -74,9 +75,10 @@ } -EntryPoint::EntryPoint(address bentry, address centry, address sentry, address aentry, address ientry, address lentry, address fentry, address dentry, address ventry) { - assert(number_of_states == 9, "check the code below"); +EntryPoint::EntryPoint(address bentry, address zentry, address centry, address sentry, address aentry, address ientry, address lentry, address fentry, address dentry, address ventry) { + assert(number_of_states == 10, "check the code below"); _entry[btos] = bentry; + _entry[ztos] = zentry; _entry[ctos] = centry; _entry[stos] = sentry; _entry[atos] = aentry; @@ -127,6 +129,7 @@ return EntryPoint( _table[btos][i], + _table[ztos][i], _table[ctos][i], _table[stos][i], _table[atos][i], @@ -141,8 +144,9 @@ void DispatchTable::set_entry(int i, EntryPoint& entry) { assert(0 <= i && i < length, "index out of bounds"); - assert(number_of_states == 9, "check the code below"); + assert(number_of_states == 10, "check the code below"); _table[btos][i] = entry.entry(btos); + _table[ztos][i] = entry.entry(ztos); _table[ctos][i] = entry.entry(ctos); _table[stos][i] = entry.entry(stos); _table[atos][i] = entry.entry(atos); @@ -224,6 +228,7 @@ Interpreter::_trace_code = EntryPoint( generate_trace_code(btos), + generate_trace_code(ztos), generate_trace_code(ctos), generate_trace_code(stos), generate_trace_code(atos), @@ -243,6 +248,7 @@ generate_return_entry_for(itos, i), generate_return_entry_for(itos, i), generate_return_entry_for(itos, i), + generate_return_entry_for(itos, i), generate_return_entry_for(atos, i), generate_return_entry_for(itos, i), generate_return_entry_for(ltos, i), @@ -257,6 +263,7 @@ Interpreter::_earlyret_entry = EntryPoint( generate_earlyret_entry_for(btos), + generate_earlyret_entry_for(ztos), generate_earlyret_entry_for(ctos), generate_earlyret_entry_for(stos), generate_earlyret_entry_for(atos), @@ -275,6 +282,7 @@ generate_deopt_entry_for(itos, i), generate_deopt_entry_for(itos, i), generate_deopt_entry_for(itos, i), + generate_deopt_entry_for(itos, i), generate_deopt_entry_for(atos, i), generate_deopt_entry_for(itos, i), generate_deopt_entry_for(ltos, i), @@ -299,7 +307,7 @@ } for (int j = 0; j < number_of_states; j++) { - const TosState states[] = {btos, ctos, stos, itos, ltos, ftos, dtos, atos, vtos}; + const TosState states[] = {btos, ztos, ctos, stos, itos, ltos, ftos, dtos, atos, vtos}; int index = Interpreter::TosState_as_index(states[j]); Interpreter::_return_3_addrs_by_index[index] = Interpreter::return_entry(states[j], 3); Interpreter::_return_5_addrs_by_index[index] = Interpreter::return_entry(states[j], 5); @@ -309,6 +317,7 @@ Interpreter::_continuation_entry = EntryPoint( generate_continuation_for(btos), + generate_continuation_for(ztos), generate_continuation_for(ctos), generate_continuation_for(stos), generate_continuation_for(atos), @@ -324,6 +333,7 @@ Interpreter::_safept_entry = EntryPoint( generate_safept_entry_for(btos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)), + generate_safept_entry_for(ztos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)), generate_safept_entry_for(ctos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)), generate_safept_entry_for(stos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)), generate_safept_entry_for(atos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)), @@ -418,7 +428,7 @@ void TemplateInterpreterGenerator::set_unimplemented(int i) { address e = _unimplemented_bytecode; - EntryPoint entry(e, e, e, e, e, e, e, e, e); + EntryPoint entry(e, e, e, e, e, e, e, e, e, e); Interpreter::_normal_table.set_entry(i, entry); Interpreter::_wentry_point[i] = _unimplemented_bytecode; } @@ -430,6 +440,7 @@ assert(_unimplemented_bytecode != NULL, "should have been generated before"); assert(_illegal_bytecode_sequence != NULL, "should have been generated before"); address bep = _illegal_bytecode_sequence; + address zep = _illegal_bytecode_sequence; address cep = _illegal_bytecode_sequence; address sep = _illegal_bytecode_sequence; address aep = _illegal_bytecode_sequence; @@ -451,7 +462,7 @@ set_wide_entry_point(t, wep); } // set entry points - EntryPoint entry(bep, cep, sep, aep, iep, lep, fep, dep, vep); + EntryPoint entry(bep, zep, cep, sep, aep, iep, lep, fep, dep, vep); Interpreter::_normal_table.set_entry(code, entry); Interpreter::_wentry_point[code] = wep; } @@ -468,6 +479,7 @@ assert(t->is_valid(), "template must exist"); switch (t->tos_in()) { case btos: + case ztos: case ctos: case stos: ShouldNotReachHere(); // btos/ctos/stos should use itos. diff -r fe4bbf70da7e -r 320a3e1b7325 src/share/vm/interpreter/templateInterpreter.hpp --- a/src/share/vm/interpreter/templateInterpreter.hpp Tue May 03 12:13:18 2016 +0100 +++ b/src/share/vm/interpreter/templateInterpreter.hpp Tue May 03 12:41:07 2016 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -44,7 +44,7 @@ public: // Construction EntryPoint(); - EntryPoint(address bentry, address centry, address sentry, address aentry, address ientry, address lentry, address fentry, address dentry, address ventry); + EntryPoint(address bentry, address zentry, address centry, address sentry, address aentry, address ientry, address lentry, address fentry, address dentry, address ventry); // Attributes address entry(TosState state) const; // return target address for a given tosca state diff -r fe4bbf70da7e -r 320a3e1b7325 src/share/vm/interpreter/templateTable.cpp --- a/src/share/vm/interpreter/templateTable.cpp Tue May 03 12:13:18 2016 +0100 +++ b/src/share/vm/interpreter/templateTable.cpp Tue May 03 12:41:07 2016 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -488,6 +488,7 @@ def(Bytecodes::_fast_aputfield , ubcp|____|____|____, atos, vtos, fast_storefield , atos ); def(Bytecodes::_fast_bputfield , ubcp|____|____|____, itos, vtos, fast_storefield , itos ); + def(Bytecodes::_fast_zputfield , ubcp|____|____|____, itos, vtos, fast_storefield , itos ); def(Bytecodes::_fast_cputfield , ubcp|____|____|____, itos, vtos, fast_storefield , itos ); def(Bytecodes::_fast_dputfield , ubcp|____|____|____, dtos, vtos, fast_storefield , dtos ); def(Bytecodes::_fast_fputfield , ubcp|____|____|____, ftos, vtos, fast_storefield , ftos ); diff -r fe4bbf70da7e -r 320a3e1b7325 src/share/vm/interpreter/templateTable.hpp --- a/src/share/vm/interpreter/templateTable.hpp Tue May 03 12:13:18 2016 +0100 +++ b/src/share/vm/interpreter/templateTable.hpp Tue May 03 12:41:07 2016 +0100 @@ -28,11 +28,8 @@ #include "interpreter/bytecodes.hpp" #include "memory/allocation.hpp" #include "runtime/frame.hpp" -#ifdef TARGET_ARCH_MODEL_x86_32 -# include "interp_masm_x86_32.hpp" -#endif -#ifdef TARGET_ARCH_MODEL_x86_64 -# include "interp_masm_x86_64.hpp" +#ifdef TARGET_ARCH_x86 +# include "interp_masm_x86.hpp" #endif #ifdef TARGET_ARCH_MODEL_sparc # include "interp_masm_sparc.hpp" diff -r fe4bbf70da7e -r 320a3e1b7325 src/share/vm/oops/constMethodKlass.cpp --- a/src/share/vm/oops/constMethodKlass.cpp Tue May 03 12:13:18 2016 +0100 +++ b/src/share/vm/oops/constMethodKlass.cpp Tue May 03 12:41:07 2016 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -85,6 +85,7 @@ cm->set_exception_table(NULL); cm->set_code_size(byte_code_size); cm->set_constMethod_size(size); + cm->set_result_type(T_VOID); cm->set_inlined_tables_length(checked_exceptions_length, compressed_line_number_size, localvariable_table_length); diff -r fe4bbf70da7e -r 320a3e1b7325 src/share/vm/oops/constMethodOop.hpp --- a/src/share/vm/oops/constMethodOop.hpp Tue May 03 12:13:18 2016 +0100 +++ b/src/share/vm/oops/constMethodOop.hpp Tue May 03 12:41:07 2016 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -139,6 +139,7 @@ int _constMethod_size; jbyte _interpreter_kind; jbyte _flags; + u1 _result_type; // BasicType of result // Size of Java bytecodes allocated immediately after methodOop. u2 _code_size; @@ -280,6 +281,10 @@ // interpreter support static ByteSize exception_table_offset() { return byte_offset_of(constMethodOopDesc, _exception_table); } + static ByteSize result_type_offset() + { return byte_offset_of(constMethodOopDesc, _result_type); } + void set_result_type(BasicType rt) { assert(rt < 16, "result type too large"); + _result_type = (u1)rt; } // Garbage collection support oop* adr_method() const { return (oop*)&_method; } diff -r fe4bbf70da7e -r 320a3e1b7325 src/share/vm/oops/cpCacheOop.hpp --- a/src/share/vm/oops/cpCacheOop.hpp Tue May 03 12:13:18 2016 +0100 +++ b/src/share/vm/oops/cpCacheOop.hpp Tue May 03 12:41:07 2016 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -71,18 +71,19 @@ // bit 24: m flag true if invokeinterface used for method in class Object // bit 23: 0 for fields, 1 for methods // -// The flags 31, 30, 29, 28 together build a 4 bit number 0 to 8 with the +// The flags 31, 30, 29, 28 together build a 4 bit number 0 to 16 with the // following mapping to the TosState states: // // btos: 0 -// ctos: 1 -// stos: 2 -// itos: 3 -// ltos: 4 -// ftos: 5 -// dtos: 6 -// atos: 7 -// vtos: 8 +// ztos: 1 +// ctos: 2 +// stos: 3 +// itos: 4 +// ltos: 5 +// ftos: 6 +// dtos: 7 +// atos: 8 +// vtos: 9 // // Entry specific: field entries: // _indices = get (b1 section) and put (b2 section) bytecodes, original constant pool index @@ -257,14 +258,8 @@ bool is_vfinal() const { return ((_flags & (1 << vfinalMethod)) == (1 << vfinalMethod)); } bool is_volatile() const { return ((_flags & (1 << volatileField)) == (1 << volatileField)); } bool is_methodInterface() const { return ((_flags & (1 << methodInterface)) == (1 << methodInterface)); } - bool is_byte() const { return (((uintx) _flags >> tosBits) == btos); } - bool is_char() const { return (((uintx) _flags >> tosBits) == ctos); } - bool is_short() const { return (((uintx) _flags >> tosBits) == stos); } - bool is_int() const { return (((uintx) _flags >> tosBits) == itos); } bool is_long() const { return (((uintx) _flags >> tosBits) == ltos); } - bool is_float() const { return (((uintx) _flags >> tosBits) == ftos); } bool is_double() const { return (((uintx) _flags >> tosBits) == dtos); } - bool is_object() const { return (((uintx) _flags >> tosBits) == atos); } TosState flag_state() const { assert( ( (_flags >> tosBits) & 0x0F ) < number_of_states, "Invalid state in as_flags"); return (TosState)((_flags >> tosBits) & 0x0F); } diff -r fe4bbf70da7e -r 320a3e1b7325 src/share/vm/oops/klass.hpp --- a/src/share/vm/oops/klass.hpp Tue May 03 12:13:18 2016 +0100 +++ b/src/share/vm/oops/klass.hpp Tue May 03 12:41:07 2016 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -437,6 +437,21 @@ assert(btvalue >= T_BOOLEAN && btvalue <= T_OBJECT, "sanity"); return (BasicType) btvalue; } + + // Want a pattern to quickly diff against layout header in register + // find something less clever! + static int layout_helper_boolean_diffbit() { + jint zlh = array_layout_helper(T_BOOLEAN); + jint blh = array_layout_helper(T_BYTE); + assert(zlh != blh, "array layout helpers must differ"); + int diffbit = 1; + while ((diffbit & (zlh ^ blh)) == 0 && (diffbit & zlh) == 0) { + diffbit <<= 1; + assert(diffbit != 0, "make sure T_BOOLEAN has a different bit than T_BYTE"); + } + return diffbit; + } + static int layout_helper_log2_element_size(jint lh) { assert(lh < (jint)_lh_neutral_value, "must be array"); int l2esz = (lh >> _lh_log2_element_size_shift) & _lh_log2_element_size_mask; diff -r fe4bbf70da7e -r 320a3e1b7325 src/share/vm/oops/oop.inline.hpp --- a/src/share/vm/oops/oop.inline.hpp Tue May 03 12:13:18 2016 +0100 +++ b/src/share/vm/oops/oop.inline.hpp Tue May 03 12:41:07 2016 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -345,7 +345,7 @@ inline void oopDesc::byte_field_put(int offset, jbyte contents) { *byte_field_addr(offset) = (jint) contents; } inline jboolean oopDesc::bool_field(int offset) const { return (jboolean) *bool_field_addr(offset); } -inline void oopDesc::bool_field_put(int offset, jboolean contents) { *bool_field_addr(offset) = (jint) contents; } +inline void oopDesc::bool_field_put(int offset, jboolean contents) { *bool_field_addr(offset) = (( (jint) contents) & 1); } inline jchar oopDesc::char_field(int offset) const { return (jchar) *char_field_addr(offset); } inline void oopDesc::char_field_put(int offset, jchar contents) { *char_field_addr(offset) = (jint) contents; } @@ -385,7 +385,7 @@ inline void oopDesc::release_byte_field_put(int offset, jbyte contents) { OrderAccess::release_store(byte_field_addr(offset), contents); } inline jboolean oopDesc::bool_field_acquire(int offset) const { return OrderAccess::load_acquire(bool_field_addr(offset)); } -inline void oopDesc::release_bool_field_put(int offset, jboolean contents) { OrderAccess::release_store(bool_field_addr(offset), contents); } +inline void oopDesc::release_bool_field_put(int offset, jboolean contents) { OrderAccess::release_store(bool_field_addr(offset), (contents & 1)); } inline jchar oopDesc::char_field_acquire(int offset) const { return OrderAccess::load_acquire(char_field_addr(offset)); } inline void oopDesc::release_char_field_put(int offset, jchar contents) { OrderAccess::release_store(char_field_addr(offset), contents); } diff -r fe4bbf70da7e -r 320a3e1b7325 src/share/vm/opto/memnode.cpp --- a/src/share/vm/opto/memnode.cpp Tue May 03 12:13:18 2016 +0100 +++ b/src/share/vm/opto/memnode.cpp Tue May 03 12:41:07 2016 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -2214,7 +2214,7 @@ ctl != NULL, "raw memory operations should have control edge"); switch (bt) { - case T_BOOLEAN: + case T_BOOLEAN: val = gvn.transform(new (C) AndINode(val, gvn.intcon(0x1))); // Fall through to T_BYTE case case T_BYTE: return new (C) StoreBNode(ctl, mem, adr, adr_type, val); case T_INT: return new (C) StoreINode(ctl, mem, adr, adr_type, val); case T_CHAR: diff -r fe4bbf70da7e -r 320a3e1b7325 src/share/vm/opto/parse1.cpp --- a/src/share/vm/opto/parse1.cpp Tue May 03 12:13:18 2016 +0100 +++ b/src/share/vm/opto/parse1.cpp Tue May 03 12:41:07 2016 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -706,6 +706,27 @@ #endif } +static Node* mask_int_value(Node* v, BasicType bt, PhaseGVN* gvn) { + Compile* C = gvn->C; + switch (bt) { + case T_BYTE: + v = gvn->transform(new (C) LShiftINode(v, gvn->intcon(24))); + v = gvn->transform(new (C) RShiftINode(v, gvn->intcon(24))); + break; + case T_SHORT: + v = gvn->transform(new (C) LShiftINode(v, gvn->intcon(16))); + v = gvn->transform(new (C) RShiftINode(v, gvn->intcon(16))); + break; + case T_CHAR: + v = gvn->transform(new (C) AndINode(v, gvn->intcon(0xFFFF))); + break; + case T_BOOLEAN: + v = gvn->transform(new (C) AndINode(v, gvn->intcon(0x1))); + break; + } + return v; +} + //-------------------------------build_exits---------------------------------- // Build normal and exceptional exit merge points. void Parse::build_exits() { @@ -728,6 +749,16 @@ // Add a return value to the exit state. (Do not push it yet.) if (tf()->range()->cnt() > TypeFunc::Parms) { const Type* ret_type = tf()->range()->field_at(TypeFunc::Parms); + if (ret_type->isa_int()) { + BasicType ret_bt = method()->return_type()->basic_type(); + if (ret_bt == T_BOOLEAN || + ret_bt == T_CHAR || + ret_bt == T_BYTE || + ret_bt == T_SHORT) { + ret_type = TypeInt::INT; + } + } + // Don't "bind" an unloaded return klass to the ret_phi. If the klass // becomes loaded during the subsequent parsing, the loaded and unloaded // types will not join when we transform and push in do_exits(). @@ -934,6 +965,10 @@ const Type* ret_type = tf()->range()->field_at(TypeFunc::Parms); Node* ret_phi = _gvn.transform( _exits.argument(0) ); assert(_exits.control()->is_top() || !_gvn.type(ret_phi)->empty(), "return value must be well defined"); + if (ret_type->isa_int()) { + BasicType ret_bt = method()->return_type()->basic_type(); + ret_phi = mask_int_value(ret_phi, ret_bt, &_gvn); + } _exits.push_node(ret_type->basic_type(), ret_phi); } diff -r fe4bbf70da7e -r 320a3e1b7325 src/share/vm/opto/parse2.cpp --- a/src/share/vm/opto/parse2.cpp Tue May 03 12:13:18 2016 +0100 +++ b/src/share/vm/opto/parse2.cpp Tue May 03 12:41:07 2016 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -57,11 +57,15 @@ //--------------------------------array_store---------------------------------- void Parse::array_store(BasicType elem_type) { - Node* adr = array_addressing(elem_type, 1); + const Type* elem = Type::TOP; + Node* adr = array_addressing(elem_type, 1, &elem); if (stopped()) return; // guaranteed null or range check Node* val = pop(); _sp -= 2; // Pop array and index const TypeAryPtr* adr_type = TypeAryPtr::get_array_body_type(elem_type); + if (elem == TypeInt::BOOL) { + elem_type = T_BOOLEAN; + } store_to_memory(control(), adr, val, elem_type, adr_type); } diff -r fe4bbf70da7e -r 320a3e1b7325 src/share/vm/opto/type.cpp --- a/src/share/vm/opto/type.cpp Tue May 03 12:13:18 2016 +0100 +++ b/src/share/vm/opto/type.cpp Tue May 03 12:41:07 2016 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -1657,13 +1657,15 @@ break; case T_OBJECT: case T_ARRAY: + case T_FLOAT: + case T_INT: + field_array[pos++] = get_const_type(type); + break; case T_BOOLEAN: case T_CHAR: - case T_FLOAT: case T_BYTE: case T_SHORT: - case T_INT: - field_array[pos++] = get_const_type(type); + field_array[pos++] = TypeInt::INT; break; default: ShouldNotReachHere(); diff -r fe4bbf70da7e -r 320a3e1b7325 src/share/vm/prims/jni.cpp --- a/src/share/vm/prims/jni.cpp Tue May 03 12:13:18 2016 +0100 +++ b/src/share/vm/prims/jni.cpp Tue May 03 12:41:07 2016 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -2869,6 +2869,7 @@ field_value.unionType = value; \ o = JvmtiExport::jni_SetField_probe_nh(thread, obj, o, k, fieldID, false, SigType, (jvalue *)&field_value); \ } \ + if (SigType == 'Z') { value = ((jboolean)value) & 1; } \ o->Fieldname##_field_put(offset, value); \ ReturnProbe; \ JNI_END @@ -3174,6 +3175,7 @@ field_value.unionType = value; \ JvmtiExport::jni_SetField_probe(thread, NULL, NULL, id->holder(), fieldID, true, SigType, (jvalue *)&field_value); \ } \ + if (SigType == 'Z') { value = ((jboolean)value) & 1; } \ id->holder()->java_mirror()-> Fieldname##_field_put (id->offset(), value); \ ReturnProbe;\ JNI_END diff -r fe4bbf70da7e -r 320a3e1b7325 src/share/vm/prims/jvmtiEnvBase.cpp --- a/src/share/vm/prims/jvmtiEnvBase.cpp Tue May 03 12:13:18 2016 +0100 +++ b/src/share/vm/prims/jvmtiEnvBase.cpp Tue May 03 12:41:07 2016 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -1349,7 +1349,7 @@ ResultTypeFinder rtf(signature); TosState fr_tos = as_TosState(rtf.type()); if (fr_tos != tos) { - if (tos != itos || (fr_tos != btos && fr_tos != ctos && fr_tos != stos)) { + if (tos != itos || (fr_tos != btos && fr_tos != ztos && fr_tos != ctos && fr_tos != stos)) { return JVMTI_ERROR_TYPE_MISMATCH; } } diff -r fe4bbf70da7e -r 320a3e1b7325 src/share/vm/prims/jvmtiExport.cpp --- a/src/share/vm/prims/jvmtiExport.cpp Tue May 03 12:13:18 2016 +0100 +++ b/src/share/vm/prims/jvmtiExport.cpp Tue May 03 12:41:07 2016 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -1575,7 +1575,7 @@ address location, KlassHandle field_klass, Handle object, jfieldID field, char sig_type, jvalue *value) { - if (sig_type == 'I' || sig_type == 'Z' || sig_type == 'C' || sig_type == 'S') { + if (sig_type == 'I' || sig_type == 'Z' || sig_type == 'B' || sig_type == 'C' || sig_type == 'S') { // 'I' instructions are used for byte, char, short and int. // determine which it really is, and convert fieldDescriptor fd; diff -r fe4bbf70da7e -r 320a3e1b7325 src/share/vm/prims/unsafe.cpp --- a/src/share/vm/prims/unsafe.cpp Tue May 03 12:13:18 2016 +0100 +++ b/src/share/vm/prims/unsafe.cpp Tue May 03 12:41:07 2016 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -150,13 +150,22 @@ ///// Data in the Java heap. +#define truncate_jboolean(x) ((x) & 1) +#define truncate_jbyte(x) (x) +#define truncate_jshort(x) (x) +#define truncate_jchar(x) (x) +#define truncate_jint(x) (x) +#define truncate_jlong(x) (x) +#define truncate_jfloat(x) (x) +#define truncate_jdouble(x) (x) + #define GET_FIELD(obj, offset, type_name, v) \ oop p = JNIHandles::resolve(obj); \ type_name v = *(type_name*)index_oop_from_field_offset_long(p, offset) #define SET_FIELD(obj, offset, type_name, x) \ oop p = JNIHandles::resolve(obj); \ - *(type_name*)index_oop_from_field_offset_long(p, offset) = x + *(type_name*)index_oop_from_field_offset_long(p, offset) = truncate_##type_name(x) #define GET_FIELD_VOLATILE(obj, offset, type_name, v) \ oop p = JNIHandles::resolve(obj); \ @@ -164,7 +173,7 @@ #define SET_FIELD_VOLATILE(obj, offset, type_name, x) \ oop p = JNIHandles::resolve(obj); \ - OrderAccess::release_store_fence((volatile type_name*)index_oop_from_field_offset_long(p, offset), x); + OrderAccess::release_store_fence((volatile type_name*)index_oop_from_field_offset_long(p, offset), truncate_##type_name(x)); // Macros for oops that check UseCompressedOops diff -r fe4bbf70da7e -r 320a3e1b7325 src/share/vm/runtime/reflection.cpp --- a/src/share/vm/runtime/reflection.cpp Tue May 03 12:13:18 2016 +0100 +++ b/src/share/vm/runtime/reflection.cpp Tue May 03 12:41:07 2016 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -1048,7 +1048,7 @@ void Reflection::narrow(jvalue* value, BasicType narrow_type, TRAPS) { switch (narrow_type) { case T_BOOLEAN: - value->z = (jboolean) value->i; + value->z = (jboolean) (value->i & 1); return; case T_BYTE: value->b = (jbyte) value->i; diff -r fe4bbf70da7e -r 320a3e1b7325 src/share/vm/utilities/globalDefinitions.hpp --- a/src/share/vm/utilities/globalDefinitions.hpp Tue May 03 12:13:18 2016 +0100 +++ b/src/share/vm/utilities/globalDefinitions.hpp Tue May 03 12:41:07 2016 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -648,14 +648,15 @@ enum TosState { // describes the tos cache contents btos = 0, // byte, bool tos cached - ctos = 1, // char tos cached - stos = 2, // short tos cached - itos = 3, // int tos cached - ltos = 4, // long tos cached - ftos = 5, // float tos cached - dtos = 6, // double tos cached - atos = 7, // object cached - vtos = 8, // tos not cached + ztos = 1, // byte, bool tos cached + ctos = 2, // char tos cached + stos = 3, // short tos cached + itos = 4, // int tos cached + ltos = 5, // long tos cached + ftos = 6, // float tos cached + dtos = 7, // double tos cached + atos = 8, // object cached + vtos = 9, // tos not cached number_of_states, ilgl // illegal state: should not occur }; @@ -664,7 +665,7 @@ inline TosState as_TosState(BasicType type) { switch (type) { case T_BYTE : return btos; - case T_BOOLEAN: return btos; // FIXME: Add ztos + case T_BOOLEAN: return ztos; case T_CHAR : return ctos; case T_SHORT : return stos; case T_INT : return itos; @@ -681,8 +682,8 @@ inline BasicType as_BasicType(TosState state) { switch (state) { - //case ztos: return T_BOOLEAN;//FIXME case btos : return T_BYTE; + case ztos : return T_BOOLEAN; case ctos : return T_CHAR; case stos : return T_SHORT; case itos : return T_INT;