< prev index next >

src/cpu/x86/vm/templateTable_x86.cpp

Print this page
rev 12906 : [mq]: gc_interface


   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 "asm/macroAssembler.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 // Global Register Names
  44 static const Register rbcp     = LP64_ONLY(r13) NOT_LP64(rsi);
  45 static const Register rlocals  = LP64_ONLY(r14) NOT_LP64(rdi);
  46 


 130   switch (cc) {
 131   case TemplateTable::equal        : return Assembler::notEqual;
 132   case TemplateTable::not_equal    : return Assembler::equal;
 133   case TemplateTable::less         : return Assembler::greaterEqual;
 134   case TemplateTable::less_equal   : return Assembler::greater;
 135   case TemplateTable::greater      : return Assembler::lessEqual;
 136   case TemplateTable::greater_equal: return Assembler::less;
 137   }
 138   ShouldNotReachHere();
 139   return Assembler::zero;
 140 }
 141 
 142 
 143 
 144 // Miscelaneous helper routines
 145 // Store an oop (or NULL) at the address described by obj.
 146 // If val == noreg this means store a NULL
 147 
 148 
 149 static void do_oop_store(InterpreterMacroAssembler* _masm,
 150                          Address obj,
 151                          Register val,
 152                          BarrierSet::Name barrier,
 153                          bool precise) {
 154   assert(val == noreg || val == rax, "parameter is just for looks");
 155   switch (barrier) {
 156 #if INCLUDE_ALL_GCS
 157     case BarrierSet::G1SATBCTLogging:
 158       {
 159         // flatten object address if needed
 160         // We do it regardless of precise because we need the registers
 161         if (obj.index() == noreg && obj.disp() == 0) {
 162           if (obj.base() != rdx) {
 163             __ movptr(rdx, obj.base());
 164           }
 165         } else {
 166           __ lea(rdx, obj);
 167         }
 168 
 169         Register rtmp    = LP64_ONLY(r8)         NOT_LP64(rsi);
 170         Register rthread = LP64_ONLY(r15_thread) NOT_LP64(rcx);
 171 
 172         NOT_LP64(__ get_thread(rcx));
 173         NOT_LP64(__ save_bcp());
 174 
 175         __ g1_write_barrier_pre(rdx /* obj */,
 176                                 rbx /* pre_val */,
 177                                 rthread /* thread */,
 178                                 rtmp  /* tmp */,
 179                                 val != noreg /* tosca_live */,
 180                                 false /* expand_call */);
 181         if (val == noreg) {
 182           __ store_heap_oop_null(Address(rdx, 0));
 183         } else {
 184           // G1 barrier needs uncompressed oop for region cross check.
 185           Register new_val = val;
 186           if (UseCompressedOops) {
 187             new_val = rbx;
 188             __ movptr(new_val, val);
 189           }
 190           __ store_heap_oop(Address(rdx, 0), val);
 191           __ g1_write_barrier_post(rdx /* store_adr */,
 192                                    new_val /* new_val */,
 193                                    rthread /* thread */,
 194                                    rtmp /* tmp */,
 195                                    rbx /* tmp2 */);
 196         }
 197         NOT_LP64( __ restore_bcp());
 198       }
 199       break;
 200 #endif // INCLUDE_ALL_GCS
 201     case BarrierSet::CardTableForRS:
 202     case BarrierSet::CardTableExtension:
 203       {
 204         if (val == noreg) {
 205           __ store_heap_oop_null(obj);
 206         } else {
 207           __ store_heap_oop(obj, val);
 208           // flatten object address if needed
 209           if (!precise || (obj.index() == noreg && obj.disp() == 0)) {
 210             __ store_check(obj.base());
 211           } else {
 212             __ lea(rdx, obj);
 213             __ store_check(rdx);
 214           }
 215         }
 216       }
 217       break;
 218     case BarrierSet::ModRef:
 219       if (val == noreg) {
 220         __ store_heap_oop_null(obj);
 221       } else {
 222         __ store_heap_oop(obj, val);
 223       }
 224       break;
 225     default      :
 226       ShouldNotReachHere();
 227 
 228   }





 229 }
 230 
 231 Address TemplateTable::at_bcp(int offset) {
 232   assert(_desc->uses_bcp(), "inconsistent uses_bcp information");
 233   return Address(rbcp, offset);
 234 }
 235 
 236 
 237 void TemplateTable::patch_bytecode(Bytecodes::Code bc, Register bc_reg,
 238                                    Register temp_reg, bool load_bc_into_bc_reg/*=true*/,
 239                                    int byte_no) {
 240   if (!RewriteBytecodes)  return;
 241   Label L_patch_done;
 242 
 243   switch (bc) {
 244   case Bytecodes::_fast_aputfield:
 245   case Bytecodes::_fast_bputfield:
 246   case Bytecodes::_fast_zputfield:
 247   case Bytecodes::_fast_cputfield:
 248   case Bytecodes::_fast_dputfield:


 729   __ load_float(Address(rdx, rax,
 730                         Address::times_4,
 731                         arrayOopDesc::base_offset_in_bytes(T_FLOAT)));
 732 }
 733 
 734 void TemplateTable::daload() {
 735   transition(itos, dtos);
 736   // rax: index
 737   // rdx: array
 738   index_check(rdx, rax); // kills rbx
 739   __ load_double(Address(rdx, rax,
 740                          Address::times_8,
 741                          arrayOopDesc::base_offset_in_bytes(T_DOUBLE)));
 742 }
 743 
 744 void TemplateTable::aaload() {
 745   transition(itos, atos);
 746   // rax: index
 747   // rdx: array
 748   index_check(rdx, rax); // kills rbx
 749   __ load_heap_oop(rax, Address(rdx, rax,

 750                                 UseCompressedOops ? Address::times_4 : Address::times_ptr,
 751                                 arrayOopDesc::base_offset_in_bytes(T_OBJECT)));


 752 }
 753 
 754 void TemplateTable::baload() {
 755   transition(itos, itos);
 756   // rax: index
 757   // rdx: array
 758   index_check(rdx, rax); // kills rbx
 759   __ load_signed_byte(rax, Address(rdx, rax, Address::times_1, arrayOopDesc::base_offset_in_bytes(T_BYTE)));
 760 }
 761 
 762 void TemplateTable::caload() {
 763   transition(itos, itos);
 764   // rax: index
 765   // rdx: array
 766   index_check(rdx, rax); // kills rbx
 767   __ load_unsigned_short(rax, Address(rdx, rax, Address::times_2, arrayOopDesc::base_offset_in_bytes(T_CHAR)));
 768 }
 769 
 770 // iload followed by caload frequent pair
 771 void TemplateTable::fast_icaload() {


1042   __ load_klass(rax, rdx);
1043   __ movptr(rax, Address(rax,
1044                          ObjArrayKlass::element_klass_offset()));
1045   // Compress array + index*oopSize + 12 into a single register.  Frees rcx.
1046   __ lea(rdx, element_address);
1047 
1048   // Generate subtype check.  Blows rcx, rdi
1049   // Superklass in rax.  Subklass in rbx.
1050   __ gen_subtype_check(rbx, ok_is_subtype);
1051 
1052   // Come here on failure
1053   // object is at TOS
1054   __ jump(ExternalAddress(Interpreter::_throw_ArrayStoreException_entry));
1055 
1056   // Come here on success
1057   __ bind(ok_is_subtype);
1058 
1059   // Get the value we will store
1060   __ movptr(rax, at_tos());
1061   // Now store using the appropriate barrier
1062   do_oop_store(_masm, Address(rdx, 0), rax, _bs->kind(), true);
1063   __ jmp(done);
1064 
1065   // Have a NULL in rax, rdx=array, ecx=index.  Store NULL at ary[idx]
1066   __ bind(is_null);
1067   __ profile_null_seen(rbx);
1068 
1069   // Store a NULL
1070   do_oop_store(_masm, element_address, noreg, _bs->kind(), true);
1071 
1072   // Pop stack arguments
1073   __ bind(done);
1074   __ addptr(rsp, 3 * Interpreter::stackElementSize);
1075 }
1076 
1077 void TemplateTable::bastore() {
1078   transition(itos, vtos);
1079   __ pop_i(rbx);
1080   // rax: value
1081   // rbx: index
1082   // rdx: array
1083   index_check(rdx, rbx); // prefer index in rbx
1084   // Need to check whether array is boolean or byte
1085   // since both types share the bastore bytecode.
1086   __ load_klass(rcx, rdx);
1087   __ movl(rcx, Address(rcx, Klass::layout_helper_offset()));
1088   int diffbit = Klass::layout_helper_boolean_diffbit();
1089   __ testl(rcx, diffbit);
1090   Label L_skip;


3059   {
3060     __ pop(ztos);
3061     if (!is_static) pop_and_check_object(obj);
3062     __ andl(rax, 0x1);
3063     __ movb(field, rax);
3064     if (!is_static && rc == may_rewrite) {
3065       patch_bytecode(Bytecodes::_fast_zputfield, bc, rbx, true, byte_no);
3066     }
3067     __ jmp(Done);
3068   }
3069 
3070   __ bind(notBool);
3071   __ cmpl(flags, atos);
3072   __ jcc(Assembler::notEqual, notObj);
3073 
3074   // atos
3075   {
3076     __ pop(atos);
3077     if (!is_static) pop_and_check_object(obj);
3078     // Store into the field
3079     do_oop_store(_masm, field, rax, _bs->kind(), false);
3080     if (!is_static && rc == may_rewrite) {
3081       patch_bytecode(Bytecodes::_fast_aputfield, bc, rbx, true, byte_no);
3082     }
3083     __ jmp(Done);
3084   }
3085 
3086   __ bind(notObj);
3087   __ cmpl(flags, itos);
3088   __ jcc(Assembler::notEqual, notInt);
3089 
3090   // itos
3091   {
3092     __ pop(itos);
3093     if (!is_static) pop_and_check_object(obj);
3094     __ movl(field, rax);
3095     if (!is_static && rc == may_rewrite) {
3096       patch_bytecode(Bytecodes::_fast_iputfield, bc, rbx, true, byte_no);
3097     }
3098     __ jmp(Done);
3099   }


3311   __ movptr(rbx, Address(rcx, rbx, Address::times_ptr,
3312                          in_bytes(base + ConstantPoolCacheEntry::f2_offset())));
3313 
3314   // [jk] not needed currently
3315   // volatile_barrier(Assembler::Membar_mask_bits(Assembler::LoadStore |
3316   //                                              Assembler::StoreStore));
3317 
3318   Label notVolatile;
3319   __ shrl(rdx, ConstantPoolCacheEntry::is_volatile_shift);
3320   __ andl(rdx, 0x1);
3321 
3322   // Get object from stack
3323   pop_and_check_object(rcx);
3324 
3325   // field address
3326   const Address field(rcx, rbx, Address::times_1);
3327 
3328   // access field
3329   switch (bytecode()) {
3330   case Bytecodes::_fast_aputfield:
3331     do_oop_store(_masm, field, rax, _bs->kind(), false);
3332     break;
3333   case Bytecodes::_fast_lputfield:
3334 #ifdef _LP64
3335   __ movq(field, rax);
3336 #else
3337   __ stop("should not be rewritten");
3338 #endif
3339     break;
3340   case Bytecodes::_fast_iputfield:
3341     __ movl(field, rax);
3342     break;
3343   case Bytecodes::_fast_zputfield:
3344     __ andl(rax, 0x1);  // boolean is true if LSB is 1
3345     // fall through to bputfield
3346   case Bytecodes::_fast_bputfield:
3347     __ movb(field, rax);
3348     break;
3349   case Bytecodes::_fast_sputfield:
3350     // fall through
3351   case Bytecodes::_fast_cputfield:




   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 "asm/macroAssembler.hpp"
  27 #include "gc/shared/barrierSet.hpp"
  28 #include "gc/shared/barrierSetCodeGen.hpp"
  29 #include "interpreter/interpreter.hpp"
  30 #include "interpreter/interpreterRuntime.hpp"
  31 #include "interpreter/interp_masm.hpp"
  32 #include "interpreter/templateTable.hpp"
  33 #include "memory/universe.inline.hpp"
  34 #include "oops/methodData.hpp"
  35 #include "oops/objArrayKlass.hpp"
  36 #include "oops/oop.inline.hpp"
  37 #include "prims/methodHandles.hpp"
  38 #include "runtime/sharedRuntime.hpp"
  39 #include "runtime/stubRoutines.hpp"
  40 #include "runtime/synchronizer.hpp"
  41 #include "utilities/macros.hpp"
  42 
  43 #define __ _masm->
  44 
  45 // Global Register Names
  46 static const Register rbcp     = LP64_ONLY(r13) NOT_LP64(rsi);
  47 static const Register rlocals  = LP64_ONLY(r14) NOT_LP64(rdi);
  48 


 132   switch (cc) {
 133   case TemplateTable::equal        : return Assembler::notEqual;
 134   case TemplateTable::not_equal    : return Assembler::equal;
 135   case TemplateTable::less         : return Assembler::greaterEqual;
 136   case TemplateTable::less_equal   : return Assembler::greater;
 137   case TemplateTable::greater      : return Assembler::lessEqual;
 138   case TemplateTable::greater_equal: return Assembler::less;
 139   }
 140   ShouldNotReachHere();
 141   return Assembler::zero;
 142 }
 143 
 144 
 145 
 146 // Miscelaneous helper routines
 147 // Store an oop (or NULL) at the address described by obj.
 148 // If val == noreg this means store a NULL
 149 
 150 
 151 static void do_oop_store(InterpreterMacroAssembler* _masm,
 152                          Address dst,
 153                          Register val,
 154                          DecoratorSet decorators) {

 155   assert(val == noreg || val == rax, "parameter is just for looks");
 156   BarrierSetCodeGen *code_gen = Universe::heap()->barrier_set()->code_gen();
 157   code_gen->store_at(_masm, decorators, T_OBJECT, dst, val, /*tmp1*/ rdx, /*tmp2*/ rbx);
 158 }





































































 159 
 160 static void do_oop_load(InterpreterMacroAssembler* _masm,
 161                         Address src,
 162                         Register dst,
 163                         DecoratorSet decorators) {
 164   BarrierSetCodeGen *code_gen = Universe::heap()->barrier_set()->code_gen();
 165   code_gen->load_at(_masm, decorators, T_OBJECT, dst, src, /*tmp1*/ rdx, /*tmp2*/ rbx);
 166 }
 167 
 168 Address TemplateTable::at_bcp(int offset) {
 169   assert(_desc->uses_bcp(), "inconsistent uses_bcp information");
 170   return Address(rbcp, offset);
 171 }
 172 
 173 
 174 void TemplateTable::patch_bytecode(Bytecodes::Code bc, Register bc_reg,
 175                                    Register temp_reg, bool load_bc_into_bc_reg/*=true*/,
 176                                    int byte_no) {
 177   if (!RewriteBytecodes)  return;
 178   Label L_patch_done;
 179 
 180   switch (bc) {
 181   case Bytecodes::_fast_aputfield:
 182   case Bytecodes::_fast_bputfield:
 183   case Bytecodes::_fast_zputfield:
 184   case Bytecodes::_fast_cputfield:
 185   case Bytecodes::_fast_dputfield:


 666   __ load_float(Address(rdx, rax,
 667                         Address::times_4,
 668                         arrayOopDesc::base_offset_in_bytes(T_FLOAT)));
 669 }
 670 
 671 void TemplateTable::daload() {
 672   transition(itos, dtos);
 673   // rax: index
 674   // rdx: array
 675   index_check(rdx, rax); // kills rbx
 676   __ load_double(Address(rdx, rax,
 677                          Address::times_8,
 678                          arrayOopDesc::base_offset_in_bytes(T_DOUBLE)));
 679 }
 680 
 681 void TemplateTable::aaload() {
 682   transition(itos, atos);
 683   // rax: index
 684   // rdx: array
 685   index_check(rdx, rax); // kills rbx
 686   do_oop_load(_masm,
 687               Address(rdx, rax,
 688                       UseCompressedOops ? Address::times_4 : Address::times_ptr,
 689                       arrayOopDesc::base_offset_in_bytes(T_OBJECT)),
 690               rax,
 691               ACCESS_ON_HEAP | ACCESS_ON_ARRAY);
 692 }
 693 
 694 void TemplateTable::baload() {
 695   transition(itos, itos);
 696   // rax: index
 697   // rdx: array
 698   index_check(rdx, rax); // kills rbx
 699   __ load_signed_byte(rax, Address(rdx, rax, Address::times_1, arrayOopDesc::base_offset_in_bytes(T_BYTE)));
 700 }
 701 
 702 void TemplateTable::caload() {
 703   transition(itos, itos);
 704   // rax: index
 705   // rdx: array
 706   index_check(rdx, rax); // kills rbx
 707   __ load_unsigned_short(rax, Address(rdx, rax, Address::times_2, arrayOopDesc::base_offset_in_bytes(T_CHAR)));
 708 }
 709 
 710 // iload followed by caload frequent pair
 711 void TemplateTable::fast_icaload() {


 982   __ load_klass(rax, rdx);
 983   __ movptr(rax, Address(rax,
 984                          ObjArrayKlass::element_klass_offset()));
 985   // Compress array + index*oopSize + 12 into a single register.  Frees rcx.
 986   __ lea(rdx, element_address);
 987 
 988   // Generate subtype check.  Blows rcx, rdi
 989   // Superklass in rax.  Subklass in rbx.
 990   __ gen_subtype_check(rbx, ok_is_subtype);
 991 
 992   // Come here on failure
 993   // object is at TOS
 994   __ jump(ExternalAddress(Interpreter::_throw_ArrayStoreException_entry));
 995 
 996   // Come here on success
 997   __ bind(ok_is_subtype);
 998 
 999   // Get the value we will store
1000   __ movptr(rax, at_tos());
1001   // Now store using the appropriate barrier
1002   do_oop_store(_masm, Address(rdx, 0), rax, ACCESS_ON_HEAP);
1003   __ jmp(done);
1004 
1005   // Have a NULL in rax, rdx=array, ecx=index.  Store NULL at ary[idx]
1006   __ bind(is_null);
1007   __ profile_null_seen(rbx);
1008 
1009   // Store a NULL
1010   do_oop_store(_masm, element_address, noreg, ACCESS_ON_HEAP);
1011 
1012   // Pop stack arguments
1013   __ bind(done);
1014   __ addptr(rsp, 3 * Interpreter::stackElementSize);
1015 }
1016 
1017 void TemplateTable::bastore() {
1018   transition(itos, vtos);
1019   __ pop_i(rbx);
1020   // rax: value
1021   // rbx: index
1022   // rdx: array
1023   index_check(rdx, rbx); // prefer index in rbx
1024   // Need to check whether array is boolean or byte
1025   // since both types share the bastore bytecode.
1026   __ load_klass(rcx, rdx);
1027   __ movl(rcx, Address(rcx, Klass::layout_helper_offset()));
1028   int diffbit = Klass::layout_helper_boolean_diffbit();
1029   __ testl(rcx, diffbit);
1030   Label L_skip;


2999   {
3000     __ pop(ztos);
3001     if (!is_static) pop_and_check_object(obj);
3002     __ andl(rax, 0x1);
3003     __ movb(field, rax);
3004     if (!is_static && rc == may_rewrite) {
3005       patch_bytecode(Bytecodes::_fast_zputfield, bc, rbx, true, byte_no);
3006     }
3007     __ jmp(Done);
3008   }
3009 
3010   __ bind(notBool);
3011   __ cmpl(flags, atos);
3012   __ jcc(Assembler::notEqual, notObj);
3013 
3014   // atos
3015   {
3016     __ pop(atos);
3017     if (!is_static) pop_and_check_object(obj);
3018     // Store into the field
3019     do_oop_store(_masm, field, rax, ACCESS_ON_HEAP | ACCESS_ON_ARRAY);
3020     if (!is_static && rc == may_rewrite) {
3021       patch_bytecode(Bytecodes::_fast_aputfield, bc, rbx, true, byte_no);
3022     }
3023     __ jmp(Done);
3024   }
3025 
3026   __ bind(notObj);
3027   __ cmpl(flags, itos);
3028   __ jcc(Assembler::notEqual, notInt);
3029 
3030   // itos
3031   {
3032     __ pop(itos);
3033     if (!is_static) pop_and_check_object(obj);
3034     __ movl(field, rax);
3035     if (!is_static && rc == may_rewrite) {
3036       patch_bytecode(Bytecodes::_fast_iputfield, bc, rbx, true, byte_no);
3037     }
3038     __ jmp(Done);
3039   }


3251   __ movptr(rbx, Address(rcx, rbx, Address::times_ptr,
3252                          in_bytes(base + ConstantPoolCacheEntry::f2_offset())));
3253 
3254   // [jk] not needed currently
3255   // volatile_barrier(Assembler::Membar_mask_bits(Assembler::LoadStore |
3256   //                                              Assembler::StoreStore));
3257 
3258   Label notVolatile;
3259   __ shrl(rdx, ConstantPoolCacheEntry::is_volatile_shift);
3260   __ andl(rdx, 0x1);
3261 
3262   // Get object from stack
3263   pop_and_check_object(rcx);
3264 
3265   // field address
3266   const Address field(rcx, rbx, Address::times_1);
3267 
3268   // access field
3269   switch (bytecode()) {
3270   case Bytecodes::_fast_aputfield:
3271     do_oop_store(_masm, field, rax, ACCESS_ON_HEAP | ACCESS_ON_ARRAY);
3272     break;
3273   case Bytecodes::_fast_lputfield:
3274 #ifdef _LP64
3275   __ movq(field, rax);
3276 #else
3277   __ stop("should not be rewritten");
3278 #endif
3279     break;
3280   case Bytecodes::_fast_iputfield:
3281     __ movl(field, rax);
3282     break;
3283   case Bytecodes::_fast_zputfield:
3284     __ andl(rax, 0x1);  // boolean is true if LSB is 1
3285     // fall through to bputfield
3286   case Bytecodes::_fast_bputfield:
3287     __ movb(field, rax);
3288     break;
3289   case Bytecodes::_fast_sputfield:
3290     // fall through
3291   case Bytecodes::_fast_cputfield:


< prev index next >