src/hotspot/cpu/x86/stubGenerator_x86_32.cpp
changeset 49484 ee8fa73b90f9
parent 49455 848864ed9b17
child 49754 ee93c1087584
child 56406 e629240491c7
equal deleted inserted replaced
49483:d374b1634589 49484:ee8fa73b90f9
    23  */
    23  */
    24 
    24 
    25 #include "precompiled.hpp"
    25 #include "precompiled.hpp"
    26 #include "asm/macroAssembler.hpp"
    26 #include "asm/macroAssembler.hpp"
    27 #include "asm/macroAssembler.inline.hpp"
    27 #include "asm/macroAssembler.inline.hpp"
    28 #include "gc/shared/cardTable.hpp"
    28 #include "gc/shared/barrierSet.hpp"
    29 #include "gc/shared/cardTableBarrierSet.hpp"
    29 #include "gc/shared/barrierSetAssembler.hpp"
    30 #include "interpreter/interpreter.hpp"
    30 #include "interpreter/interpreter.hpp"
    31 #include "nativeInst_x86.hpp"
    31 #include "nativeInst_x86.hpp"
    32 #include "oops/instanceOop.hpp"
    32 #include "oops/instanceOop.hpp"
    33 #include "oops/method.hpp"
    33 #include "oops/method.hpp"
    34 #include "oops/objArrayKlass.hpp"
    34 #include "oops/objArrayKlass.hpp"
   664     BLOCK_COMMENT("call MacroAssembler::debug");
   664     BLOCK_COMMENT("call MacroAssembler::debug");
   665     __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, MacroAssembler::debug32)));
   665     __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, MacroAssembler::debug32)));
   666     __ popa();
   666     __ popa();
   667     __ ret(3 * wordSize);                        // pop arguments
   667     __ ret(3 * wordSize);                        // pop arguments
   668     return start;
   668     return start;
   669   }
       
   670 
       
   671   //
       
   672   //  Generate pre-barrier for array stores
       
   673   //
       
   674   //  Input:
       
   675   //     start   -  starting address
       
   676   //     count   -  element count
       
   677   void  gen_write_ref_array_pre_barrier(Register start, Register count, bool uninitialized_target) {
       
   678     assert_different_registers(start, count);
       
   679     BarrierSet* bs = Universe::heap()->barrier_set();
       
   680     switch (bs->kind()) {
       
   681 #if INCLUDE_ALL_GCS
       
   682       case BarrierSet::G1BarrierSet:
       
   683         // With G1, don't generate the call if we statically know that the target in uninitialized
       
   684         if (!uninitialized_target) {
       
   685           Register thread = rax;
       
   686           Label filtered;
       
   687           __ push(thread);
       
   688           __ get_thread(thread);
       
   689           Address in_progress(thread, in_bytes(JavaThread::satb_mark_queue_offset() +
       
   690                                                SATBMarkQueue::byte_offset_of_active()));
       
   691           // Is marking active?
       
   692           if (in_bytes(SATBMarkQueue::byte_width_of_active()) == 4) {
       
   693             __ cmpl(in_progress, 0);
       
   694           } else {
       
   695             assert(in_bytes(SATBMarkQueue::byte_width_of_active()) == 1, "Assumption");
       
   696             __ cmpb(in_progress, 0);
       
   697           }
       
   698           __ pop(thread);
       
   699           __ jcc(Assembler::equal, filtered);
       
   700 
       
   701            __ pusha();                      // push registers
       
   702            __ call_VM_leaf(CAST_FROM_FN_PTR(address, BarrierSet::static_write_ref_array_pre),
       
   703                            start, count);
       
   704            __ popa();
       
   705 
       
   706            __ bind(filtered);
       
   707          }
       
   708         break;
       
   709 #endif // INCLUDE_ALL_GCS
       
   710       case BarrierSet::CardTableBarrierSet:
       
   711         break;
       
   712       default      :
       
   713         ShouldNotReachHere();
       
   714 
       
   715     }
       
   716   }
       
   717 
       
   718 
       
   719   //
       
   720   // Generate a post-barrier for an array store
       
   721   //
       
   722   //     start    -  starting address
       
   723   //     count    -  element count
       
   724   //
       
   725   //  The two input registers are overwritten.
       
   726   //
       
   727   void  gen_write_ref_array_post_barrier(Register start, Register count) {
       
   728     BarrierSet* bs = Universe::heap()->barrier_set();
       
   729     assert_different_registers(start, count);
       
   730     switch (bs->kind()) {
       
   731 #if INCLUDE_ALL_GCS
       
   732       case BarrierSet::G1BarrierSet:
       
   733         {
       
   734           __ pusha();                      // push registers
       
   735           __ call_VM_leaf(CAST_FROM_FN_PTR(address, BarrierSet::static_write_ref_array_post),
       
   736                           start, count);
       
   737           __ popa();
       
   738         }
       
   739         break;
       
   740 #endif // INCLUDE_ALL_GCS
       
   741 
       
   742       case BarrierSet::CardTableBarrierSet:
       
   743         {
       
   744           CardTableBarrierSet* ctbs = barrier_set_cast<CardTableBarrierSet>(bs);
       
   745           CardTable* ct = ctbs->card_table();
       
   746           assert(sizeof(*ct->byte_map_base()) == sizeof(jbyte), "adjust this code");
       
   747 
       
   748           Label L_loop;
       
   749           const Register end = count;  // elements count; end == start+count-1
       
   750           assert_different_registers(start, end);
       
   751 
       
   752           __ lea(end,  Address(start, count, Address::times_ptr, -wordSize));
       
   753           __ shrptr(start, CardTable::card_shift);
       
   754           __ shrptr(end,   CardTable::card_shift);
       
   755           __ subptr(end, start); // end --> count
       
   756         __ BIND(L_loop);
       
   757         intptr_t disp = (intptr_t) ct->byte_map_base();
       
   758           Address cardtable(start, count, Address::times_1, disp);
       
   759           __ movb(cardtable, 0);
       
   760           __ decrement(count);
       
   761           __ jcc(Assembler::greaterEqual, L_loop);
       
   762         }
       
   763         break;
       
   764       case BarrierSet::ModRef:
       
   765         break;
       
   766       default      :
       
   767         ShouldNotReachHere();
       
   768 
       
   769     }
       
   770   }
   669   }
   771 
   670 
   772 
   671 
   773   // Copy 64 bytes chunks
   672   // Copy 64 bytes chunks
   774   //
   673   //
   934     }
   833     }
   935 
   834 
   936     if (t == T_OBJECT) {
   835     if (t == T_OBJECT) {
   937       __ testl(count, count);
   836       __ testl(count, count);
   938       __ jcc(Assembler::zero, L_0_count);
   837       __ jcc(Assembler::zero, L_0_count);
   939       gen_write_ref_array_pre_barrier(to, count, dest_uninitialized);
   838     }
   940       __ mov(saved_to, to);          // save 'to'
   839 
   941     }
   840     DecoratorSet decorators = ARRAYCOPY_DISJOINT;
       
   841     if (dest_uninitialized) {
       
   842       decorators |= AS_DEST_NOT_INITIALIZED;
       
   843     }
       
   844     if (aligned) {
       
   845       decorators |= ARRAYCOPY_ALIGNED;
       
   846     }
       
   847 
       
   848     BarrierSetAssembler *bs = Universe::heap()->barrier_set()->barrier_set_assembler();
       
   849     bs->arraycopy_prologue(_masm, decorators, t, from, to, count);
   942 
   850 
   943     __ subptr(to, from); // to --> to_from
   851     __ subptr(to, from); // to --> to_from
   944     __ cmpl(count, 2<<shift); // Short arrays (< 8 bytes) copy by element
   852     __ cmpl(count, 2<<shift); // Short arrays (< 8 bytes) copy by element
   945     __ jcc(Assembler::below, L_copy_4_bytes); // use unsigned cmp
   853     __ jcc(Assembler::below, L_copy_4_bytes); // use unsigned cmp
   946     if (!UseUnalignedLoadStores && !aligned && (t == T_BYTE || t == T_SHORT)) {
   854     if (!UseUnalignedLoadStores && !aligned && (t == T_BYTE || t == T_SHORT)) {
  1022       }
   930       }
  1023     } else {
   931     } else {
  1024     __ BIND(L_copy_2_bytes);
   932     __ BIND(L_copy_2_bytes);
  1025     }
   933     }
  1026 
   934 
       
   935     __ movl(count, Address(rsp, 12+12)); // reread 'count'
       
   936     bs->arraycopy_epilogue(_masm, decorators, t, from, to, count);
       
   937 
  1027     if (t == T_OBJECT) {
   938     if (t == T_OBJECT) {
  1028       __ movl(count, Address(rsp, 12+12)); // reread 'count'
       
  1029       __ mov(to, saved_to); // restore 'to'
       
  1030       gen_write_ref_array_post_barrier(to, count);
       
  1031     __ BIND(L_0_count);
   939     __ BIND(L_0_count);
  1032     }
   940     }
  1033     inc_copy_counter_np(t);
   941     inc_copy_counter_np(t);
  1034     __ pop(rdi);
   942     __ pop(rdi);
  1035     __ pop(rsi);
   943     __ pop(rsi);
  1114     __ jump_cc(Assembler::aboveEqual, nooverlap);
  1022     __ jump_cc(Assembler::aboveEqual, nooverlap);
  1115 
  1023 
  1116     if (t == T_OBJECT) {
  1024     if (t == T_OBJECT) {
  1117       __ testl(count, count);
  1025       __ testl(count, count);
  1118       __ jcc(Assembler::zero, L_0_count);
  1026       __ jcc(Assembler::zero, L_0_count);
  1119       gen_write_ref_array_pre_barrier(dst, count, dest_uninitialized);
  1027     }
  1120     }
  1028 
       
  1029     DecoratorSet decorators = 0;
       
  1030     if (dest_uninitialized) {
       
  1031       decorators |= AS_DEST_NOT_INITIALIZED;
       
  1032     }
       
  1033     if (aligned) {
       
  1034       decorators |= ARRAYCOPY_ALIGNED;
       
  1035     }
       
  1036 
       
  1037     BarrierSetAssembler *bs = Universe::heap()->barrier_set()->barrier_set_assembler();
       
  1038     bs->arraycopy_prologue(_masm, decorators, t, from, to, count);
  1121 
  1039 
  1122     // copy from high to low
  1040     // copy from high to low
  1123     __ cmpl(count, 2<<shift); // Short arrays (< 8 bytes) copy by element
  1041     __ cmpl(count, 2<<shift); // Short arrays (< 8 bytes) copy by element
  1124     __ jcc(Assembler::below, L_copy_4_bytes); // use unsigned cmp
  1042     __ jcc(Assembler::below, L_copy_4_bytes); // use unsigned cmp
  1125     if (t == T_BYTE || t == T_SHORT) {
  1043     if (t == T_BYTE || t == T_SHORT) {
  1214         __ BIND(L_copy_byte);
  1132         __ BIND(L_copy_byte);
  1215         }
  1133         }
  1216     } else {
  1134     } else {
  1217     __ BIND(L_copy_2_bytes);
  1135     __ BIND(L_copy_2_bytes);
  1218     }
  1136     }
       
  1137 
       
  1138     __ movl2ptr(count, Address(rsp, 12+12)); // reread count
       
  1139     bs->arraycopy_epilogue(_masm, decorators, t, from, to, count);
       
  1140 
  1219     if (t == T_OBJECT) {
  1141     if (t == T_OBJECT) {
  1220       __ movl2ptr(count, Address(rsp, 12+12)); // reread count
       
  1221       gen_write_ref_array_post_barrier(to, count);
       
  1222     __ BIND(L_0_count);
  1142     __ BIND(L_0_count);
  1223     }
  1143     }
  1224     inc_copy_counter_np(t);
  1144     inc_copy_counter_np(t);
  1225     __ pop(rdi);
  1145     __ pop(rdi);
  1226     __ pop(rsi);
  1146     __ pop(rsi);
  1461     // Loop-variant addresses.  They assume post-incremented count < 0.
  1381     // Loop-variant addresses.  They assume post-incremented count < 0.
  1462     Address from_element_addr(end_from, count, Address::times_ptr, 0);
  1382     Address from_element_addr(end_from, count, Address::times_ptr, 0);
  1463     Address   to_element_addr(end_to,   count, Address::times_ptr, 0);
  1383     Address   to_element_addr(end_to,   count, Address::times_ptr, 0);
  1464     Address elem_klass_addr(elem, oopDesc::klass_offset_in_bytes());
  1384     Address elem_klass_addr(elem, oopDesc::klass_offset_in_bytes());
  1465 
  1385 
       
  1386     DecoratorSet decorators = ARRAYCOPY_CHECKCAST;
       
  1387     if (dest_uninitialized) {
       
  1388       decorators |= AS_DEST_NOT_INITIALIZED;
       
  1389     }
       
  1390 
       
  1391     BasicType type = T_OBJECT;
       
  1392     BarrierSetAssembler *bs = Universe::heap()->barrier_set()->barrier_set_assembler();
       
  1393     bs->arraycopy_prologue(_masm, decorators, type, from, to, count);
       
  1394 
  1466     // Copy from low to high addresses, indexed from the end of each array.
  1395     // Copy from low to high addresses, indexed from the end of each array.
  1467     gen_write_ref_array_pre_barrier(to, count, dest_uninitialized);
       
  1468     __ lea(end_from, end_from_addr);
  1396     __ lea(end_from, end_from_addr);
  1469     __ lea(end_to,   end_to_addr);
  1397     __ lea(end_to,   end_to_addr);
  1470     assert(length == count, "");        // else fix next line:
  1398     assert(length == count, "");        // else fix next line:
  1471     __ negptr(count);                   // negate and test the length
  1399     __ negptr(count);                   // negate and test the length
  1472     __ jccb(Assembler::notZero, L_load_element);
  1400     __ jccb(Assembler::notZero, L_load_element);
  1519     __ xorptr(rax, rax);                // return 0 on success
  1447     __ xorptr(rax, rax);                // return 0 on success
  1520     __ movl2ptr(count, length_arg);
  1448     __ movl2ptr(count, length_arg);
  1521 
  1449 
  1522     __ BIND(L_post_barrier);
  1450     __ BIND(L_post_barrier);
  1523     __ movptr(to, to_arg);              // reload
  1451     __ movptr(to, to_arg);              // reload
  1524     gen_write_ref_array_post_barrier(to, count);
  1452     bs->arraycopy_epilogue(_masm, decorators, type, from, to, count);
  1525 
  1453 
  1526     // Common exit point (success or failure).
  1454     // Common exit point (success or failure).
  1527     __ BIND(L_done);
  1455     __ BIND(L_done);
  1528     __ pop(rbx);
  1456     __ pop(rbx);
  1529     __ pop(rdi);
  1457     __ pop(rdi);