diff --git a/.hgtags b/.hgtags index 57a200e545a6fc98cde2f661e456b68de5ff9586..df06313deca45f5c57f686e7280905caa738c584 100644 --- a/.hgtags +++ b/.hgtags @@ -83,3 +83,6 @@ fafab5d5349c7c066d677538db67a1ee0fb33bd2 hs15-b05 ffc8d176b84bcfb5ac21302b4feb3b0c0d69b97c jdk7-b84 6c9796468b91dcbb39e09dfa1baf9779ac45eb66 jdk7-b85 418bc80ce13995149eadc9eecbba21d7a9fa02ae hs17-b10 +bf823ef06b4f211e66988d76a2e2669be5c0820e jdk7-b86 +07226e9eab8f74b37346b32715f829a2ef2c3188 hs18-b01 +e7e7e36ccdb5d56edd47e5744351202d38f3b7ad jdk7-b87 diff --git a/make/hotspot_version b/make/hotspot_version index b6f0792ede5c2224af4e73d3428bbbc80325e522..920a9d901a249749cf7fe9f02423a7695e07d4f6 100644 --- a/make/hotspot_version +++ b/make/hotspot_version @@ -31,11 +31,11 @@ # # Don't put quotes (fail windows build). -HOTSPOT_VM_COPYRIGHT=Copyright 2009 +HOTSPOT_VM_COPYRIGHT=Copyright 2010 -HS_MAJOR_VER=17 +HS_MAJOR_VER=18 HS_MINOR_VER=0 -HS_BUILD_NUMBER=10 +HS_BUILD_NUMBER=02 JDK_MAJOR_VER=1 JDK_MINOR_VER=7 diff --git a/src/share/vm/gc_implementation/g1/concurrentMark.cpp b/src/share/vm/gc_implementation/g1/concurrentMark.cpp index b2c0754682da662f0765d2d22cb0657a4368be8f..6a3d4b19cbdab3b7805349e30af62b9e0691f69c 100644 --- a/src/share/vm/gc_implementation/g1/concurrentMark.cpp +++ b/src/share/vm/gc_implementation/g1/concurrentMark.cpp @@ -760,7 +760,10 @@ void ConcurrentMark::checkpointRootsInitialPost() { rp->setup_policy(false); // snapshot the soft ref policy to be used in this cycle SATBMarkQueueSet& satb_mq_set = JavaThread::satb_mark_queue_set(); - satb_mq_set.set_active_all_threads(true); + // This is the start of the marking cycle, we're expected all + // threads to have SATB queues with active set to false. + satb_mq_set.set_active_all_threads(true, /* new active value */ + false /* expected_active */); // update_g1_committed() will be called at the end of an evac pause // when marking is on. So, it's also called at the end of the @@ -1079,7 +1082,11 @@ void ConcurrentMark::checkpointRootsFinal(bool clear_all_soft_refs) { gclog_or_tty->print_cr("\nRemark led to restart for overflow."); } else { // We're done with marking. - JavaThread::satb_mark_queue_set().set_active_all_threads(false); + // This is the end of the marking cycle, we're expected all + // threads to have SATB queues with active set to true. + JavaThread::satb_mark_queue_set().set_active_all_threads( + false, /* new active value */ + true /* expected_active */); if (VerifyDuringGC) { HandleMark hm; // handle scope @@ -2586,7 +2593,11 @@ void ConcurrentMark::abort() { SATBMarkQueueSet& satb_mq_set = JavaThread::satb_mark_queue_set(); satb_mq_set.abandon_partial_marking(); - satb_mq_set.set_active_all_threads(false); + // This can be called either during or outside marking, we'll read + // the expected_active value from the SATB queue set. + satb_mq_set.set_active_all_threads( + false, /* new active value */ + satb_mq_set.is_active() /* expected_active */); } static void print_ms_time_info(const char* prefix, const char* name, diff --git a/src/share/vm/gc_implementation/g1/g1SATBCardTableModRefBS.cpp b/src/share/vm/gc_implementation/g1/g1SATBCardTableModRefBS.cpp index f82b8ba8fe96436ad28ff5b4bfb1f83334e59d5f..435455522741e22217462e41a30185e1d94698d8 100644 --- a/src/share/vm/gc_implementation/g1/g1SATBCardTableModRefBS.cpp +++ b/src/share/vm/gc_implementation/g1/g1SATBCardTableModRefBS.cpp @@ -35,7 +35,7 @@ G1SATBCardTableModRefBS::G1SATBCardTableModRefBS(MemRegion whole_heap, void G1SATBCardTableModRefBS::enqueue(oop pre_val) { assert(pre_val->is_oop_or_null(true), "Error"); - if (!JavaThread::satb_mark_queue_set().active()) return; + if (!JavaThread::satb_mark_queue_set().is_active()) return; Thread* thr = Thread::current(); if (thr->is_Java_thread()) { JavaThread* jt = (JavaThread*)thr; @@ -51,7 +51,7 @@ template void G1SATBCardTableModRefBS::write_ref_field_pre_static(T* field, oop new_val, JavaThread* jt) { - if (!JavaThread::satb_mark_queue_set().active()) return; + if (!JavaThread::satb_mark_queue_set().is_active()) return; T heap_oop = oopDesc::load_heap_oop(field); if (!oopDesc::is_null(heap_oop)) { oop pre_val = oopDesc::decode_heap_oop_not_null(heap_oop); @@ -62,7 +62,7 @@ G1SATBCardTableModRefBS::write_ref_field_pre_static(T* field, template void G1SATBCardTableModRefBS::write_ref_array_pre_work(T* dst, int count) { - if (!JavaThread::satb_mark_queue_set().active()) return; + if (!JavaThread::satb_mark_queue_set().is_active()) return; T* elem_ptr = dst; for (int i = 0; i < count; i++, elem_ptr++) { T heap_oop = oopDesc::load_heap_oop(elem_ptr); diff --git a/src/share/vm/gc_implementation/g1/ptrQueue.cpp b/src/share/vm/gc_implementation/g1/ptrQueue.cpp index 4a3fac2faaf7532d50fc90b3802ca1769cc992a3..44b699ce2b06149808d0728419dbf237eea48aff 100644 --- a/src/share/vm/gc_implementation/g1/ptrQueue.cpp +++ b/src/share/vm/gc_implementation/g1/ptrQueue.cpp @@ -25,8 +25,8 @@ # include "incls/_precompiled.incl" # include "incls/_ptrQueue.cpp.incl" -PtrQueue::PtrQueue(PtrQueueSet* qset_, bool perm) : - _qset(qset_), _buf(NULL), _index(0), _active(false), +PtrQueue::PtrQueue(PtrQueueSet* qset_, bool perm, bool active) : + _qset(qset_), _buf(NULL), _index(0), _active(active), _perm(perm), _lock(NULL) {} diff --git a/src/share/vm/gc_implementation/g1/ptrQueue.hpp b/src/share/vm/gc_implementation/g1/ptrQueue.hpp index ccf5b207c760d797527f01b0eabea920fac9f485..24e8223de0c8cfef1987c65b8ff19d0d2b7789a7 100644 --- a/src/share/vm/gc_implementation/g1/ptrQueue.hpp +++ b/src/share/vm/gc_implementation/g1/ptrQueue.hpp @@ -62,7 +62,7 @@ protected: public: // Initialize this queue to contain a null buffer, and be part of the // given PtrQueueSet. - PtrQueue(PtrQueueSet*, bool perm = false); + PtrQueue(PtrQueueSet*, bool perm = false, bool active = false); // Release any contained resources. void flush(); // Calls flush() when destroyed. @@ -101,6 +101,8 @@ public: } } + bool is_active() { return _active; } + static int byte_index_to_index(int ind) { assert((ind % oopSize) == 0, "Invariant."); return ind / oopSize; @@ -257,7 +259,7 @@ public: bool process_completed_buffers() { return _process_completed; } void set_process_completed(bool x) { _process_completed = x; } - bool active() { return _all_active; } + bool is_active() { return _all_active; } // Set the buffer size. Should be called before any "enqueue" operation // can be called. And should only be called once. diff --git a/src/share/vm/gc_implementation/g1/satbQueue.cpp b/src/share/vm/gc_implementation/g1/satbQueue.cpp index 8efdc3b9c23c25020420db44282dec413116a4bf..d34d56f229a2b51ef4e81785731939e4c3a12464 100644 --- a/src/share/vm/gc_implementation/g1/satbQueue.cpp +++ b/src/share/vm/gc_implementation/g1/satbQueue.cpp @@ -82,9 +82,57 @@ void SATBMarkQueueSet::handle_zero_index_for_thread(JavaThread* t) { t->satb_mark_queue().handle_zero_index(); } -void SATBMarkQueueSet::set_active_all_threads(bool b) { +#ifdef ASSERT +void SATBMarkQueueSet::dump_active_values(JavaThread* first, + bool expected_active) { + gclog_or_tty->print_cr("SATB queue active values for Java Threads"); + gclog_or_tty->print_cr(" SATB queue set: active is %s", + (is_active()) ? "TRUE" : "FALSE"); + gclog_or_tty->print_cr(" expected_active is %s", + (expected_active) ? "TRUE" : "FALSE"); + for (JavaThread* t = first; t; t = t->next()) { + bool active = t->satb_mark_queue().is_active(); + gclog_or_tty->print_cr(" thread %s, active is %s", + t->name(), (active) ? "TRUE" : "FALSE"); + } +} +#endif // ASSERT + +void SATBMarkQueueSet::set_active_all_threads(bool b, + bool expected_active) { + assert(SafepointSynchronize::is_at_safepoint(), "Must be at safepoint."); + JavaThread* first = Threads::first(); + +#ifdef ASSERT + if (_all_active != expected_active) { + dump_active_values(first, expected_active); + + // I leave this here as a guarantee, instead of an assert, so + // that it will still be compiled in if we choose to uncomment + // the #ifdef ASSERT in a product build. The whole block is + // within an #ifdef ASSERT so the guarantee will not be compiled + // in a product build anyway. + guarantee(false, + "SATB queue set has an unexpected active value"); + } +#endif // ASSERT _all_active = b; - for(JavaThread* t = Threads::first(); t; t = t->next()) { + + for (JavaThread* t = first; t; t = t->next()) { +#ifdef ASSERT + bool active = t->satb_mark_queue().is_active(); + if (active != expected_active) { + dump_active_values(first, expected_active); + + // I leave this here as a guarantee, instead of an assert, so + // that it will still be compiled in if we choose to uncomment + // the #ifdef ASSERT in a product build. The whole block is + // within an #ifdef ASSERT so the guarantee will not be compiled + // in a product build anyway. + guarantee(false, + "thread has an unexpected active value in its SATB queue"); + } +#endif // ASSERT t->satb_mark_queue().set_active(b); } } diff --git a/src/share/vm/gc_implementation/g1/satbQueue.hpp b/src/share/vm/gc_implementation/g1/satbQueue.hpp index 76218a6363bde84da37f28daff94b87e4d0ecf68..ae0c721b3a83c61ece0e79a5cc55b60571cd352f 100644 --- a/src/share/vm/gc_implementation/g1/satbQueue.hpp +++ b/src/share/vm/gc_implementation/g1/satbQueue.hpp @@ -29,8 +29,7 @@ class JavaThread; class ObjPtrQueue: public PtrQueue { public: ObjPtrQueue(PtrQueueSet* qset_, bool perm = false) : - PtrQueue(qset_, perm) - {} + PtrQueue(qset_, perm, qset_->is_active()) { } // Apply the closure to all elements, and reset the index to make the // buffer empty. void apply_closure(ObjectClosure* cl); @@ -55,6 +54,9 @@ class SATBMarkQueueSet: public PtrQueueSet { // is ignored. bool apply_closure_to_completed_buffer_work(bool par, int worker); +#ifdef ASSERT + void dump_active_values(JavaThread* first, bool expected_active); +#endif // ASSERT public: SATBMarkQueueSet(); @@ -65,9 +67,11 @@ public: static void handle_zero_index_for_thread(JavaThread* t); - // Apply "set_active(b)" to all thread tloq's. Should be called only - // with the world stopped. - void set_active_all_threads(bool b); + // Apply "set_active(b)" to all Java threads' SATB queues. It should be + // called only with the world stopped. The method will assert that the + // SATB queues of all threads it visits, as well as the SATB queue + // set itself, has an active value same as expected_active. + void set_active_all_threads(bool b, bool expected_active); // Register "blk" as "the closure" for all queues. Only one such closure // is allowed. The "apply_closure_to_completed_buffer" method will apply