more general predication of writes JEP-349-branch
authormgronlun
Sun, 22 Sep 2019 14:00:00 +0200
branchJEP-349-branch
changeset 58254 a6ccade6b295
parent 58253 67151bcd8b14
child 58255 f9648f8ca4da
more general predication of writes
src/hotspot/share/jfr/recorder/checkpoint/jfrCheckpointManager.cpp
src/hotspot/share/jfr/recorder/storage/jfrStorage.cpp
src/hotspot/share/jfr/recorder/storage/jfrStorageUtils.hpp
src/hotspot/share/jfr/recorder/storage/jfrStorageUtils.inline.hpp
src/hotspot/share/jfr/recorder/stringpool/jfrStringPool.cpp
--- a/src/hotspot/share/jfr/recorder/checkpoint/jfrCheckpointManager.cpp	Sat Sep 21 20:13:11 2019 +0200
+++ b/src/hotspot/share/jfr/recorder/checkpoint/jfrCheckpointManager.cpp	Sun Sep 22 14:00:00 2019 +0200
@@ -317,13 +317,13 @@
 typedef CheckpointWriteOp<JfrCheckpointMspace::Type> WriteOperation;
 typedef ReleaseOp<JfrCheckpointMspace> CheckpointReleaseOperation;
 
-template <template <typename> class WriterHost, template <typename, typename> class CompositeOperation>
+template <template <typename> class WriterHost, template <typename, typename, typename> class CompositeOperation>
 static size_t write_mspace(JfrCheckpointMspace* mspace, JfrChunkWriter& chunkwriter) {
   assert(mspace != NULL, "invariant");
   WriteOperation wo(chunkwriter);
   WriterHost<WriteOperation> wh(wo);
   CheckpointReleaseOperation cro(mspace, Thread::current(), false);
-  CompositeOperation<WriterHost<WriteOperation>, CheckpointReleaseOperation> co(&wh, &cro);
+  CompositeOperation<WriterHost<WriteOperation>, CheckpointReleaseOperation, And> co(&wh, &cro);
   assert(mspace->is_full_empty(), "invariant");
   process_free_list(co, mspace);
   return wo.processed();
--- a/src/hotspot/share/jfr/recorder/storage/jfrStorage.cpp	Sat Sep 21 20:13:11 2019 +0200
+++ b/src/hotspot/share/jfr/recorder/storage/jfrStorage.cpp	Sun Sep 22 14:00:00 2019 +0200
@@ -601,12 +601,20 @@
 typedef UnBufferedWriteToChunk<JfrBuffer> WriteOperation;
 typedef MutexedWriteOp<WriteOperation> MutexedWriteOperation;
 typedef ConcurrentWriteOp<WriteOperation> ConcurrentWriteOperation;
-typedef ConcurrentWriteOpExcludeRetired<WriteOperation> ThreadLocalConcurrentWriteOperation;
+
+typedef Retired<JfrBuffer, true> NonRetired;
+typedef Excluded<JfrBuffer, true> NonExcluded;
+typedef CompositeOperation<NonRetired, NonExcluded, And> BufferPredicate;
+typedef PredicatedMutexedWriteOp<WriteOperation, BufferPredicate> ThreadLocalMutexedWriteOperation;
+typedef PredicatedConcurrentWriteOp<WriteOperation, BufferPredicate> ThreadLocalConcurrentWriteOperation;
 
 size_t JfrStorage::write() {
   const size_t full_elements = write_full();
   WriteOperation wo(_chunkwriter);
-  ThreadLocalConcurrentWriteOperation tlwo(wo);
+  NonRetired nr;
+  NonExcluded ne;
+  BufferPredicate bp(&nr, &ne);
+  ThreadLocalConcurrentWriteOperation tlwo(wo, bp);
   process_full_list(tlwo, _thread_local_mspace);
   ConcurrentWriteOperation cwo(wo);
   process_free_list(cwo, _global_mspace);
@@ -617,7 +625,11 @@
   assert(SafepointSynchronize::is_at_safepoint(), "invariant");
   WriteOperation wo(_chunkwriter);
   MutexedWriteOperation writer(wo); // mutexed write mode
-  process_full_list(writer, _thread_local_mspace);
+  NonRetired nr;
+  NonExcluded ne;
+  BufferPredicate bp(&nr, &ne);
+  ThreadLocalMutexedWriteOperation tlmwo(wo, bp);
+  process_full_list(tlmwo, _thread_local_mspace);
   assert(_transient_mspace->is_free_empty(), "invariant");
   process_full_list(writer, _transient_mspace);
   assert(_global_mspace->is_full_empty(), "invariant");
--- a/src/hotspot/share/jfr/recorder/storage/jfrStorageUtils.hpp	Sat Sep 21 20:13:11 2019 +0200
+++ b/src/hotspot/share/jfr/recorder/storage/jfrStorageUtils.hpp	Sun Sep 22 14:00:00 2019 +0200
@@ -31,7 +31,21 @@
 #include "jfr/utilities/jfrTypes.hpp"
 #include "runtime/thread.hpp"
 
-template <typename Operation, typename NextOperation>
+class Or {
+ public:
+  static bool evaluate(bool value) {
+    return !value;
+  }
+};
+
+class And {
+ public:
+  static bool evaluate(bool value) {
+    return value;
+  }
+};
+
+template <typename Operation, typename NextOperation, typename TruthFunction = And>
 class CompositeOperation {
  private:
   Operation* _op;
@@ -41,8 +55,9 @@
     assert(_op != NULL, "invariant");
   }
   typedef typename Operation::Type Type;
-  bool process(Type* t = NULL) {
-    return _next == NULL ? _op->process(t) : _op->process(t) && _next->process(t);
+  bool process(Type* t) {
+    const bool op_result = _op->process(t);
+    return _next == NULL ? op_result : TruthFunction::evaluate(op_result) ? _next->process(t) : op_result;
   }
   size_t elements() const {
     return _next == NULL ? _op->elements() : _op->elements() + _next->elements();
@@ -79,6 +94,50 @@
   size_t size() const { return _size; }
 };
 
+template <typename T, bool negation>
+class Retired {
+ public:
+  typedef typename T Type;
+  bool process(T* t) {
+    assert(t != NULL, "invariant");
+    return negation ? !t->retired() : t->retired();
+  }
+};
+
+template <typename T, bool negation>
+class Excluded {
+ public:
+  typedef typename T Type;
+  bool process(T* t) {
+    assert(t != NULL, "invariant");
+    return negation ? !t->excluded() : t->excluded();
+  }
+};
+
+template <typename Operation>
+class MutexedWriteOp {
+ private:
+  Operation& _operation;
+ public:
+  typedef typename Operation::Type Type;
+  MutexedWriteOp(Operation& operation) : _operation(operation) {}
+  bool process(Type* t);
+  size_t elements() const { return _operation.elements(); }
+  size_t size() const { return _operation.size(); }
+};
+
+template <typename Operation, typename Predicate>
+class PredicatedMutexedWriteOp : public MutexedWriteOp<Operation> {
+ private:
+  Predicate& _predicate;
+ public:
+  PredicatedMutexedWriteOp(Operation& operation, Predicate& predicate) :
+    MutexedWriteOp(operation), _predicate(predicate) {}
+  bool process(Type* t) {
+    return _predicate.process(t) ? MutexedWriteOp<Operation>::process(t) : true;
+  }
+};
+
 template <typename Operation>
 class ConcurrentWriteOp {
  private:
@@ -91,26 +150,16 @@
   size_t size() const { return _operation.size(); }
 };
 
-template <typename Operation>
-class ConcurrentWriteOpExcludeRetired : private ConcurrentWriteOp<Operation> {
+template <typename Operation, typename Predicate>
+class PredicatedConcurrentWriteOp : public ConcurrentWriteOp<Operation> {
+ private:
+  Predicate& _predicate;
  public:
-  typedef typename Operation::Type Type;
-  ConcurrentWriteOpExcludeRetired(Operation& operation) : ConcurrentWriteOp<Operation>(operation) {}
-  bool process(Type* t);
-  size_t elements() const { return ConcurrentWriteOp<Operation>::elements();}
-  size_t size() const { return ConcurrentWriteOp<Operation>::size(); }
-};
-
-template <typename Operation>
-class MutexedWriteOp {
- private:
-  Operation& _operation;
- public:
-  typedef typename Operation::Type Type;
-  MutexedWriteOp(Operation& operation) : _operation(operation) {}
-  bool process(Type* t);
-  size_t elements() const { return _operation.elements(); }
-  size_t size() const { return _operation.size(); }
+  PredicatedConcurrentWriteOp(Operation& operation, Predicate& predicate) :
+    ConcurrentWriteOp(operation), _predicate(predicate) {}
+  bool process(Type* t) {
+    return _predicate.process(t) ? ConcurrentWriteOp<Operation>::process(t) : true;
+  }
 };
 
 template <typename Operation>
--- a/src/hotspot/share/jfr/recorder/storage/jfrStorageUtils.inline.hpp	Sat Sep 21 20:13:11 2019 +0200
+++ b/src/hotspot/share/jfr/recorder/storage/jfrStorageUtils.inline.hpp	Sun Sep 22 14:00:00 2019 +0200
@@ -57,14 +57,6 @@
 }
 
 template <typename Operation>
-inline bool ConcurrentWriteOpExcludeRetired<Operation>::process(typename Operation::Type* t) {
-  if (t->retired() || t->excluded()) {
-    return true;
-  }
-  return ConcurrentWriteOp<Operation>::process(t);
-}
-
-template <typename Operation>
 inline bool MutexedWriteOp<Operation>::process(typename Operation::Type* t) {
   assert(t != NULL, "invariant");
   const u1* const current_top = t->top();
--- a/src/hotspot/share/jfr/recorder/stringpool/jfrStringPool.cpp	Sat Sep 21 20:13:11 2019 +0200
+++ b/src/hotspot/share/jfr/recorder/stringpool/jfrStringPool.cpp	Sun Sep 22 14:00:00 2019 +0200
@@ -196,9 +196,10 @@
   size_t processed() { return _strings_processed; }
 };
 
-template <typename Type>
+template <typename T>
 class StringPoolDiscarderStub {
  public:
+  typedef T Type;
   bool write(Type* buffer, const u1* data, size_t size) {
     // stub only, discard happens at higher level
     return true;