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);