33 #include "gc/shenandoah/shenandoahTimingTracker.hpp" 34 #include "gc/shenandoah/shenandoahUtils.hpp" 35 #include "runtime/thread.hpp" 36 37 void ShenandoahStringDedup::initialize() { 38 assert(UseShenandoahGC, "String deduplication available with Shenandoah GC"); 39 StringDedup::initialize_impl<ShenandoahStrDedupQueue, StringDedupStat>(); 40 } 41 42 /* Enqueue candidates for deduplication. 43 * The method should only be called by GC worker threads during marking phases. 44 */ 45 void ShenandoahStringDedup::enqueue_candidate(oop java_string) { 46 assert(Thread::current()->is_Worker_thread(), 47 "Only from a GC worker thread"); 48 49 if (java_string->age() <= StringDeduplicationAgeThreshold) { 50 const markWord mark = java_string->mark(); 51 52 // Having/had displaced header, too risk to deal with them, skip 53 if (mark == markWord::INFLATING() || mark->has_displaced_mark_helper()) { 54 return; 55 } 56 57 // Increase string age and enqueue it when it rearches age threshold 58 markWord new_mark = mark->incr_age(); 59 if (mark == java_string->cas_set_mark(new_mark, mark)) { 60 if (mark->age() == StringDeduplicationAgeThreshold) { 61 StringDedupQueue::push(ShenandoahWorkerSession::worker_id(), java_string); 62 } 63 } 64 } 65 } 66 67 // Deduplicate a string, return true if it is deduplicated. 68 void ShenandoahStringDedup::deduplicate(oop java_string) { 69 assert(is_enabled(), "String deduplication not enabled"); 70 StringDedupStat dummy; // Statistics from this path is never used 71 StringDedupTable::deduplicate(java_string, &dummy); 72 } 73 74 void ShenandoahStringDedup::parallel_oops_do(BoolObjectClosure* is_alive, OopClosure* cl, uint worker_id) { 75 assert(SafepointSynchronize::is_at_safepoint(), "Must be at a safepoint"); 76 assert(is_enabled(), "String deduplication not enabled"); 77 78 StringDedupUnlinkOrOopsDoClosure sd_cl(is_alive, cl); 79 if (ShenandoahGCPhase::is_root_work_phase()) { 80 ShenandoahWorkerTimings* worker_times = ShenandoahHeap::heap()->phase_timings()->worker_times(); | 33 #include "gc/shenandoah/shenandoahTimingTracker.hpp" 34 #include "gc/shenandoah/shenandoahUtils.hpp" 35 #include "runtime/thread.hpp" 36 37 void ShenandoahStringDedup::initialize() { 38 assert(UseShenandoahGC, "String deduplication available with Shenandoah GC"); 39 StringDedup::initialize_impl<ShenandoahStrDedupQueue, StringDedupStat>(); 40 } 41 42 /* Enqueue candidates for deduplication. 43 * The method should only be called by GC worker threads during marking phases. 44 */ 45 void ShenandoahStringDedup::enqueue_candidate(oop java_string) { 46 assert(Thread::current()->is_Worker_thread(), 47 "Only from a GC worker thread"); 48 49 if (java_string->age() <= StringDeduplicationAgeThreshold) { 50 const markWord mark = java_string->mark(); 51 52 // Having/had displaced header, too risk to deal with them, skip 53 if (mark == markWord::INFLATING() || mark.has_displaced_mark_helper()) { 54 return; 55 } 56 57 // Increase string age and enqueue it when it rearches age threshold 58 markWord new_mark = mark.incr_age(); 59 if (mark == java_string->cas_set_mark(new_mark, mark)) { 60 if (mark.age() == StringDeduplicationAgeThreshold) { 61 StringDedupQueue::push(ShenandoahWorkerSession::worker_id(), java_string); 62 } 63 } 64 } 65 } 66 67 // Deduplicate a string, return true if it is deduplicated. 68 void ShenandoahStringDedup::deduplicate(oop java_string) { 69 assert(is_enabled(), "String deduplication not enabled"); 70 StringDedupStat dummy; // Statistics from this path is never used 71 StringDedupTable::deduplicate(java_string, &dummy); 72 } 73 74 void ShenandoahStringDedup::parallel_oops_do(BoolObjectClosure* is_alive, OopClosure* cl, uint worker_id) { 75 assert(SafepointSynchronize::is_at_safepoint(), "Must be at a safepoint"); 76 assert(is_enabled(), "String deduplication not enabled"); 77 78 StringDedupUnlinkOrOopsDoClosure sd_cl(is_alive, cl); 79 if (ShenandoahGCPhase::is_root_work_phase()) { 80 ShenandoahWorkerTimings* worker_times = ShenandoahHeap::heap()->phase_timings()->worker_times(); |