diff --git a/src/os/windows/vm/os_windows.cpp b/src/os/windows/vm/os_windows.cpp index e329c9fd6cd65e8e0d7c24b9885960b4206a33f5..44d89a2885e24b2d850aebed19c57a8f628ba826 100644 --- a/src/os/windows/vm/os_windows.cpp +++ b/src/os/windows/vm/os_windows.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2016, 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 @@ -1747,8 +1747,7 @@ void os::win32::print_windows_version(outputStream* st) { if (is_workstation) { st->print("10"); } else { - // The server version name of Windows 10 is not known at this time - st->print("%d.%d", major_version, minor_version); + st->print("Server 2016"); } break; diff --git a/src/share/vm/gc_implementation/g1/concurrentMark.cpp b/src/share/vm/gc_implementation/g1/concurrentMark.cpp index 92261912a160976649b5ad2a2a0b7ce6745fcb11..a5c42614249cd62266ee6f7880c50acd1b957a3e 100644 --- a/src/share/vm/gc_implementation/g1/concurrentMark.cpp +++ b/src/share/vm/gc_implementation/g1/concurrentMark.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2016, 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 @@ -631,11 +631,10 @@ ConcurrentMark::ConcurrentMark(G1CollectedHeap* g1h, G1RegionToSpaceMapper* prev double overall_cm_overhead = (double) MaxGCPauseMillis * marking_overhead / (double) GCPauseIntervalMillis; - double cpu_ratio = 1.0 / (double) os::processor_count(); + double cpu_ratio = 1.0 / os::initial_active_processor_count(); double marking_thread_num = ceil(overall_cm_overhead / cpu_ratio); double marking_task_overhead = - overall_cm_overhead / marking_thread_num * - (double) os::processor_count(); + overall_cm_overhead / marking_thread_num * os::initial_active_processor_count(); double sleep_factor = (1.0 - marking_task_overhead) / marking_task_overhead; diff --git a/src/share/vm/gc_implementation/g1/dirtyCardQueue.cpp b/src/share/vm/gc_implementation/g1/dirtyCardQueue.cpp index 6e84e514aa7ec78afef8cd219f0f26d5ca7cbb9b..62555c9749848ba66cccbe5c6908c82852c05680 100644 --- a/src/share/vm/gc_implementation/g1/dirtyCardQueue.cpp +++ b/src/share/vm/gc_implementation/g1/dirtyCardQueue.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2016, 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 @@ -80,7 +80,7 @@ DirtyCardQueueSet::DirtyCardQueueSet(bool notify_when_complete) : // Determines how many mutator threads can process the buffers in parallel. uint DirtyCardQueueSet::num_par_ids() { - return (uint)os::processor_count(); + return (uint)os::initial_active_processor_count(); } void DirtyCardQueueSet::initialize(CardTableEntryClosure* cl, Monitor* cbl_mon, Mutex* fl_lock, diff --git a/src/share/vm/gc_implementation/parNew/parCardTableModRefBS.cpp b/src/share/vm/gc_implementation/parNew/parCardTableModRefBS.cpp index 9209f0d1a4b24efb5289d561f415fedd95b753ee..34642187d5af10c1cf662f379a422a316dee3ddb 100644 --- a/src/share/vm/gc_implementation/parNew/parCardTableModRefBS.cpp +++ b/src/share/vm/gc_implementation/parNew/parCardTableModRefBS.cpp @@ -452,9 +452,13 @@ get_LNC_array_for_space(Space* sp, // event lock and do the read again in case some other thread had already // succeeded and done the resize. int cur_collection = Universe::heap()->total_collections(); - if (_last_LNC_resizing_collection[i] != cur_collection) { + // Updated _last_LNC_resizing_collection[i] must not be visible before + // _lowest_non_clean and friends are visible. Therefore use acquire/release + // to guarantee this on non TSO architecures. + if (OrderAccess::load_acquire(&_last_LNC_resizing_collection[i]) != cur_collection) { MutexLocker x(ParGCRareEvent_lock); - if (_last_LNC_resizing_collection[i] != cur_collection) { + // This load_acquire is here for clarity only. The MutexLocker already fences. + if (OrderAccess::load_acquire(&_last_LNC_resizing_collection[i]) != cur_collection) { if (_lowest_non_clean[i] == NULL || n_chunks != _lowest_non_clean_chunk_size[i]) { @@ -474,7 +478,8 @@ get_LNC_array_for_space(Space* sp, _lowest_non_clean[i][j] = NULL; } } - _last_LNC_resizing_collection[i] = cur_collection; + // Make sure this gets visible only after _lowest_non_clean* was initialized + OrderAccess::release_store(&_last_LNC_resizing_collection[i], cur_collection); } } // In any case, now do the initialization. diff --git a/src/share/vm/memory/cardTableModRefBS.hpp b/src/share/vm/memory/cardTableModRefBS.hpp index c824e6185a0f28262be056465c72b83f1951b070..ae15ba7ed118531686a2c988b5ceaf7abb6c73a8 100644 --- a/src/share/vm/memory/cardTableModRefBS.hpp +++ b/src/share/vm/memory/cardTableModRefBS.hpp @@ -217,7 +217,7 @@ class CardTableModRefBS: public ModRefBarrierSet { CardArr* _lowest_non_clean; size_t* _lowest_non_clean_chunk_size; uintptr_t* _lowest_non_clean_base_chunk_index; - int* _last_LNC_resizing_collection; + volatile int* _last_LNC_resizing_collection; // Initializes "lowest_non_clean" to point to the array for the region // covering "sp", and "lowest_non_clean_base_chunk_index" to the chunk diff --git a/src/share/vm/runtime/os.cpp b/src/share/vm/runtime/os.cpp index 21764cb0bfa3817d2b5a38191e611c43182cae80..06e81a554ff6e96295ae1cffc322d53451afdf19 100644 --- a/src/share/vm/runtime/os.cpp +++ b/src/share/vm/runtime/os.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2016, 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 @@ -78,6 +78,7 @@ volatile int32_t* os::_mem_serialize_page = NULL; uintptr_t os::_serialize_page_mask = 0; long os::_rand_seed = 1; int os::_processor_count = 0; +int os::_initial_active_processor_count = 0; size_t os::_page_sizes[os::page_sizes_max]; #ifndef PRODUCT @@ -322,6 +323,7 @@ static void signal_thread_entry(JavaThread* thread, TRAPS) { } void os::init_before_ergo() { + initialize_initial_active_processor_count(); // We need to initialize large page support here because ergonomics takes some // decisions depending on large page support and the calculated large page size. large_page_init(); @@ -835,7 +837,11 @@ void os::print_cpu_info(outputStream* st) { st->print("CPU:"); st->print("total %d", os::processor_count()); // It's not safe to query number of active processors after crash - // st->print("(active %d)", os::active_processor_count()); + // st->print("(active %d)", os::active_processor_count()); but we can + // print the initial number of active processors. + // We access the raw value here because the assert in the accessor will + // fail if the crash occurs before initialization of this value. + st->print(" (initial active %d)", _initial_active_processor_count); st->print(" %s", VM_Version::cpu_features()); st->cr(); pd_print_cpu_info(st); @@ -1418,6 +1424,11 @@ bool os::is_server_class_machine() { return result; } +void os::initialize_initial_active_processor_count() { + assert(_initial_active_processor_count == 0, "Initial active processor count already set."); + _initial_active_processor_count = active_processor_count(); +} + void os::SuspendedThreadTask::run() { assert(Threads_lock->owned_by_self() || (_thread == VMThread::vm_thread()), "must have threads lock to call this"); internal_do_task(); diff --git a/src/share/vm/runtime/os.hpp b/src/share/vm/runtime/os.hpp index 944ec64313bd8a4a49981b8654ad89d4dac9a458..e008b9c64f98c862649fe0f1756feb5c2d1cb3d6 100644 --- a/src/share/vm/runtime/os.hpp +++ b/src/share/vm/runtime/os.hpp @@ -151,6 +151,7 @@ class os: AllStatic { static size_t page_size_for_region(size_t region_size, size_t min_pages, bool must_be_aligned); + static void initialize_initial_active_processor_count(); public: static void init(void); // Called before command line parsing static void init_before_ergo(void); // Called after command line parsing @@ -238,6 +239,13 @@ class os: AllStatic { // Note that on some OSes this can change dynamically. static int active_processor_count(); + // At startup the number of active CPUs this process is allowed to run on. + // This value does not change dynamically. May be different from active_processor_count(). + static int initial_active_processor_count() { + assert(_initial_active_processor_count > 0, "Initial active processor count not set yet."); + return _initial_active_processor_count; + } + // Bind processes to processors. // This is a two step procedure: // first you generate a distribution of processes to processors, @@ -975,8 +983,9 @@ class os: AllStatic { protected: - static long _rand_seed; // seed for random number generator - static int _processor_count; // number of processors + static long _rand_seed; // seed for random number generator + static int _processor_count; // number of processors + static int _initial_active_processor_count; // number of active processors during initialization. static char* format_boot_path(const char* format_string, const char* home, diff --git a/src/share/vm/runtime/vm_version.cpp b/src/share/vm/runtime/vm_version.cpp index a046d81422dca9abc87b95768665d39ed7165f3a..d95e3a966b0f93fa4f68c6d650f8e9f9151bd5d3 100644 --- a/src/share/vm/runtime/vm_version.cpp +++ b/src/share/vm/runtime/vm_version.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2016, 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 @@ -296,7 +296,7 @@ unsigned int Abstract_VM_Version::nof_parallel_worker_threads( // processor after the first 8. For example, on a 72 cpu machine // and a chosen fraction of 5/8 // use 8 + (72 - 8) * (5/8) == 48 worker threads. - unsigned int ncpus = (unsigned int) os::active_processor_count(); + unsigned int ncpus = (unsigned int) os::initial_active_processor_count(); return (ncpus <= switch_pt) ? ncpus : (switch_pt + ((ncpus - switch_pt) * num) / den);