comparison src/cpu/x86/vm/templateTable_x86_32.cpp @ 23614:32b682649973 jdk8u75-b04

8132051: Better byte behavior Reviewed-by: coleenp, roland
author kevinw
date Fri, 15 Jan 2016 22:33:15 +0000
parents 42790b7e4d48
children ca5c97226d1c
comparison
equal deleted inserted replaced
23613:b374548dcb48 23614:32b682649973
1 /* 1 /*
2 * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. 2 * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 * 4 *
5 * This code is free software; you can redistribute it and/or modify it 5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as 6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. 7 * published by the Free Software Foundation.
210 Label L_patch_done; 210 Label L_patch_done;
211 211
212 switch (bc) { 212 switch (bc) {
213 case Bytecodes::_fast_aputfield: 213 case Bytecodes::_fast_aputfield:
214 case Bytecodes::_fast_bputfield: 214 case Bytecodes::_fast_bputfield:
215 case Bytecodes::_fast_zputfield:
215 case Bytecodes::_fast_cputfield: 216 case Bytecodes::_fast_cputfield:
216 case Bytecodes::_fast_dputfield: 217 case Bytecodes::_fast_dputfield:
217 case Bytecodes::_fast_fputfield: 218 case Bytecodes::_fast_fputfield:
218 case Bytecodes::_fast_iputfield: 219 case Bytecodes::_fast_iputfield:
219 case Bytecodes::_fast_lputfield: 220 case Bytecodes::_fast_lputfield:
986 987
987 988
988 void TemplateTable::bastore() { 989 void TemplateTable::bastore() {
989 transition(itos, vtos); 990 transition(itos, vtos);
990 __ pop_i(rbx); 991 __ pop_i(rbx);
991 // rax,: value 992 // rax: value
993 // rbx: index
992 // rdx: array 994 // rdx: array
993 index_check(rdx, rbx); // prefer index in rbx, 995 index_check(rdx, rbx); // prefer index in rbx
994 // rbx,: index 996 // Need to check whether array is boolean or byte
995 __ movb(Address(rdx, rbx, Address::times_1, arrayOopDesc::base_offset_in_bytes(T_BYTE)), rax); 997 // since both types share the bastore bytecode.
998 __ load_klass(rcx, rdx);
999 __ movl(rcx, Address(rcx, Klass::layout_helper_offset()));
1000 int diffbit = Klass::layout_helper_boolean_diffbit();
1001 __ testl(rcx, diffbit);
1002 Label L_skip;
1003 __ jccb(Assembler::zero, L_skip);
1004 __ andl(rax, 1); // if it is a T_BOOLEAN array, mask the stored value to 0/1
1005 __ bind(L_skip);
1006 __ movb(Address(rdx, rbx, Address::times_1, arrayOopDesc::base_offset_in_bytes(T_BYTE)), rax);
996 } 1007 }
997 1008
998 1009
999 void TemplateTable::castore() { 1010 void TemplateTable::castore() {
1000 transition(itos, vtos); 1011 transition(itos, vtos);
2035 __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::register_finalizer), rax); 2046 __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::register_finalizer), rax);
2036 2047
2037 __ bind(skip_register_finalizer); 2048 __ bind(skip_register_finalizer);
2038 } 2049 }
2039 2050
2051 // Narrow result if state is itos but result type is smaller.
2052 // Need to narrow in the return bytecode rather than in generate_return_entry
2053 // since compiled code callers expect the result to already be narrowed.
2054 if (state == itos) {
2055 __ narrow(rax);
2056 }
2040 __ remove_activation(state, rsi); 2057 __ remove_activation(state, rsi);
2058
2041 __ jmp(rsi); 2059 __ jmp(rsi);
2042 } 2060 }
2043 2061
2044 2062
2045 // ---------------------------------------------------------------------------- 2063 // ----------------------------------------------------------------------------
2232 if (!is_static) pop_and_check_object(obj); 2250 if (!is_static) pop_and_check_object(obj);
2233 2251
2234 const Address lo(obj, off, Address::times_1, 0*wordSize); 2252 const Address lo(obj, off, Address::times_1, 0*wordSize);
2235 const Address hi(obj, off, Address::times_1, 1*wordSize); 2253 const Address hi(obj, off, Address::times_1, 1*wordSize);
2236 2254
2237 Label Done, notByte, notInt, notShort, notChar, notLong, notFloat, notObj, notDouble; 2255 Label Done, notByte, notBool, notInt, notShort, notChar, notLong, notFloat, notObj, notDouble;
2238 2256
2239 __ shrl(flags, ConstantPoolCacheEntry::tos_state_shift); 2257 __ shrl(flags, ConstantPoolCacheEntry::tos_state_shift);
2240 assert(btos == 0, "change code, btos != 0"); 2258 assert(btos == 0, "change code, btos != 0");
2241 // btos 2259 // btos
2242 __ andptr(flags, ConstantPoolCacheEntry::tos_state_mask); 2260 __ andptr(flags, ConstantPoolCacheEntry::tos_state_mask);
2249 patch_bytecode(Bytecodes::_fast_bgetfield, rcx, rbx); 2267 patch_bytecode(Bytecodes::_fast_bgetfield, rcx, rbx);
2250 } 2268 }
2251 __ jmp(Done); 2269 __ jmp(Done);
2252 2270
2253 __ bind(notByte); 2271 __ bind(notByte);
2272
2273 __ cmpl(flags, ztos);
2274 __ jcc(Assembler::notEqual, notBool);
2275
2276 // ztos (same code as btos)
2277 __ load_signed_byte(rax, lo);
2278 __ push(ztos);
2279 // Rewrite bytecode to be faster
2280 if (!is_static) {
2281 // use btos rewriting, no truncating to t/f bit is needed for getfield.
2282 patch_bytecode(Bytecodes::_fast_bgetfield, rcx, rbx);
2283 }
2284 __ jmp(Done);
2285
2286 __ bind(notBool);
2287
2254 // itos 2288 // itos
2255 __ cmpl(flags, itos ); 2289 __ cmpl(flags, itos );
2256 __ jcc(Assembler::notEqual, notInt); 2290 __ jcc(Assembler::notEqual, notInt);
2257 2291
2258 __ movl(rax, lo ); 2292 __ movl(rax, lo );
2448 2482
2449 // field addresses 2483 // field addresses
2450 const Address lo(obj, off, Address::times_1, 0*wordSize); 2484 const Address lo(obj, off, Address::times_1, 0*wordSize);
2451 const Address hi(obj, off, Address::times_1, 1*wordSize); 2485 const Address hi(obj, off, Address::times_1, 1*wordSize);
2452 2486
2453 Label notByte, notInt, notShort, notChar, notLong, notFloat, notObj, notDouble; 2487 Label notByte, notBool, notInt, notShort, notChar, notLong, notFloat, notObj, notDouble;
2454 2488
2455 __ shrl(flags, ConstantPoolCacheEntry::tos_state_shift); 2489 __ shrl(flags, ConstantPoolCacheEntry::tos_state_shift);
2456 assert(btos == 0, "change code, btos != 0"); 2490 assert(btos == 0, "change code, btos != 0");
2457 __ andl(flags, ConstantPoolCacheEntry::tos_state_mask); 2491 __ andl(flags, ConstantPoolCacheEntry::tos_state_mask);
2458 __ jcc(Assembler::notZero, notByte); 2492 __ jcc(Assembler::notZero, notByte);
2467 } 2501 }
2468 __ jmp(Done); 2502 __ jmp(Done);
2469 } 2503 }
2470 2504
2471 __ bind(notByte); 2505 __ bind(notByte);
2506 __ cmpl(flags, ztos);
2507 __ jcc(Assembler::notEqual, notBool);
2508
2509 // ztos
2510 {
2511 __ pop(ztos);
2512 if (!is_static) pop_and_check_object(obj);
2513 __ andl(rax, 0x1);
2514 __ movb(lo, rax);
2515 if (!is_static) {
2516 patch_bytecode(Bytecodes::_fast_zputfield, rcx, rbx, true, byte_no);
2517 }
2518 __ jmp(Done);
2519 }
2520
2521 __ bind(notBool);
2472 __ cmpl(flags, itos); 2522 __ cmpl(flags, itos);
2473 __ jcc(Assembler::notEqual, notInt); 2523 __ jcc(Assembler::notEqual, notInt);
2474 2524
2475 // itos 2525 // itos
2476 { 2526 {
2638 // to do it for every data type, we use the saved values as the 2688 // to do it for every data type, we use the saved values as the
2639 // jvalue object. 2689 // jvalue object.
2640 switch (bytecode()) { // load values into the jvalue object 2690 switch (bytecode()) { // load values into the jvalue object
2641 case Bytecodes::_fast_aputfield: __ push_ptr(rax); break; 2691 case Bytecodes::_fast_aputfield: __ push_ptr(rax); break;
2642 case Bytecodes::_fast_bputfield: // fall through 2692 case Bytecodes::_fast_bputfield: // fall through
2693 case Bytecodes::_fast_zputfield: // fall through
2643 case Bytecodes::_fast_sputfield: // fall through 2694 case Bytecodes::_fast_sputfield: // fall through
2644 case Bytecodes::_fast_cputfield: // fall through 2695 case Bytecodes::_fast_cputfield: // fall through
2645 case Bytecodes::_fast_iputfield: __ push_i(rax); break; 2696 case Bytecodes::_fast_iputfield: __ push_i(rax); break;
2646 case Bytecodes::_fast_dputfield: __ push_d(); break; 2697 case Bytecodes::_fast_dputfield: __ push_d(); break;
2647 case Bytecodes::_fast_fputfield: __ push_f(); break; 2698 case Bytecodes::_fast_fputfield: __ push_f(); break;
2660 __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::post_field_modification), rbx, rax, rcx); 2711 __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::post_field_modification), rbx, rax, rcx);
2661 2712
2662 switch (bytecode()) { // restore tos values 2713 switch (bytecode()) { // restore tos values
2663 case Bytecodes::_fast_aputfield: __ pop_ptr(rax); break; 2714 case Bytecodes::_fast_aputfield: __ pop_ptr(rax); break;
2664 case Bytecodes::_fast_bputfield: // fall through 2715 case Bytecodes::_fast_bputfield: // fall through
2716 case Bytecodes::_fast_zputfield: // fall through
2665 case Bytecodes::_fast_sputfield: // fall through 2717 case Bytecodes::_fast_sputfield: // fall through
2666 case Bytecodes::_fast_cputfield: // fall through 2718 case Bytecodes::_fast_cputfield: // fall through
2667 case Bytecodes::_fast_iputfield: __ pop_i(rax); break; 2719 case Bytecodes::_fast_iputfield: __ pop_i(rax); break;
2668 case Bytecodes::_fast_dputfield: __ pop_d(); break; 2720 case Bytecodes::_fast_dputfield: __ pop_d(); break;
2669 case Bytecodes::_fast_fputfield: __ pop_f(); break; 2721 case Bytecodes::_fast_fputfield: __ pop_f(); break;
2710 const Address lo(rcx, rbx, Address::times_1, 0*wordSize); 2762 const Address lo(rcx, rbx, Address::times_1, 0*wordSize);
2711 const Address hi(rcx, rbx, Address::times_1, 1*wordSize); 2763 const Address hi(rcx, rbx, Address::times_1, 1*wordSize);
2712 2764
2713 // access field 2765 // access field
2714 switch (bytecode()) { 2766 switch (bytecode()) {
2767 case Bytecodes::_fast_zputfield: __ andl(rax, 0x1); // boolean is true if LSB is 1
2768 // fall through to bputfield
2715 case Bytecodes::_fast_bputfield: __ movb(lo, rax); break; 2769 case Bytecodes::_fast_bputfield: __ movb(lo, rax); break;
2716 case Bytecodes::_fast_sputfield: // fall through 2770 case Bytecodes::_fast_sputfield: // fall through
2717 case Bytecodes::_fast_cputfield: __ movw(lo, rax); break; 2771 case Bytecodes::_fast_cputfield: __ movw(lo, rax); break;
2718 case Bytecodes::_fast_iputfield: __ movl(lo, rax); break; 2772 case Bytecodes::_fast_iputfield: __ movl(lo, rax); break;
2719 case Bytecodes::_fast_lputfield: 2773 case Bytecodes::_fast_lputfield:
2744 // Get object from stack 2798 // Get object from stack
2745 pop_and_check_object(rcx); 2799 pop_and_check_object(rcx);
2746 2800
2747 // access field 2801 // access field
2748 switch (bytecode()) { 2802 switch (bytecode()) {
2803 case Bytecodes::_fast_zputfield: __ andl(rax, 0x1); // boolean is true if LSB is 1
2804 // fall through to bputfield
2749 case Bytecodes::_fast_bputfield: __ movb(lo, rax); break; 2805 case Bytecodes::_fast_bputfield: __ movb(lo, rax); break;
2750 case Bytecodes::_fast_sputfield: // fall through 2806 case Bytecodes::_fast_sputfield: // fall through
2751 case Bytecodes::_fast_cputfield: __ movw(lo, rax); break; 2807 case Bytecodes::_fast_cputfield: __ movw(lo, rax); break;
2752 case Bytecodes::_fast_iputfield: __ movl(lo, rax); break; 2808 case Bytecodes::_fast_iputfield: __ movl(lo, rax); break;
2753 case Bytecodes::_fast_lputfield: 2809 case Bytecodes::_fast_lputfield: