--- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp Fri Jan 30 16:56:05 2015 -0800
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp Mon Feb 02 13:57:38 2015 +0100
@@ -139,6 +139,8 @@
_survivor_cset_region_length(0),
_old_cset_region_length(0),
+ _sigma(G1ConfidencePercent / 100.0),
+
_collection_set(NULL),
_collection_set_bytes_used_before(0),
@@ -161,17 +163,8 @@
_gc_overhead_perc(0.0) {
- uintx confidence_perc = G1ConfidencePercent;
- // Put an artificial ceiling on this so that it's not set to a silly value.
- if (confidence_perc > 100) {
- confidence_perc = 100;
- warning("G1ConfidencePercent is set to a value that is too large, "
- "it's been updated to %u", confidence_perc);
- }
- // '_sigma' must be initialized before the SurvRateGroups below because they
- // indirecty access '_sigma' trough the 'this' pointer in their constructor.
- _sigma = (double) confidence_perc / 100.0;
-
+ // SurvRateGroups below must be initialized after '_sigma' because they
+ // indirectly access '_sigma' through this object passed to their constructor.
_short_lived_surv_rate_group =
new SurvRateGroup(this, "Short Lived", G1YoungSurvRateNumRegionsSummary);
_survivor_surv_rate_group =
--- a/hotspot/src/share/vm/gc_implementation/g1/g1HotCardCache.cpp Fri Jan 30 16:56:05 2015 -0800
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1HotCardCache.cpp Mon Feb 02 13:57:38 2015 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2015, 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
@@ -36,11 +36,10 @@
if (default_use_cache()) {
_use_cache = true;
- _hot_cache_size = (1 << G1ConcRSLogCacheSize);
+ _hot_cache_size = (size_t)1 << G1ConcRSLogCacheSize;
_hot_cache = NEW_C_HEAP_ARRAY(jbyte*, _hot_cache_size, mtGC);
- _n_hot = 0;
- _hot_cache_idx = 0;
+ reset_hot_cache_internal();
// For refining the cards in the hot cache in parallel
_hot_cache_par_chunk_size = ClaimChunkSize;
@@ -64,26 +63,21 @@
// return it for immediate refining.
return card_ptr;
}
-
// Otherwise, the card is hot.
- jbyte* res = NULL;
- MutexLockerEx x(HotCardCache_lock, Mutex::_no_safepoint_check_flag);
- if (_n_hot == _hot_cache_size) {
- res = _hot_cache[_hot_cache_idx];
- _n_hot--;
- }
+ size_t index = Atomic::add(1, &_hot_cache_idx) - 1;
+ size_t masked_index = index & (_hot_cache_size - 1);
+ jbyte* current_ptr = _hot_cache[masked_index];
- // Now _n_hot < _hot_cache_size, and we can insert at _hot_cache_idx.
- _hot_cache[_hot_cache_idx] = card_ptr;
- _hot_cache_idx++;
-
- if (_hot_cache_idx == _hot_cache_size) {
- // Wrap around
- _hot_cache_idx = 0;
- }
- _n_hot++;
-
- return res;
+ // Try to store the new card pointer into the cache. Compare-and-swap to guard
+ // against the unlikely event of a race resulting in another card pointer to
+ // have already been written to the cache. In this case we will return
+ // card_ptr in favor of the other option, which would be starting over. This
+ // should be OK since card_ptr will likely be the older card already when/if
+ // this ever happens.
+ jbyte* previous_ptr = (jbyte*)Atomic::cmpxchg_ptr(card_ptr,
+ &_hot_cache[masked_index],
+ current_ptr);
+ return (previous_ptr == current_ptr) ? previous_ptr : card_ptr;
}
void G1HotCardCache::drain(uint worker_i,
@@ -96,38 +90,38 @@
assert(_hot_cache != NULL, "Logic");
assert(!use_cache(), "cache should be disabled");
- int start_idx;
-
- while ((start_idx = _hot_cache_par_claimed_idx) < _n_hot) { // read once
- int end_idx = start_idx + _hot_cache_par_chunk_size;
- if (start_idx ==
- Atomic::cmpxchg(end_idx, &_hot_cache_par_claimed_idx, start_idx)) {
- // The current worker has successfully claimed the chunk [start_idx..end_idx)
- end_idx = MIN2(end_idx, _n_hot);
- for (int i = start_idx; i < end_idx; i++) {
- jbyte* card_ptr = _hot_cache[i];
- if (card_ptr != NULL) {
- if (g1rs->refine_card(card_ptr, worker_i, true)) {
- // The part of the heap spanned by the card contains references
- // that point into the current collection set.
- // We need to record the card pointer in the DirtyCardQueueSet
- // that we use for such cards.
- //
- // The only time we care about recording cards that contain
- // references that point into the collection set is during
- // RSet updating while within an evacuation pause.
- // In this case worker_i should be the id of a GC worker thread
- assert(SafepointSynchronize::is_at_safepoint(), "Should be at a safepoint");
- assert(worker_i < ParallelGCThreads,
- err_msg("incorrect worker id: %u", worker_i));
+ while (_hot_cache_par_claimed_idx < _hot_cache_size) {
+ size_t end_idx = Atomic::add(_hot_cache_par_chunk_size,
+ &_hot_cache_par_claimed_idx);
+ size_t start_idx = end_idx - _hot_cache_par_chunk_size;
+ // The current worker has successfully claimed the chunk [start_idx..end_idx)
+ end_idx = MIN2(end_idx, _hot_cache_size);
+ for (size_t i = start_idx; i < end_idx; i++) {
+ jbyte* card_ptr = _hot_cache[i];
+ if (card_ptr != NULL) {
+ if (g1rs->refine_card(card_ptr, worker_i, true)) {
+ // The part of the heap spanned by the card contains references
+ // that point into the current collection set.
+ // We need to record the card pointer in the DirtyCardQueueSet
+ // that we use for such cards.
+ //
+ // The only time we care about recording cards that contain
+ // references that point into the collection set is during
+ // RSet updating while within an evacuation pause.
+ // In this case worker_i should be the id of a GC worker thread
+ assert(SafepointSynchronize::is_at_safepoint(), "Should be at a safepoint");
+ assert(worker_i < ParallelGCThreads,
+ err_msg("incorrect worker id: %u", worker_i));
- into_cset_dcq->enqueue(card_ptr);
- }
+ into_cset_dcq->enqueue(card_ptr);
}
+ } else {
+ break;
}
}
}
+
// The existing entries in the hot card cache, which were just refined
// above, are discarded prior to re-enabling the cache near the end of the GC.
}
--- a/hotspot/src/share/vm/gc_implementation/g1/g1HotCardCache.hpp Fri Jan 30 16:56:05 2015 -0800
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1HotCardCache.hpp Mon Feb 02 13:57:38 2015 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2015, 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
@@ -54,21 +54,30 @@
// code, increasing throughput.
class G1HotCardCache: public CHeapObj<mtGC> {
- G1CollectedHeap* _g1h;
+
+ G1CollectedHeap* _g1h;
+
+ bool _use_cache;
+
+ G1CardCounts _card_counts;
// The card cache table
- jbyte** _hot_cache;
+ jbyte** _hot_cache;
- int _hot_cache_size;
- int _n_hot;
- int _hot_cache_idx;
+ size_t _hot_cache_size;
+
+ int _hot_cache_par_chunk_size;
- int _hot_cache_par_chunk_size;
- volatile int _hot_cache_par_claimed_idx;
+ // Avoids false sharing when concurrently updating _hot_cache_idx or
+ // _hot_cache_par_claimed_idx. These are never updated at the same time
+ // thus it's not necessary to separate them as well
+ char _pad_before[DEFAULT_CACHE_LINE_SIZE];
- bool _use_cache;
+ volatile size_t _hot_cache_idx;
- G1CardCounts _card_counts;
+ volatile size_t _hot_cache_par_claimed_idx;
+
+ char _pad_after[DEFAULT_CACHE_LINE_SIZE];
// The number of cached cards a thread claims when flushing the cache
static const int ClaimChunkSize = 32;
@@ -113,16 +122,25 @@
void reset_hot_cache() {
assert(SafepointSynchronize::is_at_safepoint(), "Should be at a safepoint");
assert(Thread::current()->is_VM_thread(), "Current thread should be the VMthread");
- _hot_cache_idx = 0; _n_hot = 0;
+ if (default_use_cache()) {
+ reset_hot_cache_internal();
+ }
}
- bool hot_cache_is_empty() { return _n_hot == 0; }
-
// Zeros the values in the card counts table for entire committed heap
void reset_card_counts();
// Zeros the values in the card counts table for the given region
void reset_card_counts(HeapRegion* hr);
+
+ private:
+ void reset_hot_cache_internal() {
+ assert(_hot_cache != NULL, "Logic");
+ _hot_cache_idx = 0;
+ for (size_t i = 0; i < _hot_cache_size; i++) {
+ _hot_cache[i] = NULL;
+ }
+ }
};
#endif // SHARE_VM_GC_IMPLEMENTATION_G1_G1HOTCARDCACHE_HPP
--- a/hotspot/src/share/vm/gc_implementation/g1/g1SATBCardTableModRefBS.cpp Fri Jan 30 16:56:05 2015 -0800
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1SATBCardTableModRefBS.cpp Mon Feb 02 13:57:38 2015 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2015, 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
@@ -32,11 +32,8 @@
#include "runtime/orderAccess.inline.hpp"
#include "runtime/thread.inline.hpp"
-G1SATBCardTableModRefBS::G1SATBCardTableModRefBS(MemRegion whole_heap) :
- CardTableModRefBS(whole_heap)
-{
- _kind = G1SATBCT;
-}
+G1SATBCardTableModRefBS::G1SATBCardTableModRefBS(MemRegion whole_heap, BarrierSet::Name kind) :
+ CardTableModRefBS(whole_heap, kind) { }
void G1SATBCardTableModRefBS::enqueue(oop pre_val) {
// Nulls should have been already filtered.
@@ -132,11 +129,10 @@
G1SATBCardTableLoggingModRefBS::
G1SATBCardTableLoggingModRefBS(MemRegion whole_heap) :
- G1SATBCardTableModRefBS(whole_heap),
+ G1SATBCardTableModRefBS(whole_heap, BarrierSet::G1SATBCTLogging),
_dcqs(JavaThread::dirty_card_queue_set()),
_listener()
{
- _kind = G1SATBCTLogging;
_listener.set_card_table(this);
}
--- a/hotspot/src/share/vm/gc_implementation/g1/g1SATBCardTableModRefBS.hpp Fri Jan 30 16:56:05 2015 -0800
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1SATBCardTableModRefBS.hpp Mon Feb 02 13:57:38 2015 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2015, 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
@@ -43,6 +43,9 @@
g1_young_gen = CT_MR_BS_last_reserved << 1
};
+ G1SATBCardTableModRefBS(MemRegion whole_heap, BarrierSet::Name kind);
+ ~G1SATBCardTableModRefBS() { }
+
public:
static int g1_young_card_val() { return g1_young_gen; }
@@ -50,8 +53,6 @@
// pre-marking object graph.
static void enqueue(oop pre_val);
- G1SATBCardTableModRefBS(MemRegion whole_heap);
-
bool is_a(BarrierSet::Name bsn) {
return bsn == BarrierSet::G1SATBCT || CardTableModRefBS::is_a(bsn);
}
--- a/hotspot/src/share/vm/gc_implementation/g1/heapRegion.cpp Fri Jan 30 16:56:05 2015 -0800
+++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegion.cpp Mon Feb 02 13:57:38 2015 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2015, 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
@@ -420,7 +420,7 @@
oop obj;
HeapWord* next = cur;
- while (next <= start) {
+ do {
cur = next;
obj = oop(cur);
if (obj->klass_or_null() == NULL) {
@@ -429,45 +429,38 @@
}
// Otherwise...
next = cur + block_size(cur);
- }
+ } while (next <= start);
// If we finish the above loop...We have a parseable object that
// begins on or before the start of the memory region, and ends
// inside or spans the entire region.
-
- assert(obj == oop(cur), "sanity");
assert(cur <= start, "Loop postcondition");
assert(obj->klass_or_null() != NULL, "Loop postcondition");
- assert((cur + block_size(cur)) > start, "Loop postcondition");
- if (!g1h->is_obj_dead(obj)) {
- obj->oop_iterate(cl, mr);
- }
-
- while (cur < end) {
+ do {
obj = oop(cur);
+ assert((cur + block_size(cur)) > (HeapWord*)obj, "Loop invariant");
if (obj->klass_or_null() == NULL) {
// Ran into an unparseable point.
return cur;
- };
+ }
- // Otherwise:
- next = cur + block_size(cur);
+ // Advance the current pointer. "obj" still points to the object to iterate.
+ cur = cur + block_size(cur);
if (!g1h->is_obj_dead(obj)) {
- if (next < end || !obj->is_objArray()) {
- // This object either does not span the MemRegion
- // boundary, or if it does it's not an array.
- // Apply closure to whole object.
+ // Non-objArrays are sometimes marked imprecise at the object start. We
+ // always need to iterate over them in full.
+ // We only iterate over object arrays in full if they are completely contained
+ // in the memory region.
+ if (!obj->is_objArray() || (((HeapWord*)obj) >= start && cur <= end)) {
obj->oop_iterate(cl);
} else {
- // This obj is an array that spans the boundary.
- // Stop at the boundary.
obj->oop_iterate(cl, mr);
}
}
- cur = next;
- }
+ } while (cur < end);
+
return NULL;
}
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/cardTableExtension.hpp Fri Jan 30 16:56:05 2015 -0800
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/cardTableExtension.hpp Mon Feb 02 13:57:38 2015 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2015, 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
@@ -54,7 +54,7 @@
};
CardTableExtension(MemRegion whole_heap) :
- CardTableModRefBS(whole_heap) { }
+ CardTableModRefBS(whole_heap, BarrierSet::CardTableModRef) { }
// Too risky for the 4/10/02 putback
// BarrierSet::Name kind() { return BarrierSet::CardTableExtension; }
--- a/hotspot/src/share/vm/memory/barrierSet.hpp Fri Jan 30 16:56:05 2015 -0800
+++ b/hotspot/src/share/vm/memory/barrierSet.hpp Mon Feb 02 13:57:38 2015 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2015, 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
@@ -40,8 +40,7 @@
CardTableExtension,
G1SATBCT,
G1SATBCTLogging,
- Other,
- Uninit
+ Other
};
enum Flags {
@@ -57,9 +56,11 @@
static const int _max_covered_regions = 2;
Name _kind;
+ BarrierSet(Name kind) : _kind(kind) { }
+ ~BarrierSet() { }
+
public:
- BarrierSet() { _kind = Uninit; }
// To get around prohibition on RTTI.
BarrierSet::Name kind() { return _kind; }
virtual bool is_a(BarrierSet::Name bsn) = 0;
--- a/hotspot/src/share/vm/memory/cardTableModRefBS.cpp Fri Jan 30 16:56:05 2015 -0800
+++ b/hotspot/src/share/vm/memory/cardTableModRefBS.cpp Mon Feb 02 13:57:38 2015 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2015, 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
@@ -53,8 +53,8 @@
return align_size_up(_guard_index + 1, MAX2(_page_size, granularity));
}
-CardTableModRefBS::CardTableModRefBS(MemRegion whole_heap) :
- ModRefBarrierSet(),
+CardTableModRefBS::CardTableModRefBS(MemRegion whole_heap, BarrierSet::Name kind) :
+ ModRefBarrierSet(kind),
_whole_heap(whole_heap),
_guard_index(0),
_guard_region(),
@@ -72,8 +72,6 @@
_lowest_non_clean_base_chunk_index(NULL),
_last_LNC_resizing_collection(NULL)
{
- _kind = BarrierSet::CardTableModRef;
-
assert((uintptr_t(_whole_heap.start()) & (card_size - 1)) == 0, "heap must start at card boundary");
assert((uintptr_t(_whole_heap.end()) & (card_size - 1)) == 0, "heap must end at card boundary");
--- a/hotspot/src/share/vm/memory/cardTableModRefBS.hpp Fri Jan 30 16:56:05 2015 -0800
+++ b/hotspot/src/share/vm/memory/cardTableModRefBS.hpp Mon Feb 02 13:57:38 2015 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2015, 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
@@ -284,20 +284,22 @@
return bsn == BarrierSet::CardTableModRef || ModRefBarrierSet::is_a(bsn);
}
- CardTableModRefBS(MemRegion whole_heap);
- ~CardTableModRefBS();
-
virtual void initialize();
// *** Barrier set functions.
bool has_write_ref_pre_barrier() { return false; }
+protected:
+
+ CardTableModRefBS(MemRegion whole_heap, BarrierSet::Name kind);
+ ~CardTableModRefBS();
+
// Record a reference update. Note that these versions are precise!
// The scanning code has to handle the fact that the write barrier may be
// either precise or imprecise. We make non-virtual inline variants of
// these functions here for performance.
-protected:
+
void write_ref_field_work(oop obj, size_t offset, oop newVal);
virtual void write_ref_field_work(void* field, oop newVal, bool release = false);
public:
@@ -478,7 +480,7 @@
bool card_may_have_been_dirty(jbyte cv);
public:
CardTableModRefBSForCTRS(MemRegion whole_heap) :
- CardTableModRefBS(whole_heap) {}
+ CardTableModRefBS(whole_heap, BarrierSet::CardTableModRef) {}
void set_CTRS(CardTableRS* rs) { _rs = rs; }
};
--- a/hotspot/src/share/vm/memory/modRefBarrierSet.hpp Fri Jan 30 16:56:05 2015 -0800
+++ b/hotspot/src/share/vm/memory/modRefBarrierSet.hpp Mon Feb 02 13:57:38 2015 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2015, 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
@@ -37,8 +37,6 @@
class ModRefBarrierSet: public BarrierSet {
public:
- ModRefBarrierSet() { _kind = BarrierSet::ModRef; }
-
bool is_a(BarrierSet::Name bsn) {
return bsn == BarrierSet::ModRef;
}
@@ -59,7 +57,12 @@
void read_ref_field(void* field) {}
void read_prim_field(HeapWord* field, size_t bytes) {}
+
protected:
+
+ ModRefBarrierSet(BarrierSet::Name kind) : BarrierSet(kind) { }
+ ~ModRefBarrierSet() { }
+
virtual void write_ref_field_work(void* field, oop new_val, bool release = false) = 0;
public:
void write_prim_field(HeapWord* field, size_t bytes,
--- a/hotspot/src/share/vm/runtime/arguments.cpp Fri Jan 30 16:56:05 2015 -0800
+++ b/hotspot/src/share/vm/runtime/arguments.cpp Mon Feb 02 13:57:38 2015 +0100
@@ -2316,6 +2316,7 @@
status = status && verify_percentage(G1MaxNewSizePercent, "G1MaxNewSizePercent");
status = status && verify_interval(G1NewSizePercent, 0, G1MaxNewSizePercent, "G1NewSizePercent");
+ status = status && verify_percentage(G1ConfidencePercent, "G1ConfidencePercent");
status = status && verify_percentage(InitiatingHeapOccupancyPercent,
"InitiatingHeapOccupancyPercent");
status = status && verify_min_value(G1RefProcDrainInterval, 1,
--- a/hotspot/src/share/vm/runtime/mutexLocker.cpp Fri Jan 30 16:56:05 2015 -0800
+++ b/hotspot/src/share/vm/runtime/mutexLocker.cpp Mon Feb 02 13:57:38 2015 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2015, 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
@@ -120,7 +120,6 @@
Mutex* OldSets_lock = NULL;
Monitor* RootRegionScan_lock = NULL;
Mutex* MMUTracker_lock = NULL;
-Mutex* HotCardCache_lock = NULL;
Monitor* GCTaskManager_lock = NULL;
@@ -199,7 +198,6 @@
def(OldSets_lock , Mutex , leaf , true, Monitor::_safepoint_check_never);
def(RootRegionScan_lock , Monitor, leaf , true, Monitor::_safepoint_check_never);
def(MMUTracker_lock , Mutex , leaf , true, Monitor::_safepoint_check_never);
- def(HotCardCache_lock , Mutex , special , true, Monitor::_safepoint_check_never);
def(EvacFailureStack_lock , Mutex , nonleaf , true, Monitor::_safepoint_check_never);
def(StringDedupQueue_lock , Monitor, leaf, true, Monitor::_safepoint_check_never);
--- a/hotspot/src/share/vm/runtime/mutexLocker.hpp Fri Jan 30 16:56:05 2015 -0800
+++ b/hotspot/src/share/vm/runtime/mutexLocker.hpp Mon Feb 02 13:57:38 2015 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2015, 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
@@ -122,7 +122,6 @@
extern Monitor* RootRegionScan_lock; // used to notify that the CM threads have finished scanning the IM snapshot regions
extern Mutex* MMUTracker_lock; // protects the MMU
// tracker data structures
-extern Mutex* HotCardCache_lock; // protects the hot card cache
extern Mutex* Management_lock; // a lock used to serialize JVM management
extern Monitor* Service_lock; // a lock used for service thread operation
--- a/hotspot/test/TEST.groups Fri Jan 30 16:56:05 2015 -0800
+++ b/hotspot/test/TEST.groups Mon Feb 02 13:57:38 2015 +0100
@@ -224,6 +224,7 @@
gc/arguments/TestAlignmentToUseLargePages.java \
gc/arguments/TestG1HeapRegionSize.java \
gc/arguments/TestG1HeapSizeFlags.java \
+ gc/arguments/TestG1PercentageOptions.java \
gc/arguments/TestMaxHeapSizeTools.java \
gc/arguments/TestMaxNewSize.java \
gc/arguments/TestParallelGCThreads.java \
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/gc/arguments/TestG1PercentageOptions.java Mon Feb 02 13:57:38 2015 +0100
@@ -0,0 +1,89 @@
+/*
+* Copyright (c) 2015, 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
+* under the terms of the GNU General Public License version 2 only, as
+* published by the Free Software Foundation.
+*
+* This code is distributed in the hope that it will be useful, but WITHOUT
+* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+* version 2 for more details (a copy is included in the LICENSE file that
+* accompanied this code).
+*
+* You should have received a copy of the GNU General Public License version
+* 2 along with this work; if not, write to the Free Software Foundation,
+* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+*
+* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+* or visit www.oracle.com if you need additional information or have any
+* questions.
+*/
+
+/*
+ * @test TestG1PercentageOptions
+ * @key gc
+ * @bug 8068942
+ * @summary Test argument processing of various percentage options
+ * @library /testlibrary
+ * @run driver TestG1PercentageOptions
+ */
+
+import com.oracle.java.testlibrary.*;
+
+public class TestG1PercentageOptions {
+
+ private static final class OptionDescription {
+ public final String name;
+ public final String[] valid;
+ public final String[] invalid;
+
+ OptionDescription(String name_, String[] valid_, String[] invalid_) {
+ name = name_;
+ valid = valid_;
+ invalid = invalid_;
+ }
+ }
+
+ private static final String[] defaultValid = new String[] {
+ "0", "1", "50", "95", "100" };
+ private static final String[] defaultInvalid = new String[] {
+ "-10", "110", "bad" };
+
+ // All of the G1 product arguments that are percentages.
+ private static final OptionDescription[] percentOptions = new OptionDescription[] {
+ new OptionDescription("G1ConfidencePercent", defaultValid, defaultInvalid)
+ // Other percentage options are not yet validated by argument processing.
+ };
+
+ private static void check(String flag, boolean is_valid) throws Exception {
+ String[] flags = new String[] { "-XX:+UseG1GC", flag, "-version" };
+ ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(flags);
+ OutputAnalyzer output = new OutputAnalyzer(pb.start());
+ if (is_valid) {
+ output.shouldHaveExitValue(0);
+ } else {
+ output.shouldHaveExitValue(1);
+ }
+ }
+
+ private static
+ void check(String name, String value, boolean is_valid) throws Exception {
+ check("-XX:" + name + "=" + value, is_valid);
+ }
+
+ public static void main(String args[]) throws Exception {
+ for (OptionDescription option : percentOptions) {
+ for (String value : option.valid) {
+ check(option.name, value, true);
+ }
+ for (String value : option.invalid) {
+ check(option.name, value, false);
+ }
+ check("-XX:" + option.name, false);
+ check("-XX:+" + option.name, false);
+ check("-XX:-" + option.name, false);
+ }
+ }
+}