88 89 // Not a candidate 90 return false; 91 } 92 93 void G1StringDedup::enqueue_from_evacuation(bool from_young, bool to_young, uint worker_id, oop java_string) { 94 assert(is_enabled(), "String deduplication not enabled"); 95 if (is_candidate_from_evacuation(from_young, to_young, java_string)) { 96 G1StringDedupQueue::push(worker_id, java_string); 97 } 98 } 99 100 void G1StringDedup::deduplicate(oop java_string) { 101 assert(is_enabled(), "String deduplication not enabled"); 102 G1StringDedupStat dummy; // Statistics from this path is never used 103 G1StringDedupTable::deduplicate(java_string, dummy); 104 } 105 106 void G1StringDedup::oops_do(OopClosure* keep_alive) { 107 assert(is_enabled(), "String deduplication not enabled"); 108 unlink_or_oops_do(NULL, keep_alive); 109 } 110 111 void G1StringDedup::unlink(BoolObjectClosure* is_alive) { 112 assert(is_enabled(), "String deduplication not enabled"); 113 // Don't allow a potential resize or rehash during unlink, as the unlink 114 // operation itself might remove enough entries to invalidate such a decision. 115 unlink_or_oops_do(is_alive, NULL, false /* allow_resize_and_rehash */); 116 } 117 118 // 119 // Task for parallel unlink_or_oops_do() operation on the deduplication queue 120 // and table. 121 // 122 class G1StringDedupUnlinkOrOopsDoTask : public AbstractGangTask { 123 private: 124 G1StringDedupUnlinkOrOopsDoClosure _cl; 125 126 public: 127 G1StringDedupUnlinkOrOopsDoTask(BoolObjectClosure* is_alive, 128 OopClosure* keep_alive, 129 bool allow_resize_and_rehash) : 130 AbstractGangTask("G1StringDedupUnlinkOrOopsDoTask"), 131 _cl(is_alive, keep_alive, allow_resize_and_rehash) { 132 } 133 134 virtual void work(uint worker_id) { 135 double queue_fixup_start = os::elapsedTime(); 136 G1StringDedupQueue::unlink_or_oops_do(&_cl); 137 138 double table_fixup_start = os::elapsedTime(); 139 G1StringDedupTable::unlink_or_oops_do(&_cl, worker_id); 140 141 double queue_fixup_time_ms = (table_fixup_start - queue_fixup_start) * 1000.0; 142 double table_fixup_time_ms = (os::elapsedTime() - table_fixup_start) * 1000.0; 143 G1CollectorPolicy* g1p = G1CollectedHeap::heap()->g1_policy(); 144 g1p->phase_times()->record_string_dedup_queue_fixup_worker_time(worker_id, queue_fixup_time_ms); 145 g1p->phase_times()->record_string_dedup_table_fixup_worker_time(worker_id, table_fixup_time_ms); 146 } 147 }; 148 149 void G1StringDedup::unlink_or_oops_do(BoolObjectClosure* is_alive, OopClosure* keep_alive, bool allow_resize_and_rehash) { 150 assert(is_enabled(), "String deduplication not enabled"); 151 G1CollectorPolicy* g1p = G1CollectedHeap::heap()->g1_policy(); 152 g1p->phase_times()->note_string_dedup_fixup_start(); 153 double fixup_start = os::elapsedTime(); 154 155 G1StringDedupUnlinkOrOopsDoTask task(is_alive, keep_alive, allow_resize_and_rehash); 156 if (G1CollectedHeap::use_parallel_gc_threads()) { 157 G1CollectedHeap* g1h = G1CollectedHeap::heap(); 158 g1h->set_par_threads(); 159 g1h->workers()->run_task(&task); 160 g1h->set_par_threads(0); 161 } else { 162 task.work(0); 163 } 164 165 double fixup_time_ms = (os::elapsedTime() - fixup_start) * 1000.0; 166 g1p->phase_times()->record_string_dedup_fixup_time(fixup_time_ms); 167 g1p->phase_times()->note_string_dedup_fixup_end(); 168 } 169 170 void G1StringDedup::threads_do(ThreadClosure* tc) { 171 assert(is_enabled(), "String deduplication not enabled"); 172 tc->do_thread(G1StringDedupThread::thread()); 173 } 174 175 void G1StringDedup::print_worker_threads_on(outputStream* st) { 176 assert(is_enabled(), "String deduplication not enabled"); 177 G1StringDedupThread::thread()->print_on(st); 178 st->cr(); 179 } 180 181 void G1StringDedup::verify() { 182 assert(is_enabled(), "String deduplication not enabled"); 183 G1StringDedupQueue::verify(); 184 G1StringDedupTable::verify(); 185 } 186 187 G1StringDedupUnlinkOrOopsDoClosure::G1StringDedupUnlinkOrOopsDoClosure(BoolObjectClosure* is_alive, | 88 89 // Not a candidate 90 return false; 91 } 92 93 void G1StringDedup::enqueue_from_evacuation(bool from_young, bool to_young, uint worker_id, oop java_string) { 94 assert(is_enabled(), "String deduplication not enabled"); 95 if (is_candidate_from_evacuation(from_young, to_young, java_string)) { 96 G1StringDedupQueue::push(worker_id, java_string); 97 } 98 } 99 100 void G1StringDedup::deduplicate(oop java_string) { 101 assert(is_enabled(), "String deduplication not enabled"); 102 G1StringDedupStat dummy; // Statistics from this path is never used 103 G1StringDedupTable::deduplicate(java_string, dummy); 104 } 105 106 void G1StringDedup::oops_do(OopClosure* keep_alive) { 107 assert(is_enabled(), "String deduplication not enabled"); 108 unlink_or_oops_do(NULL, keep_alive, true /* allow_resize_and_rehash */); 109 } 110 111 void G1StringDedup::unlink(BoolObjectClosure* is_alive) { 112 assert(is_enabled(), "String deduplication not enabled"); 113 // Don't allow a potential resize or rehash during unlink, as the unlink 114 // operation itself might remove enough entries to invalidate such a decision. 115 unlink_or_oops_do(is_alive, NULL, false /* allow_resize_and_rehash */); 116 } 117 118 // 119 // Task for parallel unlink_or_oops_do() operation on the deduplication queue 120 // and table. 121 // 122 class G1StringDedupUnlinkOrOopsDoTask : public AbstractGangTask { 123 private: 124 G1StringDedupUnlinkOrOopsDoClosure _cl; 125 G1GCPhaseTimes* _phase_times; 126 127 public: 128 G1StringDedupUnlinkOrOopsDoTask(BoolObjectClosure* is_alive, 129 OopClosure* keep_alive, 130 bool allow_resize_and_rehash, 131 G1GCPhaseTimes* phase_times) : 132 AbstractGangTask("G1StringDedupUnlinkOrOopsDoTask"), 133 _cl(is_alive, keep_alive, allow_resize_and_rehash), _phase_times(phase_times) { } 134 135 virtual void work(uint worker_id) { 136 { 137 G1GCParPhaseTimesTracker x(_phase_times, G1GCPhaseTimes::StringDedupQueueFixup, worker_id); 138 G1StringDedupQueue::unlink_or_oops_do(&_cl); 139 } 140 { 141 G1GCParPhaseTimesTracker x(_phase_times, G1GCPhaseTimes::StringDedupTableFixup, worker_id); 142 G1StringDedupTable::unlink_or_oops_do(&_cl, worker_id); 143 } 144 } 145 }; 146 147 void G1StringDedup::unlink_or_oops_do(BoolObjectClosure* is_alive, 148 OopClosure* keep_alive, 149 bool allow_resize_and_rehash, 150 G1GCPhaseTimes* phase_times) { 151 assert(is_enabled(), "String deduplication not enabled"); 152 153 G1StringDedupUnlinkOrOopsDoTask task(is_alive, keep_alive, allow_resize_and_rehash, phase_times); 154 if (G1CollectedHeap::use_parallel_gc_threads()) { 155 G1CollectedHeap* g1h = G1CollectedHeap::heap(); 156 g1h->set_par_threads(); 157 g1h->workers()->run_task(&task); 158 g1h->set_par_threads(0); 159 } else { 160 task.work(0); 161 } 162 } 163 164 void G1StringDedup::threads_do(ThreadClosure* tc) { 165 assert(is_enabled(), "String deduplication not enabled"); 166 tc->do_thread(G1StringDedupThread::thread()); 167 } 168 169 void G1StringDedup::print_worker_threads_on(outputStream* st) { 170 assert(is_enabled(), "String deduplication not enabled"); 171 G1StringDedupThread::thread()->print_on(st); 172 st->cr(); 173 } 174 175 void G1StringDedup::verify() { 176 assert(is_enabled(), "String deduplication not enabled"); 177 G1StringDedupQueue::verify(); 178 G1StringDedupTable::verify(); 179 } 180 181 G1StringDedupUnlinkOrOopsDoClosure::G1StringDedupUnlinkOrOopsDoClosure(BoolObjectClosure* is_alive, |