547
548 class ObjArrayTask
549 {
550 public:
551 ObjArrayTask(oop o = NULL, int idx = 0): _obj(o), _index(idx) { }
552 ObjArrayTask(oop o, size_t idx): _obj(o), _index(int(idx)) {
553 assert(idx <= size_t(max_jint), "too big");
554 }
555 // Trivially copyable, for use in GenericTaskQueue.
556
557 inline oop obj() const { return _obj; }
558 inline int index() const { return _index; }
559
560 DEBUG_ONLY(bool is_valid() const); // Tasks to be pushed/popped must be valid.
561
562 private:
563 oop _obj;
564 int _index;
565 };
566
567 #endif // SHARE_GC_SHARED_TASKQUEUE_HPP
|
547
548 class ObjArrayTask
549 {
550 public:
551 ObjArrayTask(oop o = NULL, int idx = 0): _obj(o), _index(idx) { }
552 ObjArrayTask(oop o, size_t idx): _obj(o), _index(int(idx)) {
553 assert(idx <= size_t(max_jint), "too big");
554 }
555 // Trivially copyable, for use in GenericTaskQueue.
556
557 inline oop obj() const { return _obj; }
558 inline int index() const { return _index; }
559
560 DEBUG_ONLY(bool is_valid() const); // Tasks to be pushed/popped must be valid.
561
562 private:
563 oop _obj;
564 int _index;
565 };
566
567 // Wrapper over an oop that is a partially scanned array.
568 // Can be converted to a ScannerTask for placement in associated task queues.
569 // Refers to the partially copied source array oop.
570 class PartialArrayScanTask {
571 void* _p;
572
573 public:
574 PartialArrayScanTask() : _p(NULL) {}
575 explicit PartialArrayScanTask(oop src_array) : _p(src_array) {}
576 // Trivially copyable.
577
578 oop to_source_array() const { return oop(_p); }
579 };
580
581 // Discriminated union over oop*, narrowOop*, and PartialArrayScanTask.
582 // Uses a low tag in the associated pointer to identify the category.
583 // Used as a task queue element type.
584 class ScannerTask {
585 void* _p;
586
587 static const uintptr_t OopTag = 0;
588 static const uintptr_t NarrowOopTag = 1;
589 static const uintptr_t PartialArrayTag = 2;
590 static const uintptr_t TagSize = 2;
591 static const uintptr_t TagAlignment = 1 << TagSize;
592 static const uintptr_t TagMask = TagAlignment - 1;
593
594 static void* encode(void* p, uintptr_t tag) {
595 assert(is_aligned(p, TagAlignment), "misaligned: " PTR_FORMAT, p2i(p));
596 return static_cast<char*>(p) + tag;
597 }
598
599 uintptr_t raw_value() const {
600 return reinterpret_cast<uintptr_t>(_p);
601 }
602
603 bool has_tag(uintptr_t tag) const {
604 return (raw_value() & TagMask) == tag;
605 }
606
607 void* decode(uintptr_t tag) const {
608 assert(has_tag(tag), "precondition");
609 return static_cast<char*>(_p) - tag;
610 }
611
612 public:
613 ScannerTask() : _p(NULL) {}
614
615 explicit ScannerTask(oop* p) : _p(encode(p, OopTag)) {}
616
617 explicit ScannerTask(narrowOop* p) : _p(encode(p, NarrowOopTag)) {}
618
619 explicit ScannerTask(PartialArrayScanTask t) :
620 _p(encode(t.to_source_array(), PartialArrayTag)) {}
621
622 // Trivially copyable.
623
624 // Predicate implementations assume OopTag == 0, others are powers of 2.
625
626 bool is_oop_ptr() const {
627 return (raw_value() & (NarrowOopTag | PartialArrayTag)) == 0;
628 }
629
630 bool is_narrow_oop_ptr() const {
631 return (raw_value() & NarrowOopTag) != 0;
632 }
633
634 bool is_partial_array_task() const {
635 return (raw_value() & PartialArrayTag) != 0;
636 }
637
638 oop* to_oop_ptr() const {
639 return static_cast<oop*>(decode(OopTag));
640 }
641
642 narrowOop* to_narrow_oop_ptr() const {
643 return static_cast<narrowOop*>(decode(NarrowOopTag));
644 }
645
646 PartialArrayScanTask to_partial_array_task() const {
647 return PartialArrayScanTask(oop(decode(PartialArrayTag)));
648 }
649 };
650
651 #endif // SHARE_GC_SHARED_TASKQUEUE_HPP
|