src/cpu/x86/vm/templateTable_x86_64.cpp

changeset 797
f8199438385b
parent 739
dc7f315e41f7
parent 791
1ee8caae33af
child 1040
98cb887364d3
     1.1 --- a/src/cpu/x86/vm/templateTable_x86_64.cpp	Thu Sep 04 18:40:43 2008 -0700
     1.2 +++ b/src/cpu/x86/vm/templateTable_x86_64.cpp	Wed Sep 17 16:49:18 2008 +0400
     1.3 @@ -115,6 +115,69 @@
     1.4  
     1.5  
     1.6  // Miscelaneous helper routines
     1.7 +// Store an oop (or NULL) at the address described by obj.
     1.8 +// If val == noreg this means store a NULL
     1.9 +
    1.10 +static void do_oop_store(InterpreterMacroAssembler* _masm,
    1.11 +                         Address obj,
    1.12 +                         Register val,
    1.13 +                         BarrierSet::Name barrier,
    1.14 +                         bool precise) {
    1.15 +  assert(val == noreg || val == rax, "parameter is just for looks");
    1.16 +  switch (barrier) {
    1.17 +#ifndef SERIALGC
    1.18 +    case BarrierSet::G1SATBCT:
    1.19 +    case BarrierSet::G1SATBCTLogging:
    1.20 +      {
    1.21 +        // flatten object address if needed
    1.22 +        if (obj.index() == noreg && obj.disp() == 0) {
    1.23 +          if (obj.base() != rdx) {
    1.24 +            __ movq(rdx, obj.base());
    1.25 +          }
    1.26 +        } else {
    1.27 +          __ leaq(rdx, obj);
    1.28 +        }
    1.29 +        __ g1_write_barrier_pre(rdx, r8, rbx, val != noreg);
    1.30 +        if (val == noreg) {
    1.31 +          __ store_heap_oop(Address(rdx, 0), NULL_WORD);
    1.32 +        } else {
    1.33 +          __ store_heap_oop(Address(rdx, 0), val);
    1.34 +          __ g1_write_barrier_post(rdx, val, r8, rbx);
    1.35 +        }
    1.36 +
    1.37 +      }
    1.38 +      break;
    1.39 +#endif // SERIALGC
    1.40 +    case BarrierSet::CardTableModRef:
    1.41 +    case BarrierSet::CardTableExtension:
    1.42 +      {
    1.43 +        if (val == noreg) {
    1.44 +          __ store_heap_oop(obj, NULL_WORD);
    1.45 +        } else {
    1.46 +          __ store_heap_oop(obj, val);
    1.47 +          // flatten object address if needed
    1.48 +          if (!precise || (obj.index() == noreg && obj.disp() == 0)) {
    1.49 +            __ store_check(obj.base());
    1.50 +          } else {
    1.51 +            __ leaq(rdx, obj);
    1.52 +            __ store_check(rdx);
    1.53 +          }
    1.54 +        }
    1.55 +      }
    1.56 +      break;
    1.57 +    case BarrierSet::ModRef:
    1.58 +    case BarrierSet::Other:
    1.59 +      if (val == noreg) {
    1.60 +        __ store_heap_oop(obj, NULL_WORD);
    1.61 +      } else {
    1.62 +        __ store_heap_oop(obj, val);
    1.63 +      }
    1.64 +      break;
    1.65 +    default      :
    1.66 +      ShouldNotReachHere();
    1.67 +
    1.68 +  }
    1.69 +}
    1.70  
    1.71  Address TemplateTable::at_bcp(int offset) {
    1.72    assert(_desc->uses_bcp(), "inconsistent uses_bcp information");
    1.73 @@ -560,8 +623,8 @@
    1.74    // rdx: array
    1.75    index_check(rdx, rax); // kills rbx
    1.76    __ load_heap_oop(rax, Address(rdx, rax,
    1.77 -                       UseCompressedOops ? Address::times_4 : Address::times_8,
    1.78 -                       arrayOopDesc::base_offset_in_bytes(T_OBJECT)));
    1.79 +                                UseCompressedOops ? Address::times_4 : Address::times_8,
    1.80 +                                arrayOopDesc::base_offset_in_bytes(T_OBJECT)));
    1.81  }
    1.82  
    1.83  void TemplateTable::baload() {
    1.84 @@ -866,6 +929,11 @@
    1.85    __ movptr(rax, at_tos());    // value
    1.86    __ movl(rcx, at_tos_p1()); // index
    1.87    __ movptr(rdx, at_tos_p2()); // array
    1.88 +
    1.89 +  Address element_address(rdx, rcx,
    1.90 +                          UseCompressedOops? Address::times_4 : Address::times_8,
    1.91 +                          arrayOopDesc::base_offset_in_bytes(T_OBJECT));
    1.92 +
    1.93    index_check(rdx, rcx);     // kills rbx
    1.94    // do array store check - check for NULL value first
    1.95    __ testptr(rax, rax);
    1.96 @@ -879,9 +947,7 @@
    1.97                           sizeof(oopDesc) +
    1.98                           objArrayKlass::element_klass_offset_in_bytes()));
    1.99    // Compress array + index*oopSize + 12 into a single register.  Frees rcx.
   1.100 -  __ lea(rdx, Address(rdx, rcx,
   1.101 -                      UseCompressedOops ? Address::times_4 : Address::times_8,
   1.102 -                      arrayOopDesc::base_offset_in_bytes(T_OBJECT)));
   1.103 +  __ lea(rdx, element_address);
   1.104  
   1.105    // Generate subtype check.  Blows rcx, rdi
   1.106    // Superklass in rax.  Subklass in rbx.
   1.107 @@ -893,18 +959,19 @@
   1.108  
   1.109    // Come here on success
   1.110    __ bind(ok_is_subtype);
   1.111 -  __ movptr(rax, at_tos()); // Value
   1.112 -  __ store_heap_oop(Address(rdx, 0), rax);
   1.113 -  __ store_check(rdx);
   1.114 +
   1.115 +  // Get the value we will store
   1.116 +  __ movptr(rax, at_tos());
   1.117 +  // Now store using the appropriate barrier
   1.118 +  do_oop_store(_masm, Address(rdx, 0), rax, _bs->kind(), true);
   1.119    __ jmp(done);
   1.120  
   1.121    // Have a NULL in rax, rdx=array, ecx=index.  Store NULL at ary[idx]
   1.122    __ bind(is_null);
   1.123    __ profile_null_seen(rbx);
   1.124 -  __ store_heap_oop(Address(rdx, rcx,
   1.125 -                            UseCompressedOops ? Address::times_4 : Address::times_8,
   1.126 -                            arrayOopDesc::base_offset_in_bytes(T_OBJECT)),
   1.127 -                    rax);
   1.128 +
   1.129 +  // Store a NULL
   1.130 +  do_oop_store(_masm, element_address, noreg, _bs->kind(), true);
   1.131  
   1.132    // Pop stack arguments
   1.133    __ bind(done);
   1.134 @@ -2396,8 +2463,10 @@
   1.135    // atos
   1.136    __ pop(atos);
   1.137    if (!is_static) pop_and_check_object(obj);
   1.138 -  __ store_heap_oop(field, rax);
   1.139 -  __ store_check(obj, field); // Need to mark card
   1.140 +
   1.141 +  // Store into the field
   1.142 +  do_oop_store(_masm, field, rax, _bs->kind(), false);
   1.143 +
   1.144    if (!is_static) {
   1.145      patch_bytecode(Bytecodes::_fast_aputfield, bc, rbx);
   1.146    }
   1.147 @@ -2584,8 +2653,7 @@
   1.148    // access field
   1.149    switch (bytecode()) {
   1.150    case Bytecodes::_fast_aputfield:
   1.151 -    __ store_heap_oop(field, rax);
   1.152 -    __ store_check(rcx, field);
   1.153 +    do_oop_store(_masm, field, rax, _bs->kind(), false);
   1.154      break;
   1.155    case Bytecodes::_fast_lputfield:
   1.156      __ movq(field, rax);
   1.157 @@ -3044,8 +3112,6 @@
   1.158    Label initialize_header;
   1.159    Label initialize_object; // including clearing the fields
   1.160    Label allocate_shared;
   1.161 -  ExternalAddress top((address)Universe::heap()->top_addr());
   1.162 -  ExternalAddress end((address)Universe::heap()->end_addr());
   1.163  
   1.164    __ get_cpool_and_tags(rsi, rax);
   1.165    // get instanceKlass
   1.166 @@ -3106,6 +3172,9 @@
   1.167    if (allow_shared_alloc) {
   1.168      __ bind(allocate_shared);
   1.169  
   1.170 +    ExternalAddress top((address)Universe::heap()->top_addr());
   1.171 +    ExternalAddress end((address)Universe::heap()->end_addr());
   1.172 +
   1.173      const Register RtopAddr = rscratch1;
   1.174      const Register RendAddr = rscratch2;
   1.175  

mercurial