--- old/src/hotspot/share/gc/g1/g1ConcurrentRefine.cpp 2017-11-20 12:09:39.086589448 +0100 +++ new/src/hotspot/share/gc/g1/g1ConcurrentRefine.cpp 2017-11-20 12:09:38.685577273 +0100 @@ -33,8 +33,21 @@ #include "utilities/pair.hpp" #include +G1ConcurrentRefineThread* G1ConcurrentRefineThreadControl::create_refinement_thread(uint worker_id, bool initializing) { + G1ConcurrentRefineThread* result = NULL; + if (initializing || !InjectGCWorkerCreationFailure) { + result = new G1ConcurrentRefineThread(_cr, worker_id); + } + if (result == NULL || result->osthread() == NULL) { + log_warning(gc)("Failed to create refinement thread %u, no more %s", + worker_id, + result == NULL ? "memory" : "OS threads"); + } + return result; +} + G1ConcurrentRefineThreadControl::G1ConcurrentRefineThreadControl() : - _cg1r(NULL), + _cr(NULL), _threads(NULL), _num_max_threads(0) { @@ -50,22 +63,35 @@ FREE_C_HEAP_ARRAY(G1ConcurrentRefineThread*, _threads); } -void G1ConcurrentRefineThreadControl::initialize(G1ConcurrentRefine* cg1r, uint num_max_threads) { - assert(cg1r != NULL, "Passed g1ConcurrentRefine must not be NULL"); - _cg1r = cg1r; +jint G1ConcurrentRefineThreadControl::initialize(G1ConcurrentRefine* cr, uint num_max_threads) { + assert(cr != NULL, "G1ConcurrentRefine must not be NULL"); + _cr = cr; _num_max_threads = num_max_threads; - _threads = NEW_C_HEAP_ARRAY(G1ConcurrentRefineThread*, num_max_threads, mtGC); + + _threads = NEW_C_HEAP_ARRAY_RETURN_NULL(G1ConcurrentRefineThread*, num_max_threads, mtGC); + if (_threads == NULL) { + vm_shutdown_during_initialization("Could not allocate thread holder array."); + return JNI_ENOMEM; + } + for (uint i = 0; i < num_max_threads; i++) { - if (UseDynamicNumberOfGCThreads) { + if (UseDynamicNumberOfGCThreads && i != 0 /* Always start first thread. */) { _threads[i] = NULL; } else { - _threads[i] = new G1ConcurrentRefineThread(_cg1r, i); + _threads[i] = create_refinement_thread(i, true); + if (_threads[i] == NULL) { + vm_shutdown_during_initialization("Could not allocate refinement threads."); + return JNI_ENOMEM; + } } } + return JNI_OK; } void G1ConcurrentRefineThreadControl::maybe_activate_next(uint cur_worker_id) { - assert(cur_worker_id < _num_max_threads, "Tried to activate from impossible thread %u", cur_worker_id); + assert(cur_worker_id < _num_max_threads, + "Activating another thread from %u not allowed since there can be at most %u", + cur_worker_id, _num_max_threads); if (cur_worker_id == (_num_max_threads - 1)) { // Already the last thread, there is no more thread to activate. return; @@ -75,10 +101,12 @@ G1ConcurrentRefineThread* thread_to_activate = _threads[worker_id]; if (thread_to_activate == NULL) { // Still need to create the thread... - _threads[worker_id] = new G1ConcurrentRefineThread(_cg1r, worker_id); + _threads[worker_id] = create_refinement_thread(worker_id, false); thread_to_activate = _threads[worker_id]; } - thread_to_activate->activate(); + if (thread_to_activate != NULL) { + thread_to_activate->activate(); + } } void G1ConcurrentRefineThreadControl::print_on(outputStream* st) const { @@ -195,7 +223,10 @@ _min_yellow_zone_size(min_yellow_zone_size) { assert_zone_constraints_gyr(green_zone, yellow_zone, red_zone); - _thread_control.initialize(this, max_num_threads()); +} + +jint G1ConcurrentRefine::initialize() { + return _thread_control.initialize(this, max_num_threads()); } static size_t calc_min_yellow_zone_size() { @@ -264,7 +295,7 @@ return NULL; } - *ecode = JNI_OK; + *ecode = cr->initialize(); return cr; }