Mon, 25 Apr 2016 21:03:53 +0000
Merge
src/share/vm/opto/compile.cpp | file | annotate | diff | comparison | revisions |
1.1 --- a/.hgtags Thu Apr 21 16:19:33 2016 +0300 1.2 +++ b/.hgtags Mon Apr 25 21:03:53 2016 +0000 1.3 @@ -670,6 +670,7 @@ 1.4 20bad8c6c7b406c3603b4e22b15cd990840a9d62 jdk8u51-b31 1.5 e51afd2a1fc17de59ff3c79003210a40a28ac960 jdk8u51-b32 1.6 b2427357cc98aeb2716ee2e89e733794afb4057b jdk8u51-b33 1.7 +4b722db6d38583ee3e71c43d9996bf1ebb8a412e jdk8u51-b34 1.8 d9349fa8822336e0244da0a8448f3e6b2d62741d jdk8u60-b00 1.9 d9349fa8822336e0244da0a8448f3e6b2d62741d hs25.60-b00 1.10 ebf89088c08ab0508b9002b48dd3d68a340259af hs25.60-b01 1.11 @@ -763,6 +764,11 @@ 1.12 a6f2a7ba281291f5dab79fa494f7cfaa6232c88b jdk8u66-b17 1.13 9ae2a5adabba97d9ebf79e13b325f1ff368ce014 jdk8u66-b18 1.14 527f62b70faee4a0c15f365def024b87012e6934 jdk8u66-b31 1.15 +d8be40462cfb6de441818aec8c30e03077189010 jdk8u66-b32 1.16 +6a0b19c56d797c2975f0cf505190e8f5d69b0b7a jdk8u66-b33 1.17 +3d55b1055c782375e39ebbddba2887379bc3531c jdk8u66-b34 1.18 +95b0e04287fb443a4eee64504e0f18bc324c7abd jdk8u66-b35 1.19 +dce99debdba26def128cd8b2d3eae93d7d789ee2 jdk8u66-b36 1.20 9a158a0c243beb610dbaabd63d6218d3ce5825f1 jdk8u71-b00 1.21 67df26e363fb7e722032fd286673642fc999957c jdk8u71-b01 1.22 1a799d49de23d84f658ade1d3805a1924e7e1e84 jdk8u71-b02 1.23 @@ -801,6 +807,26 @@ 1.24 451dda77f6c29bd3260e87f847a9eadae122a759 jdk8u74-b00 1.25 c1031a924f2c910fad078838b88a2f0146f2de98 jdk8u74-b01 1.26 ca9cae9aa9e989bbe6713c91d55c913edeaecce4 jdk8u74-b02 1.27 +da43260704c28b9f19cb652090ae65c258220fd6 jdk8u72-b31 1.28 +c0242ea4bde19d72be5149feda112a39e8c89b0a jdk8u75-b00 1.29 +ca3b8c8e390ab0540b0cc2e5def869b38e460d86 jdk8u75-b01 1.30 +9aef5b5e0a68f20059cfa9e2806b4ff0e11a3d31 jdk8u75-b02 1.31 +2df9fe896819362b9075a670b78106b249e50d6d jdk8u75-b03 1.32 +32b682649973231b54740c09b10889660f6ebde5 jdk8u75-b04 1.33 +1f43bd4fab06d2ca5d1964611df14d8506d6b36e jdk8u75-b05 1.34 +916712f178c39d0acbc590f38802133fc86a7346 jdk8u75-b06 1.35 +8c791dd1c24d85ebd18b03d49185c2a25263c129 jdk8u75-b07 1.36 +e4a935cb6f7178912fd653e2a9514eadec7935ab jdk8u75-b08 1.37 +e97c45c377eb8d022cfe24b73737fa312107e0a5 jdk8u75-b09 1.38 +d44c7e324682a30e064503ef9582d83a41f4173e jdk8u75-b10 1.39 +cc78c97abff85062d6844fa253081e26a0a60150 jdk8u75-b12 1.40 +1b6d4fd2730e58f17820930f797938dc182117c4 jdk8u77-b00 1.41 +ddd297e340b1170d3cec011ee64e729f8b493c86 jdk8u77-b01 1.42 +1b4072e4bb3ad54c4e894998486a8b33f0689160 jdk8u77-b02 1.43 +223b64a19e94222dd97b92bb40abcfbc0bf6ef1f jdk8u77-b03 1.44 +bbbb05e91c629f8d9eef2ba43933767f68a898b0 jdk8u91-b00 1.45 +e36b6ade0499eadfd8673fe62ef0a613af2e6d67 jdk8u91-b13 1.46 +fa8991ccf6e5b74890a0b5672440b3c09d8d8732 jdk8u91-b14 1.47 1b6d4fd2730e58f17820930f797938dc182117c4 jdk8u77-b00 1.48 ddd297e340b1170d3cec011ee64e729f8b493c86 jdk8u77-b01 1.49 1b4072e4bb3ad54c4e894998486a8b33f0689160 jdk8u77-b02 1.50 @@ -810,7 +836,19 @@ 1.51 218483967e52b419d885d34af4488a81c5133804 jdk8u76-b02 1.52 2a2720daacaa8d9a3ba9435cfaaf9751241d2062 jdk8u76-b03 1.53 16f7b676725aadafb79ea105b22df112e2593a78 jdk8u76-b04 1.54 +35bfaf7f9021b5c1e86effbeac075753a82e9a0c jdk8u76-b05 1.55 +6449ee3bf707225372709ac830524c00984c601f jdk8u76-b06 1.56 +7d1074c74d6000ec8257917ebfcee3fed4249f7d jdk8u76-b07 1.57 +392f8722fc513e28f78c5c563d51af7dc8466b29 jdk8u76-b08 1.58 +3bf0f5b8a892defd0bf9731b4e15926881fcda74 jdk8u76-b09 1.59 +a2b0ee820059a44be558a2d435b7d85ed5a8b63a jdk8u76-b10 1.60 +16aa1f621ec67db1a55ebf6527750164ab63088d jdk8u76-b11 1.61 +9a87701e22b3cae79fdfd8cdb732051e02a710fa jdk8u76-b12 1.62 +481dcde745b6aec035781ed9f6797cfc93719f71 jdk8u92-b00 1.63 +f3e1e734e2d29101a9537ddeb71ecad413fcd352 jdk8u92-b13 1.64 +24a09407d71bb2cc4848bfa21660c890b4d722b1 jdk8u92-b14 1.65 d6c92b9e192ef97305a699e868387d55821c81ad jdk8u102-b00 1.66 d6c92b9e192ef97305a699e868387d55821c81ad jdk8u82-b00 1.67 516a64e6d7c2dc29fd932bf3b8313e560a01bcd0 jdk8u102-b01 1.68 83dc7e55f71596e6e76fabfa56b6008e070ff44c jdk8u102-b02 1.69 +ef01a1634bb41dd5b36fc9824f8d35f745c6bd5a jdk8u102-b03
2.1 --- a/agent/src/share/classes/sun/jvm/hotspot/interpreter/Bytecodes.java Thu Apr 21 16:19:33 2016 +0300 2.2 +++ b/agent/src/share/classes/sun/jvm/hotspot/interpreter/Bytecodes.java Mon Apr 25 21:03:53 2016 +0000 2.3 @@ -1,5 +1,5 @@ 2.4 /* 2.5 - * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved. 2.6 + * Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved. 2.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 2.8 * 2.9 * This code is free software; you can redistribute it and/or modify it 2.10 @@ -253,29 +253,30 @@ 2.11 public static final int _fast_sgetfield = 210; 2.12 public static final int _fast_aputfield = 211; 2.13 public static final int _fast_bputfield = 212; 2.14 - public static final int _fast_cputfield = 213; 2.15 - public static final int _fast_dputfield = 214; 2.16 - public static final int _fast_fputfield = 215; 2.17 - public static final int _fast_iputfield = 216; 2.18 - public static final int _fast_lputfield = 217; 2.19 - public static final int _fast_sputfield = 218; 2.20 - public static final int _fast_aload_0 = 219; 2.21 - public static final int _fast_iaccess_0 = 220; 2.22 - public static final int _fast_aaccess_0 = 221; 2.23 - public static final int _fast_faccess_0 = 222; 2.24 - public static final int _fast_iload = 223; 2.25 - public static final int _fast_iload2 = 224; 2.26 - public static final int _fast_icaload = 225; 2.27 - public static final int _fast_invokevfinal = 226; 2.28 - public static final int _fast_linearswitch = 227; 2.29 - public static final int _fast_binaryswitch = 228; 2.30 - public static final int _fast_aldc = 229; 2.31 - public static final int _fast_aldc_w = 230; 2.32 - public static final int _return_register_finalizer = 231; 2.33 - public static final int _invokehandle = 232; 2.34 - public static final int _shouldnotreachhere = 233; // For debugging 2.35 + public static final int _fast_zputfield = 213; 2.36 + public static final int _fast_cputfield = 214; 2.37 + public static final int _fast_dputfield = 215; 2.38 + public static final int _fast_fputfield = 216; 2.39 + public static final int _fast_iputfield = 217; 2.40 + public static final int _fast_lputfield = 218; 2.41 + public static final int _fast_sputfield = 219; 2.42 + public static final int _fast_aload_0 = 220; 2.43 + public static final int _fast_iaccess_0 = 221; 2.44 + public static final int _fast_aaccess_0 = 222; 2.45 + public static final int _fast_faccess_0 = 223; 2.46 + public static final int _fast_iload = 224; 2.47 + public static final int _fast_iload2 = 225; 2.48 + public static final int _fast_icaload = 226; 2.49 + public static final int _fast_invokevfinal = 227; 2.50 + public static final int _fast_linearswitch = 228; 2.51 + public static final int _fast_binaryswitch = 229; 2.52 + public static final int _fast_aldc = 230; 2.53 + public static final int _fast_aldc_w = 231; 2.54 + public static final int _return_register_finalizer = 232; 2.55 + public static final int _invokehandle = 233; 2.56 + public static final int _shouldnotreachhere = 234; // For debugging 2.57 2.58 - public static final int number_of_codes = 234; 2.59 + public static final int number_of_codes = 235; 2.60 2.61 // Flag bits derived from format strings, can_trap, can_rewrite, etc.: 2.62 // semantic flags: 2.63 @@ -776,6 +777,7 @@ 2.64 2.65 def(_fast_aputfield , "fast_aputfield" , "bJJ" , null , BasicType.getTObject() , 0, true , _putfield ); 2.66 def(_fast_bputfield , "fast_bputfield" , "bJJ" , null , BasicType.getTInt() , 0, true , _putfield ); 2.67 + def(_fast_zputfield , "fast_zputfield" , "bJJ" , null , BasicType.getTInt() , 0, true , _putfield ); 2.68 def(_fast_cputfield , "fast_cputfield" , "bJJ" , null , BasicType.getTChar() , 0, true , _putfield ); 2.69 def(_fast_dputfield , "fast_dputfield" , "bJJ" , null , BasicType.getTDouble() , 0, true , _putfield ); 2.70 def(_fast_fputfield , "fast_fputfield" , "bJJ" , null , BasicType.getTFloat() , 0, true , _putfield );
3.1 --- a/src/cpu/ppc/vm/interp_masm_ppc_64.cpp Thu Apr 21 16:19:33 2016 +0300 3.2 +++ b/src/cpu/ppc/vm/interp_masm_ppc_64.cpp Mon Apr 25 21:03:53 2016 +0000 3.3 @@ -174,6 +174,7 @@ 3.4 case ltos: ld(R17_tos, in_bytes(JvmtiThreadState::earlyret_value_offset()), RjvmtiState); 3.5 break; 3.6 case btos: // fall through 3.7 + case ztos: // fall through 3.8 case ctos: // fall through 3.9 case stos: // fall through 3.10 case itos: lwz(R17_tos, in_bytes(JvmtiThreadState::earlyret_value_offset()), RjvmtiState); 3.11 @@ -302,6 +303,7 @@ 3.12 switch (state) { 3.13 case atos: push_ptr(); break; 3.14 case btos: 3.15 + case ztos: 3.16 case ctos: 3.17 case stos: 3.18 case itos: push_i(); break; 3.19 @@ -317,6 +319,7 @@ 3.20 switch (state) { 3.21 case atos: pop_ptr(); break; 3.22 case btos: 3.23 + case ztos: 3.24 case ctos: 3.25 case stos: 3.26 case itos: pop_i(); break; 3.27 @@ -751,6 +754,43 @@ 3.28 stdux(Rscratch2, R1_SP, Rscratch1); // atomically set *(SP = top_frame_sp) = **SP 3.29 } 3.30 3.31 +void InterpreterMacroAssembler::narrow(Register result) { 3.32 + Register ret_type = R11_scratch1; 3.33 + ld(R11_scratch1, in_bytes(Method::const_offset()), R19_method); 3.34 + lbz(ret_type, in_bytes(ConstMethod::result_type_offset()), R11_scratch1); 3.35 + 3.36 + Label notBool, notByte, notChar, done; 3.37 + 3.38 + // common case first 3.39 + cmpwi(CCR0, ret_type, T_INT); 3.40 + beq(CCR0, done); 3.41 + 3.42 + cmpwi(CCR0, ret_type, T_BOOLEAN); 3.43 + bne(CCR0, notBool); 3.44 + andi(result, result, 0x1); 3.45 + b(done); 3.46 + 3.47 + bind(notBool); 3.48 + cmpwi(CCR0, ret_type, T_BYTE); 3.49 + bne(CCR0, notByte); 3.50 + extsb(result, result); 3.51 + b(done); 3.52 + 3.53 + bind(notByte); 3.54 + cmpwi(CCR0, ret_type, T_CHAR); 3.55 + bne(CCR0, notChar); 3.56 + andi(result, result, 0xffff); 3.57 + b(done); 3.58 + 3.59 + bind(notChar); 3.60 + // cmpwi(CCR0, ret_type, T_SHORT); // all that's left 3.61 + // bne(CCR0, done); 3.62 + extsh(result, result); 3.63 + 3.64 + // Nothing to do for T_INT 3.65 + bind(done); 3.66 +} 3.67 + 3.68 // Remove activation. 3.69 // 3.70 // Unlock the receiver if this is a synchronized method.
4.1 --- a/src/cpu/ppc/vm/interp_masm_ppc_64.hpp Thu Apr 21 16:19:33 2016 +0300 4.2 +++ b/src/cpu/ppc/vm/interp_masm_ppc_64.hpp Mon Apr 25 21:03:53 2016 +0000 4.3 @@ -149,6 +149,8 @@ 4.4 void get_cpool_and_tags(Register Rcpool, Register Rtags); 4.5 void is_a(Label& L); 4.6 4.7 + void narrow(Register result); 4.8 + 4.9 // Java Call Helpers 4.10 void call_from_interpreter(Register Rtarget_method, Register Rret_addr, Register Rscratch1, Register Rscratch2); 4.11
5.1 --- a/src/cpu/ppc/vm/interpreter_ppc.cpp Thu Apr 21 16:19:33 2016 +0300 5.2 +++ b/src/cpu/ppc/vm/interpreter_ppc.cpp Mon Apr 25 21:03:53 2016 +0000 5.3 @@ -640,6 +640,16 @@ 5.4 __ blr(); 5.5 } 5.6 5.7 + if (branch_table[ztos] == 0) { // generate only once 5.8 + __ align(32, 28, 28); // align load 5.9 + __ fence(); // volatile entry point (one instruction before non-volatile_entry point) 5.10 + branch_table[ztos] = __ pc(); // non-volatile_entry point 5.11 + __ lbzx(R3_RET, Rclass_or_obj, Roffset); 5.12 + __ extsb(R3_RET, R3_RET); 5.13 + __ beq(CCR6, Lacquire); 5.14 + __ blr(); 5.15 + } 5.16 + 5.17 if (branch_table[ctos] == 0) { // generate only once 5.18 __ align(32, 28, 28); // align load 5.19 __ fence(); // volatile entry point (one instruction before non-volatile_entry point)
6.1 --- a/src/cpu/ppc/vm/templateInterpreter_ppc.cpp Thu Apr 21 16:19:33 2016 +0300 6.2 +++ b/src/cpu/ppc/vm/templateInterpreter_ppc.cpp Mon Apr 25 21:03:53 2016 +0000 6.3 @@ -154,6 +154,7 @@ 6.4 switch (state) { 6.5 case ltos: 6.6 case btos: 6.7 + case ztos: 6.8 case ctos: 6.9 case stos: 6.10 case atos: 6.11 @@ -200,6 +201,7 @@ 6.12 switch (state) { 6.13 case ltos: 6.14 case btos: 6.15 + case ztos: 6.16 case ctos: 6.17 case stos: 6.18 case atos: 6.19 @@ -1642,12 +1644,14 @@ 6.20 // Copied from TemplateTable::_return. 6.21 // Restoration of lr done by remove_activation. 6.22 switch (state) { 6.23 + // Narrow result if state is itos but result type is smaller. 6.24 + case itos: __ narrow(R17_tos); /* fall through */ 6.25 case ltos: 6.26 case btos: 6.27 + case ztos: 6.28 case ctos: 6.29 case stos: 6.30 - case atos: 6.31 - case itos: __ mr(R3_RET, R17_tos); break; 6.32 + case atos: __ mr(R3_RET, R17_tos); break; 6.33 case ftos: 6.34 case dtos: __ fmr(F1_RET, F15_ftos); break; 6.35 case vtos: // This might be a constructor. Final fields (and volatile fields on PPC64) need 6.36 @@ -1717,6 +1721,10 @@ 6.37 bname = "trace_code_btos {"; 6.38 tsize = 2; 6.39 break; 6.40 + case ztos: 6.41 + bname = "trace_code_ztos {"; 6.42 + tsize = 2; 6.43 + break; 6.44 case ctos: 6.45 bname = "trace_code_ctos {"; 6.46 tsize = 2;
7.1 --- a/src/cpu/ppc/vm/templateTable_ppc_64.cpp Thu Apr 21 16:19:33 2016 +0300 7.2 +++ b/src/cpu/ppc/vm/templateTable_ppc_64.cpp Mon Apr 25 21:03:53 2016 +0000 7.3 @@ -173,6 +173,7 @@ 7.4 switch (new_bc) { 7.5 case Bytecodes::_fast_aputfield: 7.6 case Bytecodes::_fast_bputfield: 7.7 + case Bytecodes::_fast_zputfield: 7.8 case Bytecodes::_fast_cputfield: 7.9 case Bytecodes::_fast_dputfield: 7.10 case Bytecodes::_fast_fputfield: 7.11 @@ -969,9 +970,21 @@ 7.12 Rarray = R12_scratch2, 7.13 Rscratch = R3_ARG1; 7.14 __ pop_i(Rindex); 7.15 + __ pop_ptr(Rarray); 7.16 // tos: val 7.17 - // Rarray: array ptr (popped by index_check) 7.18 - __ index_check(Rarray, Rindex, 0, Rscratch, Rarray); 7.19 + 7.20 + // Need to check whether array is boolean or byte 7.21 + // since both types share the bastore bytecode. 7.22 + __ load_klass(Rscratch, Rarray); 7.23 + __ lwz(Rscratch, in_bytes(Klass::layout_helper_offset()), Rscratch); 7.24 + int diffbit = exact_log2(Klass::layout_helper_boolean_diffbit()); 7.25 + __ testbitdi(CCR0, R0, Rscratch, diffbit); 7.26 + Label L_skip; 7.27 + __ bfalse(CCR0, L_skip); 7.28 + __ andi(R17_tos, R17_tos, 1); // if it is a T_BOOLEAN array, mask the stored value to 0/1 7.29 + __ bind(L_skip); 7.30 + 7.31 + __ index_check_without_pop(Rarray, Rindex, 0, Rscratch, Rarray); 7.32 __ stb(R17_tos, arrayOopDesc::base_offset_in_bytes(T_BYTE), Rarray); 7.33 } 7.34 7.35 @@ -2100,12 +2113,16 @@ 7.36 __ remove_activation(state, /* throw_monitor_exception */ true); 7.37 // Restoration of lr done by remove_activation. 7.38 switch (state) { 7.39 + // Narrow result if state is itos but result type is smaller. 7.40 + // Need to narrow in the return bytecode rather than in generate_return_entry 7.41 + // since compiled code callers expect the result to already be narrowed. 7.42 + case itos: __ narrow(R17_tos); /* fall through */ 7.43 case ltos: 7.44 case btos: 7.45 + case ztos: 7.46 case ctos: 7.47 case stos: 7.48 - case atos: 7.49 - case itos: __ mr(R3_RET, R17_tos); break; 7.50 + case atos: __ mr(R3_RET, R17_tos); break; 7.51 case ftos: 7.52 case dtos: __ fmr(F1_RET, F15_ftos); break; 7.53 case vtos: // This might be a constructor. Final fields (and volatile fields on PPC64) need 7.54 @@ -2501,6 +2518,21 @@ 7.55 __ dispatch_epilog(vtos, Bytecodes::length_for(bytecode())); 7.56 7.57 __ align(32, 28, 28); // Align load. 7.58 + // __ bind(Lztos); (same code as btos) 7.59 + __ fence(); // Volatile entry point (one instruction before non-volatile_entry point). 7.60 + assert(branch_table[ztos] == 0, "can't compute twice"); 7.61 + branch_table[ztos] = __ pc(); // non-volatile_entry point 7.62 + __ lbzx(R17_tos, Rclass_or_obj, Roffset); 7.63 + __ extsb(R17_tos, R17_tos); 7.64 + __ push(ztos); 7.65 + if (!is_static) { 7.66 + // use btos rewriting, no truncating to t/f bit is needed for getfield. 7.67 + patch_bytecode(Bytecodes::_fast_bgetfield, Rbc, Rscratch); 7.68 + } 7.69 + __ beq(CCR6, Lacquire); // Volatile? 7.70 + __ dispatch_epilog(vtos, Bytecodes::length_for(bytecode())); 7.71 + 7.72 + __ align(32, 28, 28); // Align load. 7.73 // __ bind(Lctos); 7.74 __ fence(); // Volatile entry point (one instruction before non-volatile_entry point). 7.75 assert(branch_table[ctos] == 0, "can't compute twice"); 7.76 @@ -2590,6 +2622,7 @@ 7.77 case Bytecodes::_fast_aputfield: __ push_ptr(); offs+= Interpreter::stackElementSize; break; 7.78 case Bytecodes::_fast_iputfield: // Fall through 7.79 case Bytecodes::_fast_bputfield: // Fall through 7.80 + case Bytecodes::_fast_zputfield: // Fall through 7.81 case Bytecodes::_fast_cputfield: // Fall through 7.82 case Bytecodes::_fast_sputfield: __ push_i(); offs+= Interpreter::stackElementSize; break; 7.83 case Bytecodes::_fast_lputfield: __ push_l(); offs+=2*Interpreter::stackElementSize; break; 7.84 @@ -2630,6 +2663,7 @@ 7.85 case Bytecodes::_fast_aputfield: __ pop_ptr(); break; 7.86 case Bytecodes::_fast_iputfield: // Fall through 7.87 case Bytecodes::_fast_bputfield: // Fall through 7.88 + case Bytecodes::_fast_zputfield: // Fall through 7.89 case Bytecodes::_fast_cputfield: // Fall through 7.90 case Bytecodes::_fast_sputfield: __ pop_i(); break; 7.91 case Bytecodes::_fast_lputfield: __ pop_l(); break; 7.92 @@ -2781,6 +2815,21 @@ 7.93 __ dispatch_epilog(vtos, Bytecodes::length_for(bytecode())); 7.94 7.95 __ align(32, 28, 28); // Align pop. 7.96 + // __ bind(Lztos); 7.97 + __ release(); // Volatile entry point (one instruction before non-volatile_entry point). 7.98 + assert(branch_table[ztos] == 0, "can't compute twice"); 7.99 + branch_table[ztos] = __ pc(); // non-volatile_entry point 7.100 + __ pop(ztos); 7.101 + if (!is_static) { pop_and_check_object(Rclass_or_obj); } // Kills R11_scratch1. 7.102 + __ andi(R17_tos, R17_tos, 0x1); 7.103 + __ stbx(R17_tos, Rclass_or_obj, Roffset); 7.104 + if (!is_static) { patch_bytecode(Bytecodes::_fast_zputfield, Rbc, Rscratch, true, byte_no); } 7.105 + if (!support_IRIW_for_not_multiple_copy_atomic_cpu) { 7.106 + __ beq(CR_is_vol, Lvolatile); // Volatile? 7.107 + } 7.108 + __ dispatch_epilog(vtos, Bytecodes::length_for(bytecode())); 7.109 + 7.110 + __ align(32, 28, 28); // Align pop. 7.111 // __ bind(Lctos); 7.112 __ release(); // Volatile entry point (one instruction before non-volatile_entry point). 7.113 assert(branch_table[ctos] == 0, "can't compute twice"); 7.114 @@ -2895,6 +2944,9 @@ 7.115 __ stdx(R17_tos, Rclass_or_obj, Roffset); 7.116 break; 7.117 7.118 + case Bytecodes::_fast_zputfield: 7.119 + __ andi(R17_tos, R17_tos, 0x1); // boolean is true if LSB is 1 7.120 + // fall through to bputfield 7.121 case Bytecodes::_fast_bputfield: 7.122 __ stbx(R17_tos, Rclass_or_obj, Roffset); 7.123 break;
8.1 --- a/src/cpu/sparc/vm/c1_LIRGenerator_sparc.cpp Thu Apr 21 16:19:33 2016 +0300 8.2 +++ b/src/cpu/sparc/vm/c1_LIRGenerator_sparc.cpp Mon Apr 25 21:03:53 2016 +0000 8.3 @@ -1,5 +1,5 @@ 8.4 /* 8.5 - * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved. 8.6 + * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved. 8.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 8.8 * 8.9 * This code is free software; you can redistribute it and/or modify it 8.10 @@ -343,7 +343,7 @@ 8.11 length.set_instruction(x->length()); 8.12 length.load_item(); 8.13 } 8.14 - if (needs_store_check) { 8.15 + if (needs_store_check || x->check_boolean()) { 8.16 value.load_item(); 8.17 } else { 8.18 value.load_for_store(x->elt_type()); 8.19 @@ -388,7 +388,8 @@ 8.20 pre_barrier(LIR_OprFact::address(array_addr), LIR_OprFact::illegalOpr /* pre_val */, 8.21 true /* do_load */, false /* patch */, NULL); 8.22 } 8.23 - __ move(value.result(), array_addr, null_check_info); 8.24 + LIR_Opr result = maybe_mask_boolean(x, array.result(), value.result(), null_check_info); 8.25 + __ move(result, array_addr, null_check_info); 8.26 if (obj_store) { 8.27 // Precise card mark 8.28 post_barrier(LIR_OprFact::address(array_addr), value.result());
9.1 --- a/src/cpu/sparc/vm/cppInterpreter_sparc.cpp Thu Apr 21 16:19:33 2016 +0300 9.2 +++ b/src/cpu/sparc/vm/cppInterpreter_sparc.cpp Mon Apr 25 21:03:53 2016 +0000 9.3 @@ -1,5 +1,5 @@ 9.4 /* 9.5 - * Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved. 9.6 + * Copyright (c) 2007, 2016, Oracle and/or its affiliates. All rights reserved. 9.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 9.8 * 9.9 * This code is free software; you can redistribute it and/or modify it 9.10 @@ -539,6 +539,9 @@ 9.11 __ cmp(G1_scratch, btos); 9.12 __ br(Assembler::equal, true, Assembler::pt, xreturn_path); 9.13 __ delayed()->ldsb(Otos_i, G3_scratch, Otos_i); 9.14 + __ cmp(G1_scratch, ztos); 9.15 + __ br(Assembler::equal, true, Assembler::pt, xreturn_path); 9.16 + __ delayed()->ldsb(Otos_i, G3_scratch, Otos_i); 9.17 __ should_not_reach_here(); 9.18 #endif 9.19 __ ldsb(Otos_i, G3_scratch, Otos_i);
10.1 --- a/src/cpu/sparc/vm/interp_masm_sparc.cpp Thu Apr 21 16:19:33 2016 +0300 10.2 +++ b/src/cpu/sparc/vm/interp_masm_sparc.cpp Mon Apr 25 21:03:53 2016 +0000 10.3 @@ -1,5 +1,5 @@ 10.4 /* 10.5 - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. 10.6 + * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. 10.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 10.8 * 10.9 * This code is free software; you can redistribute it and/or modify it 10.10 @@ -211,6 +211,7 @@ 10.11 case atos: ld_ptr(oop_addr, Otos_l); 10.12 st_ptr(G0, oop_addr); break; 10.13 case btos: // fall through 10.14 + case ztos: // fall through 10.15 case ctos: // fall through 10.16 case stos: // fall through 10.17 case itos: ld(val_addr, Otos_l1); break; 10.18 @@ -459,9 +460,10 @@ 10.19 interp_verify_oop(Otos_i, state, __FILE__, __LINE__); 10.20 switch (state) { 10.21 case atos: push_ptr(); break; 10.22 - case btos: push_i(); break; 10.23 - case ctos: 10.24 - case stos: push_i(); break; 10.25 + case btos: // fall through 10.26 + case ztos: // fall through 10.27 + case ctos: // fall through 10.28 + case stos: // fall through 10.29 case itos: push_i(); break; 10.30 case ltos: push_l(); break; 10.31 case ftos: push_f(); break; 10.32 @@ -475,9 +477,10 @@ 10.33 void InterpreterMacroAssembler::pop(TosState state) { 10.34 switch (state) { 10.35 case atos: pop_ptr(); break; 10.36 - case btos: pop_i(); break; 10.37 - case ctos: 10.38 - case stos: pop_i(); break; 10.39 + case btos: // fall through 10.40 + case ztos: // fall through 10.41 + case ctos: // fall through 10.42 + case stos: // fall through 10.43 case itos: pop_i(); break; 10.44 case ltos: pop_l(); break; 10.45 case ftos: pop_f(); break; 10.46 @@ -1111,6 +1114,49 @@ 10.47 interp_verify_oop(Otos_i, state, __FILE__, __LINE__); 10.48 } 10.49 10.50 +void InterpreterMacroAssembler::narrow(Register result) { 10.51 + 10.52 + ld_ptr(Address(Lmethod, Method::const_offset()), G3_scratch); 10.53 + ldub(G3_scratch, in_bytes(ConstMethod::result_type_offset()), G3_scratch); 10.54 + 10.55 + Label notBool, notByte, notChar, done; 10.56 + 10.57 + // common case first 10.58 + cmp(G3_scratch, T_INT); 10.59 + br(Assembler::equal, true, pn, done); 10.60 + delayed()->nop(); 10.61 + 10.62 + cmp(G3_scratch, T_BOOLEAN); 10.63 + br(Assembler::notEqual, true, pn, notBool); 10.64 + delayed()->cmp(G3_scratch, T_BYTE); 10.65 + and3(result, 1, result); 10.66 + ba(done); 10.67 + delayed()->nop(); 10.68 + 10.69 + bind(notBool); 10.70 + // cmp(G3_scratch, T_BYTE); 10.71 + br(Assembler::notEqual, true, pn, notByte); 10.72 + delayed()->cmp(G3_scratch, T_CHAR); 10.73 + sll(result, 24, result); 10.74 + sra(result, 24, result); 10.75 + ba(done); 10.76 + delayed()->nop(); 10.77 + 10.78 + bind(notByte); 10.79 + // cmp(G3_scratch, T_CHAR); 10.80 + sll(result, 16, result); 10.81 + br(Assembler::notEqual, true, pn, done); 10.82 + delayed()->sra(result, 16, result); 10.83 + // sll(result, 16, result); 10.84 + srl(result, 16, result); 10.85 + 10.86 + // bind(notChar); 10.87 + // must be short, instructions already executed in delay slot 10.88 + // sll(result, 16, result); 10.89 + // sra(result, 16, result); 10.90 + 10.91 + bind(done); 10.92 +} 10.93 10.94 // remove activation 10.95 // 10.96 @@ -1146,6 +1192,7 @@ 10.97 case ltos: mov(Otos_l2, Otos_l2->after_save()); // fall through // O1 -> I1 10.98 #endif 10.99 case btos: // fall through 10.100 + case ztos: // fall through 10.101 case ctos: 10.102 case stos: // fall through 10.103 case atos: // fall through
11.1 --- a/src/cpu/sparc/vm/interp_masm_sparc.hpp Thu Apr 21 16:19:33 2016 +0300 11.2 +++ b/src/cpu/sparc/vm/interp_masm_sparc.hpp Mon Apr 25 21:03:53 2016 +0000 11.3 @@ -1,5 +1,5 @@ 11.4 /* 11.5 - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. 11.6 + * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. 11.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 11.8 * 11.9 * This code is free software; you can redistribute it and/or modify it 11.10 @@ -105,6 +105,8 @@ 11.11 void dispatch_via (TosState state, address* table); 11.12 11.13 11.14 + void narrow(Register result); 11.15 + 11.16 // Removes the current activation (incl. unlocking of monitors). 11.17 // Additionally this code is used for earlyReturn in which case we 11.18 // want to skip throwing an exception and installing an exception.
12.1 --- a/src/cpu/sparc/vm/templateInterpreter_sparc.cpp Thu Apr 21 16:19:33 2016 +0300 12.2 +++ b/src/cpu/sparc/vm/templateInterpreter_sparc.cpp Mon Apr 25 21:03:53 2016 +0000 12.3 @@ -1,5 +1,5 @@ 12.4 /* 12.5 - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. 12.6 + * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. 12.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 12.8 * 12.9 * This code is free software; you can redistribute it and/or modify it 12.10 @@ -711,6 +711,9 @@ 12.11 __ cmp(G1_scratch, btos); 12.12 __ br(Assembler::equal, true, Assembler::pt, xreturn_path); 12.13 __ delayed()->ldsb(Otos_i, G3_scratch, Otos_i); 12.14 + __ cmp(G1_scratch, ztos); 12.15 + __ br(Assembler::equal, true, Assembler::pt, xreturn_path); 12.16 + __ delayed()->ldsb(Otos_i, G3_scratch, Otos_i); 12.17 __ should_not_reach_here(); 12.18 #endif 12.19 __ ldsb(Otos_i, G3_scratch, Otos_i);
13.1 --- a/src/cpu/sparc/vm/templateTable_sparc.cpp Thu Apr 21 16:19:33 2016 +0300 13.2 +++ b/src/cpu/sparc/vm/templateTable_sparc.cpp Mon Apr 25 21:03:53 2016 +0000 13.3 @@ -1,5 +1,5 @@ 13.4 /* 13.5 - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. 13.6 + * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. 13.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 13.8 * 13.9 * This code is free software; you can redistribute it and/or modify it 13.10 @@ -167,6 +167,7 @@ 13.11 switch (bc) { 13.12 case Bytecodes::_fast_aputfield: 13.13 case Bytecodes::_fast_bputfield: 13.14 + case Bytecodes::_fast_zputfield: 13.15 case Bytecodes::_fast_cputfield: 13.16 case Bytecodes::_fast_dputfield: 13.17 case Bytecodes::_fast_fputfield: 13.18 @@ -913,8 +914,20 @@ 13.19 transition(itos, vtos); 13.20 __ pop_i(O2); // index 13.21 // Otos_i: val 13.22 + // O2: index 13.23 // O3: array 13.24 __ index_check(O3, O2, 0, G3_scratch, O2); 13.25 + // Need to check whether array is boolean or byte 13.26 + // since both types share the bastore bytecode. 13.27 + __ load_klass(O3, G4_scratch); 13.28 + __ ld(G4_scratch, in_bytes(Klass::layout_helper_offset()), G4_scratch); 13.29 + __ set(Klass::layout_helper_boolean_diffbit(), G3_scratch); 13.30 + __ andcc(G3_scratch, G4_scratch, G0); 13.31 + Label L_skip; 13.32 + __ br(Assembler::zero, false, Assembler::pn, L_skip); 13.33 + __ delayed()->nop(); 13.34 + __ and3(Otos_i, 1, Otos_i); // if it is a T_BOOLEAN array, mask the stored value to 0/1 13.35 + __ bind(L_skip); 13.36 __ stb(Otos_i, O2, arrayOopDesc::base_offset_in_bytes(T_BYTE)); 13.37 } 13.38 13.39 @@ -1997,6 +2010,12 @@ 13.40 __ bind(skip_register_finalizer); 13.41 } 13.42 13.43 + // Narrow result if state is itos but result type is smaller. 13.44 + // Need to narrow in the return bytecode rather than in generate_return_entry 13.45 + // since compiled code callers expect the result to already be narrowed. 13.46 + if (state == itos) { 13.47 + __ narrow(Otos_i); 13.48 + } 13.49 __ remove_activation(state, /* throw_monitor_exception */ true); 13.50 13.51 // The caller's SP was adjusted upon method entry to accomodate 13.52 @@ -2216,7 +2235,7 @@ 13.53 Label checkVolatile; 13.54 13.55 // compute field type 13.56 - Label notByte, notInt, notShort, notChar, notLong, notFloat, notObj; 13.57 + Label notByte, notBool, notInt, notShort, notChar, notLong, notFloat, notObj; 13.58 __ srl(Rflags, ConstantPoolCacheEntry::tos_state_shift, Rflags); 13.59 // Make sure we don't need to mask Rflags after the above shift 13.60 ConstantPoolCacheEntry::verify_tos_state_shift(); 13.61 @@ -2271,7 +2290,7 @@ 13.62 13.63 // cmp(Rflags, btos); 13.64 __ br(Assembler::notEqual, false, Assembler::pt, notByte); 13.65 - __ delayed() ->cmp(Rflags, ctos); 13.66 + __ delayed() ->cmp(Rflags, ztos); 13.67 13.68 // btos 13.69 __ ldsb(Rclass, Roffset, Otos_i); 13.70 @@ -2284,6 +2303,22 @@ 13.71 13.72 __ bind(notByte); 13.73 13.74 + // cmp(Rflags, ztos); 13.75 + __ br(Assembler::notEqual, false, Assembler::pt, notBool); 13.76 + __ delayed() ->cmp(Rflags, ctos); 13.77 + 13.78 + // ztos 13.79 + __ ldsb(Rclass, Roffset, Otos_i); 13.80 + __ push(itos); 13.81 + if (!is_static) { 13.82 + // use btos rewriting, no truncating to t/f bit is needed for getfield. 13.83 + patch_bytecode(Bytecodes::_fast_bgetfield, G3_scratch, G4_scratch); 13.84 + } 13.85 + __ ba(checkVolatile); 13.86 + __ delayed()->tst(Lscratch); 13.87 + 13.88 + __ bind(notBool); 13.89 + 13.90 // cmp(Rflags, ctos); 13.91 __ br(Assembler::notEqual, false, Assembler::pt, notChar); 13.92 __ delayed() ->cmp(Rflags, stos); 13.93 @@ -2445,6 +2480,7 @@ 13.94 switch (bytecode()) { // save tos values before call_VM() clobbers them 13.95 case Bytecodes::_fast_aputfield: __ push_ptr(Otos_i); break; 13.96 case Bytecodes::_fast_bputfield: // fall through 13.97 + case Bytecodes::_fast_zputfield: // fall through 13.98 case Bytecodes::_fast_sputfield: // fall through 13.99 case Bytecodes::_fast_cputfield: // fall through 13.100 case Bytecodes::_fast_iputfield: __ push_i(Otos_i); break; 13.101 @@ -2462,6 +2498,7 @@ 13.102 switch (bytecode()) { // restore tos values 13.103 case Bytecodes::_fast_aputfield: __ pop_ptr(Otos_i); break; 13.104 case Bytecodes::_fast_bputfield: // fall through 13.105 + case Bytecodes::_fast_zputfield: // fall through 13.106 case Bytecodes::_fast_sputfield: // fall through 13.107 case Bytecodes::_fast_cputfield: // fall through 13.108 case Bytecodes::_fast_iputfield: __ pop_i(Otos_i); break; 13.109 @@ -2577,7 +2614,7 @@ 13.110 ConstantPoolCacheEntry::verify_tos_state_shift(); 13.111 13.112 // compute field type 13.113 - Label notInt, notShort, notChar, notObj, notByte, notLong, notFloat; 13.114 + Label notInt, notShort, notChar, notObj, notByte, notBool, notLong, notFloat; 13.115 13.116 if (is_static) { 13.117 // putstatic with object type most likely, check that first 13.118 @@ -2645,7 +2682,7 @@ 13.119 13.120 // cmp(Rflags, btos); 13.121 __ br(Assembler::notEqual, false, Assembler::pt, notByte); 13.122 - __ delayed()->cmp(Rflags, ltos); 13.123 + __ delayed()->cmp(Rflags, ztos); 13.124 13.125 // btos 13.126 { 13.127 @@ -2660,6 +2697,25 @@ 13.128 } 13.129 13.130 __ bind(notByte); 13.131 + 13.132 + // cmp(Rflags, btos); 13.133 + __ br(Assembler::notEqual, false, Assembler::pt, notBool); 13.134 + __ delayed()->cmp(Rflags, ltos); 13.135 + 13.136 + // ztos 13.137 + { 13.138 + __ pop_i(); 13.139 + if (!is_static) pop_and_check_object(Rclass); 13.140 + __ and3(Otos_i, 1, Otos_i); 13.141 + __ stb(Otos_i, Rclass, Roffset); 13.142 + if (!is_static) { 13.143 + patch_bytecode(Bytecodes::_fast_zputfield, G3_scratch, G4_scratch, true, byte_no); 13.144 + } 13.145 + __ ba(checkVolatile); 13.146 + __ delayed()->tst(Lscratch); 13.147 + } 13.148 + 13.149 + __ bind(notBool); 13.150 // cmp(Rflags, ltos); 13.151 __ br(Assembler::notEqual, false, Assembler::pt, notLong); 13.152 __ delayed()->cmp(Rflags, ctos); 13.153 @@ -2783,6 +2839,7 @@ 13.154 pop_and_check_object(Rclass); 13.155 13.156 switch (bytecode()) { 13.157 + case Bytecodes::_fast_zputfield: __ and3(Otos_i, 1, Otos_i); // fall through to bputfield 13.158 case Bytecodes::_fast_bputfield: __ stb(Otos_i, Rclass, Roffset); break; 13.159 case Bytecodes::_fast_cputfield: /* fall through */ 13.160 case Bytecodes::_fast_sputfield: __ sth(Otos_i, Rclass, Roffset); break;
14.1 --- a/src/cpu/x86/vm/c1_LIRGenerator_x86.cpp Thu Apr 21 16:19:33 2016 +0300 14.2 +++ b/src/cpu/x86/vm/c1_LIRGenerator_x86.cpp Mon Apr 25 21:03:53 2016 +0000 14.3 @@ -1,5 +1,5 @@ 14.4 /* 14.5 - * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved. 14.6 + * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved. 14.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 14.8 * 14.9 * This code is free software; you can redistribute it and/or modify it 14.10 @@ -283,7 +283,7 @@ 14.11 length.load_item(); 14.12 14.13 } 14.14 - if (needs_store_check) { 14.15 + if (needs_store_check || x->check_boolean()) { 14.16 value.load_item(); 14.17 } else { 14.18 value.load_for_store(x->elt_type()); 14.19 @@ -331,7 +331,8 @@ 14.20 // Seems to be a precise 14.21 post_barrier(LIR_OprFact::address(array_addr), value.result()); 14.22 } else { 14.23 - __ move(value.result(), array_addr, null_check_info); 14.24 + LIR_Opr result = maybe_mask_boolean(x, array.result(), value.result(), null_check_info); 14.25 + __ move(result, array_addr, null_check_info); 14.26 } 14.27 } 14.28
15.1 --- a/src/cpu/x86/vm/cppInterpreter_x86.cpp Thu Apr 21 16:19:33 2016 +0300 15.2 +++ b/src/cpu/x86/vm/cppInterpreter_x86.cpp Mon Apr 25 21:03:53 2016 +0000 15.3 @@ -1,5 +1,5 @@ 15.4 /* 15.5 - * Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved. 15.6 + * Copyright (c) 2007, 2016, Oracle and/or its affiliates. All rights reserved. 15.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 15.8 * 15.9 * This code is free software; you can redistribute it and/or modify it 15.10 @@ -870,7 +870,7 @@ 15.11 rdx, 15.12 Address::times_ptr, ConstantPoolCache::base_offset() + ConstantPoolCacheEntry::flags_offset())); 15.13 15.14 - Label notByte, notShort, notChar; 15.15 + Label notByte, notBool, notShort, notChar; 15.16 const Address field_address (rax, rcx, Address::times_1); 15.17 15.18 // Need to differentiate between igetfield, agetfield, bgetfield etc. 15.19 @@ -889,6 +889,11 @@ 15.20 15.21 __ bind(notObj); 15.22 #endif // _LP64 15.23 + __ cmpl(rdx, ztos); 15.24 + __ jcc(Assembler::notEqual, notBool); 15.25 + __ load_signed_byte(rax, field_address); 15.26 + __ jmp(xreturn_path); 15.27 + 15.28 __ cmpl(rdx, btos); 15.29 __ jcc(Assembler::notEqual, notByte); 15.30 __ load_signed_byte(rax, field_address);
16.1 --- a/src/cpu/x86/vm/interp_masm_x86.cpp Thu Apr 21 16:19:33 2016 +0300 16.2 +++ b/src/cpu/x86/vm/interp_masm_x86.cpp Mon Apr 25 21:03:53 2016 +0000 16.3 @@ -1,5 +1,5 @@ 16.4 /* 16.5 - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. 16.6 + * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. 16.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 16.8 * 16.9 * This code is free software; you can redistribute it and/or modify it 16.10 @@ -27,6 +27,54 @@ 16.11 #include "interpreter/interpreter.hpp" 16.12 #include "oops/methodData.hpp" 16.13 16.14 + 16.15 +// 8u does not have InterpreterMacroAssembler::load_earlyret_value here 16.16 + 16.17 +void InterpreterMacroAssembler::narrow(Register result) { 16.18 + 16.19 + // Get method->_constMethod->_result_type 16.20 + movptr(rcx, Address(rbp, frame::interpreter_frame_method_offset * wordSize)); 16.21 + movptr(rcx, Address(rcx, Method::const_offset())); 16.22 + load_unsigned_byte(rcx, Address(rcx, ConstMethod::result_type_offset())); 16.23 + 16.24 + Label done, notBool, notByte, notChar; 16.25 + 16.26 + // common case first 16.27 + cmpl(rcx, T_INT); 16.28 + jcc(Assembler::equal, done); 16.29 + 16.30 + // mask integer result to narrower return type. 16.31 + cmpl(rcx, T_BOOLEAN); 16.32 + jcc(Assembler::notEqual, notBool); 16.33 + andl(result, 0x1); 16.34 + jmp(done); 16.35 + 16.36 + bind(notBool); 16.37 + cmpl(rcx, T_BYTE); 16.38 + jcc(Assembler::notEqual, notByte); 16.39 + LP64_ONLY(movsbl(result, result);) 16.40 + NOT_LP64(shll(result, 24);) // truncate upper 24 bits 16.41 + NOT_LP64(sarl(result, 24);) // and sign-extend byte 16.42 + jmp(done); 16.43 + 16.44 + bind(notByte); 16.45 + cmpl(rcx, T_CHAR); 16.46 + jcc(Assembler::notEqual, notChar); 16.47 + LP64_ONLY(movzwl(result, result);) 16.48 + NOT_LP64(andl(result, 0xFFFF);) // truncate upper 16 bits 16.49 + jmp(done); 16.50 + 16.51 + bind(notChar); 16.52 + // cmpl(rcx, T_SHORT); // all that's left 16.53 + // jcc(Assembler::notEqual, done); 16.54 + LP64_ONLY(movswl(result, result);) 16.55 + NOT_LP64(shll(result, 16);) // truncate upper 16 bits 16.56 + NOT_LP64(sarl(result, 16);) // and sign-extend short 16.57 + 16.58 + // Nothing to do for T_INT 16.59 + bind(done); 16.60 +} 16.61 + 16.62 #ifndef CC_INTERP 16.63 void InterpreterMacroAssembler::profile_obj_type(Register obj, const Address& mdo_addr) { 16.64 Label update, next, none;
17.1 --- a/src/cpu/x86/vm/interp_masm_x86.hpp Thu Apr 21 16:19:33 2016 +0300 17.2 +++ b/src/cpu/x86/vm/interp_masm_x86.hpp Mon Apr 25 21:03:53 2016 +0000 17.3 @@ -1,5 +1,5 @@ 17.4 /* 17.5 - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. 17.6 + * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved. 17.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 17.8 * 17.9 * This code is free software; you can redistribute it and/or modify it 17.10 @@ -48,6 +48,9 @@ 17.11 Register _bcp_register; // register that contains the bcp 17.12 17.13 public: 17.14 + // narrow int return value 17.15 + void narrow(Register result); 17.16 + 17.17 #ifndef CC_INTERP 17.18 void profile_obj_type(Register obj, const Address& mdo_addr); 17.19 void profile_arguments_type(Register mdp, Register callee, Register tmp, bool is_virtual);
18.1 --- a/src/cpu/x86/vm/interp_masm_x86_32.cpp Thu Apr 21 16:19:33 2016 +0300 18.2 +++ b/src/cpu/x86/vm/interp_masm_x86_32.cpp Mon Apr 25 21:03:53 2016 +0000 18.3 @@ -1,5 +1,5 @@ 18.4 /* 18.5 - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. 18.6 + * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. 18.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 18.8 * 18.9 * This code is free software; you can redistribute it and/or modify it 18.10 @@ -151,6 +151,7 @@ 18.11 case ltos: 18.12 movl(rdx, val_addr1); // fall through 18.13 case btos: // fall through 18.14 + case ztos: // fall through 18.15 case ctos: // fall through 18.16 case stos: // fall through 18.17 case itos: movl(rax, val_addr); break; 18.18 @@ -362,6 +363,7 @@ 18.19 switch (state) { 18.20 case atos: pop_ptr(rax); break; 18.21 case btos: // fall through 18.22 + case ztos: // fall through 18.23 case ctos: // fall through 18.24 case stos: // fall through 18.25 case itos: pop_i(rax); break; 18.26 @@ -405,6 +407,7 @@ 18.27 switch (state) { 18.28 case atos: push_ptr(rax); break; 18.29 case btos: // fall through 18.30 + case ztos: // fall through 18.31 case ctos: // fall through 18.32 case stos: // fall through 18.33 case itos: push_i(rax); break;
19.1 --- a/src/cpu/x86/vm/interp_masm_x86_64.cpp Thu Apr 21 16:19:33 2016 +0300 19.2 +++ b/src/cpu/x86/vm/interp_masm_x86_64.cpp Mon Apr 25 21:03:53 2016 +0000 19.3 @@ -1,5 +1,5 @@ 19.4 /* 19.5 - * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. 19.6 + * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved. 19.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 19.8 * 19.9 * This code is free software; you can redistribute it and/or modify it 19.10 @@ -149,6 +149,7 @@ 19.11 verify_oop(rax, state); break; 19.12 case ltos: movptr(rax, val_addr); break; 19.13 case btos: // fall through 19.14 + case ztos: // fall through 19.15 case ctos: // fall through 19.16 case stos: // fall through 19.17 case itos: movl(rax, val_addr); break; 19.18 @@ -387,6 +388,7 @@ 19.19 switch (state) { 19.20 case atos: pop_ptr(); break; 19.21 case btos: 19.22 + case ztos: 19.23 case ctos: 19.24 case stos: 19.25 case itos: pop_i(); break; 19.26 @@ -404,6 +406,7 @@ 19.27 switch (state) { 19.28 case atos: push_ptr(); break; 19.29 case btos: 19.30 + case ztos: 19.31 case ctos: 19.32 case stos: 19.33 case itos: push_i(); break;
20.1 --- a/src/cpu/x86/vm/templateInterpreter_x86_32.cpp Thu Apr 21 16:19:33 2016 +0300 20.2 +++ b/src/cpu/x86/vm/templateInterpreter_x86_32.cpp Mon Apr 25 21:03:53 2016 +0000 20.3 @@ -1,5 +1,5 @@ 20.4 /* 20.5 - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. 20.6 + * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. 20.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 20.8 * 20.9 * This code is free software; you can redistribute it and/or modify it 20.10 @@ -713,7 +713,7 @@ 20.11 rdx, 20.12 Address::times_ptr, ConstantPoolCache::base_offset() + ConstantPoolCacheEntry::flags_offset())); 20.13 20.14 - Label notByte, notShort, notChar; 20.15 + Label notByte, notBool, notShort, notChar; 20.16 const Address field_address (rax, rcx, Address::times_1); 20.17 20.18 // Need to differentiate between igetfield, agetfield, bgetfield etc. 20.19 @@ -728,6 +728,12 @@ 20.20 __ jmp(xreturn_path); 20.21 20.22 __ bind(notByte); 20.23 + __ cmpl(rdx, ztos); 20.24 + __ jcc(Assembler::notEqual, notBool); 20.25 + __ load_signed_byte(rax, field_address); 20.26 + __ jmp(xreturn_path); 20.27 + 20.28 + __ bind(notBool); 20.29 __ cmpl(rdx, stos); 20.30 __ jcc(Assembler::notEqual, notShort); 20.31 __ load_signed_short(rax, field_address);
21.1 --- a/src/cpu/x86/vm/templateInterpreter_x86_64.cpp Thu Apr 21 16:19:33 2016 +0300 21.2 +++ b/src/cpu/x86/vm/templateInterpreter_x86_64.cpp Mon Apr 25 21:03:53 2016 +0000 21.3 @@ -1,5 +1,5 @@ 21.4 /* 21.5 - * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. 21.6 + * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved. 21.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 21.8 * 21.9 * This code is free software; you can redistribute it and/or modify it 21.10 @@ -680,7 +680,7 @@ 21.11 ConstantPoolCache::base_offset() + 21.12 ConstantPoolCacheEntry::flags_offset())); 21.13 21.14 - Label notObj, notInt, notByte, notShort; 21.15 + Label notObj, notInt, notByte, notBool, notShort; 21.16 const Address field_address(rax, rcx, Address::times_1); 21.17 21.18 // Need to differentiate between igetfield, agetfield, bgetfield etc. 21.19 @@ -711,6 +711,13 @@ 21.20 __ jmp(xreturn_path); 21.21 21.22 __ bind(notByte); 21.23 + __ cmpl(rdx, ztos); 21.24 + __ jcc(Assembler::notEqual, notBool); 21.25 + // ztos 21.26 + __ load_signed_byte(rax, field_address); 21.27 + __ jmp(xreturn_path); 21.28 + 21.29 + __ bind(notBool); 21.30 __ cmpl(rdx, stos); 21.31 __ jcc(Assembler::notEqual, notShort); 21.32 // stos
22.1 --- a/src/cpu/x86/vm/templateTable_x86_32.cpp Thu Apr 21 16:19:33 2016 +0300 22.2 +++ b/src/cpu/x86/vm/templateTable_x86_32.cpp Mon Apr 25 21:03:53 2016 +0000 22.3 @@ -1,5 +1,5 @@ 22.4 /* 22.5 - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. 22.6 + * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. 22.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 22.8 * 22.9 * This code is free software; you can redistribute it and/or modify it 22.10 @@ -212,6 +212,7 @@ 22.11 switch (bc) { 22.12 case Bytecodes::_fast_aputfield: 22.13 case Bytecodes::_fast_bputfield: 22.14 + case Bytecodes::_fast_zputfield: 22.15 case Bytecodes::_fast_cputfield: 22.16 case Bytecodes::_fast_dputfield: 22.17 case Bytecodes::_fast_fputfield: 22.18 @@ -988,11 +989,21 @@ 22.19 void TemplateTable::bastore() { 22.20 transition(itos, vtos); 22.21 __ pop_i(rbx); 22.22 - // rax,: value 22.23 + // rax: value 22.24 + // rbx: index 22.25 // rdx: array 22.26 - index_check(rdx, rbx); // prefer index in rbx, 22.27 - // rbx,: index 22.28 - __ movb(Address(rdx, rbx, Address::times_1, arrayOopDesc::base_offset_in_bytes(T_BYTE)), rax); 22.29 + index_check(rdx, rbx); // prefer index in rbx 22.30 + // Need to check whether array is boolean or byte 22.31 + // since both types share the bastore bytecode. 22.32 + __ load_klass(rcx, rdx); 22.33 + __ movl(rcx, Address(rcx, Klass::layout_helper_offset())); 22.34 + int diffbit = Klass::layout_helper_boolean_diffbit(); 22.35 + __ testl(rcx, diffbit); 22.36 + Label L_skip; 22.37 + __ jccb(Assembler::zero, L_skip); 22.38 + __ andl(rax, 1); // if it is a T_BOOLEAN array, mask the stored value to 0/1 22.39 + __ bind(L_skip); 22.40 + __ movb(Address(rdx, rbx, Address::times_1, arrayOopDesc::base_offset_in_bytes(T_BYTE)), rax); 22.41 } 22.42 22.43 22.44 @@ -2037,7 +2048,14 @@ 22.45 __ bind(skip_register_finalizer); 22.46 } 22.47 22.48 + // Narrow result if state is itos but result type is smaller. 22.49 + // Need to narrow in the return bytecode rather than in generate_return_entry 22.50 + // since compiled code callers expect the result to already be narrowed. 22.51 + if (state == itos) { 22.52 + __ narrow(rax); 22.53 + } 22.54 __ remove_activation(state, rsi); 22.55 + 22.56 __ jmp(rsi); 22.57 } 22.58 22.59 @@ -2234,7 +2252,7 @@ 22.60 const Address lo(obj, off, Address::times_1, 0*wordSize); 22.61 const Address hi(obj, off, Address::times_1, 1*wordSize); 22.62 22.63 - Label Done, notByte, notInt, notShort, notChar, notLong, notFloat, notObj, notDouble; 22.64 + Label Done, notByte, notBool, notInt, notShort, notChar, notLong, notFloat, notObj, notDouble; 22.65 22.66 __ shrl(flags, ConstantPoolCacheEntry::tos_state_shift); 22.67 assert(btos == 0, "change code, btos != 0"); 22.68 @@ -2251,6 +2269,22 @@ 22.69 __ jmp(Done); 22.70 22.71 __ bind(notByte); 22.72 + 22.73 + __ cmpl(flags, ztos); 22.74 + __ jcc(Assembler::notEqual, notBool); 22.75 + 22.76 + // ztos (same code as btos) 22.77 + __ load_signed_byte(rax, lo); 22.78 + __ push(ztos); 22.79 + // Rewrite bytecode to be faster 22.80 + if (!is_static) { 22.81 + // use btos rewriting, no truncating to t/f bit is needed for getfield. 22.82 + patch_bytecode(Bytecodes::_fast_bgetfield, rcx, rbx); 22.83 + } 22.84 + __ jmp(Done); 22.85 + 22.86 + __ bind(notBool); 22.87 + 22.88 // itos 22.89 __ cmpl(flags, itos ); 22.90 __ jcc(Assembler::notEqual, notInt); 22.91 @@ -2450,7 +2484,7 @@ 22.92 const Address lo(obj, off, Address::times_1, 0*wordSize); 22.93 const Address hi(obj, off, Address::times_1, 1*wordSize); 22.94 22.95 - Label notByte, notInt, notShort, notChar, notLong, notFloat, notObj, notDouble; 22.96 + Label notByte, notBool, notInt, notShort, notChar, notLong, notFloat, notObj, notDouble; 22.97 22.98 __ shrl(flags, ConstantPoolCacheEntry::tos_state_shift); 22.99 assert(btos == 0, "change code, btos != 0"); 22.100 @@ -2469,6 +2503,22 @@ 22.101 } 22.102 22.103 __ bind(notByte); 22.104 + __ cmpl(flags, ztos); 22.105 + __ jcc(Assembler::notEqual, notBool); 22.106 + 22.107 + // ztos 22.108 + { 22.109 + __ pop(ztos); 22.110 + if (!is_static) pop_and_check_object(obj); 22.111 + __ andl(rax, 0x1); 22.112 + __ movb(lo, rax); 22.113 + if (!is_static) { 22.114 + patch_bytecode(Bytecodes::_fast_zputfield, rcx, rbx, true, byte_no); 22.115 + } 22.116 + __ jmp(Done); 22.117 + } 22.118 + 22.119 + __ bind(notBool); 22.120 __ cmpl(flags, itos); 22.121 __ jcc(Assembler::notEqual, notInt); 22.122 22.123 @@ -2640,6 +2690,7 @@ 22.124 switch (bytecode()) { // load values into the jvalue object 22.125 case Bytecodes::_fast_aputfield: __ push_ptr(rax); break; 22.126 case Bytecodes::_fast_bputfield: // fall through 22.127 + case Bytecodes::_fast_zputfield: // fall through 22.128 case Bytecodes::_fast_sputfield: // fall through 22.129 case Bytecodes::_fast_cputfield: // fall through 22.130 case Bytecodes::_fast_iputfield: __ push_i(rax); break; 22.131 @@ -2662,6 +2713,7 @@ 22.132 switch (bytecode()) { // restore tos values 22.133 case Bytecodes::_fast_aputfield: __ pop_ptr(rax); break; 22.134 case Bytecodes::_fast_bputfield: // fall through 22.135 + case Bytecodes::_fast_zputfield: // fall through 22.136 case Bytecodes::_fast_sputfield: // fall through 22.137 case Bytecodes::_fast_cputfield: // fall through 22.138 case Bytecodes::_fast_iputfield: __ pop_i(rax); break; 22.139 @@ -2712,6 +2764,8 @@ 22.140 22.141 // access field 22.142 switch (bytecode()) { 22.143 + case Bytecodes::_fast_zputfield: __ andl(rax, 0x1); // boolean is true if LSB is 1 22.144 + // fall through to bputfield 22.145 case Bytecodes::_fast_bputfield: __ movb(lo, rax); break; 22.146 case Bytecodes::_fast_sputfield: // fall through 22.147 case Bytecodes::_fast_cputfield: __ movw(lo, rax); break; 22.148 @@ -2746,6 +2800,8 @@ 22.149 22.150 // access field 22.151 switch (bytecode()) { 22.152 + case Bytecodes::_fast_zputfield: __ andl(rax, 0x1); // boolean is true if LSB is 1 22.153 + // fall through to bputfield 22.154 case Bytecodes::_fast_bputfield: __ movb(lo, rax); break; 22.155 case Bytecodes::_fast_sputfield: // fall through 22.156 case Bytecodes::_fast_cputfield: __ movw(lo, rax); break;
23.1 --- a/src/cpu/x86/vm/templateTable_x86_64.cpp Thu Apr 21 16:19:33 2016 +0300 23.2 +++ b/src/cpu/x86/vm/templateTable_x86_64.cpp Mon Apr 25 21:03:53 2016 +0000 23.3 @@ -1,5 +1,5 @@ 23.4 /* 23.5 - * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. 23.6 + * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved. 23.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 23.8 * 23.9 * This code is free software; you can redistribute it and/or modify it 23.10 @@ -219,6 +219,7 @@ 23.11 switch (bc) { 23.12 case Bytecodes::_fast_aputfield: 23.13 case Bytecodes::_fast_bputfield: 23.14 + case Bytecodes::_fast_zputfield: 23.15 case Bytecodes::_fast_cputfield: 23.16 case Bytecodes::_fast_dputfield: 23.17 case Bytecodes::_fast_fputfield: 23.18 @@ -1018,6 +1019,16 @@ 23.19 // ebx: index 23.20 // rdx: array 23.21 index_check(rdx, rbx); // prefer index in ebx 23.22 + // Need to check whether array is boolean or byte 23.23 + // since both types share the bastore bytecode. 23.24 + __ load_klass(rcx, rdx); 23.25 + __ movl(rcx, Address(rcx, Klass::layout_helper_offset())); 23.26 + int diffbit = Klass::layout_helper_boolean_diffbit(); 23.27 + __ testl(rcx, diffbit); 23.28 + Label L_skip; 23.29 + __ jccb(Assembler::zero, L_skip); 23.30 + __ andl(rax, 1); // if it is a T_BOOLEAN array, mask the stored value to 0/1 23.31 + __ bind(L_skip); 23.32 __ movb(Address(rdx, rbx, 23.33 Address::times_1, 23.34 arrayOopDesc::base_offset_in_bytes(T_BYTE)), 23.35 @@ -2071,7 +2082,14 @@ 23.36 __ bind(skip_register_finalizer); 23.37 } 23.38 23.39 + // Narrow result if state is itos but result type is smaller. 23.40 + // Need to narrow in the return bytecode rather than in generate_return_entry 23.41 + // since compiled code callers expect the result to already be narrowed. 23.42 + if (state == itos) { 23.43 + __ narrow(rax); 23.44 + } 23.45 __ remove_activation(state, r13); 23.46 + 23.47 __ jmp(r13); 23.48 } 23.49 23.50 @@ -2289,7 +2307,7 @@ 23.51 23.52 const Address field(obj, off, Address::times_1); 23.53 23.54 - Label Done, notByte, notInt, notShort, notChar, 23.55 + Label Done, notByte, notBool, notInt, notShort, notChar, 23.56 notLong, notFloat, notObj, notDouble; 23.57 23.58 __ shrl(flags, ConstantPoolCacheEntry::tos_state_shift); 23.59 @@ -2308,6 +2326,20 @@ 23.60 __ jmp(Done); 23.61 23.62 __ bind(notByte); 23.63 + __ cmpl(flags, ztos); 23.64 + __ jcc(Assembler::notEqual, notBool); 23.65 + 23.66 + // ztos (same code as btos) 23.67 + __ load_signed_byte(rax, field); 23.68 + __ push(ztos); 23.69 + // Rewrite bytecode to be faster 23.70 + if (!is_static) { 23.71 + // use btos rewriting, no truncating to t/f bit is needed for getfield. 23.72 + patch_bytecode(Bytecodes::_fast_bgetfield, bc, rbx); 23.73 + } 23.74 + __ jmp(Done); 23.75 + 23.76 + __ bind(notBool); 23.77 __ cmpl(flags, atos); 23.78 __ jcc(Assembler::notEqual, notObj); 23.79 // atos 23.80 @@ -2497,7 +2529,7 @@ 23.81 // field address 23.82 const Address field(obj, off, Address::times_1); 23.83 23.84 - Label notByte, notInt, notShort, notChar, 23.85 + Label notByte, notBool, notInt, notShort, notChar, 23.86 notLong, notFloat, notObj, notDouble; 23.87 23.88 __ shrl(flags, ConstantPoolCacheEntry::tos_state_shift); 23.89 @@ -2518,6 +2550,22 @@ 23.90 } 23.91 23.92 __ bind(notByte); 23.93 + __ cmpl(flags, ztos); 23.94 + __ jcc(Assembler::notEqual, notBool); 23.95 + 23.96 + // ztos 23.97 + { 23.98 + __ pop(ztos); 23.99 + if (!is_static) pop_and_check_object(obj); 23.100 + __ andl(rax, 0x1); 23.101 + __ movb(field, rax); 23.102 + if (!is_static) { 23.103 + patch_bytecode(Bytecodes::_fast_zputfield, bc, rbx, true, byte_no); 23.104 + } 23.105 + __ jmp(Done); 23.106 + } 23.107 + 23.108 + __ bind(notBool); 23.109 __ cmpl(flags, atos); 23.110 __ jcc(Assembler::notEqual, notObj); 23.111 23.112 @@ -2666,6 +2714,7 @@ 23.113 switch (bytecode()) { // load values into the jvalue object 23.114 case Bytecodes::_fast_aputfield: __ push_ptr(rax); break; 23.115 case Bytecodes::_fast_bputfield: // fall through 23.116 + case Bytecodes::_fast_zputfield: // fall through 23.117 case Bytecodes::_fast_sputfield: // fall through 23.118 case Bytecodes::_fast_cputfield: // fall through 23.119 case Bytecodes::_fast_iputfield: __ push_i(rax); break; 23.120 @@ -2691,6 +2740,7 @@ 23.121 switch (bytecode()) { // restore tos values 23.122 case Bytecodes::_fast_aputfield: __ pop_ptr(rax); break; 23.123 case Bytecodes::_fast_bputfield: // fall through 23.124 + case Bytecodes::_fast_zputfield: // fall through 23.125 case Bytecodes::_fast_sputfield: // fall through 23.126 case Bytecodes::_fast_cputfield: // fall through 23.127 case Bytecodes::_fast_iputfield: __ pop_i(rax); break; 23.128 @@ -2746,6 +2796,9 @@ 23.129 case Bytecodes::_fast_iputfield: 23.130 __ movl(field, rax); 23.131 break; 23.132 + case Bytecodes::_fast_zputfield: 23.133 + __ andl(rax, 0x1); // boolean is true if LSB is 1 23.134 + // fall through to bputfield 23.135 case Bytecodes::_fast_bputfield: 23.136 __ movb(field, rax); 23.137 break;
24.1 --- a/src/cpu/zero/vm/cppInterpreter_zero.cpp Thu Apr 21 16:19:33 2016 +0300 24.2 +++ b/src/cpu/zero/vm/cppInterpreter_zero.cpp Mon Apr 25 21:03:53 2016 +0000 24.3 @@ -1,5 +1,5 @@ 24.4 /* 24.5 - * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. 24.6 + * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved. 24.7 * Copyright 2007, 2008, 2009, 2010, 2011 Red Hat, Inc. 24.8 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 24.9 * 24.10 @@ -81,6 +81,30 @@ 24.11 return 0; 24.12 } 24.13 24.14 +intptr_t narrow(BasicType type, intptr_t result) { 24.15 + // mask integer result to narrower return type. 24.16 + switch (type) { 24.17 + case T_BOOLEAN: 24.18 + return result&1; 24.19 + case T_BYTE: 24.20 + return (intptr_t)(jbyte)result; 24.21 + case T_CHAR: 24.22 + return (intptr_t)(uintptr_t)(jchar)result; 24.23 + case T_SHORT: 24.24 + return (intptr_t)(jshort)result; 24.25 + case T_OBJECT: // nothing to do fall through 24.26 + case T_ARRAY: 24.27 + case T_LONG: 24.28 + case T_INT: 24.29 + case T_FLOAT: 24.30 + case T_DOUBLE: 24.31 + case T_VOID: 24.32 + return result; 24.33 + default : ShouldNotReachHere(); 24.34 + } 24.35 +} 24.36 + 24.37 + 24.38 void CppInterpreter::main_loop(int recurse, TRAPS) { 24.39 JavaThread *thread = (JavaThread *) THREAD; 24.40 ZeroStack *stack = thread->zero_stack(); 24.41 @@ -160,7 +184,7 @@ 24.42 } 24.43 else if (istate->msg() == BytecodeInterpreter::return_from_method) { 24.44 // Copy the result into the caller's frame 24.45 - result_slots = type2size[result_type_of(method)]; 24.46 + result_slots = type2size[method->result_type()]; 24.47 assert(result_slots >= 0 && result_slots <= 2, "what?"); 24.48 result = istate->stack() + result_slots; 24.49 break; 24.50 @@ -194,8 +218,14 @@ 24.51 stack->set_sp(stack->sp() + method->max_locals()); 24.52 24.53 // Push our result 24.54 - for (int i = 0; i < result_slots; i++) 24.55 - stack->push(result[-i]); 24.56 + for (int i = 0; i < result_slots; i++) { 24.57 + // Adjust result to smaller 24.58 + intptr_t res = result[-i]; 24.59 + if (result_slots == 1) { 24.60 + res = narrow(method->result_type(), res); 24.61 + } 24.62 + stack->push(res); 24.63 + } 24.64 } 24.65 24.66 int CppInterpreter::native_entry(Method* method, intptr_t UNUSED, TRAPS) { 24.67 @@ -406,7 +436,7 @@ 24.68 24.69 // Push our result 24.70 if (!HAS_PENDING_EXCEPTION) { 24.71 - BasicType type = result_type_of(method); 24.72 + BasicType type = method->result_type(); 24.73 stack->set_sp(stack->sp() - type2size[type]); 24.74 24.75 switch (type) { 24.76 @@ -528,6 +558,7 @@ 24.77 break; 24.78 24.79 case btos: 24.80 + case ztos: 24.81 SET_LOCALS_INT(object->byte_field_acquire(entry->f2_as_index()), 0); 24.82 break; 24.83 24.84 @@ -566,6 +597,7 @@ 24.85 break; 24.86 24.87 case btos: 24.88 + case ztos: 24.89 SET_LOCALS_INT(object->byte_field(entry->f2_as_index()), 0); 24.90 break; 24.91 24.92 @@ -764,26 +796,6 @@ 24.93 return i; 24.94 } 24.95 24.96 -BasicType CppInterpreter::result_type_of(Method* method) { 24.97 - BasicType t; 24.98 - switch (method->result_index()) { 24.99 - case 0 : t = T_BOOLEAN; break; 24.100 - case 1 : t = T_CHAR; break; 24.101 - case 2 : t = T_BYTE; break; 24.102 - case 3 : t = T_SHORT; break; 24.103 - case 4 : t = T_INT; break; 24.104 - case 5 : t = T_LONG; break; 24.105 - case 6 : t = T_VOID; break; 24.106 - case 7 : t = T_FLOAT; break; 24.107 - case 8 : t = T_DOUBLE; break; 24.108 - case 9 : t = T_OBJECT; break; 24.109 - default: ShouldNotReachHere(); 24.110 - } 24.111 - assert(AbstractInterpreter::BasicType_as_index(t) == method->result_index(), 24.112 - "out of step with AbstractInterpreter::BasicType_as_index"); 24.113 - return t; 24.114 -} 24.115 - 24.116 address InterpreterGenerator::generate_empty_entry() { 24.117 if (!UseFastEmptyMethods) 24.118 return NULL;
25.1 --- a/src/cpu/zero/vm/cppInterpreter_zero.hpp Thu Apr 21 16:19:33 2016 +0300 25.2 +++ b/src/cpu/zero/vm/cppInterpreter_zero.hpp Mon Apr 25 21:03:53 2016 +0000 25.3 @@ -1,5 +1,5 @@ 25.4 /* 25.5 - * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. 25.6 + * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. 25.7 * Copyright 2007, 2008, 2010, 2011 Red Hat, Inc. 25.8 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 25.9 * 25.10 @@ -49,8 +49,4 @@ 25.11 static intptr_t* calculate_unwind_sp(ZeroStack* stack, oop method_handle); 25.12 static void throw_exception(JavaThread* thread, Symbol* name,char *msg=NULL); 25.13 25.14 - private: 25.15 - // Fast result type determination 25.16 - static BasicType result_type_of(Method* method); 25.17 - 25.18 #endif // CPU_ZERO_VM_CPPINTERPRETER_ZERO_HPP
26.1 --- a/src/os/posix/vm/os_posix.cpp Thu Apr 21 16:19:33 2016 +0300 26.2 +++ b/src/os/posix/vm/os_posix.cpp Mon Apr 25 21:03:53 2016 +0000 26.3 @@ -1,5 +1,5 @@ 26.4 /* 26.5 -* Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved. 26.6 +* Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved. 26.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 26.8 * 26.9 * This code is free software; you can redistribute it and/or modify it 26.10 @@ -678,6 +678,21 @@ 26.11 #if defined(IA64) && !defined(AIX) 26.12 { SIGSEGV, SEGV_PSTKOVF, "SEGV_PSTKOVF", "Paragraph stack overflow" }, 26.13 #endif 26.14 +#if defined(__sparc) && defined(SOLARIS) 26.15 +// define Solaris Sparc M7 ADI SEGV signals 26.16 +#if !defined(SEGV_ACCADI) 26.17 +#define SEGV_ACCADI 3 26.18 +#endif 26.19 + { SIGSEGV, SEGV_ACCADI, "SEGV_ACCADI", "ADI not enabled for mapped object." }, 26.20 +#if !defined(SEGV_ACCDERR) 26.21 +#define SEGV_ACCDERR 4 26.22 +#endif 26.23 + { SIGSEGV, SEGV_ACCDERR, "SEGV_ACCDERR", "ADI disrupting exception." }, 26.24 +#if !defined(SEGV_ACCPERR) 26.25 +#define SEGV_ACCPERR 5 26.26 +#endif 26.27 + { SIGSEGV, SEGV_ACCPERR, "SEGV_ACCPERR", "ADI precise exception." }, 26.28 +#endif // defined(__sparc) && defined(SOLARIS) 26.29 { SIGBUS, BUS_ADRALN, "BUS_ADRALN", "Invalid address alignment." }, 26.30 { SIGBUS, BUS_ADRERR, "BUS_ADRERR", "Nonexistent physical address." }, 26.31 { SIGBUS, BUS_OBJERR, "BUS_OBJERR", "Object-specific hardware error." },
27.1 --- a/src/os/solaris/vm/os_solaris.cpp Thu Apr 21 16:19:33 2016 +0300 27.2 +++ b/src/os/solaris/vm/os_solaris.cpp Mon Apr 25 21:03:53 2016 +0000 27.3 @@ -6248,14 +6248,7 @@ 27.4 } 27.5 27.6 size_t os::write(int fd, const void *buf, unsigned int nBytes) { 27.7 - Thread* t = ThreadLocalStorage::thread(); 27.8 - if (t->is_Java_thread()) { 27.9 - INTERRUPTIBLE_RETURN_INT(::write(fd, buf, nBytes), os::Solaris::clear_interrupted); 27.10 - } else { 27.11 - size_t res; 27.12 - RESTARTABLE((size_t) ::write(fd, buf, (size_t) nBytes), res); 27.13 - return res; 27.14 - } 27.15 + INTERRUPTIBLE_RETURN_INT(::write(fd, buf, nBytes), os::Solaris::clear_interrupted); 27.16 } 27.17 27.18 int os::close(int fd) {
28.1 --- a/src/share/vm/c1/c1_Canonicalizer.cpp Thu Apr 21 16:19:33 2016 +0300 28.2 +++ b/src/share/vm/c1/c1_Canonicalizer.cpp Mon Apr 25 21:03:53 2016 +0000 28.3 @@ -1,5 +1,5 @@ 28.4 /* 28.5 - * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. 28.6 + * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved. 28.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 28.8 * 28.9 * This code is free software; you can redistribute it and/or modify it 28.10 @@ -265,7 +265,8 @@ 28.11 // limit this optimization to current block 28.12 if (value != NULL && in_current_block(conv)) { 28.13 set_canonical(new StoreIndexed(x->array(), x->index(), x->length(), 28.14 - x->elt_type(), value, x->state_before())); 28.15 + x->elt_type(), value, x->state_before(), 28.16 + x->check_boolean())); 28.17 return; 28.18 } 28.19 }
29.1 --- a/src/share/vm/c1/c1_GraphBuilder.cpp Thu Apr 21 16:19:33 2016 +0300 29.2 +++ b/src/share/vm/c1/c1_GraphBuilder.cpp Mon Apr 25 21:03:53 2016 +0000 29.3 @@ -1,5 +1,5 @@ 29.4 /* 29.5 - * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. 29.6 + * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved. 29.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 29.8 * 29.9 * This code is free software; you can redistribute it and/or modify it 29.10 @@ -975,7 +975,19 @@ 29.11 (array->as_NewArray() && array->as_NewArray()->length() && array->as_NewArray()->length()->type()->is_constant())) { 29.12 length = append(new ArrayLength(array, state_before)); 29.13 } 29.14 - StoreIndexed* result = new StoreIndexed(array, index, length, type, value, state_before); 29.15 + ciType* array_type = array->declared_type(); 29.16 + bool check_boolean = false; 29.17 + if (array_type != NULL) { 29.18 + if (array_type->is_loaded() && 29.19 + array_type->as_array_klass()->element_type()->basic_type() == T_BOOLEAN) { 29.20 + assert(type == T_BYTE, "boolean store uses bastore"); 29.21 + Value mask = append(new Constant(new IntConstant(1))); 29.22 + value = append(new LogicOp(Bytecodes::_iand, value, mask)); 29.23 + } 29.24 + } else if (type == T_BYTE) { 29.25 + check_boolean = true; 29.26 + } 29.27 + StoreIndexed* result = new StoreIndexed(array, index, length, type, value, state_before, check_boolean); 29.28 append(result); 29.29 _memory->store_value(value); 29.30 29.31 @@ -1440,6 +1452,36 @@ 29.32 need_mem_bar = true; 29.33 } 29.34 29.35 + BasicType bt = method()->return_type()->basic_type(); 29.36 + switch (bt) { 29.37 + case T_BYTE: 29.38 + { 29.39 + Value shift = append(new Constant(new IntConstant(24))); 29.40 + x = append(new ShiftOp(Bytecodes::_ishl, x, shift)); 29.41 + x = append(new ShiftOp(Bytecodes::_ishr, x, shift)); 29.42 + break; 29.43 + } 29.44 + case T_SHORT: 29.45 + { 29.46 + Value shift = append(new Constant(new IntConstant(16))); 29.47 + x = append(new ShiftOp(Bytecodes::_ishl, x, shift)); 29.48 + x = append(new ShiftOp(Bytecodes::_ishr, x, shift)); 29.49 + break; 29.50 + } 29.51 + case T_CHAR: 29.52 + { 29.53 + Value mask = append(new Constant(new IntConstant(0xFFFF))); 29.54 + x = append(new LogicOp(Bytecodes::_iand, x, mask)); 29.55 + break; 29.56 + } 29.57 + case T_BOOLEAN: 29.58 + { 29.59 + Value mask = append(new Constant(new IntConstant(1))); 29.60 + x = append(new LogicOp(Bytecodes::_iand, x, mask)); 29.61 + break; 29.62 + } 29.63 + } 29.64 + 29.65 // Check to see whether we are inlining. If so, Return 29.66 // instructions become Gotos to the continuation point. 29.67 if (continuation() != NULL) { 29.68 @@ -1587,6 +1629,10 @@ 29.69 if (state_before == NULL) { 29.70 state_before = copy_state_for_exception(); 29.71 } 29.72 + if (field->type()->basic_type() == T_BOOLEAN) { 29.73 + Value mask = append(new Constant(new IntConstant(1))); 29.74 + val = append(new LogicOp(Bytecodes::_iand, val, mask)); 29.75 + } 29.76 append(new StoreField(append(obj), offset, field, val, true, state_before, needs_patching)); 29.77 } 29.78 break; 29.79 @@ -1657,6 +1703,10 @@ 29.80 if (state_before == NULL) { 29.81 state_before = copy_state_for_exception(); 29.82 } 29.83 + if (field->type()->basic_type() == T_BOOLEAN) { 29.84 + Value mask = append(new Constant(new IntConstant(1))); 29.85 + val = append(new LogicOp(Bytecodes::_iand, val, mask)); 29.86 + } 29.87 StoreField* store = new StoreField(obj, offset, field, val, false, state_before, needs_patching); 29.88 if (!needs_patching) store = _memory->store(store); 29.89 if (store != NULL) { 29.90 @@ -4222,7 +4272,12 @@ 29.91 #ifndef _LP64 29.92 offset = append(new Convert(Bytecodes::_l2i, offset, as_ValueType(T_INT))); 29.93 #endif 29.94 - Instruction* op = append(new UnsafePutObject(t, args->at(1), offset, args->at(3), is_volatile)); 29.95 + Value val = args->at(3); 29.96 + if (t == T_BOOLEAN) { 29.97 + Value mask = append(new Constant(new IntConstant(1))); 29.98 + val = append(new LogicOp(Bytecodes::_iand, val, mask)); 29.99 + } 29.100 + Instruction* op = append(new UnsafePutObject(t, args->at(1), offset, val, is_volatile)); 29.101 compilation()->set_has_unsafe_access(true); 29.102 kill_all(); 29.103 }
30.1 --- a/src/share/vm/c1/c1_Instruction.hpp Thu Apr 21 16:19:33 2016 +0300 30.2 +++ b/src/share/vm/c1/c1_Instruction.hpp Mon Apr 25 21:03:53 2016 +0000 30.3 @@ -1,5 +1,5 @@ 30.4 /* 30.5 - * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. 30.6 + * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved. 30.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 30.8 * 30.9 * This code is free software; you can redistribute it and/or modify it 30.10 @@ -976,11 +976,13 @@ 30.11 30.12 ciMethod* _profiled_method; 30.13 int _profiled_bci; 30.14 + bool _check_boolean; 30.15 + 30.16 public: 30.17 // creation 30.18 - StoreIndexed(Value array, Value index, Value length, BasicType elt_type, Value value, ValueStack* state_before) 30.19 + StoreIndexed(Value array, Value index, Value length, BasicType elt_type, Value value, ValueStack* state_before, bool check_boolean) 30.20 : AccessIndexed(array, index, length, elt_type, state_before) 30.21 - , _value(value), _profiled_method(NULL), _profiled_bci(0) 30.22 + , _value(value), _profiled_method(NULL), _profiled_bci(0), _check_boolean(check_boolean) 30.23 { 30.24 set_flag(NeedsWriteBarrierFlag, (as_ValueType(elt_type)->is_object())); 30.25 set_flag(NeedsStoreCheckFlag, (as_ValueType(elt_type)->is_object())); 30.26 @@ -992,6 +994,7 @@ 30.27 Value value() const { return _value; } 30.28 bool needs_write_barrier() const { return check_flag(NeedsWriteBarrierFlag); } 30.29 bool needs_store_check() const { return check_flag(NeedsStoreCheckFlag); } 30.30 + bool check_boolean() const { return _check_boolean; } 30.31 // Helpers for MethodData* profiling 30.32 void set_should_profile(bool value) { set_flag(ProfileMDOFlag, value); } 30.33 void set_profiled_method(ciMethod* method) { _profiled_method = method; }
31.1 --- a/src/share/vm/c1/c1_LIRGenerator.cpp Thu Apr 21 16:19:33 2016 +0300 31.2 +++ b/src/share/vm/c1/c1_LIRGenerator.cpp Mon Apr 25 21:03:53 2016 +0000 31.3 @@ -1,5 +1,5 @@ 31.4 /* 31.5 - * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved. 31.6 + * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved. 31.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 31.8 * 31.9 * This code is free software; you can redistribute it and/or modify it 31.10 @@ -3646,3 +3646,26 @@ 31.11 } 31.12 } 31.13 } 31.14 + 31.15 +LIR_Opr LIRGenerator::maybe_mask_boolean(StoreIndexed* x, LIR_Opr array, LIR_Opr value, CodeEmitInfo*& null_check_info) { 31.16 + if (x->check_boolean()) { 31.17 + LIR_Opr value_fixed = rlock_byte(T_BYTE); 31.18 + if (TwoOperandLIRForm) { 31.19 + __ move(value, value_fixed); 31.20 + __ logical_and(value_fixed, LIR_OprFact::intConst(1), value_fixed); 31.21 + } else { 31.22 + __ logical_and(value, LIR_OprFact::intConst(1), value_fixed); 31.23 + } 31.24 + LIR_Opr klass = new_register(T_METADATA); 31.25 + __ move(new LIR_Address(array, oopDesc::klass_offset_in_bytes(), T_ADDRESS), klass, null_check_info); 31.26 + null_check_info = NULL; 31.27 + LIR_Opr layout = new_register(T_INT); 31.28 + __ move(new LIR_Address(klass, in_bytes(Klass::layout_helper_offset()), T_INT), layout); 31.29 + int diffbit = Klass::layout_helper_boolean_diffbit(); 31.30 + __ logical_and(layout, LIR_OprFact::intConst(diffbit), layout); 31.31 + __ cmp(lir_cond_notEqual, layout, LIR_OprFact::intConst(0)); 31.32 + __ cmove(lir_cond_notEqual, value_fixed, value, value_fixed, T_BYTE); 31.33 + value = value_fixed; 31.34 + } 31.35 + return value; 31.36 +}
32.1 --- a/src/share/vm/c1/c1_LIRGenerator.hpp Thu Apr 21 16:19:33 2016 +0300 32.2 +++ b/src/share/vm/c1/c1_LIRGenerator.hpp Mon Apr 25 21:03:53 2016 +0000 32.3 @@ -1,5 +1,5 @@ 32.4 /* 32.5 - * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved. 32.6 + * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved. 32.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 32.8 * 32.9 * This code is free software; you can redistribute it and/or modify it 32.10 @@ -446,6 +446,7 @@ 32.11 void profile_arguments(ProfileCall* x); 32.12 void profile_parameters(Base* x); 32.13 void profile_parameters_at_call(ProfileCall* x); 32.14 + LIR_Opr maybe_mask_boolean(StoreIndexed* x, LIR_Opr array, LIR_Opr value, CodeEmitInfo*& null_check_info); 32.15 32.16 public: 32.17 Compilation* compilation() const { return _compilation; }
33.1 --- a/src/share/vm/classfile/classFileParser.cpp Thu Apr 21 16:19:33 2016 +0300 33.2 +++ b/src/share/vm/classfile/classFileParser.cpp Mon Apr 25 21:03:53 2016 +0000 33.3 @@ -1,5 +1,5 @@ 33.4 /* 33.5 - * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. 33.6 + * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. 33.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 33.8 * 33.9 * This code is free software; you can redistribute it and/or modify it 33.10 @@ -2417,11 +2417,9 @@ 33.11 m->set_constants(_cp); 33.12 m->set_name_index(name_index); 33.13 m->set_signature_index(signature_index); 33.14 -#ifdef CC_INTERP 33.15 - // hmm is there a gc issue here?? 33.16 + 33.17 ResultTypeFinder rtf(_cp->symbol_at(signature_index)); 33.18 - m->set_result_index(rtf.type()); 33.19 -#endif 33.20 + m->constMethod()->set_result_type(rtf.type()); 33.21 33.22 if (args_size >= 0) { 33.23 m->set_size_of_parameters(args_size);
34.1 --- a/src/share/vm/classfile/defaultMethods.cpp Thu Apr 21 16:19:33 2016 +0300 34.2 +++ b/src/share/vm/classfile/defaultMethods.cpp Mon Apr 25 21:03:53 2016 +0000 34.3 @@ -1,5 +1,5 @@ 34.4 /* 34.5 - * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved. 34.6 + * Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved. 34.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 34.8 * 34.9 * This code is free software; you can redistribute it and/or modify it 34.10 @@ -892,10 +892,8 @@ 34.11 m->set_constants(NULL); // This will get filled in later 34.12 m->set_name_index(cp->utf8(name)); 34.13 m->set_signature_index(cp->utf8(sig)); 34.14 -#ifdef CC_INTERP 34.15 ResultTypeFinder rtf(sig); 34.16 - m->set_result_index(rtf.type()); 34.17 -#endif 34.18 + m->constMethod()->set_result_type(rtf.type()); 34.19 m->set_size_of_parameters(params); 34.20 m->set_max_stack(max_stack); 34.21 m->set_max_locals(params);
35.1 --- a/src/share/vm/interpreter/bytecodeInterpreter.cpp Thu Apr 21 16:19:33 2016 +0300 35.2 +++ b/src/share/vm/interpreter/bytecodeInterpreter.cpp Mon Apr 25 21:03:53 2016 +0000 35.3 @@ -1,5 +1,5 @@ 35.4 /* 35.5 - * Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. 35.6 + * Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved. 35.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 35.8 * 35.9 * This code is free software; you can redistribute it and/or modify it 35.10 @@ -1780,8 +1780,19 @@ 35.11 ((objArrayOop) arrObj)->obj_at_put(index, rhsObject); 35.12 UPDATE_PC_AND_TOS_AND_CONTINUE(1, -3); 35.13 } 35.14 - CASE(_bastore): 35.15 - ARRAY_STOREFROM32(T_BYTE, jbyte, "%d", STACK_INT, 0); 35.16 + CASE(_bastore): { 35.17 + ARRAY_INTRO(-3); 35.18 + int item = STACK_INT(-1); 35.19 + // if it is a T_BOOLEAN array, mask the stored value to 0/1 35.20 + if (arrObj->klass() == Universe::boolArrayKlassObj()) { 35.21 + item &= 1; 35.22 + } else { 35.23 + assert(arrObj->klass() == Universe::byteArrayKlassObj(), 35.24 + "should be byte array otherwise"); 35.25 + } 35.26 + ((typeArrayOop)arrObj)->byte_at_put(index, item); 35.27 + UPDATE_PC_AND_TOS_AND_CONTINUE(1, -3); 35.28 + } 35.29 CASE(_castore): 35.30 ARRAY_STOREFROM32(T_CHAR, jchar, "%d", STACK_INT, 0); 35.31 CASE(_sastore): 35.32 @@ -2012,7 +2023,7 @@ 35.33 } else if (tos_type == ltos) { 35.34 SET_STACK_LONG(obj->long_field_acquire(field_offset), 0); 35.35 MORE_STACK(1); 35.36 - } else if (tos_type == btos) { 35.37 + } else if (tos_type == btos || tos_type == ztos) { 35.38 SET_STACK_INT(obj->byte_field_acquire(field_offset), -1); 35.39 } else if (tos_type == ctos) { 35.40 SET_STACK_INT(obj->char_field_acquire(field_offset), -1); 35.41 @@ -2033,7 +2044,7 @@ 35.42 } else if (tos_type == ltos) { 35.43 SET_STACK_LONG(obj->long_field(field_offset), 0); 35.44 MORE_STACK(1); 35.45 - } else if (tos_type == btos) { 35.46 + } else if (tos_type == btos || tos_type == ztos) { 35.47 SET_STACK_INT(obj->byte_field(field_offset), -1); 35.48 } else if (tos_type == ctos) { 35.49 SET_STACK_INT(obj->char_field(field_offset), -1); 35.50 @@ -2122,6 +2133,9 @@ 35.51 obj->release_obj_field_put(field_offset, STACK_OBJECT(-1)); 35.52 } else if (tos_type == btos) { 35.53 obj->release_byte_field_put(field_offset, STACK_INT(-1)); 35.54 + } else if (tos_type == ztos) { 35.55 + int bool_field = STACK_INT(-1); // only store LSB 35.56 + obj->release_byte_field_put(field_offset, (bool_field & 1)); 35.57 } else if (tos_type == ltos) { 35.58 obj->release_long_field_put(field_offset, STACK_LONG(-1)); 35.59 } else if (tos_type == ctos) { 35.60 @@ -2142,6 +2156,9 @@ 35.61 obj->obj_field_put(field_offset, STACK_OBJECT(-1)); 35.62 } else if (tos_type == btos) { 35.63 obj->byte_field_put(field_offset, STACK_INT(-1)); 35.64 + } else if (tos_type == ztos) { 35.65 + int bool_field = STACK_INT(-1); // only store LSB 35.66 + obj->byte_field_put(field_offset, (bool_field & 1)); 35.67 } else if (tos_type == ltos) { 35.68 obj->long_field_put(field_offset, STACK_LONG(-1)); 35.69 } else if (tos_type == ctos) {
36.1 --- a/src/share/vm/interpreter/bytecodes.cpp Thu Apr 21 16:19:33 2016 +0300 36.2 +++ b/src/share/vm/interpreter/bytecodes.cpp Mon Apr 25 21:03:53 2016 +0000 36.3 @@ -1,5 +1,5 @@ 36.4 /* 36.5 - * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. 36.6 + * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. 36.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 36.8 * 36.9 * This code is free software; you can redistribute it and/or modify it 36.10 @@ -510,6 +510,7 @@ 36.11 36.12 def(_fast_aputfield , "fast_aputfield" , "bJJ" , NULL , T_OBJECT , 0, true , _putfield ); 36.13 def(_fast_bputfield , "fast_bputfield" , "bJJ" , NULL , T_INT , 0, true , _putfield ); 36.14 + def(_fast_zputfield , "fast_zputfield" , "bJJ" , NULL , T_INT , 0, true , _putfield ); 36.15 def(_fast_cputfield , "fast_cputfield" , "bJJ" , NULL , T_CHAR , 0, true , _putfield ); 36.16 def(_fast_dputfield , "fast_dputfield" , "bJJ" , NULL , T_DOUBLE , 0, true , _putfield ); 36.17 def(_fast_fputfield , "fast_fputfield" , "bJJ" , NULL , T_FLOAT , 0, true , _putfield );
37.1 --- a/src/share/vm/interpreter/bytecodes.hpp Thu Apr 21 16:19:33 2016 +0300 37.2 +++ b/src/share/vm/interpreter/bytecodes.hpp Mon Apr 25 21:03:53 2016 +0000 37.3 @@ -1,5 +1,5 @@ 37.4 /* 37.5 - * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved. 37.6 + * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. 37.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 37.8 * 37.9 * This code is free software; you can redistribute it and/or modify it 37.10 @@ -256,6 +256,7 @@ 37.11 37.12 _fast_aputfield , 37.13 _fast_bputfield , 37.14 + _fast_zputfield , 37.15 _fast_cputfield , 37.16 _fast_dputfield , 37.17 _fast_fputfield ,
38.1 --- a/src/share/vm/interpreter/interpreterRuntime.cpp Thu Apr 21 16:19:33 2016 +0300 38.2 +++ b/src/share/vm/interpreter/interpreterRuntime.cpp Mon Apr 25 21:03:53 2016 +0000 38.3 @@ -1,5 +1,5 @@ 38.4 /* 38.5 - * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. 38.6 + * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. 38.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 38.8 * 38.9 * This code is free software; you can redistribute it and/or modify it 38.10 @@ -1011,6 +1011,7 @@ 38.11 38.12 switch(cp_entry->flag_state()) { 38.13 case btos: // fall through 38.14 + case ztos: // fall through 38.15 case ctos: // fall through 38.16 case stos: // fall through 38.17 case itos: // fall through 38.18 @@ -1047,7 +1048,8 @@ 38.19 char sig_type = '\0'; 38.20 38.21 switch(cp_entry->flag_state()) { 38.22 - case btos: sig_type = 'Z'; break; 38.23 + case btos: sig_type = 'B'; break; 38.24 + case ztos: sig_type = 'Z'; break; 38.25 case ctos: sig_type = 'C'; break; 38.26 case stos: sig_type = 'S'; break; 38.27 case itos: sig_type = 'I'; break;
39.1 --- a/src/share/vm/interpreter/templateInterpreter.cpp Thu Apr 21 16:19:33 2016 +0300 39.2 +++ b/src/share/vm/interpreter/templateInterpreter.cpp Mon Apr 25 21:03:53 2016 +0000 39.3 @@ -1,5 +1,5 @@ 39.4 /* 39.5 - * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. 39.6 + * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. 39.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 39.8 * 39.9 * This code is free software; you can redistribute it and/or modify it 39.10 @@ -61,8 +61,9 @@ 39.11 // Implementation of EntryPoint 39.12 39.13 EntryPoint::EntryPoint() { 39.14 - assert(number_of_states == 9, "check the code below"); 39.15 + assert(number_of_states == 10, "check the code below"); 39.16 _entry[btos] = NULL; 39.17 + _entry[ztos] = NULL; 39.18 _entry[ctos] = NULL; 39.19 _entry[stos] = NULL; 39.20 _entry[atos] = NULL; 39.21 @@ -74,9 +75,10 @@ 39.22 } 39.23 39.24 39.25 -EntryPoint::EntryPoint(address bentry, address centry, address sentry, address aentry, address ientry, address lentry, address fentry, address dentry, address ventry) { 39.26 - assert(number_of_states == 9, "check the code below"); 39.27 +EntryPoint::EntryPoint(address bentry, address zentry, address centry, address sentry, address aentry, address ientry, address lentry, address fentry, address dentry, address ventry) { 39.28 + assert(number_of_states == 10, "check the code below"); 39.29 _entry[btos] = bentry; 39.30 + _entry[ztos] = zentry; 39.31 _entry[ctos] = centry; 39.32 _entry[stos] = sentry; 39.33 _entry[atos] = aentry; 39.34 @@ -127,6 +129,7 @@ 39.35 return 39.36 EntryPoint( 39.37 _table[btos][i], 39.38 + _table[ztos][i], 39.39 _table[ctos][i], 39.40 _table[stos][i], 39.41 _table[atos][i], 39.42 @@ -141,8 +144,9 @@ 39.43 39.44 void DispatchTable::set_entry(int i, EntryPoint& entry) { 39.45 assert(0 <= i && i < length, "index out of bounds"); 39.46 - assert(number_of_states == 9, "check the code below"); 39.47 + assert(number_of_states == 10, "check the code below"); 39.48 _table[btos][i] = entry.entry(btos); 39.49 + _table[ztos][i] = entry.entry(ztos); 39.50 _table[ctos][i] = entry.entry(ctos); 39.51 _table[stos][i] = entry.entry(stos); 39.52 _table[atos][i] = entry.entry(atos); 39.53 @@ -225,6 +229,7 @@ 39.54 Interpreter::_trace_code = 39.55 EntryPoint( 39.56 generate_trace_code(btos), 39.57 + generate_trace_code(ztos), 39.58 generate_trace_code(ctos), 39.59 generate_trace_code(stos), 39.60 generate_trace_code(atos), 39.61 @@ -245,6 +250,7 @@ 39.62 generate_return_entry_for(itos, i, index_size), 39.63 generate_return_entry_for(itos, i, index_size), 39.64 generate_return_entry_for(itos, i, index_size), 39.65 + generate_return_entry_for(itos, i, index_size), 39.66 generate_return_entry_for(atos, i, index_size), 39.67 generate_return_entry_for(itos, i, index_size), 39.68 generate_return_entry_for(ltos, i, index_size), 39.69 @@ -256,13 +262,16 @@ 39.70 } 39.71 39.72 { CodeletMark cm(_masm, "invoke return entry points"); 39.73 - const TosState states[] = {itos, itos, itos, itos, ltos, ftos, dtos, atos, vtos}; 39.74 + // These states are in order specified in TosState, except btos/ztos/ctos/stos are 39.75 + // really the same as itos since there is no top of stack optimization for these types 39.76 + const TosState states[] = {itos, itos, itos, itos, itos, ltos, ftos, dtos, atos, vtos, ilgl}; 39.77 const int invoke_length = Bytecodes::length_for(Bytecodes::_invokestatic); 39.78 const int invokeinterface_length = Bytecodes::length_for(Bytecodes::_invokeinterface); 39.79 const int invokedynamic_length = Bytecodes::length_for(Bytecodes::_invokedynamic); 39.80 39.81 for (int i = 0; i < Interpreter::number_of_return_addrs; i++) { 39.82 TosState state = states[i]; 39.83 + assert(state != ilgl, "states array is wrong above"); 39.84 Interpreter::_invoke_return_entry[i] = generate_return_entry_for(state, invoke_length, sizeof(u2)); 39.85 Interpreter::_invokeinterface_return_entry[i] = generate_return_entry_for(state, invokeinterface_length, sizeof(u2)); 39.86 Interpreter::_invokedynamic_return_entry[i] = generate_return_entry_for(state, invokedynamic_length, sizeof(u4)); 39.87 @@ -273,6 +282,7 @@ 39.88 Interpreter::_earlyret_entry = 39.89 EntryPoint( 39.90 generate_earlyret_entry_for(btos), 39.91 + generate_earlyret_entry_for(ztos), 39.92 generate_earlyret_entry_for(ctos), 39.93 generate_earlyret_entry_for(stos), 39.94 generate_earlyret_entry_for(atos), 39.95 @@ -291,6 +301,7 @@ 39.96 generate_deopt_entry_for(itos, i), 39.97 generate_deopt_entry_for(itos, i), 39.98 generate_deopt_entry_for(itos, i), 39.99 + generate_deopt_entry_for(itos, i), 39.100 generate_deopt_entry_for(atos, i), 39.101 generate_deopt_entry_for(itos, i), 39.102 generate_deopt_entry_for(ltos, i), 39.103 @@ -318,6 +329,7 @@ 39.104 Interpreter::_continuation_entry = 39.105 EntryPoint( 39.106 generate_continuation_for(btos), 39.107 + generate_continuation_for(ztos), 39.108 generate_continuation_for(ctos), 39.109 generate_continuation_for(stos), 39.110 generate_continuation_for(atos), 39.111 @@ -333,6 +345,7 @@ 39.112 Interpreter::_safept_entry = 39.113 EntryPoint( 39.114 generate_safept_entry_for(btos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)), 39.115 + generate_safept_entry_for(ztos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)), 39.116 generate_safept_entry_for(ctos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)), 39.117 generate_safept_entry_for(stos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)), 39.118 generate_safept_entry_for(atos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)), 39.119 @@ -436,7 +449,7 @@ 39.120 39.121 void TemplateInterpreterGenerator::set_unimplemented(int i) { 39.122 address e = _unimplemented_bytecode; 39.123 - EntryPoint entry(e, e, e, e, e, e, e, e, e); 39.124 + EntryPoint entry(e, e, e, e, e, e, e, e, e, e); 39.125 Interpreter::_normal_table.set_entry(i, entry); 39.126 Interpreter::_wentry_point[i] = _unimplemented_bytecode; 39.127 } 39.128 @@ -448,6 +461,7 @@ 39.129 assert(_unimplemented_bytecode != NULL, "should have been generated before"); 39.130 assert(_illegal_bytecode_sequence != NULL, "should have been generated before"); 39.131 address bep = _illegal_bytecode_sequence; 39.132 + address zep = _illegal_bytecode_sequence; 39.133 address cep = _illegal_bytecode_sequence; 39.134 address sep = _illegal_bytecode_sequence; 39.135 address aep = _illegal_bytecode_sequence; 39.136 @@ -469,7 +483,7 @@ 39.137 set_wide_entry_point(t, wep); 39.138 } 39.139 // set entry points 39.140 - EntryPoint entry(bep, cep, sep, aep, iep, lep, fep, dep, vep); 39.141 + EntryPoint entry(bep, zep, cep, sep, aep, iep, lep, fep, dep, vep); 39.142 Interpreter::_normal_table.set_entry(code, entry); 39.143 Interpreter::_wentry_point[code] = wep; 39.144 } 39.145 @@ -486,6 +500,7 @@ 39.146 assert(t->is_valid(), "template must exist"); 39.147 switch (t->tos_in()) { 39.148 case btos: 39.149 + case ztos: 39.150 case ctos: 39.151 case stos: 39.152 ShouldNotReachHere(); // btos/ctos/stos should use itos.
40.1 --- a/src/share/vm/interpreter/templateInterpreter.hpp Thu Apr 21 16:19:33 2016 +0300 40.2 +++ b/src/share/vm/interpreter/templateInterpreter.hpp Mon Apr 25 21:03:53 2016 +0000 40.3 @@ -1,5 +1,5 @@ 40.4 /* 40.5 - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. 40.6 + * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. 40.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 40.8 * 40.9 * This code is free software; you can redistribute it and/or modify it 40.10 @@ -44,7 +44,7 @@ 40.11 public: 40.12 // Construction 40.13 EntryPoint(); 40.14 - EntryPoint(address bentry, address centry, address sentry, address aentry, address ientry, address lentry, address fentry, address dentry, address ventry); 40.15 + EntryPoint(address bentry, address zentry, address centry, address sentry, address aentry, address ientry, address lentry, address fentry, address dentry, address ventry); 40.16 40.17 // Attributes 40.18 address entry(TosState state) const; // return target address for a given tosca state
41.1 --- a/src/share/vm/interpreter/templateTable.cpp Thu Apr 21 16:19:33 2016 +0300 41.2 +++ b/src/share/vm/interpreter/templateTable.cpp Mon Apr 25 21:03:53 2016 +0000 41.3 @@ -1,5 +1,5 @@ 41.4 /* 41.5 - * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. 41.6 + * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. 41.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 41.8 * 41.9 * This code is free software; you can redistribute it and/or modify it 41.10 @@ -488,6 +488,7 @@ 41.11 41.12 def(Bytecodes::_fast_aputfield , ubcp|____|____|____, atos, vtos, fast_storefield , atos ); 41.13 def(Bytecodes::_fast_bputfield , ubcp|____|____|____, itos, vtos, fast_storefield , itos ); 41.14 + def(Bytecodes::_fast_zputfield , ubcp|____|____|____, itos, vtos, fast_storefield , itos ); 41.15 def(Bytecodes::_fast_cputfield , ubcp|____|____|____, itos, vtos, fast_storefield , itos ); 41.16 def(Bytecodes::_fast_dputfield , ubcp|____|____|____, dtos, vtos, fast_storefield , dtos ); 41.17 def(Bytecodes::_fast_fputfield , ubcp|____|____|____, ftos, vtos, fast_storefield , ftos );
42.1 --- a/src/share/vm/oops/constMethod.cpp Thu Apr 21 16:19:33 2016 +0300 42.2 +++ b/src/share/vm/oops/constMethod.cpp Mon Apr 25 21:03:53 2016 +0000 42.3 @@ -1,5 +1,5 @@ 42.4 /* 42.5 - * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved. 42.6 + * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved. 42.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 42.8 * 42.9 * This code is free software; you can redistribute it and/or modify it 42.10 @@ -65,6 +65,7 @@ 42.11 set_max_locals(0); 42.12 set_method_idnum(0); 42.13 set_size_of_parameters(0); 42.14 + set_result_type(T_VOID); 42.15 } 42.16 42.17 // Accessor that copies to metadata.
43.1 --- a/src/share/vm/oops/constMethod.hpp Thu Apr 21 16:19:33 2016 +0300 43.2 +++ b/src/share/vm/oops/constMethod.hpp Mon Apr 25 21:03:53 2016 +0000 43.3 @@ -1,5 +1,5 @@ 43.4 /* 43.5 - * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. 43.6 + * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved. 43.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 43.8 * 43.9 * This code is free software; you can redistribute it and/or modify it 43.10 @@ -211,6 +211,7 @@ 43.11 43.12 int _constMethod_size; 43.13 u2 _flags; 43.14 + u1 _result_type; // BasicType of result 43.15 43.16 // Size of Java bytecodes allocated immediately after Method*. 43.17 u2 _code_size; 43.18 @@ -469,6 +470,8 @@ 43.19 static ByteSize size_of_parameters_offset() 43.20 { return byte_offset_of(ConstMethod, _size_of_parameters); } 43.21 43.22 + static ByteSize result_type_offset() 43.23 + { return byte_offset_of(ConstMethod, _result_type); } 43.24 43.25 // Unique id for the method 43.26 static const u2 MAX_IDNUM; 43.27 @@ -491,6 +494,8 @@ 43.28 int size_of_parameters() const { return _size_of_parameters; } 43.29 void set_size_of_parameters(int size) { _size_of_parameters = size; } 43.30 43.31 + void set_result_type(BasicType rt) { assert(rt < 16, "result type too large"); 43.32 + _result_type = (u1)rt; } 43.33 // Deallocation for RedefineClasses 43.34 void deallocate_contents(ClassLoaderData* loader_data); 43.35 bool is_klass() const { return false; }
44.1 --- a/src/share/vm/oops/cpCache.hpp Thu Apr 21 16:19:33 2016 +0300 44.2 +++ b/src/share/vm/oops/cpCache.hpp Mon Apr 25 21:03:53 2016 +0000 44.3 @@ -1,5 +1,5 @@ 44.4 /* 44.5 - * Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved. 44.6 + * Copyright (c) 1998, 2016, Oracle and/or its affiliates. All rights reserved. 44.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 44.8 * 44.9 * This code is free software; you can redistribute it and/or modify it 44.10 @@ -77,18 +77,19 @@ 44.11 // f2 flag true if f2 contains an oop (e.g., virtual final method) 44.12 // fv flag true if invokeinterface used for method in class Object 44.13 // 44.14 -// The flags 31, 30, 29, 28 together build a 4 bit number 0 to 8 with the 44.15 +// The flags 31, 30, 29, 28 together build a 4 bit number 0 to 16 with the 44.16 // following mapping to the TosState states: 44.17 // 44.18 // btos: 0 44.19 -// ctos: 1 44.20 -// stos: 2 44.21 -// itos: 3 44.22 -// ltos: 4 44.23 -// ftos: 5 44.24 -// dtos: 6 44.25 -// atos: 7 44.26 -// vtos: 8 44.27 +// ztos: 1 44.28 +// ctos: 2 44.29 +// stos: 3 44.30 +// itos: 4 44.31 +// ltos: 5 44.32 +// ftos: 6 44.33 +// dtos: 7 44.34 +// atos: 8 44.35 +// vtos: 9 44.36 // 44.37 // Entry specific: field entries: 44.38 // _indices = get (b1 section) and put (b2 section) bytecodes, original constant pool index 44.39 @@ -351,14 +352,8 @@ 44.40 bool has_method_type() const { return (!is_f1_null()) && (_flags & (1 << has_method_type_shift)) != 0; } 44.41 bool is_method_entry() const { return (_flags & (1 << is_field_entry_shift)) == 0; } 44.42 bool is_field_entry() const { return (_flags & (1 << is_field_entry_shift)) != 0; } 44.43 - bool is_byte() const { return flag_state() == btos; } 44.44 - bool is_char() const { return flag_state() == ctos; } 44.45 - bool is_short() const { return flag_state() == stos; } 44.46 - bool is_int() const { return flag_state() == itos; } 44.47 bool is_long() const { return flag_state() == ltos; } 44.48 - bool is_float() const { return flag_state() == ftos; } 44.49 bool is_double() const { return flag_state() == dtos; } 44.50 - bool is_object() const { return flag_state() == atos; } 44.51 TosState flag_state() const { assert((uint)number_of_states <= (uint)tos_state_mask+1, ""); 44.52 return (TosState)((_flags >> tos_state_shift) & tos_state_mask); } 44.53
45.1 --- a/src/share/vm/oops/klass.hpp Thu Apr 21 16:19:33 2016 +0300 45.2 +++ b/src/share/vm/oops/klass.hpp Mon Apr 25 21:03:53 2016 +0000 45.3 @@ -1,5 +1,5 @@ 45.4 /* 45.5 - * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. 45.6 + * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. 45.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 45.8 * 45.9 * This code is free software; you can redistribute it and/or modify it 45.10 @@ -370,6 +370,21 @@ 45.11 assert(btvalue >= T_BOOLEAN && btvalue <= T_OBJECT, "sanity"); 45.12 return (BasicType) btvalue; 45.13 } 45.14 + 45.15 + // Want a pattern to quickly diff against layout header in register 45.16 + // find something less clever! 45.17 + static int layout_helper_boolean_diffbit() { 45.18 + jint zlh = array_layout_helper(T_BOOLEAN); 45.19 + jint blh = array_layout_helper(T_BYTE); 45.20 + assert(zlh != blh, "array layout helpers must differ"); 45.21 + int diffbit = 1; 45.22 + while ((diffbit & (zlh ^ blh)) == 0 && (diffbit & zlh) == 0) { 45.23 + diffbit <<= 1; 45.24 + assert(diffbit != 0, "make sure T_BOOLEAN has a different bit than T_BYTE"); 45.25 + } 45.26 + return diffbit; 45.27 + } 45.28 + 45.29 static int layout_helper_log2_element_size(jint lh) { 45.30 assert(lh < (jint)_lh_neutral_value, "must be array"); 45.31 int l2esz = (lh >> _lh_log2_element_size_shift) & _lh_log2_element_size_mask;
46.1 --- a/src/share/vm/oops/method.cpp Thu Apr 21 16:19:33 2016 +0300 46.2 +++ b/src/share/vm/oops/method.cpp Mon Apr 25 21:03:53 2016 +0000 46.3 @@ -1,5 +1,5 @@ 46.4 /* 46.5 - * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved. 46.6 + * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. 46.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 46.8 * 46.9 * This code is free software; you can redistribute it and/or modify it 46.10 @@ -84,9 +84,6 @@ 46.11 set_constMethod(xconst); 46.12 set_access_flags(access_flags); 46.13 set_method_size(size); 46.14 -#ifdef CC_INTERP 46.15 - set_result_index(T_VOID); 46.16 -#endif 46.17 set_intrinsic_id(vmIntrinsics::_none); 46.18 set_jfr_towrite(false); 46.19 set_force_inline(false); 46.20 @@ -412,12 +409,6 @@ 46.21 set_size_of_parameters(asc.size() + (is_static() ? 0 : 1)); 46.22 } 46.23 46.24 -#ifdef CC_INTERP 46.25 -void Method::set_result_index(BasicType type) { 46.26 - _result_index = Interpreter::BasicType_as_index(type); 46.27 -} 46.28 -#endif 46.29 - 46.30 BasicType Method::result_type() const { 46.31 ResultTypeFinder rtf(signature()); 46.32 return rtf.type(); 46.33 @@ -1123,10 +1114,8 @@ 46.34 m->set_signature_index(_imcp_invoke_signature); 46.35 assert(MethodHandles::is_signature_polymorphic_name(m->name()), ""); 46.36 assert(m->signature() == signature, ""); 46.37 -#ifdef CC_INTERP 46.38 ResultTypeFinder rtf(signature); 46.39 - m->set_result_index(rtf.type()); 46.40 -#endif 46.41 + m->constMethod()->set_result_type(rtf.type()); 46.42 m->compute_size_of_parameters(THREAD); 46.43 m->init_intrinsic_id(); 46.44 assert(m->is_method_handle_intrinsic(), "");
47.1 --- a/src/share/vm/oops/method.hpp Thu Apr 21 16:19:33 2016 +0300 47.2 +++ b/src/share/vm/oops/method.hpp Mon Apr 25 21:03:53 2016 +0000 47.3 @@ -1,5 +1,5 @@ 47.4 /* 47.5 - * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved. 47.6 + * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. 47.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 47.8 * 47.9 * This code is free software; you can redistribute it and/or modify it 47.10 @@ -105,9 +105,6 @@ 47.11 AccessFlags _access_flags; // Access flags 47.12 int _vtable_index; // vtable index of this method (see VtableIndexFlag) 47.13 // note: can have vtables with >2**16 elements (because of inheritance) 47.14 -#ifdef CC_INTERP 47.15 - int _result_index; // C++ interpreter needs for converting results to/from stack 47.16 -#endif 47.17 u2 _method_size; // size of this object 47.18 u1 _intrinsic_id; // vmSymbols::intrinsic_id (0 == _none) 47.19 u1 _jfr_towrite : 1, // Flags 47.20 @@ -202,11 +199,6 @@ 47.21 return constMethod()->type_annotations(); 47.22 } 47.23 47.24 -#ifdef CC_INTERP 47.25 - void set_result_index(BasicType type); 47.26 - int result_index() { return _result_index; } 47.27 -#endif 47.28 - 47.29 // Helper routine: get klass name + "." + method name + signature as 47.30 // C string, for the purpose of providing more useful NoSuchMethodErrors 47.31 // and fatal error handling. The string is allocated in resource 47.32 @@ -559,7 +551,6 @@ 47.33 void compute_size_of_parameters(Thread *thread); // word size of parameters (receiver if any + arguments) 47.34 Symbol* klass_name() const; // returns the name of the method holder 47.35 BasicType result_type() const; // type of the method result 47.36 - int result_type_index() const; // type index of the method result 47.37 bool is_returning_oop() const { BasicType r = result_type(); return (r == T_OBJECT || r == T_ARRAY); } 47.38 bool is_returning_fp() const { BasicType r = result_type(); return (r == T_FLOAT || r == T_DOUBLE); } 47.39 47.40 @@ -652,9 +643,6 @@ 47.41 // interpreter support 47.42 static ByteSize const_offset() { return byte_offset_of(Method, _constMethod ); } 47.43 static ByteSize access_flags_offset() { return byte_offset_of(Method, _access_flags ); } 47.44 -#ifdef CC_INTERP 47.45 - static ByteSize result_index_offset() { return byte_offset_of(Method, _result_index ); } 47.46 -#endif /* CC_INTERP */ 47.47 static ByteSize from_compiled_offset() { return byte_offset_of(Method, _from_compiled_entry); } 47.48 static ByteSize code_offset() { return byte_offset_of(Method, _code); } 47.49 static ByteSize method_data_offset() {
48.1 --- a/src/share/vm/oops/oop.inline.hpp Thu Apr 21 16:19:33 2016 +0300 48.2 +++ b/src/share/vm/oops/oop.inline.hpp Mon Apr 25 21:03:53 2016 +0000 48.3 @@ -1,5 +1,5 @@ 48.4 /* 48.5 - * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. 48.6 + * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. 48.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 48.8 * 48.9 * This code is free software; you can redistribute it and/or modify it 48.10 @@ -339,7 +339,7 @@ 48.11 inline void oopDesc::byte_field_put(int offset, jbyte contents) { *byte_field_addr(offset) = (jint) contents; } 48.12 48.13 inline jboolean oopDesc::bool_field(int offset) const { return (jboolean) *bool_field_addr(offset); } 48.14 -inline void oopDesc::bool_field_put(int offset, jboolean contents) { *bool_field_addr(offset) = (jint) contents; } 48.15 +inline void oopDesc::bool_field_put(int offset, jboolean contents) { *bool_field_addr(offset) = (( (jint) contents) & 1); } 48.16 48.17 inline jchar oopDesc::char_field(int offset) const { return (jchar) *char_field_addr(offset); } 48.18 inline void oopDesc::char_field_put(int offset, jchar contents) { *char_field_addr(offset) = (jint) contents; } 48.19 @@ -379,7 +379,7 @@ 48.20 inline void oopDesc::release_byte_field_put(int offset, jbyte contents) { OrderAccess::release_store(byte_field_addr(offset), contents); } 48.21 48.22 inline jboolean oopDesc::bool_field_acquire(int offset) const { return OrderAccess::load_acquire(bool_field_addr(offset)); } 48.23 -inline void oopDesc::release_bool_field_put(int offset, jboolean contents) { OrderAccess::release_store(bool_field_addr(offset), contents); } 48.24 +inline void oopDesc::release_bool_field_put(int offset, jboolean contents) { OrderAccess::release_store(bool_field_addr(offset), (contents & 1)); } 48.25 48.26 inline jchar oopDesc::char_field_acquire(int offset) const { return OrderAccess::load_acquire(char_field_addr(offset)); } 48.27 inline void oopDesc::release_char_field_put(int offset, jchar contents) { OrderAccess::release_store(char_field_addr(offset), contents); }
49.1 --- a/src/share/vm/oops/typeArrayOop.hpp Thu Apr 21 16:19:33 2016 +0300 49.2 +++ b/src/share/vm/oops/typeArrayOop.hpp Mon Apr 25 21:03:53 2016 +0000 49.3 @@ -96,7 +96,7 @@ 49.4 void byte_at_put(int which, jbyte contents) { *byte_at_addr(which) = contents; } 49.5 49.6 jboolean bool_at(int which) const { return *bool_at_addr(which); } 49.7 - void bool_at_put(int which, jboolean contents) { *bool_at_addr(which) = contents; } 49.8 + void bool_at_put(int which, jboolean contents) { *bool_at_addr(which) = (((jint)contents) & 1); } 49.9 49.10 jchar char_at(int which) const { return *char_at_addr(which); } 49.11 void char_at_put(int which, jchar contents) { *char_at_addr(which) = contents; }
50.1 --- a/src/share/vm/opto/c2compiler.cpp Thu Apr 21 16:19:33 2016 +0300 50.2 +++ b/src/share/vm/opto/c2compiler.cpp Mon Apr 25 21:03:53 2016 +0000 50.3 @@ -49,6 +49,9 @@ 50.4 const char* C2Compiler::retry_no_escape_analysis() { 50.5 return "retry without escape analysis"; 50.6 } 50.7 +const char* C2Compiler::retry_class_loading_during_parsing() { 50.8 + return "retry class loading during parsing"; 50.9 +} 50.10 bool C2Compiler::init_c2_runtime() { 50.11 50.12 // Check assumptions used while running ADLC 50.13 @@ -115,6 +118,10 @@ 50.14 50.15 // Check result and retry if appropriate. 50.16 if (C.failure_reason() != NULL) { 50.17 + if (C.failure_reason_is(retry_class_loading_during_parsing())) { 50.18 + env->record_failure(C.failure_reason()); 50.19 + continue; // retry 50.20 + } 50.21 if (C.failure_reason_is(retry_no_subsuming_loads())) { 50.22 assert(subsume_loads, "must make progress"); 50.23 subsume_loads = false;
51.1 --- a/src/share/vm/opto/c2compiler.hpp Thu Apr 21 16:19:33 2016 +0300 51.2 +++ b/src/share/vm/opto/c2compiler.hpp Mon Apr 25 21:03:53 2016 +0000 51.3 @@ -49,6 +49,7 @@ 51.4 // sentinel value used to trigger backtracking in compile_method(). 51.5 static const char* retry_no_subsuming_loads(); 51.6 static const char* retry_no_escape_analysis(); 51.7 + static const char* retry_class_loading_during_parsing(); 51.8 51.9 // Print compilation timers and statistics 51.10 void print_timers();
52.1 --- a/src/share/vm/opto/cfgnode.cpp Thu Apr 21 16:19:33 2016 +0300 52.2 +++ b/src/share/vm/opto/cfgnode.cpp Mon Apr 25 21:03:53 2016 +0000 52.3 @@ -973,7 +973,7 @@ 52.4 #ifdef ASSERT 52.5 // The following logic has been moved into TypeOopPtr::filter. 52.6 const Type* jt = t->join_speculative(_type); 52.7 - if( jt->empty() ) { // Emptied out??? 52.8 + if (jt->empty()) { // Emptied out??? 52.9 52.10 // Check for evil case of 't' being a class and '_type' expecting an 52.11 // interface. This can happen because the bytecodes do not contain 52.12 @@ -984,14 +984,21 @@ 52.13 // be 'I' or 'j/l/O'. Thus we'll pick 'j/l/O'. If this then flows 52.14 // into a Phi which "knows" it's an Interface type we'll have to 52.15 // uplift the type. 52.16 - if( !t->empty() && ttip && ttip->is_loaded() && ttip->klass()->is_interface() ) 52.17 - { assert(ft == _type, ""); } // Uplift to interface 52.18 - else if( !t->empty() && ttkp && ttkp->is_loaded() && ttkp->klass()->is_interface() ) 52.19 - { assert(ft == _type, ""); } // Uplift to interface 52.20 - // Otherwise it's something stupid like non-overlapping int ranges 52.21 - // found on dying counted loops. 52.22 - else 52.23 - { assert(ft == Type::TOP, ""); } // Canonical empty value 52.24 + if (!t->empty() && ttip && ttip->is_loaded() && ttip->klass()->is_interface()) { 52.25 + assert(ft == _type, ""); // Uplift to interface 52.26 + } else if (!t->empty() && ttkp && ttkp->is_loaded() && ttkp->klass()->is_interface()) { 52.27 + assert(ft == _type, ""); // Uplift to interface 52.28 + } else { 52.29 + // We also have to handle 'evil cases' of interface- vs. class-arrays 52.30 + Type::get_arrays_base_elements(jt, _type, NULL, &ttip); 52.31 + if (!t->empty() && ttip != NULL && ttip->is_loaded() && ttip->klass()->is_interface()) { 52.32 + assert(ft == _type, ""); // Uplift to array of interface 52.33 + } else { 52.34 + // Otherwise it's something stupid like non-overlapping int ranges 52.35 + // found on dying counted loops. 52.36 + assert(ft == Type::TOP, ""); // Canonical empty value 52.37 + } 52.38 + } 52.39 } 52.40 52.41 else {
53.1 --- a/src/share/vm/opto/compile.cpp Thu Apr 21 16:19:33 2016 +0300 53.2 +++ b/src/share/vm/opto/compile.cpp Mon Apr 25 21:03:53 2016 +0000 53.3 @@ -795,7 +795,9 @@ 53.4 } 53.5 JVMState* jvms = build_start_state(start(), tf()); 53.6 if ((jvms = cg->generate(jvms)) == NULL) { 53.7 - record_method_not_compilable("method parse failed"); 53.8 + if (!failure_reason_is(C2Compiler::retry_class_loading_during_parsing())) { 53.9 + record_method_not_compilable("method parse failed"); 53.10 + } 53.11 return; 53.12 } 53.13 GraphKit kit(jvms);
54.1 --- a/src/share/vm/opto/memnode.cpp Thu Apr 21 16:19:33 2016 +0300 54.2 +++ b/src/share/vm/opto/memnode.cpp Mon Apr 25 21:03:53 2016 +0000 54.3 @@ -1,5 +1,5 @@ 54.4 /* 54.5 - * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. 54.6 + * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. 54.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 54.8 * 54.9 * This code is free software; you can redistribute it and/or modify it 54.10 @@ -2370,7 +2370,7 @@ 54.11 ctl != NULL, "raw memory operations should have control edge"); 54.12 54.13 switch (bt) { 54.14 - case T_BOOLEAN: 54.15 + case T_BOOLEAN: val = gvn.transform(new (C) AndINode(val, gvn.intcon(0x1))); // Fall through to T_BYTE case 54.16 case T_BYTE: return new (C) StoreBNode(ctl, mem, adr, adr_type, val, mo); 54.17 case T_INT: return new (C) StoreINode(ctl, mem, adr, adr_type, val, mo); 54.18 case T_CHAR:
55.1 --- a/src/share/vm/opto/parse1.cpp Thu Apr 21 16:19:33 2016 +0300 55.2 +++ b/src/share/vm/opto/parse1.cpp Mon Apr 25 21:03:53 2016 +0000 55.3 @@ -1,5 +1,5 @@ 55.4 /* 55.5 - * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. 55.6 + * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. 55.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 55.8 * 55.9 * This code is free software; you can redistribute it and/or modify it 55.10 @@ -27,6 +27,7 @@ 55.11 #include "interpreter/linkResolver.hpp" 55.12 #include "oops/method.hpp" 55.13 #include "opto/addnode.hpp" 55.14 +#include "opto/c2compiler.hpp" 55.15 #include "opto/idealGraphPrinter.hpp" 55.16 #include "opto/locknode.hpp" 55.17 #include "opto/memnode.hpp" 55.18 @@ -717,6 +718,27 @@ 55.19 #endif 55.20 } 55.21 55.22 +static Node* mask_int_value(Node* v, BasicType bt, PhaseGVN* gvn) { 55.23 + Compile* C = gvn->C; 55.24 + switch (bt) { 55.25 + case T_BYTE: 55.26 + v = gvn->transform(new (C) LShiftINode(v, gvn->intcon(24))); 55.27 + v = gvn->transform(new (C) RShiftINode(v, gvn->intcon(24))); 55.28 + break; 55.29 + case T_SHORT: 55.30 + v = gvn->transform(new (C) LShiftINode(v, gvn->intcon(16))); 55.31 + v = gvn->transform(new (C) RShiftINode(v, gvn->intcon(16))); 55.32 + break; 55.33 + case T_CHAR: 55.34 + v = gvn->transform(new (C) AndINode(v, gvn->intcon(0xFFFF))); 55.35 + break; 55.36 + case T_BOOLEAN: 55.37 + v = gvn->transform(new (C) AndINode(v, gvn->intcon(0x1))); 55.38 + break; 55.39 + } 55.40 + return v; 55.41 +} 55.42 + 55.43 //-------------------------------build_exits---------------------------------- 55.44 // Build normal and exceptional exit merge points. 55.45 void Parse::build_exits() { 55.46 @@ -741,6 +763,16 @@ 55.47 // Add a return value to the exit state. (Do not push it yet.) 55.48 if (tf()->range()->cnt() > TypeFunc::Parms) { 55.49 const Type* ret_type = tf()->range()->field_at(TypeFunc::Parms); 55.50 + if (ret_type->isa_int()) { 55.51 + BasicType ret_bt = method()->return_type()->basic_type(); 55.52 + if (ret_bt == T_BOOLEAN || 55.53 + ret_bt == T_CHAR || 55.54 + ret_bt == T_BYTE || 55.55 + ret_bt == T_SHORT) { 55.56 + ret_type = TypeInt::INT; 55.57 + } 55.58 + } 55.59 + 55.60 // Don't "bind" an unloaded return klass to the ret_phi. If the klass 55.61 // becomes loaded during the subsequent parsing, the loaded and unloaded 55.62 // types will not join when we transform and push in do_exits(). 55.63 @@ -957,7 +989,27 @@ 55.64 if (tf()->range()->cnt() > TypeFunc::Parms) { 55.65 const Type* ret_type = tf()->range()->field_at(TypeFunc::Parms); 55.66 Node* ret_phi = _gvn.transform( _exits.argument(0) ); 55.67 - assert(_exits.control()->is_top() || !_gvn.type(ret_phi)->empty(), "return value must be well defined"); 55.68 + if (!_exits.control()->is_top() && _gvn.type(ret_phi)->empty()) { 55.69 + // In case of concurrent class loading, the type we set for the 55.70 + // ret_phi in build_exits() may have been too optimistic and the 55.71 + // ret_phi may be top now. 55.72 + // Otherwise, we've encountered an error and have to mark the method as 55.73 + // not compilable. Just using an assertion instead would be dangerous 55.74 + // as this could lead to an infinite compile loop in non-debug builds. 55.75 + { 55.76 + MutexLockerEx ml(Compile_lock, Mutex::_no_safepoint_check_flag); 55.77 + if (C->env()->system_dictionary_modification_counter_changed()) { 55.78 + C->record_failure(C2Compiler::retry_class_loading_during_parsing()); 55.79 + } else { 55.80 + C->record_method_not_compilable("Can't determine return type."); 55.81 + } 55.82 + } 55.83 + return; 55.84 + } 55.85 + if (ret_type->isa_int()) { 55.86 + BasicType ret_bt = method()->return_type()->basic_type(); 55.87 + ret_phi = mask_int_value(ret_phi, ret_bt, &_gvn); 55.88 + } 55.89 _exits.push_node(ret_type->basic_type(), ret_phi); 55.90 } 55.91 55.92 @@ -2081,15 +2133,24 @@ 55.93 // here. 55.94 Node* phi = _exits.argument(0); 55.95 const TypeInstPtr *tr = phi->bottom_type()->isa_instptr(); 55.96 - if( tr && tr->klass()->is_loaded() && 55.97 - tr->klass()->is_interface() ) { 55.98 + if (tr && tr->klass()->is_loaded() && 55.99 + tr->klass()->is_interface()) { 55.100 const TypeInstPtr *tp = value->bottom_type()->isa_instptr(); 55.101 if (tp && tp->klass()->is_loaded() && 55.102 !tp->klass()->is_interface()) { 55.103 // sharpen the type eagerly; this eases certain assert checking 55.104 if (tp->higher_equal(TypeInstPtr::NOTNULL)) 55.105 tr = tr->join_speculative(TypeInstPtr::NOTNULL)->is_instptr(); 55.106 - value = _gvn.transform(new (C) CheckCastPPNode(0,value,tr)); 55.107 + value = _gvn.transform(new (C) CheckCastPPNode(0, value, tr)); 55.108 + } 55.109 + } else { 55.110 + // Also handle returns of oop-arrays to an arrays-of-interface return 55.111 + const TypeInstPtr* phi_tip; 55.112 + const TypeInstPtr* val_tip; 55.113 + Type::get_arrays_base_elements(phi->bottom_type(), value->bottom_type(), &phi_tip, &val_tip); 55.114 + if (phi_tip != NULL && phi_tip->is_loaded() && phi_tip->klass()->is_interface() && 55.115 + val_tip != NULL && val_tip->is_loaded() && !val_tip->klass()->is_interface()) { 55.116 + value = _gvn.transform(new (C) CheckCastPPNode(0, value, phi->bottom_type())); 55.117 } 55.118 } 55.119 phi->add_req(value);
56.1 --- a/src/share/vm/opto/parse2.cpp Thu Apr 21 16:19:33 2016 +0300 56.2 +++ b/src/share/vm/opto/parse2.cpp Mon Apr 25 21:03:53 2016 +0000 56.3 @@ -1,5 +1,5 @@ 56.4 /* 56.5 - * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved. 56.6 + * Copyright (c) 1998, 2016, Oracle and/or its affiliates. All rights reserved. 56.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 56.8 * 56.9 * This code is free software; you can redistribute it and/or modify it 56.10 @@ -57,11 +57,15 @@ 56.11 56.12 //--------------------------------array_store---------------------------------- 56.13 void Parse::array_store(BasicType elem_type) { 56.14 - Node* adr = array_addressing(elem_type, 1); 56.15 + const Type* elem = Type::TOP; 56.16 + Node* adr = array_addressing(elem_type, 1, &elem); 56.17 if (stopped()) return; // guaranteed null or range check 56.18 Node* val = pop(); 56.19 dec_sp(2); // Pop array and index 56.20 const TypeAryPtr* adr_type = TypeAryPtr::get_array_body_type(elem_type); 56.21 + if (elem == TypeInt::BOOL) { 56.22 + elem_type = T_BOOLEAN; 56.23 + } 56.24 store_to_memory(control(), adr, val, elem_type, adr_type, StoreNode::release_if_reference(elem_type)); 56.25 } 56.26
57.1 --- a/src/share/vm/opto/type.cpp Thu Apr 21 16:19:33 2016 +0300 57.2 +++ b/src/share/vm/opto/type.cpp Mon Apr 25 21:03:53 2016 +0000 57.3 @@ -1,5 +1,5 @@ 57.4 /* 57.5 - * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. 57.6 + * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. 57.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 57.8 * 57.9 * This code is free software; you can redistribute it and/or modify it 57.10 @@ -149,6 +149,33 @@ 57.11 return bt; 57.12 } 57.13 57.14 +// For two instance arrays of same dimension, return the base element types. 57.15 +// Otherwise or if the arrays have different dimensions, return NULL. 57.16 +void Type::get_arrays_base_elements(const Type *a1, const Type *a2, 57.17 + const TypeInstPtr **e1, const TypeInstPtr **e2) { 57.18 + 57.19 + if (e1) *e1 = NULL; 57.20 + if (e2) *e2 = NULL; 57.21 + const TypeAryPtr* a1tap = (a1 == NULL) ? NULL : a1->isa_aryptr(); 57.22 + const TypeAryPtr* a2tap = (a2 == NULL) ? NULL : a2->isa_aryptr(); 57.23 + 57.24 + if (a1tap != NULL && a2tap != NULL) { 57.25 + // Handle multidimensional arrays 57.26 + const TypePtr* a1tp = a1tap->elem()->make_ptr(); 57.27 + const TypePtr* a2tp = a2tap->elem()->make_ptr(); 57.28 + while (a1tp && a1tp->isa_aryptr() && a2tp && a2tp->isa_aryptr()) { 57.29 + a1tap = a1tp->is_aryptr(); 57.30 + a2tap = a2tp->is_aryptr(); 57.31 + a1tp = a1tap->elem()->make_ptr(); 57.32 + a2tp = a2tap->elem()->make_ptr(); 57.33 + } 57.34 + if (a1tp && a1tp->isa_instptr() && a2tp && a2tp->isa_instptr()) { 57.35 + if (e1) *e1 = a1tp->is_instptr(); 57.36 + if (e2) *e2 = a2tp->is_instptr(); 57.37 + } 57.38 + } 57.39 +} 57.40 + 57.41 //---------------------------get_typeflow_type--------------------------------- 57.42 // Import a type produced by ciTypeFlow. 57.43 const Type* Type::get_typeflow_type(ciType* type) { 57.44 @@ -1767,13 +1794,15 @@ 57.45 break; 57.46 case T_OBJECT: 57.47 case T_ARRAY: 57.48 + case T_FLOAT: 57.49 + case T_INT: 57.50 + field_array[pos++] = get_const_type(type); 57.51 + break; 57.52 case T_BOOLEAN: 57.53 case T_CHAR: 57.54 - case T_FLOAT: 57.55 case T_BYTE: 57.56 case T_SHORT: 57.57 - case T_INT: 57.58 - field_array[pos++] = get_const_type(type); 57.59 + field_array[pos++] = TypeInt::INT; 57.60 break; 57.61 default: 57.62 ShouldNotReachHere(); 57.63 @@ -1982,7 +2011,11 @@ 57.64 bool TypeAry::interface_vs_oop(const Type *t) const { 57.65 const TypeAry* t_ary = t->is_ary(); 57.66 if (t_ary) { 57.67 - return _elem->interface_vs_oop(t_ary->_elem); 57.68 + const TypePtr* this_ptr = _elem->make_ptr(); // In case we have narrow_oops 57.69 + const TypePtr* t_ptr = t_ary->_elem->make_ptr(); 57.70 + if(this_ptr != NULL && t_ptr != NULL) { 57.71 + return this_ptr->interface_vs_oop(t_ptr); 57.72 + } 57.73 } 57.74 return false; 57.75 } 57.76 @@ -2834,8 +2867,17 @@ 57.77 // be 'I' or 'j/l/O'. Thus we'll pick 'j/l/O'. If this then flows 57.78 // into a Phi which "knows" it's an Interface type we'll have to 57.79 // uplift the type. 57.80 - if (!empty() && ktip != NULL && ktip->is_loaded() && ktip->klass()->is_interface()) 57.81 - return kills; // Uplift to interface 57.82 + if (!empty()) { 57.83 + if (ktip != NULL && ktip->is_loaded() && ktip->klass()->is_interface()) { 57.84 + return kills; // Uplift to interface 57.85 + } 57.86 + // Also check for evil cases of 'this' being a class array 57.87 + // and 'kills' expecting an array of interfaces. 57.88 + Type::get_arrays_base_elements(ft, kills, NULL, &ktip); 57.89 + if (ktip != NULL && ktip->is_loaded() && ktip->klass()->is_interface()) { 57.90 + return kills; // Uplift to array of interface 57.91 + } 57.92 + } 57.93 57.94 return Type::TOP; // Canonical empty value 57.95 }
58.1 --- a/src/share/vm/opto/type.hpp Thu Apr 21 16:19:33 2016 +0300 58.2 +++ b/src/share/vm/opto/type.hpp Mon Apr 25 21:03:53 2016 +0000 58.3 @@ -367,6 +367,11 @@ 58.4 return _const_basic_type[type]; 58.5 } 58.6 58.7 + // For two instance arrays of same dimension, return the base element types. 58.8 + // Otherwise or if the arrays have different dimensions, return NULL. 58.9 + static void get_arrays_base_elements(const Type *a1, const Type *a2, 58.10 + const TypeInstPtr **e1, const TypeInstPtr **e2); 58.11 + 58.12 // Mapping to the array element's basic type. 58.13 BasicType array_element_basic_type() const; 58.14
59.1 --- a/src/share/vm/prims/jni.cpp Thu Apr 21 16:19:33 2016 +0300 59.2 +++ b/src/share/vm/prims/jni.cpp Mon Apr 25 21:03:53 2016 +0000 59.3 @@ -1,5 +1,5 @@ 59.4 /* 59.5 - * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. 59.6 + * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. 59.7 * Copyright (c) 2012 Red Hat, Inc. 59.8 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 59.9 * 59.10 @@ -1121,7 +1121,14 @@ 59.11 protected: 59.12 va_list _ap; 59.13 59.14 - inline void get_bool() { _arguments->push_int(va_arg(_ap, jint)); } // bool is coerced to int when using va_arg 59.15 + inline void get_bool() { 59.16 + // Normalize boolean arguments from native code by converting 1-255 to JNI_TRUE and 59.17 + // 0 to JNI_FALSE. Boolean return values from native are normalized the same in 59.18 + // TemplateInterpreterGenerator::generate_result_handler_for and 59.19 + // SharedRuntime::generate_native_wrapper. 59.20 + jboolean b = va_arg(_ap, jint); 59.21 + _arguments->push_int((jint)(b == 0 ? JNI_FALSE : JNI_TRUE)); 59.22 + } 59.23 inline void get_char() { _arguments->push_int(va_arg(_ap, jint)); } // char is coerced to int when using va_arg 59.24 inline void get_short() { _arguments->push_int(va_arg(_ap, jint)); } // short is coerced to int when using va_arg 59.25 inline void get_byte() { _arguments->push_int(va_arg(_ap, jint)); } // byte is coerced to int when using va_arg 59.26 @@ -1167,9 +1174,17 @@ 59.27 while ( 1 ) { 59.28 switch ( fingerprint & parameter_feature_mask ) { 59.29 case bool_parm: 59.30 + get_bool(); 59.31 + break; 59.32 case char_parm: 59.33 + get_char(); 59.34 + break; 59.35 case short_parm: 59.36 + get_short(); 59.37 + break; 59.38 case byte_parm: 59.39 + get_byte(); 59.40 + break; 59.41 case int_parm: 59.42 get_int(); 59.43 break; 59.44 @@ -1203,7 +1218,14 @@ 59.45 protected: 59.46 const jvalue *_ap; 59.47 59.48 - inline void get_bool() { _arguments->push_int((jint)(_ap++)->z); } 59.49 + inline void get_bool() { 59.50 + // Normalize boolean arguments from native code by converting 1-255 to JNI_TRUE and 59.51 + // 0 to JNI_FALSE. Boolean return values from native are normalized the same in 59.52 + // TemplateInterpreterGenerator::generate_result_handler_for and 59.53 + // SharedRuntime::generate_native_wrapper. 59.54 + jboolean b = (_ap++)->z; 59.55 + _arguments->push_int((jint)(b == 0 ? JNI_FALSE : JNI_TRUE)); 59.56 + } 59.57 inline void get_char() { _arguments->push_int((jint)(_ap++)->c); } 59.58 inline void get_short() { _arguments->push_int((jint)(_ap++)->s); } 59.59 inline void get_byte() { _arguments->push_int((jint)(_ap++)->b); } 59.60 @@ -2828,6 +2850,7 @@ 59.61 field_value.unionType = value; \ 59.62 o = JvmtiExport::jni_SetField_probe_nh(thread, obj, o, k, fieldID, false, SigType, (jvalue *)&field_value); \ 59.63 } \ 59.64 + if (SigType == 'Z') { value = ((jboolean)value) & 1; } \ 59.65 o->Fieldname##_field_put(offset, value); \ 59.66 ReturnProbe; \ 59.67 JNI_END 59.68 @@ -3132,6 +3155,7 @@ 59.69 field_value.unionType = value; \ 59.70 JvmtiExport::jni_SetField_probe(thread, NULL, NULL, id->holder(), fieldID, true, SigType, (jvalue *)&field_value); \ 59.71 } \ 59.72 + if (SigType == 'Z') { value = ((jboolean)value) & 1; } \ 59.73 id->holder()->java_mirror()-> Fieldname##_field_put (id->offset(), value); \ 59.74 ReturnProbe;\ 59.75 JNI_END
60.1 --- a/src/share/vm/prims/jvmtiEnvBase.cpp Thu Apr 21 16:19:33 2016 +0300 60.2 +++ b/src/share/vm/prims/jvmtiEnvBase.cpp Mon Apr 25 21:03:53 2016 +0000 60.3 @@ -1,5 +1,5 @@ 60.4 /* 60.5 - * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. 60.6 + * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved. 60.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 60.8 * 60.9 * This code is free software; you can redistribute it and/or modify it 60.10 @@ -1348,7 +1348,7 @@ 60.11 ResultTypeFinder rtf(signature); 60.12 TosState fr_tos = as_TosState(rtf.type()); 60.13 if (fr_tos != tos) { 60.14 - if (tos != itos || (fr_tos != btos && fr_tos != ctos && fr_tos != stos)) { 60.15 + if (tos != itos || (fr_tos != btos && fr_tos != ztos && fr_tos != ctos && fr_tos != stos)) { 60.16 return JVMTI_ERROR_TYPE_MISMATCH; 60.17 } 60.18 }
61.1 --- a/src/share/vm/prims/jvmtiExport.cpp Thu Apr 21 16:19:33 2016 +0300 61.2 +++ b/src/share/vm/prims/jvmtiExport.cpp Mon Apr 25 21:03:53 2016 +0000 61.3 @@ -1,5 +1,5 @@ 61.4 /* 61.5 - * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved. 61.6 + * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved. 61.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 61.8 * 61.9 * This code is free software; you can redistribute it and/or modify it 61.10 @@ -1588,7 +1588,7 @@ 61.11 address location, KlassHandle field_klass, Handle object, jfieldID field, 61.12 char sig_type, jvalue *value) { 61.13 61.14 - if (sig_type == 'I' || sig_type == 'Z' || sig_type == 'C' || sig_type == 'S') { 61.15 + if (sig_type == 'I' || sig_type == 'Z' || sig_type == 'B' || sig_type == 'C' || sig_type == 'S') { 61.16 // 'I' instructions are used for byte, char, short and int. 61.17 // determine which it really is, and convert 61.18 fieldDescriptor fd;
62.1 --- a/src/share/vm/prims/unsafe.cpp Thu Apr 21 16:19:33 2016 +0300 62.2 +++ b/src/share/vm/prims/unsafe.cpp Mon Apr 25 21:03:53 2016 +0000 62.3 @@ -1,5 +1,5 @@ 62.4 /* 62.5 - * Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved. 62.6 + * Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved. 62.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 62.8 * 62.9 * This code is free software; you can redistribute it and/or modify it 62.10 @@ -156,13 +156,22 @@ 62.11 62.12 ///// Data in the Java heap. 62.13 62.14 +#define truncate_jboolean(x) ((x) & 1) 62.15 +#define truncate_jbyte(x) (x) 62.16 +#define truncate_jshort(x) (x) 62.17 +#define truncate_jchar(x) (x) 62.18 +#define truncate_jint(x) (x) 62.19 +#define truncate_jlong(x) (x) 62.20 +#define truncate_jfloat(x) (x) 62.21 +#define truncate_jdouble(x) (x) 62.22 + 62.23 #define GET_FIELD(obj, offset, type_name, v) \ 62.24 oop p = JNIHandles::resolve(obj); \ 62.25 type_name v = *(type_name*)index_oop_from_field_offset_long(p, offset) 62.26 62.27 #define SET_FIELD(obj, offset, type_name, x) \ 62.28 oop p = JNIHandles::resolve(obj); \ 62.29 - *(type_name*)index_oop_from_field_offset_long(p, offset) = x 62.30 + *(type_name*)index_oop_from_field_offset_long(p, offset) = truncate_##type_name(x) 62.31 62.32 #define GET_FIELD_VOLATILE(obj, offset, type_name, v) \ 62.33 oop p = JNIHandles::resolve(obj); \ 62.34 @@ -173,7 +182,7 @@ 62.35 62.36 #define SET_FIELD_VOLATILE(obj, offset, type_name, x) \ 62.37 oop p = JNIHandles::resolve(obj); \ 62.38 - OrderAccess::release_store_fence((volatile type_name*)index_oop_from_field_offset_long(p, offset), x); 62.39 + OrderAccess::release_store_fence((volatile type_name*)index_oop_from_field_offset_long(p, offset), truncate_##type_name(x)); 62.40 62.41 // Macros for oops that check UseCompressedOops 62.42
63.1 --- a/src/share/vm/runtime/deoptimization.cpp Thu Apr 21 16:19:33 2016 +0300 63.2 +++ b/src/share/vm/runtime/deoptimization.cpp Mon Apr 25 21:03:53 2016 +0000 63.3 @@ -1,5 +1,5 @@ 63.4 /* 63.5 - * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved. 63.6 + * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. 63.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 63.8 * 63.9 * This code is free software; you can redistribute it and/or modify it 63.10 @@ -847,13 +847,25 @@ 63.11 _obj->int_field_put(offset, (jint)*((jint*)&val)); 63.12 break; 63.13 63.14 - case T_SHORT: case T_CHAR: // 2 bytes 63.15 + case T_SHORT: 63.16 assert(value->type() == T_INT, "Agreement."); 63.17 val = value->get_int(); 63.18 _obj->short_field_put(offset, (jshort)*((jint*)&val)); 63.19 break; 63.20 63.21 - case T_BOOLEAN: case T_BYTE: // 1 byte 63.22 + case T_CHAR: 63.23 + assert(value->type() == T_INT, "Agreement."); 63.24 + val = value->get_int(); 63.25 + _obj->char_field_put(offset, (jchar)*((jint*)&val)); 63.26 + break; 63.27 + 63.28 + case T_BYTE: 63.29 + assert(value->type() == T_INT, "Agreement."); 63.30 + val = value->get_int(); 63.31 + _obj->byte_field_put(offset, (jbyte)*((jint*)&val)); 63.32 + break; 63.33 + 63.34 + case T_BOOLEAN: 63.35 assert(value->type() == T_INT, "Agreement."); 63.36 val = value->get_int(); 63.37 _obj->bool_field_put(offset, (jboolean)*((jint*)&val)); 63.38 @@ -899,13 +911,25 @@ 63.39 obj->int_at_put(index, (jint)*((jint*)&val)); 63.40 break; 63.41 63.42 - case T_SHORT: case T_CHAR: // 2 bytes 63.43 + case T_SHORT: 63.44 assert(value->type() == T_INT, "Agreement."); 63.45 val = value->get_int(); 63.46 obj->short_at_put(index, (jshort)*((jint*)&val)); 63.47 break; 63.48 63.49 - case T_BOOLEAN: case T_BYTE: // 1 byte 63.50 + case T_CHAR: 63.51 + assert(value->type() == T_INT, "Agreement."); 63.52 + val = value->get_int(); 63.53 + obj->char_at_put(index, (jchar)*((jint*)&val)); 63.54 + break; 63.55 + 63.56 + case T_BYTE: 63.57 + assert(value->type() == T_INT, "Agreement."); 63.58 + val = value->get_int(); 63.59 + obj->byte_at_put(index, (jbyte)*((jint*)&val)); 63.60 + break; 63.61 + 63.62 + case T_BOOLEAN: 63.63 assert(value->type() == T_INT, "Agreement."); 63.64 val = value->get_int(); 63.65 obj->bool_at_put(index, (jboolean)*((jint*)&val));
64.1 --- a/src/share/vm/runtime/reflection.cpp Thu Apr 21 16:19:33 2016 +0300 64.2 +++ b/src/share/vm/runtime/reflection.cpp Mon Apr 25 21:03:53 2016 +0000 64.3 @@ -1,5 +1,5 @@ 64.4 /* 64.5 - * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. 64.6 + * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. 64.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 64.8 * 64.9 * This code is free software; you can redistribute it and/or modify it 64.10 @@ -1101,7 +1101,7 @@ 64.11 void Reflection::narrow(jvalue* value, BasicType narrow_type, TRAPS) { 64.12 switch (narrow_type) { 64.13 case T_BOOLEAN: 64.14 - value->z = (jboolean) value->i; 64.15 + value->z = (jboolean) (value->i & 1); 64.16 return; 64.17 case T_BYTE: 64.18 value->b = (jbyte) value->i;
65.1 --- a/src/share/vm/services/heapDumper.cpp Thu Apr 21 16:19:33 2016 +0300 65.2 +++ b/src/share/vm/services/heapDumper.cpp Mon Apr 25 21:03:53 2016 +0000 65.3 @@ -468,7 +468,7 @@ 65.4 // flush and close dump file 65.5 if (is_open()) { 65.6 flush(); 65.7 - os::close(file_descriptor()); 65.8 + ::close(file_descriptor()); 65.9 set_file_descriptor(-1); 65.10 } 65.11 } 65.12 @@ -480,12 +480,11 @@ 65.13 ssize_t n = 0; 65.14 while (len > 0) { 65.15 uint tmp = (uint)MIN2(len, (size_t)UINT_MAX); 65.16 - n = os::write(file_descriptor(), pos, tmp); 65.17 + n = ::write(file_descriptor(), pos, tmp); 65.18 65.19 if (n < 0) { 65.20 - // EINTR cannot happen here, os::write will take care of that 65.21 set_error(strerror(errno)); 65.22 - os::close(file_descriptor()); 65.23 + ::close(file_descriptor()); 65.24 set_file_descriptor(-1); 65.25 return; 65.26 }
66.1 --- a/src/share/vm/utilities/globalDefinitions.hpp Thu Apr 21 16:19:33 2016 +0300 66.2 +++ b/src/share/vm/utilities/globalDefinitions.hpp Mon Apr 25 21:03:53 2016 +0000 66.3 @@ -1,5 +1,5 @@ 66.4 /* 66.5 - * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. 66.6 + * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. 66.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 66.8 * 66.9 * This code is free software; you can redistribute it and/or modify it 66.10 @@ -796,14 +796,15 @@ 66.11 66.12 enum TosState { // describes the tos cache contents 66.13 btos = 0, // byte, bool tos cached 66.14 - ctos = 1, // char tos cached 66.15 - stos = 2, // short tos cached 66.16 - itos = 3, // int tos cached 66.17 - ltos = 4, // long tos cached 66.18 - ftos = 5, // float tos cached 66.19 - dtos = 6, // double tos cached 66.20 - atos = 7, // object cached 66.21 - vtos = 8, // tos not cached 66.22 + ztos = 1, // byte, bool tos cached 66.23 + ctos = 2, // char tos cached 66.24 + stos = 3, // short tos cached 66.25 + itos = 4, // int tos cached 66.26 + ltos = 5, // long tos cached 66.27 + ftos = 6, // float tos cached 66.28 + dtos = 7, // double tos cached 66.29 + atos = 8, // object cached 66.30 + vtos = 9, // tos not cached 66.31 number_of_states, 66.32 ilgl // illegal state: should not occur 66.33 }; 66.34 @@ -812,7 +813,7 @@ 66.35 inline TosState as_TosState(BasicType type) { 66.36 switch (type) { 66.37 case T_BYTE : return btos; 66.38 - case T_BOOLEAN: return btos; // FIXME: Add ztos 66.39 + case T_BOOLEAN: return ztos; 66.40 case T_CHAR : return ctos; 66.41 case T_SHORT : return stos; 66.42 case T_INT : return itos; 66.43 @@ -828,8 +829,8 @@ 66.44 66.45 inline BasicType as_BasicType(TosState state) { 66.46 switch (state) { 66.47 - //case ztos: return T_BOOLEAN;//FIXME 66.48 case btos : return T_BYTE; 66.49 + case ztos : return T_BOOLEAN; 66.50 case ctos : return T_CHAR; 66.51 case stos : return T_SHORT; 66.52 case itos : return T_INT;
67.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 67.2 +++ b/test/compiler/types/TestMeetIncompatibleInterfaceArrays.java Mon Apr 25 21:03:53 2016 +0000 67.3 @@ -0,0 +1,351 @@ 67.4 +/* 67.5 + * Copyright 2015 SAP AG. All Rights Reserved. 67.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 67.7 + * 67.8 + * This code is free software; you can redistribute it and/or modify it 67.9 + * under the terms of the GNU General Public License version 2 only, as 67.10 + * published by the Free Software Foundation. 67.11 + * 67.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 67.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 67.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 67.15 + * version 2 for more details (a copy is included in the LICENSE file that 67.16 + * accompanied this code). 67.17 + * 67.18 + * You should have received a copy of the GNU General Public License version 67.19 + * 2 along with this work; if not, write to the Free Software Foundation, 67.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 67.21 + * 67.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 67.23 + * or visit www.oracle.com if you need additional information or have any 67.24 + * questions. 67.25 + */ 67.26 + 67.27 +/* 67.28 + * @test 67.29 + * @bug 8141551 67.30 + * @summary C2 can not handle returns with inccompatible interface arrays 67.31 + * @library /testlibrary /testlibrary/whitebox/ 67.32 + * @build sun.hotspot.WhiteBox 67.33 + * @run main ClassFileInstaller sun.hotspot.WhiteBox 67.34 + * sun.hotspot.WhiteBox$WhiteBoxPermission 67.35 + * @run main/othervm 67.36 + * -Xbootclasspath/a:. 67.37 + * -XX:+UnlockDiagnosticVMOptions 67.38 + * -XX:+WhiteBoxAPI 67.39 + * -Xbatch 67.40 + * -XX:CompileThreshold=1 67.41 + * -XX:-TieredCompilation 67.42 + * -XX:CICompilerCount=1 67.43 + * -XX:+PrintCompilation 67.44 + * -XX:+PrintInlining 67.45 + * -XX:CompileCommand=compileonly,MeetIncompatibleInterfaceArrays*.run 67.46 + * -XX:CompileCommand=dontinline,TestMeetIncompatibleInterfaceArrays$Helper.createI2* 67.47 + * -XX:CompileCommand=quiet 67.48 + * TestMeetIncompatibleInterfaceArrays 0 67.49 + * @run main/othervm 67.50 + * -Xbootclasspath/a:. 67.51 + * -XX:+UnlockDiagnosticVMOptions 67.52 + * -XX:+WhiteBoxAPI 67.53 + * -Xbatch 67.54 + * -XX:CompileThreshold=1 67.55 + * -XX:-TieredCompilation 67.56 + * -XX:CICompilerCount=1 67.57 + * -XX:+PrintCompilation 67.58 + * -XX:+PrintInlining 67.59 + * -XX:CompileCommand=compileonly,MeetIncompatibleInterfaceArrays*.run 67.60 + * -XX:CompileCommand=inline,TestMeetIncompatibleInterfaceArrays$Helper.createI2* 67.61 + * -XX:CompileCommand=quiet 67.62 + * TestMeetIncompatibleInterfaceArrays 1 67.63 + * @run main/othervm 67.64 + * -Xbootclasspath/a:. 67.65 + * -XX:+UnlockDiagnosticVMOptions 67.66 + * -XX:+WhiteBoxAPI 67.67 + * -Xbatch 67.68 + * -XX:CompileThreshold=1 67.69 + * -XX:Tier0InvokeNotifyFreqLog=0 -XX:Tier2InvokeNotifyFreqLog=0 -XX:Tier3InvokeNotifyFreqLog=0 -XX:Tier23InlineeNotifyFreqLog=0 67.70 + * -XX:Tier3InvocationThreshold=2 -XX:Tier3MinInvocationThreshold=2 -XX:Tier3CompileThreshold=2 67.71 + * -XX:Tier4InvocationThreshold=1 -XX:Tier4MinInvocationThreshold=1 -XX:Tier4CompileThreshold=1 67.72 + * -XX:+TieredCompilation 67.73 + * -XX:CICompilerCount=2 67.74 + * -XX:+PrintCompilation 67.75 + * -XX:+PrintInlining 67.76 + * -XX:CompileCommand=compileonly,MeetIncompatibleInterfaceArrays*.run 67.77 + * -XX:CompileCommand=compileonly,TestMeetIncompatibleInterfaceArrays$Helper.createI2* 67.78 + * -XX:CompileCommand=inline,TestMeetIncompatibleInterfaceArrays$Helper.createI2* 67.79 + * -XX:CompileCommand=quiet 67.80 + * TestMeetIncompatibleInterfaceArrays 2 67.81 + * 67.82 + * @author volker.simonis@gmail.com 67.83 + */ 67.84 + 67.85 +import java.io.FileOutputStream; 67.86 +import java.lang.reflect.InvocationTargetException; 67.87 +import java.lang.reflect.Method; 67.88 +import jdk.internal.org.objectweb.asm.ClassWriter; 67.89 +import jdk.internal.org.objectweb.asm.MethodVisitor; 67.90 +import static jdk.internal.org.objectweb.asm.Opcodes.*; 67.91 +import sun.hotspot.WhiteBox; 67.92 + 67.93 +public class TestMeetIncompatibleInterfaceArrays extends ClassLoader { 67.94 + 67.95 + private static final WhiteBox WB = WhiteBox.getWhiteBox(); 67.96 + 67.97 + public static interface I1 { public String getName(); } 67.98 + public static interface I2 { public String getName(); } 67.99 + public static class I2C implements I2 { public String getName() { return "I2";} } 67.100 + public static class I21C implements I2, I1 { public String getName() { return "I2 and I1";} } 67.101 + 67.102 + public static class Helper { 67.103 + public static I2 createI2Array0() { 67.104 + return new I2C(); 67.105 + } 67.106 + public static I2[] createI2Array1() { 67.107 + return new I2C[] { new I2C() }; 67.108 + } 67.109 + public static I2[][] createI2Array2() { 67.110 + return new I2C[][] { new I2C[] { new I2C() } }; 67.111 + } 67.112 + public static I2[][][] createI2Array3() { 67.113 + return new I2C[][][] { new I2C[][] { new I2C[] { new I2C() } } }; 67.114 + } 67.115 + public static I2[][][][] createI2Array4() { 67.116 + return new I2C[][][][] { new I2C[][][] { new I2C[][] { new I2C[] { new I2C() } } } }; 67.117 + } 67.118 + public static I2[][][][][] createI2Array5() { 67.119 + return new I2C[][][][][] { new I2C[][][][] { new I2C[][][] { new I2C[][] { new I2C[] { new I2C() } } } } }; 67.120 + } 67.121 + public static I2 createI21Array0() { 67.122 + return new I21C(); 67.123 + } 67.124 + public static I2[] createI21Array1() { 67.125 + return new I21C[] { new I21C() }; 67.126 + } 67.127 + public static I2[][] createI21Array2() { 67.128 + return new I21C[][] { new I21C[] { new I21C() } }; 67.129 + } 67.130 + public static I2[][][] createI21Array3() { 67.131 + return new I21C[][][] { new I21C[][] { new I21C[] { new I21C() } } }; 67.132 + } 67.133 + public static I2[][][][] createI21Array4() { 67.134 + return new I21C[][][][] { new I21C[][][] { new I21C[][] { new I21C[] { new I21C() } } } }; 67.135 + } 67.136 + public static I2[][][][][] createI21Array5() { 67.137 + return new I21C[][][][][] { new I21C[][][][] { new I21C[][][] { new I21C[][] { new I21C[] { new I21C() } } } } }; 67.138 + } 67.139 + } 67.140 + 67.141 + // Location for the generated class files 67.142 + public static final String PATH = System.getProperty("test.classes", ".") + java.io.File.separator; 67.143 + 67.144 + /* 67.145 + * With 'good == false' this helper method creates the following classes 67.146 + * (using the nested 'Helper' class and the nested interfaces 'I1' and 'I2'). 67.147 + * For brevity I omit the enclosing class 'TestMeetIncompatibleInterfaceArrays' in the 67.148 + * following examples: 67.149 + * 67.150 + * public class MeetIncompatibleInterfaceArrays0ASM { 67.151 + * public static I1 run() { 67.152 + * return Helper.createI2Array0(); // returns I2 67.153 + * } 67.154 + * public static void test() { 67.155 + * I1 i1 = run(); 67.156 + * System.out.println(i1.getName()); 67.157 + * } 67.158 + * } 67.159 + * public class MeetIncompatibleInterfaceArrays1ASM { 67.160 + * public static I1[] run() { 67.161 + * return Helper.createI2Array1(); // returns I2[] 67.162 + * } 67.163 + * public static void test() { 67.164 + * I1[] i1 = run(); 67.165 + * System.out.println(i1[0].getName()); 67.166 + * } 67.167 + * } 67.168 + * ... 67.169 + * // MeetIncompatibleInterfaceArrays4ASM is special because it creates 67.170 + * // an illegal class which will be rejected by the verifier. 67.171 + * public class MeetIncompatibleInterfaceArrays4ASM { 67.172 + * public static I1[][][][] run() { 67.173 + * return Helper.createI2Array3(); // returns I1[][][] which gives a verifier error because return expects I1[][][][] 67.174 + * } 67.175 + * public static void test() { 67.176 + * I1[][][][][] i1 = run(); 67.177 + * System.out.println(i1[0][0][0][0][0].getName()); 67.178 + * } 67.179 + * ... 67.180 + * public class MeetIncompatibleInterfaceArrays5ASM { 67.181 + * public static I1[][][][][] run() { 67.182 + * return Helper.createI2Array5(); // returns I2[][][][][] 67.183 + * } 67.184 + * public static void test() { 67.185 + * I1[][][][][] i1 = run(); 67.186 + * System.out.println(i1[0][0][0][0][0].getName()); 67.187 + * } 67.188 + * } 67.189 + * 67.190 + * Notice that this is not legal Java code. We would have to use a cast in "run()" to make it legal: 67.191 + * 67.192 + * public static I1[] run() { 67.193 + * return (I1[])Helper.createI2Array1(); // returns I2[] 67.194 + * } 67.195 + * 67.196 + * But in pure bytecode, the "run()" methods are perfectly legal: 67.197 + * 67.198 + * public static I1[] run(); 67.199 + * Code: 67.200 + * 0: invokestatic #16 // Method Helper.createI2Array1:()[LI2; 67.201 + * 3: areturn 67.202 + * 67.203 + * The "test()" method calls the "getName()" function from I1 on the objects returned by "run()". 67.204 + * This will epectedly fail with an "IncompatibleClassChangeError" because the objects returned 67.205 + * by "run()" (and by createI2Array()) are actually of type "I2C" and only implement "I2" but not "I1". 67.206 + * 67.207 + * 67.208 + * With 'good == true' this helper method will create the following classes: 67.209 + * 67.210 + * public class MeetIncompatibleInterfaceArraysGood0ASM { 67.211 + * public static I1 run() { 67.212 + * return Helper.createI21Array0(); // returns I2 67.213 + * } 67.214 + * public static void test() { 67.215 + * I1 i1 = run(); 67.216 + * System.out.println(i1.getName()); 67.217 + * } 67.218 + * } 67.219 + * 67.220 + * Calling "test()" on these objects will succeed and output "I2 and I1" because now the "run()" 67.221 + * method calls "createI21Array()" which actually return an object (or an array of objects) of 67.222 + * type "I21C" which implements both "I2" and "I1". 67.223 + * 67.224 + * Notice that at the bytecode level, the code for the "run()" and "test()" methods in 67.225 + * "MeetIncompatibleInterfaceArraysASM" and "MeetIncompatibleInterfaceArraysGoodASM" look exactly 67.226 + * the same. I.e. the verifier has no chance to verify if the I2 object returned by "createI1Array()" 67.227 + * or "createI21Array()" implements "I1" or not. That's actually the reason why both versions of 67.228 + * generated classes are legal from a verifier point of view. 67.229 + * 67.230 + */ 67.231 + static void generateTestClass(int dim, boolean good) throws Exception { 67.232 + String baseClassName = "MeetIncompatibleInterfaceArrays"; 67.233 + if (good) 67.234 + baseClassName += "Good"; 67.235 + String createName = "createI2" + (good ? "1" : "") + "Array"; 67.236 + String a = ""; 67.237 + for (int i = 0; i < dim; i++) 67.238 + a += "["; 67.239 + ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES); 67.240 + cw.visit(V1_8, ACC_PUBLIC, baseClassName + dim + "ASM", null, "java/lang/Object", null); 67.241 + MethodVisitor constr = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null); 67.242 + constr.visitCode(); 67.243 + constr.visitVarInsn(ALOAD, 0); 67.244 + constr.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false); 67.245 + constr.visitInsn(RETURN); 67.246 + constr.visitMaxs(0, 0); 67.247 + constr.visitEnd(); 67.248 + MethodVisitor run = cw.visitMethod(ACC_PUBLIC | ACC_STATIC, "run", 67.249 + "()" + a + "LTestMeetIncompatibleInterfaceArrays$I1;", null, null); 67.250 + run.visitCode(); 67.251 + if (dim == 4) { 67.252 + run.visitMethodInsn(INVOKESTATIC, "TestMeetIncompatibleInterfaceArrays$Helper", createName + 3, 67.253 + "()" + "[[[" + "LTestMeetIncompatibleInterfaceArrays$I2;", false); 67.254 + } else { 67.255 + run.visitMethodInsn(INVOKESTATIC, "TestMeetIncompatibleInterfaceArrays$Helper", createName + dim, 67.256 + "()" + a + "LTestMeetIncompatibleInterfaceArrays$I2;", false); 67.257 + } 67.258 + run.visitInsn(ARETURN); 67.259 + run.visitMaxs(0, 0); 67.260 + run.visitEnd(); 67.261 + MethodVisitor test = cw.visitMethod(ACC_PUBLIC | ACC_STATIC, "test", "()V", null, null); 67.262 + test.visitCode(); 67.263 + test.visitMethodInsn(INVOKESTATIC, baseClassName + dim + "ASM", "run", 67.264 + "()" + a + "LTestMeetIncompatibleInterfaceArrays$I1;", false); 67.265 + test.visitVarInsn(ASTORE, 0); 67.266 + if (dim > 0) { 67.267 + test.visitVarInsn(ALOAD, 0); 67.268 + for (int i = 1; i <= dim; i++) { 67.269 + test.visitInsn(ICONST_0); 67.270 + test.visitInsn(AALOAD); 67.271 + } 67.272 + test.visitVarInsn(ASTORE, 1); 67.273 + } 67.274 + test.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;"); 67.275 + test.visitVarInsn(ALOAD, dim > 0 ? 1 : 0); 67.276 + test.visitMethodInsn(INVOKEINTERFACE, "TestMeetIncompatibleInterfaceArrays$I1", "getName", 67.277 + "()Ljava/lang/String;", true); 67.278 + test.visitMethodInsn(INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/Object;)V", false); 67.279 + test.visitInsn(RETURN); 67.280 + test.visitMaxs(0, 0); 67.281 + test.visitEnd(); 67.282 + 67.283 + // Get the bytes of the class.. 67.284 + byte[] b = cw.toByteArray(); 67.285 + // ..and write them into a class file (for debugging) 67.286 + FileOutputStream fos = new FileOutputStream(PATH + baseClassName + dim + "ASM.class"); 67.287 + fos.write(b); 67.288 + fos.close(); 67.289 + 67.290 + } 67.291 + 67.292 + public static String[][] tier = { { "interpreted", "C2 (tier 4) without inlining", "C2 (tier4) without inlining" }, 67.293 + { "interpreted", "C2 (tier 4) with inlining", "C2 (tier4) with inlining" }, 67.294 + { "interpreted", "C1 (tier 3) with inlining", "C2 (tier4) with inlining" } }; 67.295 + 67.296 + public static void main(String[] args) throws Exception { 67.297 + final int pass = Integer.parseInt(args.length > 0 ? args[0] : "0"); 67.298 + 67.299 + // Load and initialize some classes required for compilation 67.300 + Class.forName("TestMeetIncompatibleInterfaceArrays$I1"); 67.301 + Class.forName("TestMeetIncompatibleInterfaceArrays$I2"); 67.302 + Class.forName("TestMeetIncompatibleInterfaceArrays$Helper"); 67.303 + 67.304 + for (int g = 0; g < 2; g++) { 67.305 + String baseClassName = "MeetIncompatibleInterfaceArrays"; 67.306 + boolean good = (g == 0) ? false : true; 67.307 + if (good) 67.308 + baseClassName += "Good"; 67.309 + for (int i = 0; i < 6; i++) { 67.310 + System.out.println(); 67.311 + System.out.println("Creating " + baseClassName + i + "ASM.class"); 67.312 + System.out.println("========================================" + "=" + "========="); 67.313 + // Create the "MeetIncompatibleInterfaceArrays<i>ASM" class 67.314 + generateTestClass(i, good); 67.315 + Class<?> c = null; 67.316 + try { 67.317 + c = Class.forName(baseClassName + i + "ASM"); 67.318 + } catch (VerifyError ve) { 67.319 + if (i == 4) { 67.320 + System.out.println("OK - must be (" + ve.getMessage() + ")."); 67.321 + } else { 67.322 + throw ve; 67.323 + } 67.324 + continue; 67.325 + } 67.326 + // Call MeetIncompatibleInterfaceArrays<i>ASM.test() 67.327 + Method m = c.getMethod("test"); 67.328 + Method r = c.getMethod("run"); 67.329 + for (int j = 0; j < 3; j++) { 67.330 + System.out.println((j + 1) + ". invokation of " + baseClassName + i + "ASM.test() [should be " 67.331 + + tier[pass][j] + "]"); 67.332 + try { 67.333 + m.invoke(null); 67.334 + } catch (InvocationTargetException ite) { 67.335 + if (good) { 67.336 + throw ite; 67.337 + } else { 67.338 + if (ite.getCause() instanceof IncompatibleClassChangeError) { 67.339 + System.out.println(" OK - catched InvocationTargetException(" 67.340 + + ite.getCause().getMessage() + ")."); 67.341 + } else { 67.342 + throw ite; 67.343 + } 67.344 + } 67.345 + } 67.346 + } 67.347 + System.out.println("Method " + r + (WB.isMethodCompiled(r) ? " has" : " has not") + " been compiled."); 67.348 + if (!WB.isMethodCompiled(r)) { 67.349 + throw new Exception("Method " + r + " must be compiled!"); 67.350 + } 67.351 + } 67.352 + } 67.353 + } 67.354 +}