# HG changeset patch # User mdoerr # Date 1476261660 -7200 # Node ID b830f5141dbb80a775f046644339a91516c7bed5 # Parent 6a0b0026bc251b3bbaa5dd3c8a3a7e0c22c63118 8166970: Adapt mutex padding according to DEFAULT_CACHE_LINE_SIZE Reviewed-by: coleenp, dholmes, dcubed, redestad diff -r 6a0b0026bc25 -r b830f5141dbb hotspot/src/share/vm/runtime/mutex.hpp --- a/hotspot/src/share/vm/runtime/mutex.hpp Thu Oct 13 08:57:54 2016 -0700 +++ b/hotspot/src/share/vm/runtime/mutex.hpp Wed Oct 12 10:41:00 2016 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2014, 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 @@ -81,7 +81,9 @@ // *in that order*. If their implementations change such that these // assumptions are violated, a whole lot of code will break. -// The default length of monitor name is chosen to be 64 to avoid false sharing. +// The default length of monitor name was originally chosen to be 64 to avoid +// false sharing. Now, PaddedMonitor is available for this purpose. +// TODO: Check if _name[MONITOR_NAME_LEN] should better get replaced by const char*. static const int MONITOR_NAME_LEN = 64; class Monitor : public CHeapObj { @@ -254,6 +256,18 @@ }; +class PaddedMonitor : public Monitor { + enum { + CACHE_LINE_PADDING = (int)DEFAULT_CACHE_LINE_SIZE - (int)sizeof(Monitor), + PADDING_LEN = CACHE_LINE_PADDING > 0 ? CACHE_LINE_PADDING : 1 + }; + char _padding[PADDING_LEN]; + public: + PaddedMonitor(int rank, const char *name, bool allow_vm_block = false, + SafepointCheckRequired safepoint_check_required = _safepoint_check_always) : + Monitor(rank, name, allow_vm_block, safepoint_check_required) {}; +}; + // Normally we'd expect Monitor to extend Mutex in the sense that a monitor // constructed from pthreads primitives might extend a mutex by adding // a condvar and some extra metadata. In fact this was the case until J2SE7. @@ -292,5 +306,16 @@ } }; +class PaddedMutex : public Mutex { + enum { + CACHE_LINE_PADDING = (int)DEFAULT_CACHE_LINE_SIZE - (int)sizeof(Mutex), + PADDING_LEN = CACHE_LINE_PADDING > 0 ? CACHE_LINE_PADDING : 1 + }; + char _padding[PADDING_LEN]; +public: + PaddedMutex(int rank, const char *name, bool allow_vm_block = false, + SafepointCheckRequired safepoint_check_required = _safepoint_check_always) : + Mutex(rank, name, allow_vm_block, safepoint_check_required) {}; +}; #endif // SHARE_VM_RUNTIME_MUTEX_HPP diff -r 6a0b0026bc25 -r b830f5141dbb hotspot/src/share/vm/runtime/mutexLocker.cpp --- a/hotspot/src/share/vm/runtime/mutexLocker.cpp Thu Oct 13 08:57:54 2016 -0700 +++ b/hotspot/src/share/vm/runtime/mutexLocker.cpp Wed Oct 12 10:41:00 2016 +0200 @@ -169,122 +169,123 @@ _mutex_array[_num_mutex++] = var; \ } +// Using Padded subclasses to prevent false sharing of these global monitors and mutexes. void mutex_init() { - def(tty_lock , Mutex , event, true, Monitor::_safepoint_check_never); // allow to lock in VM + def(tty_lock , PaddedMutex , event, true, Monitor::_safepoint_check_never); // allow to lock in VM - def(CGC_lock , Monitor, special, true, Monitor::_safepoint_check_never); // coordinate between fore- and background GC - def(STS_lock , Monitor, leaf, true, Monitor::_safepoint_check_never); + def(CGC_lock , PaddedMonitor, special, true, Monitor::_safepoint_check_never); // coordinate between fore- and background GC + def(STS_lock , PaddedMonitor, leaf, true, Monitor::_safepoint_check_never); if (UseConcMarkSweepGC || UseG1GC) { - def(FullGCCount_lock , Monitor, leaf, true, Monitor::_safepoint_check_never); // in support of ExplicitGCInvokesConcurrent + def(FullGCCount_lock , PaddedMonitor, leaf, true, Monitor::_safepoint_check_never); // in support of ExplicitGCInvokesConcurrent } if (UseG1GC) { - def(SATB_Q_FL_lock , Mutex , special, true, Monitor::_safepoint_check_never); - def(SATB_Q_CBL_mon , Monitor, nonleaf, true, Monitor::_safepoint_check_never); - def(Shared_SATB_Q_lock , Mutex, nonleaf, true, Monitor::_safepoint_check_never); + def(SATB_Q_FL_lock , PaddedMutex , special, true, Monitor::_safepoint_check_never); + def(SATB_Q_CBL_mon , PaddedMonitor, nonleaf, true, Monitor::_safepoint_check_never); + def(Shared_SATB_Q_lock , PaddedMutex , nonleaf, true, Monitor::_safepoint_check_never); - def(DirtyCardQ_FL_lock , Mutex , special, true, Monitor::_safepoint_check_never); - def(DirtyCardQ_CBL_mon , Monitor, nonleaf, true, Monitor::_safepoint_check_never); - def(Shared_DirtyCardQ_lock , Mutex, nonleaf, true, Monitor::_safepoint_check_never); + def(DirtyCardQ_FL_lock , PaddedMutex , special, true, Monitor::_safepoint_check_never); + def(DirtyCardQ_CBL_mon , PaddedMonitor, nonleaf, true, Monitor::_safepoint_check_never); + def(Shared_DirtyCardQ_lock , PaddedMutex , nonleaf, true, Monitor::_safepoint_check_never); - def(FreeList_lock , Mutex, leaf , true, Monitor::_safepoint_check_never); - def(SecondaryFreeList_lock , Monitor, leaf , true, Monitor::_safepoint_check_never); - def(OldSets_lock , Mutex , leaf , true, Monitor::_safepoint_check_never); - def(RootRegionScan_lock , Monitor, leaf , true, Monitor::_safepoint_check_never); - def(MMUTracker_lock , Mutex , leaf , true, Monitor::_safepoint_check_never); + def(FreeList_lock , PaddedMutex , leaf , true, Monitor::_safepoint_check_never); + def(SecondaryFreeList_lock , PaddedMonitor, leaf , true, Monitor::_safepoint_check_never); + def(OldSets_lock , PaddedMutex , leaf , true, Monitor::_safepoint_check_never); + def(RootRegionScan_lock , PaddedMonitor, leaf , true, Monitor::_safepoint_check_never); + def(MMUTracker_lock , PaddedMutex , leaf , true, Monitor::_safepoint_check_never); - def(StringDedupQueue_lock , Monitor, leaf, true, Monitor::_safepoint_check_never); - def(StringDedupTable_lock , Mutex , leaf, true, Monitor::_safepoint_check_never); + def(StringDedupQueue_lock , PaddedMonitor, leaf, true, Monitor::_safepoint_check_never); + def(StringDedupTable_lock , PaddedMutex , leaf, true, Monitor::_safepoint_check_never); - def(MarkStackFreeList_lock , Mutex , leaf , true, Monitor::_safepoint_check_never); - def(MarkStackChunkList_lock , Mutex , leaf , true, Monitor::_safepoint_check_never); + def(MarkStackFreeList_lock , PaddedMutex , leaf , true, Monitor::_safepoint_check_never); + def(MarkStackChunkList_lock , PaddedMutex , leaf , true, Monitor::_safepoint_check_never); } - def(ParGCRareEvent_lock , Mutex , leaf , true, Monitor::_safepoint_check_sometimes); - def(DerivedPointerTableGC_lock , Mutex, leaf, true, Monitor::_safepoint_check_never); - def(CodeCache_lock , Mutex , special, true, Monitor::_safepoint_check_never); - def(RawMonitor_lock , Mutex, special, true, Monitor::_safepoint_check_never); - def(OopMapCacheAlloc_lock , Mutex, leaf, true, Monitor::_safepoint_check_always); // used for oop_map_cache allocation. + def(ParGCRareEvent_lock , PaddedMutex , leaf , true, Monitor::_safepoint_check_sometimes); + def(DerivedPointerTableGC_lock , PaddedMutex , leaf, true, Monitor::_safepoint_check_never); + def(CodeCache_lock , PaddedMutex , special, true, Monitor::_safepoint_check_never); + def(RawMonitor_lock , PaddedMutex , special, true, Monitor::_safepoint_check_never); + def(OopMapCacheAlloc_lock , PaddedMutex , leaf, true, Monitor::_safepoint_check_always); // used for oop_map_cache allocation. - def(Patching_lock , Mutex , special, true, Monitor::_safepoint_check_never); // used for safepointing and code patching. - def(Service_lock , Monitor, special, true, Monitor::_safepoint_check_never); // used for service thread operations - def(JmethodIdCreation_lock , Mutex , leaf, true, Monitor::_safepoint_check_always); // used for creating jmethodIDs. + def(Patching_lock , PaddedMutex , special, true, Monitor::_safepoint_check_never); // used for safepointing and code patching. + def(Service_lock , PaddedMonitor, special, true, Monitor::_safepoint_check_never); // used for service thread operations + def(JmethodIdCreation_lock , PaddedMutex , leaf, true, Monitor::_safepoint_check_always); // used for creating jmethodIDs. - def(SystemDictionary_lock , Monitor, leaf, true, Monitor::_safepoint_check_always); // lookups done by VM thread - def(Module_lock , Mutex , leaf+2, true, Monitor::_safepoint_check_always); - def(InlineCacheBuffer_lock , Mutex , leaf, true, Monitor::_safepoint_check_always); - def(VMStatistic_lock , Mutex , leaf, false, Monitor::_safepoint_check_always); - def(ExpandHeap_lock , Mutex , leaf, true, Monitor::_safepoint_check_always); // Used during compilation by VM thread - def(JNIHandleBlockFreeList_lock , Mutex , leaf, true, Monitor::_safepoint_check_never); // handles are used by VM thread - def(SignatureHandlerLibrary_lock , Mutex , leaf, false, Monitor::_safepoint_check_always); - def(SymbolTable_lock , Mutex , leaf+2, true, Monitor::_safepoint_check_always); - def(StringTable_lock , Mutex , leaf, true, Monitor::_safepoint_check_always); - def(ProfilePrint_lock , Mutex , leaf, false, Monitor::_safepoint_check_always); // serial profile printing - def(ExceptionCache_lock , Mutex , leaf, false, Monitor::_safepoint_check_always); // serial profile printing - def(OsrList_lock , Mutex , leaf, true, Monitor::_safepoint_check_never); - def(Debug1_lock , Mutex , leaf, true, Monitor::_safepoint_check_never); + def(SystemDictionary_lock , PaddedMonitor, leaf, true, Monitor::_safepoint_check_always); // lookups done by VM thread + def(Module_lock , PaddedMutex , leaf+2, true, Monitor::_safepoint_check_always); + def(InlineCacheBuffer_lock , PaddedMutex , leaf, true, Monitor::_safepoint_check_always); + def(VMStatistic_lock , PaddedMutex , leaf, false, Monitor::_safepoint_check_always); + def(ExpandHeap_lock , PaddedMutex , leaf, true, Monitor::_safepoint_check_always); // Used during compilation by VM thread + def(JNIHandleBlockFreeList_lock , PaddedMutex , leaf, true, Monitor::_safepoint_check_never); // handles are used by VM thread + def(SignatureHandlerLibrary_lock , PaddedMutex , leaf, false, Monitor::_safepoint_check_always); + def(SymbolTable_lock , PaddedMutex , leaf+2, true, Monitor::_safepoint_check_always); + def(StringTable_lock , PaddedMutex , leaf, true, Monitor::_safepoint_check_always); + def(ProfilePrint_lock , PaddedMutex , leaf, false, Monitor::_safepoint_check_always); // serial profile printing + def(ExceptionCache_lock , PaddedMutex , leaf, false, Monitor::_safepoint_check_always); // serial profile printing + def(OsrList_lock , PaddedMutex , leaf, true, Monitor::_safepoint_check_never); + def(Debug1_lock , PaddedMutex , leaf, true, Monitor::_safepoint_check_never); #ifndef PRODUCT - def(FullGCALot_lock , Mutex , leaf, false, Monitor::_safepoint_check_always); // a lock to make FullGCALot MT safe + def(FullGCALot_lock , PaddedMutex , leaf, false, Monitor::_safepoint_check_always); // a lock to make FullGCALot MT safe #endif - def(BeforeExit_lock , Monitor, leaf, true, Monitor::_safepoint_check_always); - def(PerfDataMemAlloc_lock , Mutex , leaf, true, Monitor::_safepoint_check_always); // used for allocating PerfData memory for performance data - def(PerfDataManager_lock , Mutex , leaf, true, Monitor::_safepoint_check_always); // used for synchronized access to PerfDataManager resources + def(BeforeExit_lock , PaddedMonitor, leaf, true, Monitor::_safepoint_check_always); + def(PerfDataMemAlloc_lock , PaddedMutex , leaf, true, Monitor::_safepoint_check_always); // used for allocating PerfData memory for performance data + def(PerfDataManager_lock , PaddedMutex , leaf, true, Monitor::_safepoint_check_always); // used for synchronized access to PerfDataManager resources // CMS_modUnionTable_lock leaf // CMS_bitMap_lock leaf 1 // CMS_freeList_lock leaf 2 - def(Safepoint_lock , Monitor, safepoint, true, Monitor::_safepoint_check_sometimes); // locks SnippetCache_lock/Threads_lock + def(Safepoint_lock , PaddedMonitor, safepoint, true, Monitor::_safepoint_check_sometimes); // locks SnippetCache_lock/Threads_lock - def(Threads_lock , Monitor, barrier, true, Monitor::_safepoint_check_sometimes); + def(Threads_lock , PaddedMonitor, barrier, true, Monitor::_safepoint_check_sometimes); - def(VMOperationQueue_lock , Monitor, nonleaf, true, Monitor::_safepoint_check_sometimes); // VM_thread allowed to block on these - def(VMOperationRequest_lock , Monitor, nonleaf, true, Monitor::_safepoint_check_sometimes); - def(RetData_lock , Mutex , nonleaf, false, Monitor::_safepoint_check_always); - def(Terminator_lock , Monitor, nonleaf, true, Monitor::_safepoint_check_sometimes); - def(VtableStubs_lock , Mutex , nonleaf, true, Monitor::_safepoint_check_always); - def(Notify_lock , Monitor, nonleaf, true, Monitor::_safepoint_check_always); - def(JNIGlobalHandle_lock , Mutex , nonleaf, true, Monitor::_safepoint_check_always); // locks JNIHandleBlockFreeList_lock - def(JNICritical_lock , Monitor, nonleaf, true, Monitor::_safepoint_check_always); // used for JNI critical regions - def(AdapterHandlerLibrary_lock , Mutex , nonleaf, true, Monitor::_safepoint_check_always); + def(VMOperationQueue_lock , PaddedMonitor, nonleaf, true, Monitor::_safepoint_check_sometimes); // VM_thread allowed to block on these + def(VMOperationRequest_lock , PaddedMonitor, nonleaf, true, Monitor::_safepoint_check_sometimes); + def(RetData_lock , PaddedMutex , nonleaf, false, Monitor::_safepoint_check_always); + def(Terminator_lock , PaddedMonitor, nonleaf, true, Monitor::_safepoint_check_sometimes); + def(VtableStubs_lock , PaddedMutex , nonleaf, true, Monitor::_safepoint_check_always); + def(Notify_lock , PaddedMonitor, nonleaf, true, Monitor::_safepoint_check_always); + def(JNIGlobalHandle_lock , PaddedMutex , nonleaf, true, Monitor::_safepoint_check_always); // locks JNIHandleBlockFreeList_lock + def(JNICritical_lock , PaddedMonitor, nonleaf, true, Monitor::_safepoint_check_always); // used for JNI critical regions + def(AdapterHandlerLibrary_lock , PaddedMutex , nonleaf, true, Monitor::_safepoint_check_always); - def(Heap_lock , Monitor, nonleaf+1, false, Monitor::_safepoint_check_sometimes); - def(JfieldIdCreation_lock , Mutex , nonleaf+1, true, Monitor::_safepoint_check_always); // jfieldID, Used in VM_Operation - def(MemberNameTable_lock , Mutex , nonleaf+1, false, Monitor::_safepoint_check_always); // Used to protect MemberNameTable + def(Heap_lock , PaddedMonitor, nonleaf+1, false, Monitor::_safepoint_check_sometimes); + def(JfieldIdCreation_lock , PaddedMutex , nonleaf+1, true, Monitor::_safepoint_check_always); // jfieldID, Used in VM_Operation + def(MemberNameTable_lock , PaddedMutex , nonleaf+1, false, Monitor::_safepoint_check_always); // Used to protect MemberNameTable - def(CompiledIC_lock , Mutex , nonleaf+2, false, Monitor::_safepoint_check_always); // locks VtableStubs_lock, InlineCacheBuffer_lock - def(CompileTaskAlloc_lock , Mutex , nonleaf+2, true, Monitor::_safepoint_check_always); - def(CompileStatistics_lock , Mutex , nonleaf+2, false, Monitor::_safepoint_check_always); - def(DirectivesStack_lock , Mutex , special, true, Monitor::_safepoint_check_never); - def(MultiArray_lock , Mutex , nonleaf+2, false, Monitor::_safepoint_check_always); // locks SymbolTable_lock + def(CompiledIC_lock , PaddedMutex , nonleaf+2, false, Monitor::_safepoint_check_always); // locks VtableStubs_lock, InlineCacheBuffer_lock + def(CompileTaskAlloc_lock , PaddedMutex , nonleaf+2, true, Monitor::_safepoint_check_always); + def(CompileStatistics_lock , PaddedMutex , nonleaf+2, false, Monitor::_safepoint_check_always); + def(DirectivesStack_lock , PaddedMutex , special, true, Monitor::_safepoint_check_never); + def(MultiArray_lock , PaddedMutex , nonleaf+2, false, Monitor::_safepoint_check_always); // locks SymbolTable_lock - def(JvmtiThreadState_lock , Mutex , nonleaf+2, false, Monitor::_safepoint_check_always); // Used by JvmtiThreadState/JvmtiEventController - def(Management_lock , Mutex , nonleaf+2, false, Monitor::_safepoint_check_always); // used for JVM management + def(JvmtiThreadState_lock , PaddedMutex , nonleaf+2, false, Monitor::_safepoint_check_always); // Used by JvmtiThreadState/JvmtiEventController + def(Management_lock , PaddedMutex , nonleaf+2, false, Monitor::_safepoint_check_always); // used for JVM management - def(Compile_lock , Mutex , nonleaf+3, true, Monitor::_safepoint_check_sometimes); - def(MethodData_lock , Mutex , nonleaf+3, false, Monitor::_safepoint_check_always); - def(TouchedMethodLog_lock , Mutex , nonleaf+3, false, Monitor::_safepoint_check_always); + def(Compile_lock , PaddedMutex , nonleaf+3, true, Monitor::_safepoint_check_sometimes); + def(MethodData_lock , PaddedMutex , nonleaf+3, false, Monitor::_safepoint_check_always); + def(TouchedMethodLog_lock , PaddedMutex , nonleaf+3, false, Monitor::_safepoint_check_always); - def(MethodCompileQueue_lock , Monitor, nonleaf+4, true, Monitor::_safepoint_check_always); - def(Debug2_lock , Mutex , nonleaf+4, true, Monitor::_safepoint_check_never); - def(Debug3_lock , Mutex , nonleaf+4, true, Monitor::_safepoint_check_never); - def(CompileThread_lock , Monitor, nonleaf+5, false, Monitor::_safepoint_check_always); - def(PeriodicTask_lock , Monitor, nonleaf+5, true, Monitor::_safepoint_check_sometimes); - def(RedefineClasses_lock , Monitor, nonleaf+5, true, Monitor::_safepoint_check_always); + def(MethodCompileQueue_lock , PaddedMonitor, nonleaf+4, true, Monitor::_safepoint_check_always); + def(Debug2_lock , PaddedMutex , nonleaf+4, true, Monitor::_safepoint_check_never); + def(Debug3_lock , PaddedMutex , nonleaf+4, true, Monitor::_safepoint_check_never); + def(CompileThread_lock , PaddedMonitor, nonleaf+5, false, Monitor::_safepoint_check_always); + def(PeriodicTask_lock , PaddedMonitor, nonleaf+5, true, Monitor::_safepoint_check_sometimes); + def(RedefineClasses_lock , PaddedMonitor, nonleaf+5, true, Monitor::_safepoint_check_always); if (WhiteBoxAPI) { - def(Compilation_lock , Monitor, leaf, false, Monitor::_safepoint_check_never); + def(Compilation_lock , PaddedMonitor, leaf, false, Monitor::_safepoint_check_never); } #ifdef INCLUDE_TRACE - def(JfrMsg_lock , Monitor, leaf, true, Monitor::_safepoint_check_always); - def(JfrBuffer_lock , Mutex, leaf, true, Monitor::_safepoint_check_never); - def(JfrThreadGroups_lock , Mutex, leaf, true, Monitor::_safepoint_check_always); - def(JfrStream_lock , Mutex, leaf+1, true, Monitor::_safepoint_check_never); // ensure to rank lower than 'safepoint' - def(JfrStacktrace_lock , Mutex, special, true, Monitor::_safepoint_check_sometimes); + def(JfrMsg_lock , PaddedMonitor, leaf, true, Monitor::_safepoint_check_always); + def(JfrBuffer_lock , PaddedMutex , leaf, true, Monitor::_safepoint_check_never); + def(JfrThreadGroups_lock , PaddedMutex , leaf, true, Monitor::_safepoint_check_always); + def(JfrStream_lock , PaddedMutex , leaf+1, true, Monitor::_safepoint_check_never); // ensure to rank lower than 'safepoint' + def(JfrStacktrace_lock , PaddedMutex , special, true, Monitor::_safepoint_check_sometimes); #endif #ifndef SUPPORTS_NATIVE_CX8 - def(UnsafeJlong_lock , Mutex, special, false, Monitor::_safepoint_check_never); + def(UnsafeJlong_lock , PaddedMutex , special, false, Monitor::_safepoint_check_never); #endif }