src/share/vm/opto/library_call.cpp

changeset 548
ba764ed4b6f2
parent 469
545c277a3ecf
child 598
885ed790ecf0
     1.1 --- a/src/share/vm/opto/library_call.cpp	Fri Apr 11 09:56:35 2008 -0400
     1.2 +++ b/src/share/vm/opto/library_call.cpp	Sun Apr 13 17:43:42 2008 -0400
     1.3 @@ -1847,7 +1847,7 @@
     1.4  
     1.5      // See if it is a narrow oop array.
     1.6      if (adr_type->isa_aryptr()) {
     1.7 -      if (adr_type->offset() >= objArrayOopDesc::header_size() * wordSize) {
     1.8 +      if (adr_type->offset() >= objArrayOopDesc::base_offset_in_bytes(type)) {
     1.9          const TypeOopPtr *elem_type = adr_type->is_aryptr()->elem()->isa_oopptr();
    1.10          if (elem_type != NULL) {
    1.11            sharpened_klass = elem_type->klass();
    1.12 @@ -2164,10 +2164,19 @@
    1.13      cas = _gvn.transform(new (C, 5) CompareAndSwapLNode(control(), mem, adr, newval, oldval));
    1.14      break;
    1.15    case T_OBJECT:
    1.16 -    // reference stores need a store barrier.
    1.17 +     // reference stores need a store barrier.
    1.18      // (They don't if CAS fails, but it isn't worth checking.)
    1.19      pre_barrier(control(), base, adr, alias_idx, newval, value_type, T_OBJECT);
    1.20 -    cas = _gvn.transform(new (C, 5) CompareAndSwapPNode(control(), mem, adr, newval, oldval));
    1.21 +#ifdef _LP64
    1.22 +    if (adr->bottom_type()->is_narrow()) {
    1.23 +      cas = _gvn.transform(new (C, 5) CompareAndSwapNNode(control(), mem, adr,
    1.24 +                                                           EncodePNode::encode(&_gvn, newval),
    1.25 +                                                           EncodePNode::encode(&_gvn, oldval)));
    1.26 +    } else
    1.27 +#endif
    1.28 +      {
    1.29 +        cas = _gvn.transform(new (C, 5) CompareAndSwapPNode(control(), mem, adr, newval, oldval));
    1.30 +      }
    1.31      post_barrier(control(), cas, base, adr, alias_idx, newval, T_OBJECT, true);
    1.32      break;
    1.33    default:
    1.34 @@ -3824,7 +3833,15 @@
    1.35      Node* size = _gvn.transform(alloc_siz);
    1.36  
    1.37      // Exclude the header.
    1.38 -    int base_off = sizeof(oopDesc);
    1.39 +    int base_off = instanceOopDesc::base_offset_in_bytes();
    1.40 +    if (UseCompressedOops) {
    1.41 +      // copy the header gap though.
    1.42 +      Node* sptr = basic_plus_adr(src,  base_off);
    1.43 +      Node* dptr = basic_plus_adr(dest, base_off);
    1.44 +      Node* sval = make_load(control(), sptr, TypeInt::INT, T_INT, raw_adr_type);
    1.45 +      store_to_memory(control(), dptr, sval, T_INT, raw_adr_type);
    1.46 +      base_off += sizeof(int);
    1.47 +    }
    1.48      src  = basic_plus_adr(src,  base_off);
    1.49      dest = basic_plus_adr(dest, base_off);
    1.50      end  = basic_plus_adr(end,  size);
    1.51 @@ -4389,7 +4406,7 @@
    1.52      // Let's see if we need card marks:
    1.53      if (alloc != NULL && use_ReduceInitialCardMarks()) {
    1.54        // If we do not need card marks, copy using the jint or jlong stub.
    1.55 -      copy_type = LP64_ONLY(T_LONG) NOT_LP64(T_INT);
    1.56 +      copy_type = LP64_ONLY(UseCompressedOops ? T_INT : T_LONG) NOT_LP64(T_INT);
    1.57        assert(type2aelembytes(basic_elem_type) == type2aelembytes(copy_type),
    1.58               "sizes agree");
    1.59      }
    1.60 @@ -4715,23 +4732,25 @@
    1.61        int to_clear = (bump_bit | clear_low);
    1.62        // Align up mod 8, then store a jint zero unconditionally
    1.63        // just before the mod-8 boundary.
    1.64 -      // This would only fail if the first array element were immediately
    1.65 -      // after the length field, and were also at an even offset mod 8.
    1.66 -      assert(((abase + bump_bit) & ~to_clear) - BytesPerInt
    1.67 -             >= arrayOopDesc::length_offset_in_bytes() + BytesPerInt,
    1.68 -             "store must not trash length field");
    1.69 -
    1.70 -      // Bump 'start' up to (or past) the next jint boundary:
    1.71 -      start = _gvn.transform( new(C,3) AddXNode(start, MakeConX(bump_bit)) );
    1.72 +      if (((abase + bump_bit) & ~to_clear) - bump_bit
    1.73 +          < arrayOopDesc::length_offset_in_bytes() + BytesPerInt) {
    1.74 +        bump_bit = 0;
    1.75 +        assert((abase & to_clear) == 0, "array base must be long-aligned");
    1.76 +      } else {
    1.77 +        // Bump 'start' up to (or past) the next jint boundary:
    1.78 +        start = _gvn.transform( new(C,3) AddXNode(start, MakeConX(bump_bit)) );
    1.79 +        assert((abase & clear_low) == 0, "array base must be int-aligned");
    1.80 +      }
    1.81        // Round bumped 'start' down to jlong boundary in body of array.
    1.82        start = _gvn.transform( new(C,3) AndXNode(start, MakeConX(~to_clear)) );
    1.83 -      // Store a zero to the immediately preceding jint:
    1.84 -      Node* x1 = _gvn.transform( new(C,3) AddXNode(start, MakeConX(-BytesPerInt)) );
    1.85 -      Node* p1 = basic_plus_adr(dest, x1);
    1.86 -      mem = StoreNode::make(C, control(), mem, p1, adr_type, intcon(0), T_INT);
    1.87 -      mem = _gvn.transform(mem);
    1.88 +      if (bump_bit != 0) {
    1.89 +        // Store a zero to the immediately preceding jint:
    1.90 +        Node* x1 = _gvn.transform( new(C,3) AddXNode(start, MakeConX(-bump_bit)) );
    1.91 +        Node* p1 = basic_plus_adr(dest, x1);
    1.92 +        mem = StoreNode::make(_gvn, control(), mem, p1, adr_type, intcon(0), T_INT);
    1.93 +        mem = _gvn.transform(mem);
    1.94 +      }
    1.95      }
    1.96 -
    1.97      Node* end = dest_size; // pre-rounded
    1.98      mem = ClearArrayNode::clear_memory(control(), mem, dest,
    1.99                                         start, end, &_gvn);

mercurial