Mercurial > hg > graal-jvmci-8
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: |