comparison src/share/vm/runtime/os.cpp @ 55:2a8eb116ebbe

6610420: Debug VM crashes during monitor lock rank checking Summary: Make SerializePage lock as raw lock and add name for mutex locks Reviewed-by: never, dice, dholmes
author xlu
date Tue, 05 Feb 2008 23:21:57 -0800
parents a61af66fc99e
children 5a76ab815e34
comparison
equal deleted inserted replaced
54:d4a0f561287a 55:2a8eb116ebbe
954 Arguments::set_sysclasspath(sysclasspath); 954 Arguments::set_sysclasspath(sysclasspath);
955 955
956 return true; 956 return true;
957 } 957 }
958 958
959
960 void os::set_memory_serialize_page(address page) { 959 void os::set_memory_serialize_page(address page) {
961 int count = log2_intptr(sizeof(class JavaThread)) - log2_intptr(64); 960 int count = log2_intptr(sizeof(class JavaThread)) - log2_intptr(64);
962 _mem_serialize_page = (volatile int32_t *)page; 961 _mem_serialize_page = (volatile int32_t *)page;
963 // We initialize the serialization page shift count here 962 // We initialize the serialization page shift count here
964 // We assume a cache line size of 64 bytes 963 // We assume a cache line size of 64 bytes
965 assert(SerializePageShiftCount == count, 964 assert(SerializePageShiftCount == count,
966 "thread size changed, fix SerializePageShiftCount constant"); 965 "thread size changed, fix SerializePageShiftCount constant");
967 set_serialize_page_mask((uintptr_t)(vm_page_size() - sizeof(int32_t))); 966 set_serialize_page_mask((uintptr_t)(vm_page_size() - sizeof(int32_t)));
968 } 967 }
969 968
969 static volatile intptr_t SerializePageLock = 0;
970
970 // This method is called from signal handler when SIGSEGV occurs while the current 971 // This method is called from signal handler when SIGSEGV occurs while the current
971 // thread tries to store to the "read-only" memory serialize page during state 972 // thread tries to store to the "read-only" memory serialize page during state
972 // transition. 973 // transition.
973 void os::block_on_serialize_page_trap() { 974 void os::block_on_serialize_page_trap() {
974 if (TraceSafepoint) { 975 if (TraceSafepoint) {
975 tty->print_cr("Block until the serialize page permission restored"); 976 tty->print_cr("Block until the serialize page permission restored");
976 } 977 }
977 // When VMThread is holding the SerializePage_lock during modifying the 978 // When VMThread is holding the SerializePageLock during modifying the
978 // access permission of the memory serialize page, the following call 979 // access permission of the memory serialize page, the following call
979 // will block until the permission of that page is restored to rw. 980 // will block until the permission of that page is restored to rw.
980 // Generally, it is unsafe to manipulate locks in signal handlers, but in 981 // Generally, it is unsafe to manipulate locks in signal handlers, but in
981 // this case, it's OK as the signal is synchronous and we know precisely when 982 // this case, it's OK as the signal is synchronous and we know precisely when
982 // it can occur. SerializePage_lock is a transiently-held leaf lock, so 983 // it can occur.
983 // lock_without_safepoint_check should be safe. 984 Thread::muxAcquire(&SerializePageLock, "set_memory_serialize_page");
984 SerializePage_lock->lock_without_safepoint_check(); 985 Thread::muxRelease(&SerializePageLock);
985 SerializePage_lock->unlock();
986 } 986 }
987 987
988 // Serialize all thread state variables 988 // Serialize all thread state variables
989 void os::serialize_thread_states() { 989 void os::serialize_thread_states() {
990 // On some platforms such as Solaris & Linux, the time duration of the page 990 // On some platforms such as Solaris & Linux, the time duration of the page
991 // permission restoration is observed to be much longer than expected due to 991 // permission restoration is observed to be much longer than expected due to
992 // scheduler starvation problem etc. To avoid the long synchronization 992 // scheduler starvation problem etc. To avoid the long synchronization
993 // time and expensive page trap spinning, 'SerializePage_lock' is used to block 993 // time and expensive page trap spinning, 'SerializePageLock' is used to block
994 // the mutator thread if such case is encountered. Since this method is always 994 // the mutator thread if such case is encountered. See bug 6546278 for details.
995 // called by VMThread during safepoint, lock_without_safepoint_check is used 995 Thread::muxAcquire(&SerializePageLock, "serialize_thread_states");
996 // instead. See bug 6546278.
997 SerializePage_lock->lock_without_safepoint_check();
998 os::protect_memory( (char *)os::get_memory_serialize_page(), os::vm_page_size() ); 996 os::protect_memory( (char *)os::get_memory_serialize_page(), os::vm_page_size() );
999 os::unguard_memory( (char *)os::get_memory_serialize_page(), os::vm_page_size() ); 997 os::unguard_memory( (char *)os::get_memory_serialize_page(), os::vm_page_size() );
1000 SerializePage_lock->unlock(); 998 Thread::muxRelease(&SerializePageLock);
1001 } 999 }
1002 1000
1003 // Returns true if the current stack pointer is above the stack shadow 1001 // Returns true if the current stack pointer is above the stack shadow
1004 // pages, false otherwise. 1002 // pages, false otherwise.
1005 1003