# HG changeset patch # User rehn # Date 1529927916 -7200 # Mon Jun 25 13:58:36 2018 +0200 # Node ID 186a35190f0d355e1b3368e98e1e988be4323e9e # Parent 66aa2e3ffcbce1fd9928a21a1be1a013bbc23994 8205583: Crash in ConcurrentHashTable do_bulk_delete_locked_for Reviewed-by: diff --git a/src/hotspot/share/classfile/stringTable.cpp b/src/hotspot/share/classfile/stringTable.cpp --- a/src/hotspot/share/classfile/stringTable.cpp +++ b/src/hotspot/share/classfile/stringTable.cpp @@ -507,15 +507,8 @@ { ThreadBlockInVM tbivm(jt); } - if (!bdt.cont(jt)) { - interrupted = true; - break; - } + bdt.cont(jt); } - } - if (interrupted) { - _has_work = true; - } else { bdt.done(jt); } log_debug(stringtable)("Cleaned %ld of %ld", stdc._count, stdc._item); diff --git a/src/hotspot/share/utilities/concurrentHashTableTasks.inline.hpp b/src/hotspot/share/utilities/concurrentHashTableTasks.inline.hpp --- a/src/hotspot/share/utilities/concurrentHashTableTasks.inline.hpp +++ b/src/hotspot/share/utilities/concurrentHashTableTasks.inline.hpp @@ -76,12 +76,6 @@ return OrderAccess::load_acquire(&_next_to_claim) >= _stop_task; } - // If we have changed size. - bool is_same_table() { - // Not entirely true. - return _size_log2 != _cht->_table->_log2_size; - } - void thread_owns_resize_lock(Thread* thread) { assert(BucketsOperation::_cht->_resize_lock_owner == thread, "Should be locked by me"); @@ -100,6 +94,24 @@ assert(BucketsOperation::_cht->_resize_lock_owner != thread, "Should not be locked by me"); } + +public: + // Pauses for safepoint + void pause(Thread* thread) { + // This leaves internal state locked. + this->thread_owns_resize_lock(thread); + BucketsOperation::_cht->_resize_lock->unlock(); + this->thread_owns_only_state_lock(thread); + } + + // Continues after safepoint. + void cont(Thread* thread) { + this->thread_owns_only_state_lock(thread); + // If someone slips in here directly after safepoint. + while (!BucketsOperation::_cht->_resize_lock->try_lock()) + { /* for ever */ }; + this->thread_owns_resize_lock(thread); + } }; // For doing pausable/parallel bulk delete. @@ -117,8 +129,8 @@ if (!lock) { return false; } + this->thread_owns_resize_lock(thread); this->setup(); - this->thread_owns_resize_lock(thread); return true; } @@ -135,30 +147,8 @@ BucketsOperation::_cht->do_bulk_delete_locked_for(thread, start, stop, eval_f, del_f, BucketsOperation::_is_mt); - return true; - } - - // Pauses this operations for a safepoint. - void pause(Thread* thread) { - this->thread_owns_resize_lock(thread); - // This leaves internal state locked. - BucketsOperation::_cht->unlock_resize_lock(thread); - this->thread_do_not_own_resize_lock(thread); - } - - // Continues this operations after a safepoint. - bool cont(Thread* thread) { - this->thread_do_not_own_resize_lock(thread); - if (!BucketsOperation::_cht->try_resize_lock(thread)) { - this->thread_do_not_own_resize_lock(thread); - return false; - } - if (BucketsOperation::is_same_table()) { - BucketsOperation::_cht->unlock_resize_lock(thread); - this->thread_do_not_own_resize_lock(thread); - return false; - } - this->thread_owns_resize_lock(thread); + assert(BucketsOperation::_cht->_resize_lock_owner != NULL, + "Should be locked"); return true; } @@ -184,7 +174,7 @@ return false; } this->thread_owns_resize_lock(thread); - BucketsOperation::setup(); + this->setup(); return true; } @@ -202,23 +192,6 @@ return true; } - // Pauses growing for safepoint - void pause(Thread* thread) { - // This leaves internal state locked. - this->thread_owns_resize_lock(thread); - BucketsOperation::_cht->_resize_lock->unlock(); - this->thread_owns_only_state_lock(thread); - } - - // Continues growing after safepoint. - void cont(Thread* thread) { - this->thread_owns_only_state_lock(thread); - // If someone slips in here directly after safepoint. - while (!BucketsOperation::_cht->_resize_lock->try_lock()) - { /* for ever */ }; - this->thread_owns_resize_lock(thread); - } - // Must be called after do_task returns false. void done(Thread* thread) { this->thread_owns_resize_lock(thread); diff --git a/test/hotspot/gtest/utilities/test_concurrentHashtable.cpp b/test/hotspot/gtest/utilities/test_concurrentHashtable.cpp --- a/test/hotspot/gtest/utilities/test_concurrentHashtable.cpp +++ b/test/hotspot/gtest/utilities/test_concurrentHashtable.cpp @@ -213,7 +213,7 @@ if (bdt.prepare(thr)) { while(bdt.do_task(thr, getinsert_bulkdelete_eval, getinsert_bulkdelete_del)) { bdt.pause(thr); - EXPECT_TRUE(bdt.cont(thr)) << "Uncontended continue should work."; + bdt.cont(thr); } bdt.done(thr); }