1 /* 2 * Copyright (c) 2017, 2018, Red Hat, Inc. All rights reserved. 3 * 4 * This code is free software; you can redistribute it and/or modify it 5 * under the terms of the GNU General Public License version 2 only, as 6 * published by the Free Software Foundation. 7 * 8 * This code is distributed in the hope that it will be useful, but WITHOUT 9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 11 * version 2 for more details (a copy is included in the LICENSE file that 12 * accompanied this code). 13 * 14 * You should have received a copy of the GNU General Public License version 15 * 2 along with this work; if not, write to the Free Software Foundation, 16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 17 * 18 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 19 * or visit www.oracle.com if you need additional information or have any 20 * questions. 21 * 22 */ 23 24 #ifndef SHARE_VM_GC_SHENANDOAH_SHENANDOAHSTRINGDEDUPQUEUE_HPP 25 #define SHARE_VM_GC_SHENANDOAH_SHENANDOAHSTRINGDEDUPQUEUE_HPP 26 27 #include "gc/shared/stringdedup/stringDedup.hpp" 28 #include "gc/shenandoah/shenandoahHeap.hpp" 29 #include "oops/oop.hpp" 30 31 template <uint buffer_size> 32 class ShenandoahOopBuffer : public CHeapObj<mtGC> { 33 private: 34 oop _buf[buffer_size]; 35 uint _index; 36 ShenandoahOopBuffer<buffer_size>* _next; 37 38 public: 39 ShenandoahOopBuffer(); 40 41 bool is_full() const; 42 bool is_empty() const; 43 uint size() const; 44 45 void push(oop obj); 46 oop pop(); 47 48 void reset(); 49 50 void set_next(ShenandoahOopBuffer<buffer_size>* next); 51 ShenandoahOopBuffer<buffer_size>* next() const; 52 53 void unlink_or_oops_do(StringDedupUnlinkOrOopsDoClosure* cl); 54 void oops_do(OopClosure* cl); 55 }; 56 57 typedef ShenandoahOopBuffer<64> ShenandoahQueueBuffer; 58 59 // Muti-producer and single consumer queue set 60 class ShenandoahStrDedupQueue : public StringDedupQueue { 61 private: 62 ShenandoahQueueBuffer** _producer_queues; 63 ShenandoahQueueBuffer* _consumer_queue; 64 size_t _num_producer_queue; 65 66 // The queue is used for producers to publish completed buffers 67 ShenandoahQueueBuffer* _published_queues; 68 69 // Cached free buffers 70 ShenandoahQueueBuffer* _free_list; 71 size_t _num_free_buffer; 72 const size_t _max_free_buffer; 73 74 bool _cancel; 75 76 // statistics 77 size_t _total_buffers; 78 79 private: 80 ~ShenandoahStrDedupQueue(); 81 82 public: 83 ShenandoahStrDedupQueue(); 84 85 void wait_impl(); 86 void cancel_wait_impl(); 87 88 void push_impl(uint worker_id, oop string_oop); 89 oop pop_impl(); 90 91 void unlink_or_oops_do_impl(StringDedupUnlinkOrOopsDoClosure* cl, size_t queue); 92 93 void print_statistics_impl(); 94 void verify_impl(); 95 96 protected: 97 size_t num_queues() const { return (_num_producer_queue + 2); } 98 99 private: 100 ShenandoahQueueBuffer* new_buffer(); 101 102 void release_buffers(ShenandoahQueueBuffer* list); 103 104 ShenandoahQueueBuffer* queue_at(size_t queue_id) const; 105 106 bool pop_candidate(oop& obj); 107 108 void set_producer_buffer(ShenandoahQueueBuffer* buf, size_t queue_id); 109 110 void verify(ShenandoahQueueBuffer* head); 111 }; 112 113 #endif // SHARE_VM_GC_SHENANDOAH_SHENANDOAHSTRINGDEDUPQUEUE_HPP