Mercurial > hg > truffle
diff src/share/vm/opto/library_call.cpp @ 113:ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
Summary: Compressed oops in instances, arrays, and headers. Code contributors are coleenp, phh, never, swamyv
Reviewed-by: jmasa, kamg, acorn, tbell, kvn, rasbold
author | coleenp |
---|---|
date | Sun, 13 Apr 2008 17:43:42 -0400 |
parents | 545c277a3ecf |
children | 885ed790ecf0 |
line wrap: on
line diff
--- a/src/share/vm/opto/library_call.cpp Fri Apr 11 09:56:35 2008 -0400 +++ b/src/share/vm/opto/library_call.cpp Sun Apr 13 17:43:42 2008 -0400 @@ -1847,7 +1847,7 @@ // See if it is a narrow oop array. if (adr_type->isa_aryptr()) { - if (adr_type->offset() >= objArrayOopDesc::header_size() * wordSize) { + if (adr_type->offset() >= objArrayOopDesc::base_offset_in_bytes(type)) { const TypeOopPtr *elem_type = adr_type->is_aryptr()->elem()->isa_oopptr(); if (elem_type != NULL) { sharpened_klass = elem_type->klass(); @@ -2164,10 +2164,19 @@ cas = _gvn.transform(new (C, 5) CompareAndSwapLNode(control(), mem, adr, newval, oldval)); break; case T_OBJECT: - // reference stores need a store barrier. + // reference stores need a store barrier. // (They don't if CAS fails, but it isn't worth checking.) pre_barrier(control(), base, adr, alias_idx, newval, value_type, T_OBJECT); - cas = _gvn.transform(new (C, 5) CompareAndSwapPNode(control(), mem, adr, newval, oldval)); +#ifdef _LP64 + if (adr->bottom_type()->is_narrow()) { + cas = _gvn.transform(new (C, 5) CompareAndSwapNNode(control(), mem, adr, + EncodePNode::encode(&_gvn, newval), + EncodePNode::encode(&_gvn, oldval))); + } else +#endif + { + cas = _gvn.transform(new (C, 5) CompareAndSwapPNode(control(), mem, adr, newval, oldval)); + } post_barrier(control(), cas, base, adr, alias_idx, newval, T_OBJECT, true); break; default: @@ -3824,7 +3833,15 @@ Node* size = _gvn.transform(alloc_siz); // Exclude the header. - int base_off = sizeof(oopDesc); + int base_off = instanceOopDesc::base_offset_in_bytes(); + if (UseCompressedOops) { + // copy the header gap though. + Node* sptr = basic_plus_adr(src, base_off); + Node* dptr = basic_plus_adr(dest, base_off); + Node* sval = make_load(control(), sptr, TypeInt::INT, T_INT, raw_adr_type); + store_to_memory(control(), dptr, sval, T_INT, raw_adr_type); + base_off += sizeof(int); + } src = basic_plus_adr(src, base_off); dest = basic_plus_adr(dest, base_off); end = basic_plus_adr(end, size); @@ -4389,7 +4406,7 @@ // Let's see if we need card marks: if (alloc != NULL && use_ReduceInitialCardMarks()) { // If we do not need card marks, copy using the jint or jlong stub. - copy_type = LP64_ONLY(T_LONG) NOT_LP64(T_INT); + copy_type = LP64_ONLY(UseCompressedOops ? T_INT : T_LONG) NOT_LP64(T_INT); assert(type2aelembytes(basic_elem_type) == type2aelembytes(copy_type), "sizes agree"); } @@ -4715,23 +4732,25 @@ int to_clear = (bump_bit | clear_low); // Align up mod 8, then store a jint zero unconditionally // just before the mod-8 boundary. - // This would only fail if the first array element were immediately - // after the length field, and were also at an even offset mod 8. - assert(((abase + bump_bit) & ~to_clear) - BytesPerInt - >= arrayOopDesc::length_offset_in_bytes() + BytesPerInt, - "store must not trash length field"); - - // Bump 'start' up to (or past) the next jint boundary: - start = _gvn.transform( new(C,3) AddXNode(start, MakeConX(bump_bit)) ); + if (((abase + bump_bit) & ~to_clear) - bump_bit + < arrayOopDesc::length_offset_in_bytes() + BytesPerInt) { + bump_bit = 0; + assert((abase & to_clear) == 0, "array base must be long-aligned"); + } else { + // Bump 'start' up to (or past) the next jint boundary: + start = _gvn.transform( new(C,3) AddXNode(start, MakeConX(bump_bit)) ); + assert((abase & clear_low) == 0, "array base must be int-aligned"); + } // Round bumped 'start' down to jlong boundary in body of array. start = _gvn.transform( new(C,3) AndXNode(start, MakeConX(~to_clear)) ); - // Store a zero to the immediately preceding jint: - Node* x1 = _gvn.transform( new(C,3) AddXNode(start, MakeConX(-BytesPerInt)) ); - Node* p1 = basic_plus_adr(dest, x1); - mem = StoreNode::make(C, control(), mem, p1, adr_type, intcon(0), T_INT); - mem = _gvn.transform(mem); + if (bump_bit != 0) { + // Store a zero to the immediately preceding jint: + Node* x1 = _gvn.transform( new(C,3) AddXNode(start, MakeConX(-bump_bit)) ); + Node* p1 = basic_plus_adr(dest, x1); + mem = StoreNode::make(_gvn, control(), mem, p1, adr_type, intcon(0), T_INT); + mem = _gvn.transform(mem); + } } - Node* end = dest_size; // pre-rounded mem = ClearArrayNode::clear_memory(control(), mem, dest, start, end, &_gvn);