--- a/src/hotspot/share/gc/g1/g1StringDedup.hpp Thu Jun 14 15:27:49 2018 -0700
+++ b/src/hotspot/share/gc/g1/g1StringDedup.hpp Thu Jun 14 09:59:21 2018 -0400
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -26,30 +26,7 @@
#define SHARE_VM_GC_G1_G1STRINGDEDUP_HPP
//
-// String Deduplication
-//
-// String deduplication aims to reduce the heap live-set by deduplicating identical
-// instances of String so that they share the same backing character array.
-//
-// The deduplication process is divided in two main parts, 1) finding the objects to
-// deduplicate, and 2) deduplicating those objects. The first part is done as part of
-// a normal GC cycle when objects are marked or evacuated. At this time a check is
-// applied on each object to check if it is a candidate for deduplication. If so, the
-// object is placed on the deduplication queue for later processing. The second part,
-// processing the objects on the deduplication queue, is a concurrent phase which
-// starts right after the stop-the-wold marking/evacuation phase. This phase is
-// executed by the deduplication thread, which pulls deduplication candidates of the
-// deduplication queue and tries to deduplicate them.
-//
-// A deduplication hashtable is used to keep track of all unique character arrays
-// used by String objects. When deduplicating, a lookup is made in this table to see
-// if there is already an identical character array somewhere on the heap. If so, the
-// String object is adjusted to point to that character array, releasing the reference
-// to the original array allowing it to eventually be garbage collected. If the lookup
-// fails the character array is instead inserted into the hashtable so that this array
-// can be shared at some point in the future.
-//
-// Candidate selection
+// G1 string deduplication candidate selection
//
// An object is considered a deduplication candidate if all of the following
// statements are true:
@@ -70,36 +47,21 @@
// than the deduplication age threshold, is will never become a candidate again.
// This approach avoids making the same object a candidate more than once.
//
-// Interned strings are a bit special. They are explicitly deduplicated just before
-// being inserted into the StringTable (to avoid counteracting C2 optimizations done
-// on string literals), then they also become deduplication candidates if they reach
-// the deduplication age threshold or are evacuated to an old heap region. The second
-// attempt to deduplicate such strings will be in vain, but we have no fast way of
-// filtering them out. This has not shown to be a problem, as the number of interned
-// strings is usually dwarfed by the number of normal (non-interned) strings.
-//
-// For additional information on string deduplication, please see JEP 192,
-// http://openjdk.java.net/jeps/192
-//
+#include "gc/shared/stringdedup/stringDedup.hpp"
#include "memory/allocation.hpp"
#include "oops/oop.hpp"
class OopClosure;
class BoolObjectClosure;
-class ThreadClosure;
-class outputStream;
-class G1StringDedupTable;
+class G1GCPhaseTimes;
class G1StringDedupUnlinkOrOopsDoClosure;
-class G1GCPhaseTimes;
//
-// Main interface for interacting with string deduplication.
+// G1 interface for interacting with string deduplication.
//
-class G1StringDedup : public AllStatic {
+class G1StringDedup : public StringDedup {
private:
- // Single state for checking if both G1 and string deduplication is enabled.
- static bool _enabled;
// Candidate selection policies, returns true if the given object is
// candidate for string deduplication.
@@ -107,21 +69,9 @@
static bool is_candidate_from_evacuation(bool from_young, bool to_young, oop obj);
public:
- // Returns true if both G1 and string deduplication is enabled.
- static bool is_enabled() {
- return _enabled;
- }
-
// Initialize string deduplication.
static void initialize();
- // Stop the deduplication thread.
- static void stop();
-
- // Immediately deduplicates the given String object, bypassing the
- // the deduplication queue.
- static void deduplicate(oop java_string);
-
// Enqueues a deduplication candidate for later processing by the deduplication
// thread. Before enqueuing, these functions apply the appropriate candidate
// selection policy to filters out non-candidates.
@@ -133,70 +83,28 @@
static void parallel_unlink(G1StringDedupUnlinkOrOopsDoClosure* unlink, uint worker_id);
static void unlink_or_oops_do(BoolObjectClosure* is_alive, OopClosure* keep_alive,
bool allow_resize_and_rehash, G1GCPhaseTimes* phase_times = NULL);
-
- static void threads_do(ThreadClosure* tc);
- static void print_worker_threads_on(outputStream* st);
- static void verify();
};
//
// This closure encapsulates the state and the closures needed when scanning
// the deduplication queue and table during the unlink_or_oops_do() operation.
// A single instance of this closure is created and then shared by all worker
-// threads participating in the scan. The _next_queue and _next_bucket fields
-// provide a simple mechanism for GC workers to claim exclusive access to a
-// queue or a table partition.
+// threads participating in the scan.
//
-class G1StringDedupUnlinkOrOopsDoClosure : public StackObj {
-private:
- BoolObjectClosure* _is_alive;
- OopClosure* _keep_alive;
- G1StringDedupTable* _resized_table;
- G1StringDedupTable* _rehashed_table;
- size_t _next_queue;
- size_t _next_bucket;
-
+class G1StringDedupUnlinkOrOopsDoClosure : public StringDedupUnlinkOrOopsDoClosure {
public:
G1StringDedupUnlinkOrOopsDoClosure(BoolObjectClosure* is_alive,
OopClosure* keep_alive,
- bool allow_resize_and_rehash);
- ~G1StringDedupUnlinkOrOopsDoClosure();
-
- bool is_resizing() {
- return _resized_table != NULL;
- }
-
- G1StringDedupTable* resized_table() {
- return _resized_table;
- }
-
- bool is_rehashing() {
- return _rehashed_table != NULL;
- }
-
- // Atomically claims the next available queue for exclusive access by
- // the current thread. Returns the queue number of the claimed queue.
- size_t claim_queue();
+ bool allow_resize_and_rehash) :
+ StringDedupUnlinkOrOopsDoClosure(is_alive, keep_alive) {
+ if (G1StringDedup::is_enabled()) {
+ G1StringDedup::gc_prologue(allow_resize_and_rehash);
+ }
+ }
- // Atomically claims the next available table partition for exclusive
- // access by the current thread. Returns the table bucket number where
- // the claimed partition starts.
- size_t claim_table_partition(size_t partition_size);
-
- // Applies and returns the result from the is_alive closure, or
- // returns true if no such closure was provided.
- bool is_alive(oop o) {
- if (_is_alive != NULL) {
- return _is_alive->do_object_b(o);
- }
- return true;
- }
-
- // Applies the keep_alive closure, or does nothing if no such
- // closure was provided.
- void keep_alive(oop* p) {
- if (_keep_alive != NULL) {
- _keep_alive->do_oop(p);
+ ~G1StringDedupUnlinkOrOopsDoClosure() {
+ if (G1StringDedup::is_enabled()) {
+ G1StringDedup::gc_epilogue();
}
}
};