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_SHENANDOAHSTRINGDEDUP_HPP 25 #define SHARE_VM_GC_SHENANDOAH_SHENANDOAHSTRINGDEDUP_HPP 26 27 #include "classfile/javaClasses.hpp" 28 #include "gc_implementation/shenandoah/shenandoahPhaseTimings.hpp" 29 #include "memory/iterator.hpp" 30 #include "utilities/ostream.hpp" 31 32 #define STRDEDUP_TIME_FORMAT_MS "%.3fms" 33 #define STRDEDUP_TIME_PARAM_MS(time) ((time) * MILLIUNITS) 34 35 class ShenandoahStrDedupStats VALUE_OBJ_CLASS_SPEC { 36 private: 37 // Counters 38 volatile size_t _inspected; 39 volatile size_t _deduped; 40 volatile size_t _skipped; 41 volatile size_t _known; 42 43 size_t _idle; 44 size_t _exec; 45 size_t _block; 46 47 // Time spent by the deduplication thread in different phases 48 double _start_concurrent; 49 double _end_concurrent; 50 double _start_phase; 51 double _idle_elapsed; 52 double _exec_elapsed; 53 double _block_elapsed; 54 55 size_t _table_expanded_count; 56 size_t _table_shrinked_count; 57 size_t _table_rehashed_count; 58 59 public: 60 ShenandoahStrDedupStats(); 61 62 void inc_inspected() { assert_thread(); _inspected ++; } 63 void inc_skipped() { assert_thread(); _skipped ++; } 64 void inc_known() { assert_thread(); _known ++; } 65 void inc_deduped() { 66 assert_thread(); 67 _deduped ++; 68 } 69 70 void atomic_inc_inspected(size_t count); 71 void atomic_inc_deduped(size_t count); 72 void atomic_inc_skipped(size_t count); 73 void atomic_inc_known(size_t count); 74 75 void mark_idle(); 76 void mark_exec(); 77 void mark_block(); 78 void mark_unblock(); 79 void mark_done(); 80 81 void inc_table_expanded(); 82 void inc_table_shrinked(); 83 void inc_table_rehashed(); 84 85 void update(const ShenandoahStrDedupStats& sts); 86 87 void print_statistics(outputStream* out) const; 88 89 private: 90 void assert_thread() PRODUCT_RETURN; 91 }; 92 93 class ShenandoahStrDedupQueue; 94 class ShenandoahStrDedupQueueSet; 95 class ShenandoahStrDedupTable; 96 class ShenandoahStrDedupThread; 97 98 class ShenandoahStringDedup : AllStatic { 99 friend class ShenandoahStrDedupStats; 100 101 private: 102 static ShenandoahStrDedupQueueSet* _queues; 103 static ShenandoahStrDedupTable* _table; 104 static ShenandoahStrDedupThread* _thread; 105 static bool _enabled; 106 static ShenandoahStrDedupStats _stats; 107 108 public: 109 // Initialize string deduplication. 110 static void initialize(); 111 112 static bool is_enabled() { return _enabled; } 113 114 // Enqueue a string to worker's local string dedup queue 115 static void enqueue_candidate(oop java_string, ShenandoahStrDedupQueue* q); 116 117 // Get string dedup queue associated to specific worker id 118 static ShenandoahStrDedupQueue* queue(uint worker_id); 119 120 // Deduplicate a string, the call is lock-free 121 static bool deduplicate(oop java_string, bool update_counter = true); 122 123 // Parallel scan string dedup queues/table 124 static void clear_claimed(); 125 126 static void parallel_oops_do(ShenandoahPhaseTimings::Phase phase, OopClosure* cl, uint worker_id); 127 128 // For verification only 129 static void oops_do_slow(OopClosure* cl); 130 131 static void threads_do(ThreadClosure* tc); 132 133 static void print_worker_threads_on(outputStream* out) { } 134 135 static ShenandoahStrDedupStats& dedup_stats() { return _stats; } 136 137 // Parallel cleanup string dedup queues/table 138 static void parallel_cleanup(); 139 140 static void stop(); 141 142 static inline bool is_candidate(oop obj) { 143 return java_lang_String::is_instance(obj) && 144 java_lang_String::value(obj) != NULL; 145 } 146 147 static void print_statistics(outputStream* out); 148 }; 149 150 #endif // SHARE_VM_GC_SHENANDOAH_SHENANDOAHSTRINGDEDUP_HPP