--- old/src/hotspot/share/runtime/synchronizer.cpp 2019-03-11 14:27:21.554354113 +0100 +++ new/src/hotspot/share/runtime/synchronizer.cpp 2019-03-11 14:27:21.326354116 +0100 @@ -129,6 +129,19 @@ static volatile int gMonitorFreeCount = 0; // # on gFreeList static volatile int gMonitorPopulation = 0; // # Extant -- in circulation +#define CHECK_THROW_NOSYNC_IMSE(obj) \ + if ((obj)->mark()->is_always_locked()) { \ + ResourceMark rm(THREAD); \ + THROW_MSG(vmSymbols::java_lang_IllegalMonitorStateException(), obj->klass()->external_name()); \ + } + +#define CHECK_THROW_NOSYNC_IMSE_0(obj) \ + if ((obj)->mark()->is_always_locked()) { \ + ResourceMark rm(THREAD); \ + THROW_MSG_0(vmSymbols::java_lang_IllegalMonitorStateException(), obj->klass()->external_name()); \ + } + + #define CHAINMARKER (cast_to_oop(-1)) @@ -160,6 +173,7 @@ assert(((JavaThread *) self)->thread_state() == _thread_in_Java, "invariant"); NoSafepointVerifier nsv; if (obj == NULL) return false; // slow-path for invalid obj + assert(!EnableValhalla || !obj->klass()->is_value(), "monitor op on value type"); const markOop mark = obj->mark(); if (mark->has_locker() && self->is_lock_owned((address)mark->locker())) { @@ -210,6 +224,7 @@ assert(((JavaThread *) Self)->thread_state() == _thread_in_Java, "invariant"); NoSafepointVerifier nsv; if (obj == NULL) return false; // Need to throw NPE + assert(!EnableValhalla || !obj->klass()->is_value(), "monitor op on value type"); const markOop mark = obj->mark(); if (mark->has_monitor()) { @@ -265,6 +280,7 @@ void ObjectSynchronizer::fast_enter(Handle obj, BasicLock* lock, bool attempt_rebias, TRAPS) { + CHECK_THROW_NOSYNC_IMSE(obj); if (UseBiasedLocking) { if (!SafepointSynchronize::is_at_safepoint()) { BiasedLocking::Condition cond = BiasedLocking::revoke_and_rebias(obj, attempt_rebias, THREAD); @@ -283,6 +299,10 @@ void ObjectSynchronizer::fast_exit(oop object, BasicLock* lock, TRAPS) { markOop mark = object->mark(); + if (EnableValhalla && mark->is_always_locked()) { + return; + } + assert(!EnableValhalla || !object->klass()->is_value(), "monitor op on value type"); // We cannot check for Biased Locking if we are racing an inflation. assert(mark == markOopDesc::INFLATING() || !mark->has_bias_pattern(), "should not see bias pattern here"); @@ -336,6 +356,7 @@ // We don't need to use fast path here, because it must have been // failed in the interpreter/compiler code. void ObjectSynchronizer::slow_enter(Handle obj, BasicLock* lock, TRAPS) { + CHECK_THROW_NOSYNC_IMSE(obj); markOop mark = obj->mark(); assert(!mark->has_bias_pattern(), "should not see bias pattern here"); @@ -384,6 +405,7 @@ // 5) lock lock2 // NOTE: must use heavy weight monitor to handle complete_exit/reenter() intptr_t ObjectSynchronizer::complete_exit(Handle obj, TRAPS) { + assert(!EnableValhalla || !obj->klass()->is_value(), "monitor op on value type"); if (UseBiasedLocking) { BiasedLocking::revoke_and_rebias(obj, false, THREAD); assert(!obj->mark()->has_bias_pattern(), "biases should be revoked by now"); @@ -396,6 +418,7 @@ // NOTE: must use heavy weight monitor to handle complete_exit/reenter() void ObjectSynchronizer::reenter(Handle obj, intptr_t recursion, TRAPS) { + assert(!EnableValhalla || !obj->klass()->is_value(), "monitor op on value type"); if (UseBiasedLocking) { BiasedLocking::revoke_and_rebias(obj, false, THREAD); assert(!obj->mark()->has_bias_pattern(), "biases should be revoked by now"); @@ -410,6 +433,7 @@ // NOTE: must use heavy weight monitor to handle jni monitor enter void ObjectSynchronizer::jni_enter(Handle obj, TRAPS) { // the current locking is from JNI instead of Java code + CHECK_THROW_NOSYNC_IMSE(obj); if (UseBiasedLocking) { BiasedLocking::revoke_and_rebias(obj, false, THREAD); assert(!obj->mark()->has_bias_pattern(), "biases should be revoked by now"); @@ -421,6 +445,7 @@ // NOTE: must use heavy weight monitor to handle jni monitor exit void ObjectSynchronizer::jni_exit(oop obj, Thread* THREAD) { + CHECK_THROW_NOSYNC_IMSE(obj); if (UseBiasedLocking) { Handle h_obj(THREAD, obj); BiasedLocking::revoke_and_rebias(h_obj, false, THREAD); @@ -461,6 +486,7 @@ // Wait/Notify/NotifyAll // NOTE: must use heavy weight monitor to handle wait() int ObjectSynchronizer::wait(Handle obj, jlong millis, TRAPS) { + CHECK_THROW_NOSYNC_IMSE_0(obj); if (UseBiasedLocking) { BiasedLocking::revoke_and_rebias(obj, false, THREAD); assert(!obj->mark()->has_bias_pattern(), "biases should be revoked by now"); @@ -481,6 +507,7 @@ } void ObjectSynchronizer::waitUninterruptibly(Handle obj, jlong millis, TRAPS) { + CHECK_THROW_NOSYNC_IMSE(obj); if (UseBiasedLocking) { BiasedLocking::revoke_and_rebias(obj, false, THREAD); assert(!obj->mark()->has_bias_pattern(), "biases should be revoked by now"); @@ -492,6 +519,7 @@ } void ObjectSynchronizer::notify(Handle obj, TRAPS) { + CHECK_THROW_NOSYNC_IMSE(obj); if (UseBiasedLocking) { BiasedLocking::revoke_and_rebias(obj, false, THREAD); assert(!obj->mark()->has_bias_pattern(), "biases should be revoked by now"); @@ -506,6 +534,7 @@ // NOTE: see comment of notify() void ObjectSynchronizer::notifyall(Handle obj, TRAPS) { + CHECK_THROW_NOSYNC_IMSE(obj); if (UseBiasedLocking) { BiasedLocking::revoke_and_rebias(obj, false, THREAD); assert(!obj->mark()->has_bias_pattern(), "biases should be revoked by now"); @@ -679,6 +708,14 @@ } intptr_t ObjectSynchronizer::FastHashCode(Thread * Self, oop obj) { + if (EnableValhalla && obj->klass()->is_value()) { + // Expected tooling to override hashCode for value type, just don't crash + if (log_is_enabled(Debug, monitorinflation)) { + ResourceMark rm; + log_debug(monitorinflation)("FastHashCode for value type: %s", obj->klass()->external_name()); + } + return obj->klass()->java_mirror()->identity_hash(); + } if (UseBiasedLocking) { // NOTE: many places throughout the JVM do not expect a safepoint // to be taken here, in particular most operations on perm gen @@ -783,15 +820,12 @@ return hash; } -// Deprecated -- use FastHashCode() instead. - -intptr_t ObjectSynchronizer::identity_hash_value_for(Handle obj) { - return FastHashCode(Thread::current(), obj()); -} - bool ObjectSynchronizer::current_thread_holds_lock(JavaThread* thread, Handle h_obj) { + if (EnableValhalla && h_obj->mark()->is_always_locked()) { + return false; + } if (UseBiasedLocking) { BiasedLocking::revoke_and_rebias(h_obj, false, thread); assert(!h_obj->mark()->has_bias_pattern(), "biases should be revoked by now"); @@ -1302,6 +1336,10 @@ assert(Universe::verify_in_progress() || !SafepointSynchronize::is_at_safepoint(), "invariant"); + if (EnableValhalla) { + guarantee(!object->klass()->is_value(), "Attempt to inflate value type"); + } + EventJavaMonitorInflate event; for (;;) {