src/cpu/x86/vm/assembler_x86_64.cpp

changeset 779
6aae2f9d0294
parent 777
37f87013dfd8
parent 621
cf1821c649d9
child 791
1ee8caae33af
     1.1 --- a/src/cpu/x86/vm/assembler_x86_64.cpp	Thu Jun 05 15:57:56 2008 -0700
     1.2 +++ b/src/cpu/x86/vm/assembler_x86_64.cpp	Thu Jun 12 13:50:55 2008 -0700
     1.3 @@ -683,7 +683,8 @@
     1.4  
     1.5    case REP8(0xB8): // movl/q r, #32/#64(oop?)
     1.6      if (which == end_pc_operand)  return ip + (is_64bit ? 8 : 4);
     1.7 -    assert((which == call32_operand || which == imm64_operand) && is_64bit, "");
     1.8 +    assert((which == call32_operand || which == imm64_operand) && is_64bit ||
     1.9 +           which == narrow_oop_operand && !is_64bit, "");
    1.10      return ip;
    1.11  
    1.12    case 0x69: // imul r, a, #32
    1.13 @@ -909,7 +910,8 @@
    1.14    } else if (r->is_call() || format == call32_operand) {
    1.15      opnd = locate_operand(inst, call32_operand);
    1.16    } else if (r->is_data()) {
    1.17 -    assert(format == imm64_operand || format == disp32_operand, "format ok");
    1.18 +    assert(format == imm64_operand || format == disp32_operand ||
    1.19 +           format == narrow_oop_operand, "format ok");
    1.20      opnd = locate_operand(inst, (WhichOperand) format);
    1.21    } else {
    1.22      assert(format == 0, "cannot specify a format");
    1.23 @@ -5060,6 +5062,8 @@
    1.24    movq(Address(top, arrayOopDesc::length_offset_in_bytes()), t1);
    1.25    // set klass to intArrayKlass
    1.26    movptr(t1, ExternalAddress((address) Universe::intArrayKlassObj_addr()));
    1.27 +  // store klass last.  concurrent gcs assumes klass length is valid if
    1.28 +  // klass field is not null.
    1.29    store_klass(top, t1);
    1.30  
    1.31    // refill the tlab with an eden allocation
    1.32 @@ -5130,8 +5134,7 @@
    1.33    jcc(Assembler::notEqual, cas_label);
    1.34    // The bias pattern is present in the object's header. Need to check
    1.35    // whether the bias owner and the epoch are both still current.
    1.36 -  load_klass(tmp_reg, obj_reg);
    1.37 -  movq(tmp_reg, Address(tmp_reg, Klass::prototype_header_offset_in_bytes() + klassOopDesc::klass_part_offset_in_bytes()));
    1.38 +  load_prototype_header(tmp_reg, obj_reg);
    1.39    orq(tmp_reg, r15_thread);
    1.40    xorq(tmp_reg, swap_reg);
    1.41    andq(tmp_reg, ~((int) markOopDesc::age_mask_in_place));
    1.42 @@ -5205,8 +5208,7 @@
    1.43    //
    1.44    // FIXME: due to a lack of registers we currently blow away the age
    1.45    // bits in this situation. Should attempt to preserve them.
    1.46 -  load_klass(tmp_reg, obj_reg);
    1.47 -  movq(tmp_reg, Address(tmp_reg, Klass::prototype_header_offset_in_bytes() + klassOopDesc::klass_part_offset_in_bytes()));
    1.48 +  load_prototype_header(tmp_reg, obj_reg);
    1.49    orq(tmp_reg, r15_thread);
    1.50    if (os::is_MP()) {
    1.51      lock();
    1.52 @@ -5236,8 +5238,7 @@
    1.53    //
    1.54    // FIXME: due to a lack of registers we currently blow away the age
    1.55    // bits in this situation. Should attempt to preserve them.
    1.56 -  load_klass(tmp_reg, obj_reg);
    1.57 -  movq(tmp_reg, Address(tmp_reg, Klass::prototype_header_offset_in_bytes() + klassOopDesc::klass_part_offset_in_bytes()));
    1.58 +  load_prototype_header(tmp_reg, obj_reg);
    1.59    if (os::is_MP()) {
    1.60      lock();
    1.61    }
    1.62 @@ -5281,17 +5282,32 @@
    1.63    }
    1.64  }
    1.65  
    1.66 +void MacroAssembler::load_prototype_header(Register dst, Register src) {
    1.67 +  if (UseCompressedOops) {
    1.68 +    movl(dst, Address(src, oopDesc::klass_offset_in_bytes()));
    1.69 +    movq(dst, Address(r12_heapbase, dst, Address::times_8, Klass::prototype_header_offset_in_bytes() + klassOopDesc::klass_part_offset_in_bytes()));
    1.70 +  } else {
    1.71 +    movq(dst, Address(src, oopDesc::klass_offset_in_bytes()));
    1.72 +    movq(dst, Address(dst, Klass::prototype_header_offset_in_bytes() + klassOopDesc::klass_part_offset_in_bytes()));
    1.73 +  }
    1.74 +}
    1.75 +
    1.76  void MacroAssembler::store_klass(Register dst, Register src) {
    1.77    if (UseCompressedOops) {
    1.78      encode_heap_oop_not_null(src);
    1.79 -    // zero the entire klass field first as the gap needs to be zeroed too.
    1.80 -    movptr(Address(dst, oopDesc::klass_offset_in_bytes()), NULL_WORD);
    1.81      movl(Address(dst, oopDesc::klass_offset_in_bytes()), src);
    1.82    } else {
    1.83      movq(Address(dst, oopDesc::klass_offset_in_bytes()), src);
    1.84    }
    1.85  }
    1.86  
    1.87 +void MacroAssembler::store_klass_gap(Register dst, Register src) {
    1.88 +  if (UseCompressedOops) {
    1.89 +    // Store to klass gap in destination
    1.90 +    movl(Address(dst, oopDesc::klass_gap_offset_in_bytes()), src);
    1.91 +  }
    1.92 +}
    1.93 +
    1.94  void MacroAssembler::load_heap_oop(Register dst, Address src) {
    1.95    if (UseCompressedOops) {
    1.96      movl(dst, src);
    1.97 @@ -5315,13 +5331,15 @@
    1.98  void MacroAssembler::encode_heap_oop(Register r) {
    1.99    assert (UseCompressedOops, "should be compressed");
   1.100  #ifdef ASSERT
   1.101 -  Label ok;
   1.102 -  pushq(rscratch1); // cmpptr trashes rscratch1
   1.103 -  cmpptr(r12_heapbase, ExternalAddress((address)Universe::heap_base_addr()));
   1.104 -  jcc(Assembler::equal, ok);
   1.105 -  stop("MacroAssembler::encode_heap_oop: heap base corrupted?");
   1.106 -  bind(ok);
   1.107 -  popq(rscratch1);
   1.108 +  if (CheckCompressedOops) {
   1.109 +    Label ok;
   1.110 +    pushq(rscratch1); // cmpptr trashes rscratch1
   1.111 +    cmpptr(r12_heapbase, ExternalAddress((address)Universe::heap_base_addr()));
   1.112 +    jcc(Assembler::equal, ok);
   1.113 +    stop("MacroAssembler::encode_heap_oop: heap base corrupted?");
   1.114 +    bind(ok);
   1.115 +    popq(rscratch1);
   1.116 +  }
   1.117  #endif
   1.118    verify_oop(r, "broken oop in encode_heap_oop");
   1.119    testq(r, r);
   1.120 @@ -5333,11 +5351,13 @@
   1.121  void MacroAssembler::encode_heap_oop_not_null(Register r) {
   1.122    assert (UseCompressedOops, "should be compressed");
   1.123  #ifdef ASSERT
   1.124 -  Label ok;
   1.125 -  testq(r, r);
   1.126 -  jcc(Assembler::notEqual, ok);
   1.127 -  stop("null oop passed to encode_heap_oop_not_null");
   1.128 -  bind(ok);
   1.129 +  if (CheckCompressedOops) {
   1.130 +    Label ok;
   1.131 +    testq(r, r);
   1.132 +    jcc(Assembler::notEqual, ok);
   1.133 +    stop("null oop passed to encode_heap_oop_not_null");
   1.134 +    bind(ok);
   1.135 +  }
   1.136  #endif
   1.137    verify_oop(r, "broken oop in encode_heap_oop_not_null");
   1.138    subq(r, r12_heapbase);
   1.139 @@ -5347,11 +5367,13 @@
   1.140  void MacroAssembler::encode_heap_oop_not_null(Register dst, Register src) {
   1.141    assert (UseCompressedOops, "should be compressed");
   1.142  #ifdef ASSERT
   1.143 -  Label ok;
   1.144 -  testq(src, src);
   1.145 -  jcc(Assembler::notEqual, ok);
   1.146 -  stop("null oop passed to encode_heap_oop_not_null2");
   1.147 -  bind(ok);
   1.148 +  if (CheckCompressedOops) {
   1.149 +    Label ok;
   1.150 +    testq(src, src);
   1.151 +    jcc(Assembler::notEqual, ok);
   1.152 +    stop("null oop passed to encode_heap_oop_not_null2");
   1.153 +    bind(ok);
   1.154 +  }
   1.155  #endif
   1.156    verify_oop(src, "broken oop in encode_heap_oop_not_null2");
   1.157    if (dst != src) {
   1.158 @@ -5364,14 +5386,16 @@
   1.159  void  MacroAssembler::decode_heap_oop(Register r) {
   1.160    assert (UseCompressedOops, "should be compressed");
   1.161  #ifdef ASSERT
   1.162 -  Label ok;
   1.163 -  pushq(rscratch1);
   1.164 -  cmpptr(r12_heapbase,
   1.165 -         ExternalAddress((address)Universe::heap_base_addr()));
   1.166 -  jcc(Assembler::equal, ok);
   1.167 -  stop("MacroAssembler::decode_heap_oop: heap base corrupted?");
   1.168 -  bind(ok);
   1.169 -  popq(rscratch1);
   1.170 +  if (CheckCompressedOops) {
   1.171 +    Label ok;
   1.172 +    pushq(rscratch1);
   1.173 +    cmpptr(r12_heapbase,
   1.174 +           ExternalAddress((address)Universe::heap_base_addr()));
   1.175 +    jcc(Assembler::equal, ok);
   1.176 +    stop("MacroAssembler::decode_heap_oop: heap base corrupted?");
   1.177 +    bind(ok);
   1.178 +    popq(rscratch1);
   1.179 +  }
   1.180  #endif
   1.181  
   1.182    Label done;
   1.183 @@ -5392,6 +5416,7 @@
   1.184    assert (UseCompressedOops, "should only be used for compressed headers");
   1.185    // Cannot assert, unverified entry point counts instructions (see .ad file)
   1.186    // vtableStubs also counts instructions in pd_code_size_limit.
   1.187 +  // Also do not verify_oop as this is called by verify_oop.
   1.188    assert(Address::times_8 == LogMinObjAlignmentInBytes, "decode alg wrong");
   1.189    leaq(r, Address(r12_heapbase, r, Address::times_8, 0));
   1.190  }
   1.191 @@ -5400,10 +5425,24 @@
   1.192    assert (UseCompressedOops, "should only be used for compressed headers");
   1.193    // Cannot assert, unverified entry point counts instructions (see .ad file)
   1.194    // vtableStubs also counts instructions in pd_code_size_limit.
   1.195 +  // Also do not verify_oop as this is called by verify_oop.
   1.196    assert(Address::times_8 == LogMinObjAlignmentInBytes, "decode alg wrong");
   1.197    leaq(dst, Address(r12_heapbase, src, Address::times_8, 0));
   1.198  }
   1.199  
   1.200 +void  MacroAssembler::set_narrow_oop(Register dst, jobject obj) {
   1.201 +  assert(oop_recorder() != NULL, "this assembler needs an OopRecorder");
   1.202 +  int oop_index = oop_recorder()->find_index(obj);
   1.203 +  RelocationHolder rspec = oop_Relocation::spec(oop_index);
   1.204 +
   1.205 +  // movl dst,obj
   1.206 +  InstructionMark im(this);
   1.207 +  int encode = prefix_and_encode(dst->encoding());
   1.208 +  emit_byte(0xB8 | encode);
   1.209 +  emit_data(oop_index, rspec, narrow_oop_operand);
   1.210 +}
   1.211 +
   1.212 +
   1.213  Assembler::Condition MacroAssembler::negate_condition(Assembler::Condition cond) {
   1.214    switch (cond) {
   1.215      // Note some conditions are synonyms for others

mercurial