< prev index next >

src/cpu/sparc/vm/templateTable_sparc.cpp

Print this page
rev 12906 : [mq]: gc_interface


   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *
  23  */
  24 
  25 #include "precompiled.hpp"

  26 #include "interpreter/interpreter.hpp"
  27 #include "interpreter/interpreterRuntime.hpp"
  28 #include "interpreter/interp_masm.hpp"
  29 #include "interpreter/templateTable.hpp"
  30 #include "memory/universe.inline.hpp"
  31 #include "oops/methodData.hpp"
  32 #include "oops/objArrayKlass.hpp"
  33 #include "oops/oop.inline.hpp"
  34 #include "prims/methodHandles.hpp"
  35 #include "runtime/sharedRuntime.hpp"
  36 #include "runtime/stubRoutines.hpp"
  37 #include "runtime/synchronizer.hpp"
  38 #include "utilities/macros.hpp"
  39 
  40 #define __ _masm->
  41 
  42 // Misc helpers
  43 
  44 // Do an oop store like *(base + index + offset) = val
  45 // index can be noreg,
  46 static void do_oop_store(InterpreterMacroAssembler* _masm,
  47                          Register base,
  48                          Register index,
  49                          int offset,
  50                          Register val,
  51                          Register tmp,
  52                          BarrierSet::Name barrier,
  53                          bool precise) {
  54   assert(tmp != val && tmp != base && tmp != index, "register collision");
  55   assert(index == noreg || offset == 0, "only one offset");
  56   switch (barrier) {
  57 #if INCLUDE_ALL_GCS
  58     case BarrierSet::G1SATBCTLogging:
  59       {
  60         // Load and record the previous value.
  61         __ g1_write_barrier_pre(base, index, offset,
  62                                 noreg /* pre_val */,
  63                                 tmp, true /*preserve_o_regs*/);
  64 
  65         // G1 barrier needs uncompressed oop for region cross check.
  66         Register new_val = val;
  67         if (UseCompressedOops && val != G0) {
  68           new_val = tmp;
  69           __ mov(val, new_val);
  70         }
  71 
  72         if (index == noreg ) {
  73           assert(Assembler::is_simm13(offset), "fix this code");
  74           __ store_heap_oop(val, base, offset);
  75         } else {
  76           __ store_heap_oop(val, base, index);
  77         }
  78 
  79         // No need for post barrier if storing NULL
  80         if (val != G0) {
  81           if (precise) {
  82             if (index == noreg) {
  83               __ add(base, offset, base);
  84             } else {
  85               __ add(base, index, base);
  86             }
  87           }
  88           __ g1_write_barrier_post(base, new_val, tmp);
  89         }
  90       }
  91       break;
  92 #endif // INCLUDE_ALL_GCS
  93     case BarrierSet::CardTableForRS:
  94     case BarrierSet::CardTableExtension:
  95       {
  96         if (index == noreg ) {
  97           assert(Assembler::is_simm13(offset), "fix this code");
  98           __ store_heap_oop(val, base, offset);
  99         } else {
 100           __ store_heap_oop(val, base, index);
 101         }
 102         // No need for post barrier if storing NULL
 103         if (val != G0) {
 104           if (precise) {
 105             if (index == noreg) {
 106               __ add(base, offset, base);
 107             } else {
 108               __ add(base, index, base);
 109             }
 110           }
 111           __ card_write_barrier_post(base, val, tmp);
 112         }
 113       }
 114       break;
 115     case BarrierSet::ModRef:
 116       ShouldNotReachHere();
 117       break;
 118     default      :
 119       ShouldNotReachHere();
 120 
 121   }
 122 }
 123 












 124 
 125 //----------------------------------------------------------------------------------------------------
 126 // Platform-dependent initialization
 127 
 128 void TemplateTable::pd_initialize() {
 129   // (none)
 130 }
 131 
 132 
 133 //----------------------------------------------------------------------------------------------------
 134 // Condition conversion
 135 Assembler::Condition ccNot(TemplateTable::Condition cc) {
 136   switch (cc) {
 137     case TemplateTable::equal        : return Assembler::notEqual;
 138     case TemplateTable::not_equal    : return Assembler::equal;
 139     case TemplateTable::less         : return Assembler::greaterEqual;
 140     case TemplateTable::less_equal   : return Assembler::greater;
 141     case TemplateTable::greater      : return Assembler::lessEqual;
 142     case TemplateTable::greater_equal: return Assembler::less;
 143   }


 569   // O2: array
 570   __ index_check(O2, Otos_i, LogBytesPerInt, G3_scratch, O3);
 571   __ ldf(FloatRegisterImpl::S, O3, arrayOopDesc::base_offset_in_bytes(T_FLOAT), Ftos_f);
 572 }
 573 
 574 
 575 void TemplateTable::daload() {
 576   transition(itos, dtos);
 577   // Otos_i: index
 578   // O2: array
 579   __ index_check(O2, Otos_i, LogBytesPerLong, G3_scratch, O3);
 580   __ ldf(FloatRegisterImpl::D, O3, arrayOopDesc::base_offset_in_bytes(T_DOUBLE), Ftos_d);
 581 }
 582 
 583 
 584 void TemplateTable::aaload() {
 585   transition(itos, atos);
 586   // Otos_i: index
 587   // tos: array
 588   __ index_check(O2, Otos_i, UseCompressedOops ? 2 : LogBytesPerWord, G3_scratch, O3);
 589   __ load_heap_oop(O3, arrayOopDesc::base_offset_in_bytes(T_OBJECT), Otos_i);






 590   __ verify_oop(Otos_i);
 591 }
 592 
 593 
 594 void TemplateTable::baload() {
 595   transition(itos, itos);
 596   // Otos_i: index
 597   // tos: array
 598   __ index_check(O2, Otos_i, 0, G3_scratch, O3);
 599   __ ldsb(O3, arrayOopDesc::base_offset_in_bytes(T_BYTE), Otos_i);
 600 }
 601 
 602 
 603 void TemplateTable::caload() {
 604   transition(itos, itos);
 605   // Otos_i: index
 606   // tos: array
 607   __ index_check(O2, Otos_i, LogBytesPerShort, G3_scratch, O3);
 608   __ lduh(O3, arrayOopDesc::base_offset_in_bytes(T_CHAR), Otos_i);
 609 }


 869   assert(Otos_i == O0, "just checking");
 870 
 871   // Otos_i:    value
 872   // O1:        addr - offset
 873   // O2:        index
 874   // O3:        array
 875   // O4:        array element klass
 876   // O5:        value klass
 877 
 878   // Address element(O1, 0, arrayOopDesc::base_offset_in_bytes(T_OBJECT));
 879 
 880   // Generate a fast subtype check.  Branch to store_ok if no
 881   // failure.  Throw if failure.
 882   __ gen_subtype_check( O5, O4, G3_scratch, G4_scratch, G1_scratch, store_ok );
 883 
 884   // Not a subtype; so must throw exception
 885   __ throw_if_not_x( Assembler::never, Interpreter::_throw_ArrayStoreException_entry, G3_scratch );
 886 
 887   // Store is OK.
 888   __ bind(store_ok);
 889   do_oop_store(_masm, O1, noreg, arrayOopDesc::base_offset_in_bytes(T_OBJECT), Otos_i, G3_scratch, _bs->kind(), true);
 890 
 891   __ ba(done);
 892   __ delayed()->inc(Lesp, 3* Interpreter::stackElementSize); // adj sp (pops array, index and value)
 893 
 894   __ bind(is_null);
 895   do_oop_store(_masm, O1, noreg, arrayOopDesc::base_offset_in_bytes(T_OBJECT), G0, G4_scratch, _bs->kind(), true);
 896 
 897   __ profile_null_seen(G3_scratch);
 898   __ inc(Lesp, 3* Interpreter::stackElementSize);     // adj sp (pops array, index and value)
 899   __ bind(done);
 900 }
 901 
 902 
 903 void TemplateTable::bastore() {
 904   transition(itos, vtos);
 905   __ pop_i(O2); // index
 906   // Otos_i: val
 907   // O2: index
 908   // O3: array
 909   __ index_check(O3, O2, 0, G3_scratch, O2);
 910   // Need to check whether array is boolean or byte
 911   // since both types share the bastore bytecode.
 912   __ load_klass(O3, G4_scratch);
 913   __ ld(G4_scratch, in_bytes(Klass::layout_helper_offset()), G4_scratch);
 914   __ set(Klass::layout_helper_boolean_diffbit(), G3_scratch);
 915   __ andcc(G3_scratch, G4_scratch, G0);


2506     }
2507   }
2508 
2509   __ srl(Rflags, ConstantPoolCacheEntry::tos_state_shift, Rflags);
2510   // Make sure we don't need to mask Rflags after the above shift
2511   ConstantPoolCacheEntry::verify_tos_state_shift();
2512 
2513   // compute field type
2514   Label notInt, notShort, notChar, notObj, notByte, notBool, notLong, notFloat;
2515 
2516   if (is_static) {
2517     // putstatic with object type most likely, check that first
2518     __ cmp(Rflags, atos);
2519     __ br(Assembler::notEqual, false, Assembler::pt, notObj);
2520     __ delayed()->cmp(Rflags, itos);
2521 
2522     // atos
2523     {
2524       __ pop_ptr();
2525       __ verify_oop(Otos_i);
2526       do_oop_store(_masm, Rclass, Roffset, 0, Otos_i, G1_scratch, _bs->kind(), false);
2527       __ ba(checkVolatile);
2528       __ delayed()->tst(Lscratch);
2529     }
2530 
2531     __ bind(notObj);
2532     // cmp(Rflags, itos);
2533     __ br(Assembler::notEqual, false, Assembler::pt, notInt);
2534     __ delayed()->cmp(Rflags, btos);
2535 
2536     // itos
2537     {
2538       __ pop_i();
2539       __ st(Otos_i, Rclass, Roffset);
2540       __ ba(checkVolatile);
2541       __ delayed()->tst(Lscratch);
2542     }
2543 
2544     __ bind(notInt);
2545   } else {
2546     // putfield with int type most likely, check that first


2551     // itos
2552     {
2553       __ pop_i();
2554       pop_and_check_object(Rclass);
2555       __ st(Otos_i, Rclass, Roffset);
2556       if (rc == may_rewrite) patch_bytecode(Bytecodes::_fast_iputfield, G3_scratch, G4_scratch, true, byte_no);
2557       __ ba(checkVolatile);
2558       __ delayed()->tst(Lscratch);
2559     }
2560 
2561     __ bind(notInt);
2562     // cmp(Rflags, atos);
2563     __ br(Assembler::notEqual, false, Assembler::pt, notObj);
2564     __ delayed()->cmp(Rflags, btos);
2565 
2566     // atos
2567     {
2568       __ pop_ptr();
2569       pop_and_check_object(Rclass);
2570       __ verify_oop(Otos_i);
2571       do_oop_store(_masm, Rclass, Roffset, 0, Otos_i, G1_scratch, _bs->kind(), false);
2572       if (rc == may_rewrite) patch_bytecode(Bytecodes::_fast_aputfield, G3_scratch, G4_scratch, true, byte_no);
2573       __ ba(checkVolatile);
2574       __ delayed()->tst(Lscratch);
2575     }
2576 
2577     __ bind(notObj);
2578   }
2579 
2580   // cmp(Rflags, btos);
2581   __ br(Assembler::notEqual, false, Assembler::pt, notByte);
2582   __ delayed()->cmp(Rflags, ztos);
2583 
2584   // btos
2585   {
2586     __ pop_i();
2587     if (!is_static) pop_and_check_object(Rclass);
2588     __ stb(Otos_i, Rclass, Roffset);
2589     if (!is_static && rc == may_rewrite) {
2590       patch_bytecode(Bytecodes::_fast_bputfield, G3_scratch, G4_scratch, true, byte_no);
2591     }


2732     }
2733   }
2734 
2735   __ ld_ptr(Rcache, cp_base_offset + ConstantPoolCacheEntry::f2_offset(), Roffset);
2736   pop_and_check_object(Rclass);
2737 
2738   switch (bytecode()) {
2739     case Bytecodes::_fast_zputfield: __ and3(Otos_i, 1, Otos_i);  // fall through to bputfield
2740     case Bytecodes::_fast_bputfield: __ stb(Otos_i, Rclass, Roffset); break;
2741     case Bytecodes::_fast_cputfield: /* fall through */
2742     case Bytecodes::_fast_sputfield: __ sth(Otos_i, Rclass, Roffset); break;
2743     case Bytecodes::_fast_iputfield: __ st(Otos_i, Rclass, Roffset);  break;
2744     case Bytecodes::_fast_lputfield: __ st_long(Otos_l, Rclass, Roffset); break;
2745     case Bytecodes::_fast_fputfield:
2746       __ stf(FloatRegisterImpl::S, Ftos_f, Rclass, Roffset);
2747       break;
2748     case Bytecodes::_fast_dputfield:
2749       __ stf(FloatRegisterImpl::D, Ftos_d, Rclass, Roffset);
2750       break;
2751     case Bytecodes::_fast_aputfield:
2752       do_oop_store(_masm, Rclass, Roffset, 0, Otos_i, G1_scratch, _bs->kind(), false);
2753       break;
2754     default:
2755       ShouldNotReachHere();
2756   }
2757 
2758   if (__ membar_has_effect(write_bits)) {
2759     __ cmp_and_br_short(Lscratch, 0, Assembler::equal, Assembler::pt, exit);
2760     volatile_barrier(Assembler::StoreLoad);
2761     __ bind(exit);
2762   }
2763 }
2764 
2765 void TemplateTable::putfield(int byte_no) {
2766   putfield_or_static(byte_no, false);
2767 }
2768 
2769 void TemplateTable::nofast_putfield(int byte_no) {
2770   putfield_or_static(byte_no, false, may_not_rewrite);
2771 }
2772 




   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *
  23  */
  24 
  25 #include "precompiled.hpp"
  26 #include "gc/shared/barrierSetCodeGen.hpp"
  27 #include "interpreter/interpreter.hpp"
  28 #include "interpreter/interpreterRuntime.hpp"
  29 #include "interpreter/interp_masm.hpp"
  30 #include "interpreter/templateTable.hpp"
  31 #include "memory/universe.inline.hpp"
  32 #include "oops/methodData.hpp"
  33 #include "oops/objArrayKlass.hpp"
  34 #include "oops/oop.inline.hpp"
  35 #include "prims/methodHandles.hpp"
  36 #include "runtime/sharedRuntime.hpp"
  37 #include "runtime/stubRoutines.hpp"
  38 #include "runtime/synchronizer.hpp"
  39 #include "utilities/macros.hpp"
  40 
  41 #define __ _masm->
  42 
  43 // Misc helpers
  44 
  45 // Do an oop store like *(base + index + offset) = val
  46 // index can be noreg,
  47 static void do_oop_store(InterpreterMacroAssembler* _masm,
  48                          Register base,
  49                          Register index,
  50                          int offset,
  51                          Register val,
  52                          Register tmp,
  53                          DecoratorSet decorators) {

  54   assert(tmp != val && tmp != base && tmp != index, "register collision");
  55   assert(index == noreg || offset == 0, "only one offset");
  56   BarrierSetCodeGen *code_gen = Universe::heap()->barrier_set()->code_gen();
  57   code_gen->store_at(_masm, decorators, T_OBJECT, base, index, offset, val, tmp);
































































  58 }
  59 
  60 static void do_oop_load(InterpreterMacroAssembler* _masm,
  61                          Register base,
  62                          Register index,
  63                          int offset,
  64                          Register dst,
  65                          Register tmp,
  66                          DecoratorSet decorators) {
  67   assert(tmp != dst && tmp != base && tmp != index, "register collision");
  68   assert(index == noreg || offset == 0, "only one offset");
  69   BarrierSetCodeGen *code_gen = Universe::heap()->barrier_set()->code_gen();
  70   code_gen->load_at(_masm, decorators, T_OBJECT, base, index, offset, dst, tmp);
  71 }
  72 
  73 //----------------------------------------------------------------------------------------------------
  74 // Platform-dependent initialization
  75 
  76 void TemplateTable::pd_initialize() {
  77   // (none)
  78 }
  79 
  80 
  81 //----------------------------------------------------------------------------------------------------
  82 // Condition conversion
  83 Assembler::Condition ccNot(TemplateTable::Condition cc) {
  84   switch (cc) {
  85     case TemplateTable::equal        : return Assembler::notEqual;
  86     case TemplateTable::not_equal    : return Assembler::equal;
  87     case TemplateTable::less         : return Assembler::greaterEqual;
  88     case TemplateTable::less_equal   : return Assembler::greater;
  89     case TemplateTable::greater      : return Assembler::lessEqual;
  90     case TemplateTable::greater_equal: return Assembler::less;
  91   }


 517   // O2: array
 518   __ index_check(O2, Otos_i, LogBytesPerInt, G3_scratch, O3);
 519   __ ldf(FloatRegisterImpl::S, O3, arrayOopDesc::base_offset_in_bytes(T_FLOAT), Ftos_f);
 520 }
 521 
 522 
 523 void TemplateTable::daload() {
 524   transition(itos, dtos);
 525   // Otos_i: index
 526   // O2: array
 527   __ index_check(O2, Otos_i, LogBytesPerLong, G3_scratch, O3);
 528   __ ldf(FloatRegisterImpl::D, O3, arrayOopDesc::base_offset_in_bytes(T_DOUBLE), Ftos_d);
 529 }
 530 
 531 
 532 void TemplateTable::aaload() {
 533   transition(itos, atos);
 534   // Otos_i: index
 535   // tos: array
 536   __ index_check(O2, Otos_i, UseCompressedOops ? 2 : LogBytesPerWord, G3_scratch, O3);
 537   do_oop_load(_masm,
 538               O3,
 539               noreg,
 540               arrayOopDesc::base_offset_in_bytes(T_OBJECT),
 541               Otos_i,
 542               G3_scratch,
 543               ACCESS_ON_HEAP | ACCESS_ON_ARRAY);
 544   __ verify_oop(Otos_i);
 545 }
 546 
 547 
 548 void TemplateTable::baload() {
 549   transition(itos, itos);
 550   // Otos_i: index
 551   // tos: array
 552   __ index_check(O2, Otos_i, 0, G3_scratch, O3);
 553   __ ldsb(O3, arrayOopDesc::base_offset_in_bytes(T_BYTE), Otos_i);
 554 }
 555 
 556 
 557 void TemplateTable::caload() {
 558   transition(itos, itos);
 559   // Otos_i: index
 560   // tos: array
 561   __ index_check(O2, Otos_i, LogBytesPerShort, G3_scratch, O3);
 562   __ lduh(O3, arrayOopDesc::base_offset_in_bytes(T_CHAR), Otos_i);
 563 }


 823   assert(Otos_i == O0, "just checking");
 824 
 825   // Otos_i:    value
 826   // O1:        addr - offset
 827   // O2:        index
 828   // O3:        array
 829   // O4:        array element klass
 830   // O5:        value klass
 831 
 832   // Address element(O1, 0, arrayOopDesc::base_offset_in_bytes(T_OBJECT));
 833 
 834   // Generate a fast subtype check.  Branch to store_ok if no
 835   // failure.  Throw if failure.
 836   __ gen_subtype_check( O5, O4, G3_scratch, G4_scratch, G1_scratch, store_ok );
 837 
 838   // Not a subtype; so must throw exception
 839   __ throw_if_not_x( Assembler::never, Interpreter::_throw_ArrayStoreException_entry, G3_scratch );
 840 
 841   // Store is OK.
 842   __ bind(store_ok);
 843   do_oop_store(_masm, O1, noreg, arrayOopDesc::base_offset_in_bytes(T_OBJECT), Otos_i, G3_scratch, ACCESS_ON_HEAP | ACCESS_ON_ARRAY);
 844 
 845   __ ba(done);
 846   __ delayed()->inc(Lesp, 3* Interpreter::stackElementSize); // adj sp (pops array, index and value)
 847 
 848   __ bind(is_null);
 849   do_oop_store(_masm, O1, noreg, arrayOopDesc::base_offset_in_bytes(T_OBJECT), G0, G4_scratch, ACCESS_ON_HEAP | ACCESS_ON_ARRAY);
 850 
 851   __ profile_null_seen(G3_scratch);
 852   __ inc(Lesp, 3* Interpreter::stackElementSize);     // adj sp (pops array, index and value)
 853   __ bind(done);
 854 }
 855 
 856 
 857 void TemplateTable::bastore() {
 858   transition(itos, vtos);
 859   __ pop_i(O2); // index
 860   // Otos_i: val
 861   // O2: index
 862   // O3: array
 863   __ index_check(O3, O2, 0, G3_scratch, O2);
 864   // Need to check whether array is boolean or byte
 865   // since both types share the bastore bytecode.
 866   __ load_klass(O3, G4_scratch);
 867   __ ld(G4_scratch, in_bytes(Klass::layout_helper_offset()), G4_scratch);
 868   __ set(Klass::layout_helper_boolean_diffbit(), G3_scratch);
 869   __ andcc(G3_scratch, G4_scratch, G0);


2460     }
2461   }
2462 
2463   __ srl(Rflags, ConstantPoolCacheEntry::tos_state_shift, Rflags);
2464   // Make sure we don't need to mask Rflags after the above shift
2465   ConstantPoolCacheEntry::verify_tos_state_shift();
2466 
2467   // compute field type
2468   Label notInt, notShort, notChar, notObj, notByte, notBool, notLong, notFloat;
2469 
2470   if (is_static) {
2471     // putstatic with object type most likely, check that first
2472     __ cmp(Rflags, atos);
2473     __ br(Assembler::notEqual, false, Assembler::pt, notObj);
2474     __ delayed()->cmp(Rflags, itos);
2475 
2476     // atos
2477     {
2478       __ pop_ptr();
2479       __ verify_oop(Otos_i);
2480       do_oop_store(_masm, Rclass, Roffset, 0, Otos_i, G1_scratch, ACCESS_ON_HEAP);
2481       __ ba(checkVolatile);
2482       __ delayed()->tst(Lscratch);
2483     }
2484 
2485     __ bind(notObj);
2486     // cmp(Rflags, itos);
2487     __ br(Assembler::notEqual, false, Assembler::pt, notInt);
2488     __ delayed()->cmp(Rflags, btos);
2489 
2490     // itos
2491     {
2492       __ pop_i();
2493       __ st(Otos_i, Rclass, Roffset);
2494       __ ba(checkVolatile);
2495       __ delayed()->tst(Lscratch);
2496     }
2497 
2498     __ bind(notInt);
2499   } else {
2500     // putfield with int type most likely, check that first


2505     // itos
2506     {
2507       __ pop_i();
2508       pop_and_check_object(Rclass);
2509       __ st(Otos_i, Rclass, Roffset);
2510       if (rc == may_rewrite) patch_bytecode(Bytecodes::_fast_iputfield, G3_scratch, G4_scratch, true, byte_no);
2511       __ ba(checkVolatile);
2512       __ delayed()->tst(Lscratch);
2513     }
2514 
2515     __ bind(notInt);
2516     // cmp(Rflags, atos);
2517     __ br(Assembler::notEqual, false, Assembler::pt, notObj);
2518     __ delayed()->cmp(Rflags, btos);
2519 
2520     // atos
2521     {
2522       __ pop_ptr();
2523       pop_and_check_object(Rclass);
2524       __ verify_oop(Otos_i);
2525       do_oop_store(_masm, Rclass, Roffset, 0, Otos_i, G1_scratch, ACCESS_ON_HEAP);
2526       if (rc == may_rewrite) patch_bytecode(Bytecodes::_fast_aputfield, G3_scratch, G4_scratch, true, byte_no);
2527       __ ba(checkVolatile);
2528       __ delayed()->tst(Lscratch);
2529     }
2530 
2531     __ bind(notObj);
2532   }
2533 
2534   // cmp(Rflags, btos);
2535   __ br(Assembler::notEqual, false, Assembler::pt, notByte);
2536   __ delayed()->cmp(Rflags, ztos);
2537 
2538   // btos
2539   {
2540     __ pop_i();
2541     if (!is_static) pop_and_check_object(Rclass);
2542     __ stb(Otos_i, Rclass, Roffset);
2543     if (!is_static && rc == may_rewrite) {
2544       patch_bytecode(Bytecodes::_fast_bputfield, G3_scratch, G4_scratch, true, byte_no);
2545     }


2686     }
2687   }
2688 
2689   __ ld_ptr(Rcache, cp_base_offset + ConstantPoolCacheEntry::f2_offset(), Roffset);
2690   pop_and_check_object(Rclass);
2691 
2692   switch (bytecode()) {
2693     case Bytecodes::_fast_zputfield: __ and3(Otos_i, 1, Otos_i);  // fall through to bputfield
2694     case Bytecodes::_fast_bputfield: __ stb(Otos_i, Rclass, Roffset); break;
2695     case Bytecodes::_fast_cputfield: /* fall through */
2696     case Bytecodes::_fast_sputfield: __ sth(Otos_i, Rclass, Roffset); break;
2697     case Bytecodes::_fast_iputfield: __ st(Otos_i, Rclass, Roffset);  break;
2698     case Bytecodes::_fast_lputfield: __ st_long(Otos_l, Rclass, Roffset); break;
2699     case Bytecodes::_fast_fputfield:
2700       __ stf(FloatRegisterImpl::S, Ftos_f, Rclass, Roffset);
2701       break;
2702     case Bytecodes::_fast_dputfield:
2703       __ stf(FloatRegisterImpl::D, Ftos_d, Rclass, Roffset);
2704       break;
2705     case Bytecodes::_fast_aputfield:
2706       do_oop_store(_masm, Rclass, Roffset, 0, Otos_i, G1_scratch, ACCESS_ON_HEAP);
2707       break;
2708     default:
2709       ShouldNotReachHere();
2710   }
2711 
2712   if (__ membar_has_effect(write_bits)) {
2713     __ cmp_and_br_short(Lscratch, 0, Assembler::equal, Assembler::pt, exit);
2714     volatile_barrier(Assembler::StoreLoad);
2715     __ bind(exit);
2716   }
2717 }
2718 
2719 void TemplateTable::putfield(int byte_no) {
2720   putfield_or_static(byte_no, false);
2721 }
2722 
2723 void TemplateTable::nofast_putfield(int byte_no) {
2724   putfield_or_static(byte_no, false, may_not_rewrite);
2725 }
2726 


< prev index next >