8228858: Reimplement JVM_RawMonitors to use PlatformMutex

Reviewed-by: coleenp, dcubed, pchilanomate
This commit is contained in:
David Holmes 2019-08-14 18:26:23 -04:00
parent 517f13e1c6
commit 000a25c0bf
4 changed files with 15 additions and 36 deletions

View File

@ -3384,32 +3384,33 @@ JVM_ENTRY(jstring, JVM_InternString(JNIEnv *env, jstring str))
JVM_END JVM_END
// Raw monitor support ////////////////////////////////////////////////////////////////////// // VM Raw monitor support //////////////////////////////////////////////////////////////////////
// The lock routine below calls lock_without_safepoint_check in order to get a raw lock // VM Raw monitors (not to be confused with JvmtiRawMonitors) are a simple mutual exclusion
// without interfering with the safepoint mechanism. The routines are not JVM_LEAF because // lock (not actually monitors: no wait/notify) that is exported by the VM for use by JDK
// they might be called by non-java threads. The JVM_LEAF installs a NoHandleMark check // library code. They may be used by JavaThreads and non-JavaThreads and do not participate
// that only works with java threads. // in the safepoint protocol, thread suspension, thread interruption, or anything of that
// nature. JavaThreads will be "in native" when using this API from JDK code.
JNIEXPORT void* JNICALL JVM_RawMonitorCreate(void) { JNIEXPORT void* JNICALL JVM_RawMonitorCreate(void) {
VM_Exit::block_if_vm_exited(); VM_Exit::block_if_vm_exited();
JVMWrapper("JVM_RawMonitorCreate"); JVMWrapper("JVM_RawMonitorCreate");
return new Mutex(Mutex::native, "JVM_RawMonitorCreate"); return new os::PlatformMutex();
} }
JNIEXPORT void JNICALL JVM_RawMonitorDestroy(void *mon) { JNIEXPORT void JNICALL JVM_RawMonitorDestroy(void *mon) {
VM_Exit::block_if_vm_exited(); VM_Exit::block_if_vm_exited();
JVMWrapper("JVM_RawMonitorDestroy"); JVMWrapper("JVM_RawMonitorDestroy");
delete ((Mutex*) mon); delete ((os::PlatformMutex*) mon);
} }
JNIEXPORT jint JNICALL JVM_RawMonitorEnter(void *mon) { JNIEXPORT jint JNICALL JVM_RawMonitorEnter(void *mon) {
VM_Exit::block_if_vm_exited(); VM_Exit::block_if_vm_exited();
JVMWrapper("JVM_RawMonitorEnter"); JVMWrapper("JVM_RawMonitorEnter");
((Mutex*) mon)->jvm_raw_lock(); ((os::PlatformMutex*) mon)->lock();
return 0; return 0;
} }
@ -3417,7 +3418,7 @@ JNIEXPORT jint JNICALL JVM_RawMonitorEnter(void *mon) {
JNIEXPORT void JNICALL JVM_RawMonitorExit(void *mon) { JNIEXPORT void JNICALL JVM_RawMonitorExit(void *mon) {
VM_Exit::block_if_vm_exited(); VM_Exit::block_if_vm_exited();
JVMWrapper("JVM_RawMonitorExit"); JVMWrapper("JVM_RawMonitorExit");
((Mutex*) mon)->jvm_raw_unlock(); ((os::PlatformMutex*) mon)->unlock();
} }

View File

@ -232,24 +232,6 @@ bool Monitor::wait(long timeout, bool as_suspend_equivalent) {
return wait_status != 0; // return true IFF timeout return wait_status != 0; // return true IFF timeout
} }
// Temporary JVM_RawMonitor* support.
// Yet another degenerate version of Monitor::lock() or lock_without_safepoint_check()
// jvm_raw_lock() and _unlock() can be called by non-Java threads via JVM_RawMonitorEnter.
// There's no expectation that JVM_RawMonitors will interoperate properly with the native
// Mutex-Monitor constructs. We happen to implement JVM_RawMonitors in terms of
// native Mutex-Monitors simply as a matter of convenience.
void Monitor::jvm_raw_lock() {
_lock.lock();
assert_owner(NULL);
}
void Monitor::jvm_raw_unlock() {
assert_owner(NULL);
_lock.unlock();
}
Monitor::~Monitor() { Monitor::~Monitor() {
assert_owner(NULL); assert_owner(NULL);
} }

View File

@ -52,8 +52,10 @@ class Monitor : public CHeapObj<mtSynchronizer> {
// inherently a bit more special than even locks of the 'special' rank. // inherently a bit more special than even locks of the 'special' rank.
// NOTE: It is critical that the rank 'special' be the lowest (earliest) // NOTE: It is critical that the rank 'special' be the lowest (earliest)
// (except for "event" and "access") for the deadlock detection to work correctly. // (except for "event" and "access") for the deadlock detection to work correctly.
// The rank native is only for use in Mutex's created by JVM_RawMonitorCreate, // The rank native was only for use in Mutexes created by JVM_RawMonitorCreate,
// which being external to the VM are not subject to deadlock detection. // which being external to the VM are not subject to deadlock detection,
// however it has now been used by other locks that don't fit into the
// deadlock detection scheme.
// While at a safepoint no mutexes of rank safepoint are held by any thread. // While at a safepoint no mutexes of rank safepoint are held by any thread.
// The rank named "leaf" is probably historical (and should // The rank named "leaf" is probably historical (and should
// be changed) -- mutexes of this rank aren't really leaf mutexes // be changed) -- mutexes of this rank aren't really leaf mutexes
@ -174,10 +176,6 @@ class Monitor : public CHeapObj<mtSynchronizer> {
Thread* owner() const { return _owner; } Thread* owner() const { return _owner; }
bool owned_by_self() const; bool owned_by_self() const;
// Support for JVM_RawMonitorEnter & JVM_RawMonitorExit. These can be called by
// non-Java thread. (We should really have a RawMonitor abstraction)
void jvm_raw_lock();
void jvm_raw_unlock();
const char *name() const { return _name; } const char *name() const { return _name; }
void print_on_error(outputStream* st) const; void print_on_error(outputStream* st) const;

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -53,7 +53,6 @@ volatile int ParkEvent::ListLock = 0 ;
ParkEvent * volatile ParkEvent::FreeList = NULL ; ParkEvent * volatile ParkEvent::FreeList = NULL ;
ParkEvent * ParkEvent::Allocate (Thread * t) { ParkEvent * ParkEvent::Allocate (Thread * t) {
// In rare cases -- JVM_RawMonitor* operations -- we can find t == null.
ParkEvent * ev ; ParkEvent * ev ;
// Start by trying to recycle an existing but unassociated // Start by trying to recycle an existing but unassociated
@ -164,4 +163,3 @@ void Parker::Release (Parker * p) {
} }
Thread::SpinRelease(&ListLock); Thread::SpinRelease(&ListLock);
} }