1.1 --- a/src/share/vm/jfr/recorder/stringpool/jfrStringPool.cpp Mon Jun 15 20:21:56 2020 +0100 1.2 +++ b/src/share/vm/jfr/recorder/stringpool/jfrStringPool.cpp Wed Jun 17 11:43:05 2020 +0300 1.3 @@ -1,5 +1,5 @@ 1.4 /* 1.5 - * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. 1.6 + * Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved. 1.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.8 * 1.9 * This code is free software; you can redistribute it and/or modify it 1.10 @@ -139,93 +139,76 @@ 1.11 return current_epoch; 1.12 } 1.13 1.14 -class StringPoolWriteOp { 1.15 +template <template <typename> class Operation> 1.16 +class StringPoolOp { 1.17 public: 1.18 typedef JfrStringPoolBuffer Type; 1.19 private: 1.20 - UnBufferedWriteToChunk<Type> _writer; 1.21 + Operation<Type> _op; 1.22 Thread* _thread; 1.23 size_t _strings_processed; 1.24 public: 1.25 - StringPoolWriteOp(JfrChunkWriter& writer, Thread* thread) : _writer(writer), _thread(thread), _strings_processed(0) {} 1.26 + StringPoolOp() : _op(), _thread(Thread::current()), _strings_processed(0) {} 1.27 + StringPoolOp(JfrChunkWriter& writer, Thread* thread) : _op(writer), _thread(thread), _strings_processed(0) {} 1.28 bool write(Type* buffer, const u1* data, size_t size) { 1.29 - buffer->acquire(_thread); // blocking 1.30 + assert(buffer->acquired_by(_thread) || buffer->retired(), "invariant"); 1.31 const uint64_t nof_strings_used = buffer->string_count(); 1.32 assert(nof_strings_used > 0, "invariant"); 1.33 buffer->set_string_top(buffer->string_top() + nof_strings_used); 1.34 // "size processed" for string pool buffers is the number of processed string elements 1.35 _strings_processed += nof_strings_used; 1.36 - const bool ret = _writer.write(buffer, data, size); 1.37 - buffer->release(); 1.38 - return ret; 1.39 + return _op.write(buffer, data, size); 1.40 } 1.41 size_t processed() { return _strings_processed; } 1.42 }; 1.43 1.44 -typedef StringPoolWriteOp WriteOperation; 1.45 -typedef ConcurrentWriteOp<WriteOperation> ConcurrentWriteOperation; 1.46 +template <typename Type> 1.47 +class StringPoolDiscarderStub { 1.48 + public: 1.49 + bool write(Type* buffer, const u1* data, size_t size) { 1.50 + // stub only, discard happens at higher level 1.51 + return true; 1.52 + } 1.53 +}; 1.54 + 1.55 +typedef StringPoolOp<UnBufferedWriteToChunk> WriteOperation; 1.56 +typedef StringPoolOp<StringPoolDiscarderStub> DiscardOperation; 1.57 +typedef ExclusiveOp<WriteOperation> ExclusiveWriteOperation; 1.58 +typedef ExclusiveOp<DiscardOperation> ExclusiveDiscardOperation; 1.59 +typedef ReleaseOp<JfrStringPoolMspace> StringPoolReleaseOperation; 1.60 +typedef CompositeOperation<ExclusiveWriteOperation, StringPoolReleaseOperation> StringPoolWriteOperation; 1.61 +typedef CompositeOperation<ExclusiveDiscardOperation, StringPoolReleaseOperation> StringPoolDiscardOperation; 1.62 1.63 size_t JfrStringPool::write() { 1.64 Thread* const thread = Thread::current(); 1.65 WriteOperation wo(_chunkwriter, thread); 1.66 - ConcurrentWriteOperation cwo(wo); 1.67 - assert(_free_list_mspace->is_full_empty(), "invariant"); 1.68 - process_free_list(cwo, _free_list_mspace); 1.69 - return wo.processed(); 1.70 -} 1.71 - 1.72 -typedef MutexedWriteOp<WriteOperation> MutexedWriteOperation; 1.73 -typedef ReleaseOp<JfrStringPoolMspace> StringPoolReleaseOperation; 1.74 -typedef CompositeOperation<MutexedWriteOperation, StringPoolReleaseOperation> StringPoolWriteOperation; 1.75 - 1.76 -size_t JfrStringPool::write_at_safepoint() { 1.77 - assert(SafepointSynchronize::is_at_safepoint(), "invariant"); 1.78 - Thread* const thread = Thread::current(); 1.79 - WriteOperation wo(_chunkwriter, thread); 1.80 - MutexedWriteOperation mwo(wo); 1.81 + ExclusiveWriteOperation ewo(wo); 1.82 StringPoolReleaseOperation spro(_free_list_mspace, thread, false); 1.83 - StringPoolWriteOperation spwo(&mwo, &spro); 1.84 + StringPoolWriteOperation spwo(&ewo, &spro); 1.85 assert(_free_list_mspace->is_full_empty(), "invariant"); 1.86 process_free_list(spwo, _free_list_mspace); 1.87 return wo.processed(); 1.88 } 1.89 1.90 -class StringPoolBufferDiscarder { 1.91 - private: 1.92 - Thread* _thread; 1.93 - size_t _processed; 1.94 - public: 1.95 - typedef JfrStringPoolBuffer Type; 1.96 - StringPoolBufferDiscarder() : _thread(Thread::current()), _processed(0) {} 1.97 - bool process(Type* buffer) { 1.98 - buffer->acquire(_thread); // serialized access 1.99 - const u1* const current_top = buffer->top(); 1.100 - const size_t unflushed_size = buffer->pos() - current_top; 1.101 - if (unflushed_size == 0) { 1.102 - assert(buffer->string_count() == 0, "invariant"); 1.103 - buffer->release(); 1.104 - return true; 1.105 - } 1.106 - buffer->set_top(current_top + unflushed_size); 1.107 - const uint64_t nof_strings_used = buffer->string_count(); 1.108 - buffer->set_string_top(buffer->string_top() + nof_strings_used); 1.109 - // "size processed" for string pool buffers is the number of string elements 1.110 - _processed += (size_t)nof_strings_used; 1.111 - buffer->release(); 1.112 - return true; 1.113 - } 1.114 - size_t processed() const { return _processed; } 1.115 -}; 1.116 +size_t JfrStringPool::write_at_safepoint() { 1.117 + assert(SafepointSynchronize::is_at_safepoint(), "invariant"); 1.118 + return write(); 1.119 +} 1.120 1.121 size_t JfrStringPool::clear() { 1.122 - StringPoolBufferDiscarder discard_operation; 1.123 + DiscardOperation discard_operation; 1.124 + ExclusiveDiscardOperation edo(discard_operation); 1.125 + StringPoolReleaseOperation spro(_free_list_mspace, Thread::current(), false); 1.126 + StringPoolDiscardOperation spdo(&edo, &spro); 1.127 assert(_free_list_mspace->is_full_empty(), "invariant"); 1.128 - process_free_list(discard_operation, _free_list_mspace); 1.129 + process_free_list(spdo, _free_list_mspace); 1.130 return discard_operation.processed(); 1.131 } 1.132 1.133 void JfrStringPool::register_full(BufferPtr t, Thread* thread) { 1.134 // nothing here at the moment 1.135 + assert(t != NULL, "invariant"); 1.136 + assert(t->acquired_by(thread), "invariant"); 1.137 assert(t->retired(), "invariant"); 1.138 } 1.139