< prev index next >

src/hotspot/share/gc/shared/taskqueue.hpp

Print this page
rev 59232 : [mq]: scan_task
rev 59233 : [mq]: sjohanss_review

@@ -562,6 +562,90 @@
 private:
   oop _obj;
   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<char*>(p) + tag;
+  }
+
+  uintptr_t raw_value() const {
+    return reinterpret_cast<uintptr_t>(_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<char*>(_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<oop*>(decode(OopTag));
+  }
+
+  narrowOop* to_narrow_oop_ptr() const {
+    return static_cast<narrowOop*>(decode(NarrowOopTag));
+  }
+
+  PartialArrayScanTask to_partial_array_task() const {
+    return PartialArrayScanTask(oop(decode(PartialArrayTag)));
+  }
+};
+
 #endif // SHARE_GC_SHARED_TASKQUEUE_HPP
< prev index next >