--- old/src/hotspot/share/oops/oop.inline.hpp 2019-03-27 16:10:43.203249535 +0100 +++ new/src/hotspot/share/oops/oop.inline.hpp 2019-03-27 16:10:42.883244240 +0100 @@ -86,19 +86,26 @@ set_mark_raw(markOopDesc::prototype_for_object(this)); } +narrowKlass oopDesc::compressed_klass_mask() { return ((narrowKlass) 1 << narrow_storage_props_shift) - 1; } +uintptr_t oopDesc::klass_mask() { return ((uintptr_t) 1 << wide_storage_props_shift) - 1; } + +narrowKlass oopDesc::compressed_klass_masked(narrowKlass raw) { return raw & compressed_klass_mask(); } +Klass* oopDesc::klass_masked(uintptr_t raw) { return reinterpret_cast(raw & klass_mask()); } + + Klass* oopDesc::klass() const { if (UseCompressedClassPointers) { - return Klass::decode_klass_not_null(_metadata._compressed_klass); + return Klass::decode_klass_not_null(compressed_klass_masked(_metadata._compressed_klass)); } else { - return _metadata._klass; + return klass_masked(_metadata._wide_storage_props); } } Klass* oopDesc::klass_or_null() const volatile { if (UseCompressedClassPointers) { - return Klass::decode_klass(_metadata._compressed_klass); + return Klass::decode_klass(compressed_klass_masked(_metadata._compressed_klass)); } else { - return _metadata._klass; + return klass_masked(_metadata._wide_storage_props); } } @@ -107,9 +114,9 @@ // Workaround for non-const load_acquire parameter. const volatile narrowKlass* addr = &_metadata._compressed_klass; volatile narrowKlass* xaddr = const_cast(addr); - return Klass::decode_klass(OrderAccess::load_acquire(xaddr)); + return Klass::decode_klass(compressed_klass_masked(OrderAccess::load_acquire(xaddr))); } else { - return OrderAccess::load_acquire(&_metadata._klass); + return klass_masked(OrderAccess::load_acquire(&_metadata._wide_storage_props)); } } @@ -121,6 +128,12 @@ return (Klass**) (((char*)mem) + in_bytes(offset)); } +uintptr_t* oopDesc::wide_metadata_addr(HeapWord* mem) { + assert(!UseCompressedClassPointers, "only supported with uncompressed klass pointers"); + ByteSize offset = byte_offset_of(oopDesc, _metadata._wide_storage_props); + return (uintptr_t*) (((char*)mem) + in_bytes(offset)); +} + narrowKlass* oopDesc::compressed_klass_addr(HeapWord* mem) { assert(UseCompressedClassPointers, "only called by compressed klass pointers"); ByteSize offset = byte_offset_of(oopDesc, _metadata._compressed_klass); @@ -139,6 +152,8 @@ do { \ assert(Universe::is_bootstrapping() || k != NULL, "NULL Klass"); \ assert(Universe::is_bootstrapping() || k->is_klass(), "not a Klass"); \ + assert(((reinterpret_cast(k) & (~ oopDesc::klass_mask())) == 0), \ + "No room for storage props "); \ } while (0) void oopDesc::set_klass(Klass* k) { @@ -158,10 +173,40 @@ } else { OrderAccess::release_store(klass_addr(mem), klass); } + assert(((oopDesc*)mem)->klass() == klass, "failed oopDesc::klass() encode/decode"); +} + +void oopDesc::set_metadata(ArrayStorageProperties storage_props, Klass* klass) { + CHECK_SET_KLASS(klass); + if (UseCompressedClassPointers) { + *compressed_klass_addr() = (Klass::encode_klass_not_null(klass) | storage_props.encode(narrow_storage_props_shift)); + } else { + *wide_metadata_addr((HeapWord*)this) = (reinterpret_cast(klass) | storage_props.encode(wide_storage_props_shift)); + } } +void oopDesc::release_set_metadata(HeapWord* mem, ArrayStorageProperties storage_props, Klass* klass) { + CHECK_SET_KLASS(klass); + if (UseCompressedClassPointers) { + OrderAccess::release_store(oopDesc::compressed_klass_addr(mem), + Klass::encode_klass_not_null(klass) | storage_props.encode(narrow_storage_props_shift)); + } else { + OrderAccess::release_store(oopDesc::wide_metadata_addr(mem), + (reinterpret_cast(klass) | storage_props.encode(wide_storage_props_shift))); + } +} #undef CHECK_SET_KLASS + +ArrayStorageProperties oopDesc::array_storage_properties() const { + if (UseCompressedClassPointers) { + return ArrayStorageProperties(_metadata._narrow_storage_props >> narrow_storage_props_shift); + } else { + return ArrayStorageProperties(_metadata._wide_storage_props >> wide_storage_props_shift); + } +} + + int oopDesc::klass_gap() const { return *(int*)(((intptr_t)this) + klass_gap_offset_in_bytes()); }