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