--- old/src/hotspot/share/gc/shared/taskqueue.hpp 2020-05-14 07:47:51.502092660 -0400 +++ new/src/hotspot/share/gc/shared/taskqueue.hpp 2020-05-14 07:47:51.110079645 -0400 @@ -564,4 +564,88 @@ int _index; }; +// Wrapper over an oop that is a partially scanned array. +// Can be converted to a ScannerTask for placement in associated task queues. +// Refers to the partially copied source array oop. +class PartialArrayScanTask { + oop _src; + +public: + PartialArrayScanTask() : _src() {} + explicit PartialArrayScanTask(oop src_array) : _src(src_array) {} + // Trivially copyable. + + oop to_source_array() const { return _src; } +}; + +// Discriminated union over oop*, narrowOop*, and PartialArrayScanTask. +// Uses a low tag in the associated pointer to identify the category. +// Used as a task queue element type. +class ScannerTask { + void* _p; + + static const uintptr_t OopTag = 0; + static const uintptr_t NarrowOopTag = 1; + static const uintptr_t PartialArrayTag = 2; + static const uintptr_t TagSize = 2; + static const uintptr_t TagAlignment = 1 << TagSize; + static const uintptr_t TagMask = TagAlignment - 1; + + static void* encode(void* p, uintptr_t tag) { + assert(is_aligned(p, TagAlignment), "misaligned: " PTR_FORMAT, p2i(p)); + return static_cast(p) + tag; + } + + uintptr_t raw_value() const { + return reinterpret_cast(_p); + } + + bool has_tag(uintptr_t tag) const { + return (raw_value() & TagMask) == tag; + } + + void* decode(uintptr_t tag) const { + assert(has_tag(tag), "precondition"); + return static_cast(_p) - tag; + } + +public: + ScannerTask() : _p(NULL) {} + + explicit ScannerTask(oop* p) : _p(encode(p, OopTag)) {} + + explicit ScannerTask(narrowOop* p) : _p(encode(p, NarrowOopTag)) {} + + explicit ScannerTask(PartialArrayScanTask t) : + _p(encode(t.to_source_array(), PartialArrayTag)) {} + + // Trivially copyable. + + // Predicate implementations assume OopTag == 0, others are powers of 2. + + bool is_oop_ptr() const { + return (raw_value() & (NarrowOopTag | PartialArrayTag)) == 0; + } + + bool is_narrow_oop_ptr() const { + return (raw_value() & NarrowOopTag) != 0; + } + + bool is_partial_array_task() const { + return (raw_value() & PartialArrayTag) != 0; + } + + oop* to_oop_ptr() const { + return static_cast(decode(OopTag)); + } + + narrowOop* to_narrow_oop_ptr() const { + return static_cast(decode(NarrowOopTag)); + } + + PartialArrayScanTask to_partial_array_task() const { + return PartialArrayScanTask(oop(decode(PartialArrayTag))); + } +}; + #endif // SHARE_GC_SHARED_TASKQUEUE_HPP