8253037: G1: Improve check for string dedup

Combine dedup enabled and is_string into a single test, using the already in-hand klass of the object.

Reviewed-by: ayang, tschatzl
This commit is contained in:
Kim Barrett 2020-11-04 05:04:02 +00:00
parent 2668d23244
commit 4b88119b4b
5 changed files with 31 additions and 19 deletions

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2017, 2020, 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
@ -25,6 +25,7 @@
#ifndef SHARE_GC_G1_G1FULLGCMARKER_INLINE_HPP
#define SHARE_GC_G1_G1FULLGCMARKER_INLINE_HPP
#include "classfile/javaClasses.inline.hpp"
#include "gc/g1/g1Allocator.inline.hpp"
#include "gc/g1/g1ConcurrentMarkBitMap.inline.hpp"
#include "gc/g1/g1FullGCMarker.hpp"
@ -57,7 +58,8 @@ inline bool G1FullGCMarker::mark_object(oop obj) {
}
// Check if deduplicatable string.
if (G1StringDedup::is_enabled()) {
if (G1StringDedup::is_enabled() &&
java_lang_String::is_instance_inlined(obj)) {
G1StringDedup::enqueue_from_mark(obj, _worker_id);
}
return true;

View File

@ -23,6 +23,7 @@
*/
#include "precompiled.hpp"
#include "classfile/systemDictionary.hpp"
#include "gc/g1/g1Allocator.inline.hpp"
#include "gc/g1/g1CollectedHeap.inline.hpp"
#include "gc/g1/g1CollectionSet.hpp"
@ -75,10 +76,17 @@ G1ParScanThreadState::G1ParScanThreadState(G1CollectedHeap* g1h,
_old_gen_is_full(false),
_partial_objarray_chunk_size(ParGCArrayScanChunk),
_partial_array_stepper(n_workers),
_string_klass_or_null(G1StringDedup::is_enabled()
? SystemDictionary::String_klass()
: nullptr),
_num_optional_regions(optional_cset_length),
_numa(g1h->numa()),
_obj_alloc_stat(NULL)
{
// Verify klass comparison with _string_klass_or_null is sufficient
// to determine whether dedup is enabled and the object is a String.
assert(SystemDictionary::String_klass()->is_final(), "precondition");
// We allocate number of young gen regions in the collection set plus one
// entries, since entry 0 keeps track of surviving bytes for non-young regions.
// We also add a few elements at the beginning and at the end in
@ -510,7 +518,10 @@ oop G1ParScanThreadState::do_copy_to_survivor_space(G1HeapRegionAttr const regio
return obj;
}
if (G1StringDedup::is_enabled()) {
// StringDedup::is_enabled() and java_lang_String::is_instance_inline
// test of the obj, combined into a single comparison, using the klass
// already in hand and avoiding the null check in is_instance.
if (klass == _string_klass_or_null) {
const bool is_from_young = region_attr.is_young();
const bool is_to_young = dest_attr.is_young();
assert(is_from_young == from_region->is_young(),

View File

@ -42,6 +42,7 @@ class G1OopStarChunkedList;
class G1PLABAllocator;
class G1EvacuationRootClosures;
class HeapRegion;
class Klass;
class outputStream;
class G1ParScanThreadState : public CHeapObj<mtGC> {
@ -83,6 +84,8 @@ class G1ParScanThreadState : public CHeapObj<mtGC> {
// Size (in elements) of a partial objArray task chunk.
int _partial_objarray_chunk_size;
PartialArrayTaskStepper _partial_array_stepper;
// Used to check whether string dedup should be applied to an object.
Klass* _string_klass_or_null;
G1RedirtyCardsQueue& redirty_cards_queue() { return _rdcq; }
G1CardTable* ct() { return _ct; }

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, 2020, 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
@ -41,29 +41,23 @@ void G1StringDedup::initialize() {
}
bool G1StringDedup::is_candidate_from_mark(oop obj) {
if (java_lang_String::is_instance_inlined(obj)) {
bool from_young = G1CollectedHeap::heap()->heap_region_containing(obj)->is_young();
if (from_young && obj->age() < StringDeduplicationAgeThreshold) {
// Candidate found. String is being evacuated from young to old but has not
// reached the deduplication age threshold, i.e. has not previously been a
// candidate during its life in the young generation.
return true;
}
}
// Not a candidate
return false;
bool from_young = G1CollectedHeap::heap()->heap_region_containing(obj)->is_young();
// Candidate if string is being evacuated from young to old but has not
// reached the deduplication age threshold, i.e. has not previously been a
// candidate during its life in the young generation.
return from_young && (obj->age() < StringDeduplicationAgeThreshold);
}
void G1StringDedup::enqueue_from_mark(oop java_string, uint worker_id) {
assert(is_enabled(), "String deduplication not enabled");
assert(java_lang_String::is_instance(java_string), "not a String");
if (is_candidate_from_mark(java_string)) {
G1StringDedupQueue::push(worker_id, java_string);
}
}
bool G1StringDedup::is_candidate_from_evacuation(bool from_young, bool to_young, oop obj) {
if (from_young && java_lang_String::is_instance_inlined(obj)) {
if (from_young) {
if (to_young && obj->age() == StringDeduplicationAgeThreshold) {
// Candidate found. String is being evacuated from young to young and just
// reached the deduplication age threshold.
@ -83,6 +77,7 @@ bool G1StringDedup::is_candidate_from_evacuation(bool from_young, bool to_young,
void G1StringDedup::enqueue_from_evacuation(bool from_young, bool to_young, uint worker_id, oop java_string) {
assert(is_enabled(), "String deduplication not enabled");
assert(java_lang_String::is_instance(java_string), "not a String");
if (is_candidate_from_evacuation(from_young, to_young, java_string)) {
G1StringDedupQueue::push(worker_id, java_string);
}

View File

@ -65,8 +65,8 @@ private:
// Candidate selection policies, returns true if the given object is
// candidate for string deduplication.
static bool is_candidate_from_mark(oop obj);
static bool is_candidate_from_evacuation(bool from_young, bool to_young, oop obj);
static bool is_candidate_from_mark(oop java_string);
static bool is_candidate_from_evacuation(bool from_young, bool to_young, oop java_string);
public:
// Initialize string deduplication.
@ -75,6 +75,7 @@ public:
// 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.
// Precondition for both is that java_string is a String.
static void enqueue_from_mark(oop java_string, uint worker_id);
static void enqueue_from_evacuation(bool from_young, bool to_young,
unsigned int queue, oop java_string);