--- a/.hgtags-top-repo Tue Aug 06 10:10:39 2013 -0700
+++ b/.hgtags-top-repo Wed Jul 05 19:06:08 2017 +0200
@@ -222,3 +222,4 @@
0d0c983a817bbe8518a5ff201306334a8de267f2 jdk8-b98
59dc9da813794c924a0383c2a6241af94defdfed jdk8-b99
d2dcb110e9dbaf9903c05b211df800e78e4b394e jdk8-b100
+9f74a220677dc265a724515d8e2617548cef62f1 jdk8-b101
--- a/hotspot/.hgtags Tue Aug 06 10:10:39 2013 -0700
+++ b/hotspot/.hgtags Wed Jul 05 19:06:08 2017 +0200
@@ -363,3 +363,5 @@
9f71e36a471ae4a668e08827d33035963ed10c08 hs25-b42
5787fac72e760c6a5fd9efa113b0c75caf554136 jdk8-b100
46487ba40ff225654d0c51787ed3839bafcbd9f3 hs25-b43
+f6921c876db192bba389cec062855a66372da01c jdk8-b101
+530fe88b3b2c710f42810b3580d86a0d83ad6c1c hs25-b44
--- a/hotspot/make/bsd/makefiles/minimal1.make Tue Aug 06 10:10:39 2013 -0700
+++ b/hotspot/make/bsd/makefiles/minimal1.make Wed Jul 05 19:06:08 2017 +0200
@@ -24,16 +24,20 @@
TYPE=MINIMAL1
-INCLUDE_JVMTI ?= false
-INCLUDE_FPROF ?= false
-INCLUDE_VM_STRUCTS ?= false
-INCLUDE_JNI_CHECK ?= false
-INCLUDE_SERVICES ?= false
-INCLUDE_MANAGEMENT ?= false
-INCLUDE_ALL_GCS ?= false
-INCLUDE_NMT ?= false
-INCLUDE_TRACE ?= false
-INCLUDE_CDS ?= false
+# Force all variables to false, overriding any other
+# setting that may have occurred in the makefiles. These
+# can still be overridden by passing the variable as an
+# argument to 'make'
+INCLUDE_JVMTI := false
+INCLUDE_FPROF := false
+INCLUDE_VM_STRUCTS := false
+INCLUDE_JNI_CHECK := false
+INCLUDE_SERVICES := false
+INCLUDE_MANAGEMENT := false
+INCLUDE_ALL_GCS := false
+INCLUDE_NMT := false
+INCLUDE_TRACE := false
+INCLUDE_CDS := false
CXXFLAGS += -DMINIMAL_JVM -DCOMPILER1 -DVMTYPE=\"Minimal\"
CFLAGS += -DMINIMAL_JVM -DCOMPILER1 -DVMTYPE=\"Minimal\"
--- a/hotspot/make/hotspot_version Tue Aug 06 10:10:39 2013 -0700
+++ b/hotspot/make/hotspot_version Wed Jul 05 19:06:08 2017 +0200
@@ -35,7 +35,7 @@
HS_MAJOR_VER=25
HS_MINOR_VER=0
-HS_BUILD_NUMBER=43
+HS_BUILD_NUMBER=44
JDK_MAJOR_VER=1
JDK_MINOR_VER=8
--- a/hotspot/make/linux/makefiles/minimal1.make Tue Aug 06 10:10:39 2013 -0700
+++ b/hotspot/make/linux/makefiles/minimal1.make Wed Jul 05 19:06:08 2017 +0200
@@ -24,16 +24,20 @@
TYPE=MINIMAL1
-INCLUDE_JVMTI ?= false
-INCLUDE_FPROF ?= false
-INCLUDE_VM_STRUCTS ?= false
-INCLUDE_JNI_CHECK ?= false
-INCLUDE_SERVICES ?= false
-INCLUDE_MANAGEMENT ?= false
-INCLUDE_ALL_GCS ?= false
-INCLUDE_NMT ?= false
-INCLUDE_TRACE ?= false
-INCLUDE_CDS ?= false
+# Force all variables to false, overriding any other
+# setting that may have occurred in the makefiles. These
+# can still be overridden by passing the variable as an
+# argument to 'make'
+INCLUDE_JVMTI := false
+INCLUDE_FPROF := false
+INCLUDE_VM_STRUCTS := false
+INCLUDE_JNI_CHECK := false
+INCLUDE_SERVICES := false
+INCLUDE_MANAGEMENT := false
+INCLUDE_ALL_GCS := false
+INCLUDE_NMT := false
+INCLUDE_TRACE := false
+INCLUDE_CDS := false
CXXFLAGS += -DMINIMAL_JVM -DCOMPILER1 -DVMTYPE=\"Minimal\"
CFLAGS += -DMINIMAL_JVM -DCOMPILER1 -DVMTYPE=\"Minimal\"
--- a/hotspot/src/cpu/sparc/vm/c2_globals_sparc.hpp Tue Aug 06 10:10:39 2013 -0700
+++ b/hotspot/src/cpu/sparc/vm/c2_globals_sparc.hpp Wed Jul 05 19:06:08 2017 +0200
@@ -42,7 +42,7 @@
#else
define_pd_global(bool, ProfileInterpreter, true);
#endif // CC_INTERP
-define_pd_global(bool, TieredCompilation, false);
+define_pd_global(bool, TieredCompilation, trueInTiered);
define_pd_global(intx, CompileThreshold, 10000);
define_pd_global(intx, BackEdgeThreshold, 140000);
--- a/hotspot/src/cpu/x86/vm/c2_globals_x86.hpp Tue Aug 06 10:10:39 2013 -0700
+++ b/hotspot/src/cpu/x86/vm/c2_globals_x86.hpp Wed Jul 05 19:06:08 2017 +0200
@@ -44,7 +44,7 @@
#else
define_pd_global(bool, ProfileInterpreter, true);
#endif // CC_INTERP
-define_pd_global(bool, TieredCompilation, false);
+define_pd_global(bool, TieredCompilation, trueInTiered);
define_pd_global(intx, CompileThreshold, 10000);
define_pd_global(intx, BackEdgeThreshold, 100000);
--- a/hotspot/src/share/vm/ci/ciReplay.cpp Tue Aug 06 10:10:39 2013 -0700
+++ b/hotspot/src/share/vm/ci/ciReplay.cpp Wed Jul 05 19:06:08 2017 +0200
@@ -299,7 +299,7 @@
Symbol* method_signature = parse_symbol(CHECK_NULL);
Method* m = k->find_method(method_name, method_signature);
if (m == NULL) {
- report_error("can't find method");
+ report_error("Can't find method");
}
return m;
}
@@ -398,8 +398,8 @@
// compile <klass> <name> <signature> <entry_bci> <comp_level>
void process_compile(TRAPS) {
- // methodHandle method;
Method* method = parse_method(CHECK);
+ if (had_error()) return;
int entry_bci = parse_int("entry_bci");
const char* comp_level_label = "comp_level";
int comp_level = parse_int(comp_level_label);
@@ -440,6 +440,7 @@
//
void process_ciMethod(TRAPS) {
Method* method = parse_method(CHECK);
+ if (had_error()) return;
ciMethodRecord* rec = new_ciMethod(method);
rec->invocation_counter = parse_int("invocation_counter");
rec->backedge_counter = parse_int("backedge_counter");
@@ -451,6 +452,7 @@
// ciMethodData <klass> <name> <signature> <state> <current mileage> orig <length> # # ... data <length> # # ... oops <length>
void process_ciMethodData(TRAPS) {
Method* method = parse_method(CHECK);
+ if (had_error()) return;
/* jsut copied from Method, to build interpret data*/
if (InstanceRefKlass::owns_pending_list_lock((JavaThread*)THREAD)) {
return;
--- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsOopClosures.hpp Tue Aug 06 10:10:39 2013 -0700
+++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsOopClosures.hpp Wed Jul 05 19:06:08 2017 +0200
@@ -122,6 +122,22 @@
}
};
+class Par_MarkRefsIntoClosure: public CMSOopsInGenClosure {
+ private:
+ const MemRegion _span;
+ CMSBitMap* _bitMap;
+ protected:
+ DO_OOP_WORK_DEFN
+ public:
+ Par_MarkRefsIntoClosure(MemRegion span, CMSBitMap* bitMap);
+ virtual void do_oop(oop* p);
+ virtual void do_oop(narrowOop* p);
+
+ Prefetch::style prefetch_style() {
+ return Prefetch::do_read;
+ }
+};
+
// A variant of the above used in certain kinds of CMS
// marking verification.
class MarkRefsIntoVerifyClosure: public CMSOopsInGenClosure {
--- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp Tue Aug 06 10:10:39 2013 -0700
+++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp Wed Jul 05 19:06:08 2017 +0200
@@ -569,6 +569,7 @@
_restart_addr(NULL),
_overflow_list(NULL),
_stats(cmsGen),
+ _eden_chunk_lock(new Mutex(Mutex::leaf + 1, "CMS_eden_chunk_lock", true)),
_eden_chunk_array(NULL), // may be set in ctor body
_eden_chunk_capacity(0), // -- ditto --
_eden_chunk_index(0), // -- ditto --
@@ -732,7 +733,7 @@
assert(_eden_chunk_array != NULL || _eden_chunk_capacity == 0, "Error");
// Support for parallelizing survivor space rescan
- if (CMSParallelRemarkEnabled && CMSParallelSurvivorRemarkEnabled) {
+ if ((CMSParallelRemarkEnabled && CMSParallelSurvivorRemarkEnabled) || CMSParallelInitialMarkEnabled) {
const size_t max_plab_samples =
((DefNewGeneration*)_young_gen)->max_survivor_size()/MinTLABSize;
@@ -2137,6 +2138,39 @@
}
+void CMSCollector::print_eden_and_survivor_chunk_arrays() {
+ DefNewGeneration* dng = _young_gen->as_DefNewGeneration();
+ EdenSpace* eden_space = dng->eden();
+ ContiguousSpace* from_space = dng->from();
+ ContiguousSpace* to_space = dng->to();
+ // Eden
+ if (_eden_chunk_array != NULL) {
+ gclog_or_tty->print_cr("eden " PTR_FORMAT "-" PTR_FORMAT "-" PTR_FORMAT "(" SIZE_FORMAT ")",
+ eden_space->bottom(), eden_space->top(),
+ eden_space->end(), eden_space->capacity());
+ gclog_or_tty->print_cr("_eden_chunk_index=" SIZE_FORMAT ", "
+ "_eden_chunk_capacity=" SIZE_FORMAT,
+ _eden_chunk_index, _eden_chunk_capacity);
+ for (size_t i = 0; i < _eden_chunk_index; i++) {
+ gclog_or_tty->print_cr("_eden_chunk_array[" SIZE_FORMAT "]=" PTR_FORMAT,
+ i, _eden_chunk_array[i]);
+ }
+ }
+ // Survivor
+ if (_survivor_chunk_array != NULL) {
+ gclog_or_tty->print_cr("survivor " PTR_FORMAT "-" PTR_FORMAT "-" PTR_FORMAT "(" SIZE_FORMAT ")",
+ from_space->bottom(), from_space->top(),
+ from_space->end(), from_space->capacity());
+ gclog_or_tty->print_cr("_survivor_chunk_index=" SIZE_FORMAT ", "
+ "_survivor_chunk_capacity=" SIZE_FORMAT,
+ _survivor_chunk_index, _survivor_chunk_capacity);
+ for (size_t i = 0; i < _survivor_chunk_index; i++) {
+ gclog_or_tty->print_cr("_survivor_chunk_array[" SIZE_FORMAT "]=" PTR_FORMAT,
+ i, _survivor_chunk_array[i]);
+ }
+ }
+}
+
void CMSCollector::getFreelistLocks() const {
// Get locks for all free lists in all generations that this
// collector is responsible for
@@ -3549,6 +3583,31 @@
// CMS work
+// The common parts of CMSParInitialMarkTask and CMSParRemarkTask.
+class CMSParMarkTask : public AbstractGangTask {
+ protected:
+ CMSCollector* _collector;
+ int _n_workers;
+ CMSParMarkTask(const char* name, CMSCollector* collector, int n_workers) :
+ AbstractGangTask(name),
+ _collector(collector),
+ _n_workers(n_workers) {}
+ // Work method in support of parallel rescan ... of young gen spaces
+ void do_young_space_rescan(uint worker_id, OopsInGenClosure* cl,
+ ContiguousSpace* space,
+ HeapWord** chunk_array, size_t chunk_top);
+ void work_on_young_gen_roots(uint worker_id, OopsInGenClosure* cl);
+};
+
+// Parallel initial mark task
+class CMSParInitialMarkTask: public CMSParMarkTask {
+ public:
+ CMSParInitialMarkTask(CMSCollector* collector, int n_workers) :
+ CMSParMarkTask("Scan roots and young gen for initial mark in parallel",
+ collector, n_workers) {}
+ void work(uint worker_id);
+};
+
// Checkpoint the roots into this generation from outside
// this generation. [Note this initial checkpoint need only
// be approximate -- we'll do a catch up phase subsequently.]
@@ -3646,19 +3705,42 @@
// the klasses. The claimed marks need to be cleared before marking starts.
ClassLoaderDataGraph::clear_claimed_marks();
- CMKlassClosure klass_closure(¬Older);
+ if (CMSPrintEdenSurvivorChunks) {
+ print_eden_and_survivor_chunk_arrays();
+ }
+
{
COMPILER2_PRESENT(DerivedPointerTableDeactivate dpt_deact;)
- gch->rem_set()->prepare_for_younger_refs_iterate(false); // Not parallel.
- gch->gen_process_strong_roots(_cmsGen->level(),
- true, // younger gens are roots
- true, // activate StrongRootsScope
- false, // not scavenging
- SharedHeap::ScanningOption(roots_scanning_options()),
- ¬Older,
- true, // walk all of code cache if (so & SO_CodeCache)
- NULL,
- &klass_closure);
+ if (CMSParallelInitialMarkEnabled && CollectedHeap::use_parallel_gc_threads()) {
+ // The parallel version.
+ FlexibleWorkGang* workers = gch->workers();
+ assert(workers != NULL, "Need parallel worker threads.");
+ int n_workers = workers->active_workers();
+ CMSParInitialMarkTask tsk(this, n_workers);
+ gch->set_par_threads(n_workers);
+ initialize_sequential_subtasks_for_young_gen_rescan(n_workers);
+ if (n_workers > 1) {
+ GenCollectedHeap::StrongRootsScope srs(gch);
+ workers->run_task(&tsk);
+ } else {
+ GenCollectedHeap::StrongRootsScope srs(gch);
+ tsk.work(0);
+ }
+ gch->set_par_threads(0);
+ } else {
+ // The serial version.
+ CMKlassClosure klass_closure(¬Older);
+ gch->rem_set()->prepare_for_younger_refs_iterate(false); // Not parallel.
+ gch->gen_process_strong_roots(_cmsGen->level(),
+ true, // younger gens are roots
+ true, // activate StrongRootsScope
+ false, // not scavenging
+ SharedHeap::ScanningOption(roots_scanning_options()),
+ ¬Older,
+ true, // walk all of code cache if (so & SO_CodeCache)
+ NULL,
+ &klass_closure);
+ }
}
// Clear mod-union table; it will be dirtied in the prologue of
@@ -4417,7 +4499,9 @@
verify_overflow_empty();
_abort_preclean = false;
if (CMSPrecleaningEnabled) {
- _eden_chunk_index = 0;
+ if (!CMSEdenChunksRecordAlways) {
+ _eden_chunk_index = 0;
+ }
size_t used = get_eden_used();
size_t capacity = get_eden_capacity();
// Don't start sampling unless we will get sufficiently
@@ -4526,7 +4610,9 @@
if (!_start_sampling) {
return;
}
- if (_eden_chunk_array) {
+ // When CMSEdenChunksRecordAlways is true, the eden chunk array
+ // is populated by the young generation.
+ if (_eden_chunk_array != NULL && !CMSEdenChunksRecordAlways) {
if (_eden_chunk_index < _eden_chunk_capacity) {
_eden_chunk_array[_eden_chunk_index] = *_top_addr; // take sample
assert(_eden_chunk_array[_eden_chunk_index] <= *_end_addr,
@@ -5010,6 +5096,10 @@
// Update the saved marks which may affect the root scans.
gch->save_marks();
+ if (CMSPrintEdenSurvivorChunks) {
+ print_eden_and_survivor_chunk_arrays();
+ }
+
{
COMPILER2_PRESENT(DerivedPointerTableDeactivate dpt_deact;)
@@ -5116,10 +5206,53 @@
}
}
+void CMSParInitialMarkTask::work(uint worker_id) {
+ elapsedTimer _timer;
+ ResourceMark rm;
+ HandleMark hm;
+
+ // ---------- scan from roots --------------
+ _timer.start();
+ GenCollectedHeap* gch = GenCollectedHeap::heap();
+ Par_MarkRefsIntoClosure par_mri_cl(_collector->_span, &(_collector->_markBitMap));
+ CMKlassClosure klass_closure(&par_mri_cl);
+
+ // ---------- young gen roots --------------
+ {
+ work_on_young_gen_roots(worker_id, &par_mri_cl);
+ _timer.stop();
+ if (PrintCMSStatistics != 0) {
+ gclog_or_tty->print_cr(
+ "Finished young gen initial mark scan work in %dth thread: %3.3f sec",
+ worker_id, _timer.seconds());
+ }
+ }
+
+ // ---------- remaining roots --------------
+ _timer.reset();
+ _timer.start();
+ gch->gen_process_strong_roots(_collector->_cmsGen->level(),
+ false, // yg was scanned above
+ false, // this is parallel code
+ false, // not scavenging
+ SharedHeap::ScanningOption(_collector->CMSCollector::roots_scanning_options()),
+ &par_mri_cl,
+ true, // walk all of code cache if (so & SO_CodeCache)
+ NULL,
+ &klass_closure);
+ assert(_collector->should_unload_classes()
+ || (_collector->CMSCollector::roots_scanning_options() & SharedHeap::SO_CodeCache),
+ "if we didn't scan the code cache, we have to be ready to drop nmethods with expired weak oops");
+ _timer.stop();
+ if (PrintCMSStatistics != 0) {
+ gclog_or_tty->print_cr(
+ "Finished remaining root initial mark scan work in %dth thread: %3.3f sec",
+ worker_id, _timer.seconds());
+ }
+}
+
// Parallel remark task
-class CMSParRemarkTask: public AbstractGangTask {
- CMSCollector* _collector;
- int _n_workers;
+class CMSParRemarkTask: public CMSParMarkTask {
CompactibleFreeListSpace* _cms_space;
// The per-thread work queues, available here for stealing.
@@ -5133,10 +5266,9 @@
CompactibleFreeListSpace* cms_space,
int n_workers, FlexibleWorkGang* workers,
OopTaskQueueSet* task_queues):
- AbstractGangTask("Rescan roots and grey objects in parallel"),
- _collector(collector),
+ CMSParMarkTask("Rescan roots and grey objects in parallel",
+ collector, n_workers),
_cms_space(cms_space),
- _n_workers(n_workers),
_task_queues(task_queues),
_term(n_workers, task_queues) { }
@@ -5150,11 +5282,6 @@
void work(uint worker_id);
private:
- // Work method in support of parallel rescan ... of young gen spaces
- void do_young_space_rescan(int i, Par_MarkRefsIntoAndScanClosure* cl,
- ContiguousSpace* space,
- HeapWord** chunk_array, size_t chunk_top);
-
// ... of dirty cards in old space
void do_dirty_card_rescan_tasks(CompactibleFreeListSpace* sp, int i,
Par_MarkRefsIntoAndScanClosure* cl);
@@ -5186,6 +5313,25 @@
}
};
+void CMSParMarkTask::work_on_young_gen_roots(uint worker_id, OopsInGenClosure* cl) {
+ DefNewGeneration* dng = _collector->_young_gen->as_DefNewGeneration();
+ EdenSpace* eden_space = dng->eden();
+ ContiguousSpace* from_space = dng->from();
+ ContiguousSpace* to_space = dng->to();
+
+ HeapWord** eca = _collector->_eden_chunk_array;
+ size_t ect = _collector->_eden_chunk_index;
+ HeapWord** sca = _collector->_survivor_chunk_array;
+ size_t sct = _collector->_survivor_chunk_index;
+
+ assert(ect <= _collector->_eden_chunk_capacity, "out of bounds");
+ assert(sct <= _collector->_survivor_chunk_capacity, "out of bounds");
+
+ do_young_space_rescan(worker_id, cl, to_space, NULL, 0);
+ do_young_space_rescan(worker_id, cl, from_space, sca, sct);
+ do_young_space_rescan(worker_id, cl, eden_space, eca, ect);
+}
+
// work_queue(i) is passed to the closure
// Par_MarkRefsIntoAndScanClosure. The "i" parameter
// also is passed to do_dirty_card_rescan_tasks() and to
@@ -5210,23 +5356,7 @@
// work first.
// ---------- young gen roots --------------
{
- DefNewGeneration* dng = _collector->_young_gen->as_DefNewGeneration();
- EdenSpace* eden_space = dng->eden();
- ContiguousSpace* from_space = dng->from();
- ContiguousSpace* to_space = dng->to();
-
- HeapWord** eca = _collector->_eden_chunk_array;
- size_t ect = _collector->_eden_chunk_index;
- HeapWord** sca = _collector->_survivor_chunk_array;
- size_t sct = _collector->_survivor_chunk_index;
-
- assert(ect <= _collector->_eden_chunk_capacity, "out of bounds");
- assert(sct <= _collector->_survivor_chunk_capacity, "out of bounds");
-
- do_young_space_rescan(worker_id, &par_mrias_cl, to_space, NULL, 0);
- do_young_space_rescan(worker_id, &par_mrias_cl, from_space, sca, sct);
- do_young_space_rescan(worker_id, &par_mrias_cl, eden_space, eca, ect);
-
+ work_on_young_gen_roots(worker_id, &par_mrias_cl);
_timer.stop();
if (PrintCMSStatistics != 0) {
gclog_or_tty->print_cr(
@@ -5334,8 +5464,8 @@
// Note that parameter "i" is not used.
void
-CMSParRemarkTask::do_young_space_rescan(int i,
- Par_MarkRefsIntoAndScanClosure* cl, ContiguousSpace* space,
+CMSParMarkTask::do_young_space_rescan(uint worker_id,
+ OopsInGenClosure* cl, ContiguousSpace* space,
HeapWord** chunk_array, size_t chunk_top) {
// Until all tasks completed:
// . claim an unclaimed task
@@ -5530,6 +5660,32 @@
"Else our work is not yet done");
}
+// Record object boundaries in _eden_chunk_array by sampling the eden
+// top in the slow-path eden object allocation code path and record
+// the boundaries, if CMSEdenChunksRecordAlways is true. If
+// CMSEdenChunksRecordAlways is false, we use the other asynchronous
+// sampling in sample_eden() that activates during the part of the
+// preclean phase.
+void CMSCollector::sample_eden_chunk() {
+ if (CMSEdenChunksRecordAlways && _eden_chunk_array != NULL) {
+ if (_eden_chunk_lock->try_lock()) {
+ // Record a sample. This is the critical section. The contents
+ // of the _eden_chunk_array have to be non-decreasing in the
+ // address order.
+ _eden_chunk_array[_eden_chunk_index] = *_top_addr;
+ assert(_eden_chunk_array[_eden_chunk_index] <= *_end_addr,
+ "Unexpected state of Eden");
+ if (_eden_chunk_index == 0 ||
+ ((_eden_chunk_array[_eden_chunk_index] > _eden_chunk_array[_eden_chunk_index-1]) &&
+ (pointer_delta(_eden_chunk_array[_eden_chunk_index],
+ _eden_chunk_array[_eden_chunk_index-1]) >= CMSSamplingGrain))) {
+ _eden_chunk_index++; // commit sample
+ }
+ _eden_chunk_lock->unlock();
+ }
+ }
+}
+
// Return a thread-local PLAB recording array, as appropriate.
void* CMSCollector::get_data_recorder(int thr_num) {
if (_survivor_plab_array != NULL &&
@@ -5553,12 +5709,13 @@
// Merge the per-thread plab arrays into the global survivor chunk
// array which will provide the partitioning of the survivor space
-// for CMS rescan.
+// for CMS initial scan and rescan.
void CMSCollector::merge_survivor_plab_arrays(ContiguousSpace* surv,
int no_of_gc_threads) {
assert(_survivor_plab_array != NULL, "Error");
assert(_survivor_chunk_array != NULL, "Error");
- assert(_collectorState == FinalMarking, "Error");
+ assert(_collectorState == FinalMarking ||
+ (CMSParallelInitialMarkEnabled && _collectorState == InitialMarking), "Error");
for (int j = 0; j < no_of_gc_threads; j++) {
_cursor[j] = 0;
}
@@ -5621,7 +5778,7 @@
}
// Set up the space's par_seq_tasks structure for work claiming
-// for parallel rescan of young gen.
+// for parallel initial scan and rescan of young gen.
// See ParRescanTask where this is currently used.
void
CMSCollector::
@@ -6748,6 +6905,28 @@
void MarkRefsIntoClosure::do_oop(oop* p) { MarkRefsIntoClosure::do_oop_work(p); }
void MarkRefsIntoClosure::do_oop(narrowOop* p) { MarkRefsIntoClosure::do_oop_work(p); }
+Par_MarkRefsIntoClosure::Par_MarkRefsIntoClosure(
+ MemRegion span, CMSBitMap* bitMap):
+ _span(span),
+ _bitMap(bitMap)
+{
+ assert(_ref_processor == NULL, "deliberately left NULL");
+ assert(_bitMap->covers(_span), "_bitMap/_span mismatch");
+}
+
+void Par_MarkRefsIntoClosure::do_oop(oop obj) {
+ // if p points into _span, then mark corresponding bit in _markBitMap
+ assert(obj->is_oop(), "expected an oop");
+ HeapWord* addr = (HeapWord*)obj;
+ if (_span.contains(addr)) {
+ // this should be made more efficient
+ _bitMap->par_mark(addr);
+ }
+}
+
+void Par_MarkRefsIntoClosure::do_oop(oop* p) { Par_MarkRefsIntoClosure::do_oop_work(p); }
+void Par_MarkRefsIntoClosure::do_oop(narrowOop* p) { Par_MarkRefsIntoClosure::do_oop_work(p); }
+
// A variant of the above, used for CMS marking verification.
MarkRefsIntoVerifyClosure::MarkRefsIntoVerifyClosure(
MemRegion span, CMSBitMap* verification_bm, CMSBitMap* cms_bm):
@@ -9305,7 +9484,6 @@
return;
}
}
-
// Transfer some number of overflown objects to usual marking
// stack. Return true if some objects were transferred.
bool MarkRefsIntoAndScanClosure::take_from_overflow_list() {
@@ -9377,4 +9555,3 @@
ShouldNotReachHere();
}
}
-
--- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp Tue Aug 06 10:10:39 2013 -0700
+++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp Wed Jul 05 19:06:08 2017 +0200
@@ -515,6 +515,8 @@
friend class ConcurrentMarkSweepThread;
friend class ConcurrentMarkSweepGeneration;
friend class CompactibleFreeListSpace;
+ friend class CMSParMarkTask;
+ friend class CMSParInitialMarkTask;
friend class CMSParRemarkTask;
friend class CMSConcMarkingTask;
friend class CMSRefProcTaskProxy;
@@ -749,6 +751,7 @@
Generation* _young_gen; // the younger gen
HeapWord** _top_addr; // ... Top of Eden
HeapWord** _end_addr; // ... End of Eden
+ Mutex* _eden_chunk_lock;
HeapWord** _eden_chunk_array; // ... Eden partitioning array
size_t _eden_chunk_index; // ... top (exclusive) of array
size_t _eden_chunk_capacity; // ... max entries in array
@@ -950,6 +953,7 @@
// Support for parallel remark of survivor space
void* get_data_recorder(int thr_num);
+ void sample_eden_chunk();
CMSBitMap* markBitMap() { return &_markBitMap; }
void directAllocated(HeapWord* start, size_t size);
@@ -1027,6 +1031,8 @@
// Initialization errors
bool completed_initialization() { return _completed_initialization; }
+
+ void print_eden_and_survivor_chunk_arrays();
};
class CMSExpansionCause : public AllStatic {
@@ -1317,6 +1323,10 @@
//Delegate to collector
return collector()->get_data_recorder(thr_num);
}
+ void sample_eden_chunk() {
+ //Delegate to collector
+ return collector()->sample_eden_chunk();
+ }
// Printing
const char* name() const;
--- a/hotspot/src/share/vm/gc_implementation/g1/g1_globals.hpp Tue Aug 06 10:10:39 2013 -0700
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1_globals.hpp Wed Jul 05 19:06:08 2017 +0200
@@ -96,11 +96,6 @@
"the buffer will be enqueued for processing. A value of 0 " \
"specifies that mutator threads should not do such filtering.") \
\
- develop(intx, G1ExtraRegionSurvRate, 33, \
- "If the young survival rate is S, and there's room left in " \
- "to-space, we will allow regions whose survival rate is up to " \
- "S + (1 - S)*X, where X is this parameter (as a fraction.)") \
- \
develop(bool, G1SATBPrintStubs, false, \
"If true, print generated stubs for the SATB barrier") \
\
@@ -110,9 +105,6 @@
develop(bool, G1RSBarrierRegionFilter, true, \
"If true, generate region filtering code in RS barrier") \
\
- develop(bool, G1RSBarrierNullFilter, true, \
- "If true, generate null-pointer filtering code in RS barrier") \
- \
develop(bool, G1DeferredRSUpdate, true, \
"If true, use deferred RS updates") \
\
@@ -120,9 +112,6 @@
"If true, verify that no dirty cards remain after RS log " \
"processing.") \
\
- develop(bool, G1RSCountHisto, false, \
- "If true, print a histogram of RS occupancies after each pause") \
- \
diagnostic(bool, G1PrintRegionLivenessInfo, false, \
"Prints the liveness information for all regions in the heap " \
"at the end of a marking cycle.") \
@@ -169,9 +158,6 @@
product(uintx, G1ConcRSHotCardLimit, 4, \
"The threshold that defines (>=) a hot card.") \
\
- develop(bool, G1PrintOopAppls, false, \
- "When true, print applications of closures to external locs.") \
- \
develop(intx, G1RSetRegionEntriesBase, 256, \
"Max number of regions in a fine-grain table per MB.") \
\
--- a/hotspot/src/share/vm/gc_implementation/g1/heapRegion.cpp Tue Aug 06 10:10:39 2013 -0700
+++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegion.cpp Wed Jul 05 19:06:08 2017 +0200
@@ -314,6 +314,11 @@
region_size = MAX_REGION_SIZE;
}
+ if (region_size != G1HeapRegionSize) {
+ // Update the flag to make sure that PrintFlagsFinal logs the correct value
+ FLAG_SET_ERGO(uintx, G1HeapRegionSize, region_size);
+ }
+
// And recalculate the log.
region_size_log = log2_long((jlong) region_size);
--- a/hotspot/src/share/vm/memory/defNewGeneration.cpp Tue Aug 06 10:10:39 2013 -0700
+++ b/hotspot/src/share/vm/memory/defNewGeneration.cpp Wed Jul 05 19:06:08 2017 +0200
@@ -1033,6 +1033,9 @@
// have to use it here, as well.
HeapWord* result = eden()->par_allocate(word_size);
if (result != NULL) {
+ if (CMSEdenChunksRecordAlways && _next_gen != NULL) {
+ _next_gen->sample_eden_chunk();
+ }
return result;
}
do {
@@ -1063,13 +1066,19 @@
// circular dependency at compile time.
if (result == NULL) {
result = allocate_from_space(word_size);
+ } else if (CMSEdenChunksRecordAlways && _next_gen != NULL) {
+ _next_gen->sample_eden_chunk();
}
return result;
}
HeapWord* DefNewGeneration::par_allocate(size_t word_size,
bool is_tlab) {
- return eden()->par_allocate(word_size);
+ HeapWord* res = eden()->par_allocate(word_size);
+ if (CMSEdenChunksRecordAlways && _next_gen != NULL) {
+ _next_gen->sample_eden_chunk();
+ }
+ return res;
}
void DefNewGeneration::gc_prologue(bool full) {
--- a/hotspot/src/share/vm/memory/generation.hpp Tue Aug 06 10:10:39 2013 -0700
+++ b/hotspot/src/share/vm/memory/generation.hpp Wed Jul 05 19:06:08 2017 +0200
@@ -455,6 +455,7 @@
// expected to be GC worker thread-local, with the worker index
// indicated by "thr_num".
virtual void* get_data_recorder(int thr_num) { return NULL; }
+ virtual void sample_eden_chunk() {}
// Some generations may require some cleanup actions before allowing
// a verification.
--- a/hotspot/src/share/vm/memory/metaspace.cpp Tue Aug 06 10:10:39 2013 -0700
+++ b/hotspot/src/share/vm/memory/metaspace.cpp Wed Jul 05 19:06:08 2017 +0200
@@ -2254,10 +2254,11 @@
void SpaceManager::deallocate(MetaWord* p, size_t word_size) {
assert_lock_strong(_lock);
+ size_t raw_word_size = get_raw_word_size(word_size);
size_t min_size = TreeChunk<Metablock, FreeList>::min_size();
- assert(word_size >= min_size,
+ assert(raw_word_size >= min_size,
err_msg("Should not deallocate dark matter " SIZE_FORMAT, word_size));
- block_freelists()->return_block(p, word_size);
+ block_freelists()->return_block(p, raw_word_size);
}
// Adds a chunk to the list of chunks in use.
--- a/hotspot/src/share/vm/memory/sharedHeap.cpp Tue Aug 06 10:10:39 2013 -0700
+++ b/hotspot/src/share/vm/memory/sharedHeap.cpp Wed Jul 05 19:06:08 2017 +0200
@@ -65,7 +65,8 @@
}
_sh = this; // ch is static, should be set only once.
if ((UseParNewGC ||
- (UseConcMarkSweepGC && CMSParallelRemarkEnabled) ||
+ (UseConcMarkSweepGC && (CMSParallelInitialMarkEnabled ||
+ CMSParallelRemarkEnabled)) ||
UseG1GC) &&
ParallelGCThreads > 0) {
_workers = new FlexibleWorkGang("Parallel GC Threads", ParallelGCThreads,
--- a/hotspot/src/share/vm/runtime/arguments.cpp Tue Aug 06 10:10:39 2013 -0700
+++ b/hotspot/src/share/vm/runtime/arguments.cpp Wed Jul 05 19:06:08 2017 +0200
@@ -1891,6 +1891,10 @@
warning("Using MaxGCMinorPauseMillis as minor pause goal is deprecated"
"and will likely be removed in future release");
}
+ if (FLAG_IS_CMDLINE(DefaultMaxRAMFraction)) {
+ warning("DefaultMaxRAMFraction is deprecated and will likely be removed in a future release. "
+ "Use MaxRAMFraction instead.");
+ }
}
// Check stack pages settings
--- a/hotspot/src/share/vm/runtime/globals.hpp Tue Aug 06 10:10:39 2013 -0700
+++ b/hotspot/src/share/vm/runtime/globals.hpp Wed Jul 05 19:06:08 2017 +0200
@@ -1689,6 +1689,9 @@
product(bool, CMSAbortSemantics, false, \
"Whether abort-on-overflow semantics is implemented") \
\
+ product(bool, CMSParallelInitialMarkEnabled, true, \
+ "Use the parallel initial mark.") \
+ \
product(bool, CMSParallelRemarkEnabled, true, \
"Whether parallel remark enabled (only if ParNewGC)") \
\
@@ -1700,6 +1703,14 @@
"Whether to always record survivor space PLAB bdries" \
" (effective only if CMSParallelSurvivorRemarkEnabled)") \
\
+ product(bool, CMSEdenChunksRecordAlways, true, \
+ "Whether to always record eden chunks used for " \
+ "the parallel initial mark or remark of eden" ) \
+ \
+ product(bool, CMSPrintEdenSurvivorChunks, false, \
+ "Print the eden and the survivor chunks used for the parallel " \
+ "initial mark or remark of the eden/survivor spaces") \
+ \
product(bool, CMSConcurrentMTEnabled, true, \
"Whether multi-threaded concurrent work enabled (if ParNewGC)") \
\
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/gc/arguments/TestG1HeapRegionSize.java Wed Jul 05 19:06:08 2017 +0200
@@ -0,0 +1,64 @@
+/*
+* Copyright (c) 2013, 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 TestG1HeapRegionSize
+ * @key gc
+ * @bug 8021879
+ * @summary Verify that the flag G1HeapRegionSize is updated properly
+ * @run main/othervm -Xmx64m TestG1HeapRegionSize 1048576
+ * @run main/othervm -XX:G1HeapRegionSize=2m -Xmx64m TestG1HeapRegionSize 2097152
+ * @run main/othervm -XX:G1HeapRegionSize=3m -Xmx64m TestG1HeapRegionSize 2097152
+ * @run main/othervm -XX:G1HeapRegionSize=64m -Xmx256m TestG1HeapRegionSize 33554432
+ */
+
+import sun.management.ManagementFactoryHelper;
+import com.sun.management.HotSpotDiagnosticMXBean;
+import com.sun.management.VMOption;
+
+public class TestG1HeapRegionSize {
+
+ public static void main(String[] args) {
+ HotSpotDiagnosticMXBean diagnostic = ManagementFactoryHelper.getDiagnosticMXBean();
+
+ VMOption option = diagnostic.getVMOption("UseG1GC");
+ if (option.getValue().equals("false")) {
+ System.out.println("Skipping this test. It is only a G1 test.");
+ return;
+ }
+
+ String expectedValue = getExpectedValue(args);
+ option = diagnostic.getVMOption("G1HeapRegionSize");
+ if (!expectedValue.equals(option.getValue())) {
+ throw new RuntimeException("Wrong value for G1HeapRegionSize. Expected " + expectedValue + " but got " + option.getValue());
+ }
+ }
+
+ private static String getExpectedValue(String[] args) {
+ if (args.length != 1) {
+ throw new RuntimeException("Wrong number of arguments. Expected 1 but got " + args.length);
+ }
+ return args[0];
+ }
+
+}
--- a/hotspot/test/gc/g1/TestPrintRegionRememberedSetInfo.java Tue Aug 06 10:10:39 2013 -0700
+++ b/hotspot/test/gc/g1/TestPrintRegionRememberedSetInfo.java Wed Jul 05 19:06:08 2017 +0200
@@ -27,7 +27,7 @@
* @bug 8014240
* @summary Test output of G1PrintRegionRememberedSetInfo
* @library /testlibrary
- * @build TestPrintRegionRememberedSetInfo
+ * @run main TestPrintRegionRememberedSetInfo
* @author thomas.schatzl@oracle.com
*/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/gc/startup_warnings/TestDefaultMaxRAMFraction.java Wed Jul 05 19:06:08 2017 +0200
@@ -0,0 +1,44 @@
+/*
+* Copyright (c) 2013, 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 TestDefaultMaxRAMFraction
+* @key gc
+* @bug 8021967
+* @summary Test that the deprecated TestDefaultMaxRAMFraction flag print a warning message
+* @library /testlibrary
+*/
+
+import com.oracle.java.testlibrary.OutputAnalyzer;
+import com.oracle.java.testlibrary.ProcessTools;
+
+public class TestDefaultMaxRAMFraction {
+ public static void main(String[] args) throws Exception {
+ ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-XX:DefaultMaxRAMFraction=4", "-version");
+ OutputAnalyzer output = new OutputAnalyzer(pb.start());
+ output.shouldContain("warning: DefaultMaxRAMFraction is deprecated and will likely be removed in a future release. Use MaxRAMFraction instead.");
+ output.shouldNotContain("error");
+ output.shouldHaveExitValue(0);
+ }
+
+}
--- a/hotspot/test/runtime/6929067/Test6929067.sh Tue Aug 06 10:10:39 2013 -0700
+++ b/hotspot/test/runtime/6929067/Test6929067.sh Wed Jul 05 19:06:08 2017 +0200
@@ -3,6 +3,7 @@
##
## @test Test6929067.sh
## @bug 6929067
+## @bug 8021296
## @summary Stack guard pages should be removed when thread is detached
## @compile T.java
## @run shell Test6929067.sh
@@ -21,6 +22,11 @@
OS=`uname -s`
case "$OS" in
Linux)
+ gcc_cmd=`which gcc`
+ if [ "x$gcc_cmd" == "x" ]; then
+ echo "WARNING: gcc not found. Cannot execute test." 2>&1
+ exit 0;
+ fi
NULL=/dev/null
PS=":"
FS="/"
@@ -119,10 +125,10 @@
# Check to ensure you have a /usr/lib/libpthread.so if you don't please look
# for /usr/lib/`uname -m`-linux-gnu version ensure to add that path to below compilation.
-gcc -DLINUX ${COMP_FLAG} -o invoke \
- -I${COMPILEJAVA}/include -I${COMPILEJAVA}/include/linux \
- -L${COMPILEJAVA}/jre/lib/${ARCH}/${VMTYPE} \
- -ljvm -lpthread invoke.c
+$gcc_cmd -DLINUX ${COMP_FLAG} -o invoke \
+ -I${COMPILEJAVA}/include -I${COMPILEJAVA}/include/linux \
+ -L${COMPILEJAVA}/jre/lib/${ARCH}/${VMTYPE} \
+ -ljvm -lpthread invoke.c
./invoke
exit $?
--- a/hotspot/test/runtime/7107135/Test7107135.sh Tue Aug 06 10:10:39 2013 -0700
+++ b/hotspot/test/runtime/7107135/Test7107135.sh Wed Jul 05 19:06:08 2017 +0200
@@ -27,6 +27,7 @@
##
## @test Test7107135.sh
## @bug 7107135
+## @bug 8021296
## @summary Stack guard pages lost after loading library with executable stack.
## @run shell Test7107135.sh
##
@@ -45,6 +46,11 @@
case "$OS" in
Linux)
echo "Testing on Linux"
+ gcc_cmd=`which gcc`
+ if [ "x$gcc_cmd" == "x" ]; then
+ echo "WARNING: gcc not found. Cannot execute test." 2>&1
+ exit 0;
+ fi
;;
*)
NULL=NUL
@@ -62,7 +68,10 @@
cp ${TESTSRC}${FS}*.java ${THIS_DIR}
${TESTJAVA}${FS}bin${FS}javac *.java
-gcc -fPIC -shared -c -o test.o -I${TESTJAVA}${FS}include -I${TESTJAVA}${FS}include${FS}linux ${TESTSRC}${FS}test.c
+$gcc_cmd -fPIC -shared -c -o test.o \
+ -I${TESTJAVA}${FS}include -I${TESTJAVA}${FS}include${FS}linux \
+ ${TESTSRC}${FS}test.c
+
ld -shared -z execstack -o libtest-rwx.so test.o
ld -shared -z noexecstack -o libtest-rw.so test.o
--- a/hotspot/test/runtime/jsig/Test8017498.sh Tue Aug 06 10:10:39 2013 -0700
+++ b/hotspot/test/runtime/jsig/Test8017498.sh Wed Jul 05 19:06:08 2017 +0200
@@ -27,6 +27,7 @@
## @test Test8017498.sh
## @bug 8017498
## @bug 8020791
+## @bug 8021296
## @summary sigaction(sig) results in process hang/timed-out if sig is much greater than SIGRTMAX
## @run shell/timeout=30 Test8017498.sh
##
@@ -45,6 +46,11 @@
case "$OS" in
Linux)
echo "Testing on Linux"
+ gcc_cmd=`which gcc`
+ if [ "x$gcc_cmd" == "x" ]; then
+ echo "WARNING: gcc not found. Cannot execute test." 2>&1
+ exit 0;
+ fi
if [ "$VM_BITS" = "64" ]
then
MY_LD_PRELOAD=${TESTJAVA}${FS}jre${FS}lib${FS}amd64${FS}libjsig.so
@@ -64,15 +70,11 @@
cp ${TESTSRC}${FS}*.java ${THIS_DIR}
${TESTJAVA}${FS}bin${FS}javac *.java
-gcc -DLINUX -fPIC -shared \
+$gcc_cmd -DLINUX -fPIC -shared \
-o ${TESTSRC}${FS}libTestJNI.so \
-I${TESTJAVA}${FS}include \
-I${TESTJAVA}${FS}include${FS}linux \
${TESTSRC}${FS}TestJNI.c
-if [ $? != 0 ]
-then
- echo "WARNING: the gcc command failed." 2>&1
-fi
# run the java test in the background
cmd="LD_PRELOAD=$MY_LD_PRELOAD \
--- a/hotspot/test/runtime/jsig/TestJNI.c Tue Aug 06 10:10:39 2013 -0700
+++ b/hotspot/test/runtime/jsig/TestJNI.c Wed Jul 05 19:06:08 2017 +0200
@@ -21,7 +21,6 @@
* questions.
*/
-#define _GNU_SOURCE // for the definition of REG_RIP in ucontext.h
#include <stdio.h>
#include <jni.h>
#include <signal.h>
@@ -32,11 +31,8 @@
#endif
void sig_handler(int sig, siginfo_t *info, ucontext_t *context) {
- int thrNum;
printf( " HANDLER (1) " );
- // Move forward RIP to skip failing instruction
- context->uc_mcontext.gregs[REG_RIP] += 6;
}
JNIEXPORT void JNICALL Java_TestJNI_doSomething(JNIEnv *env, jclass klass, jint val) {