During the development of: JDK-8267532 which attempts to remove extra dead code during compilation, it was discovered that the nmethod::has_monitors flag may not be correct.
The current code sets the has_monitors flag based on whether monitorenter and monitorexit bytecodes are parsed during compilation. However, not every bytecode of a method is necessarily parsed. For instance, if a branch is dead, an uncommon trap may be emitted, and then the bytecode of the branch is not parsed further.
A situation like that may make this assert in 'freeze_internal' in continuationFreezeThaw.cpp fail:
assert(monitors_on_stack(current) == ((current->held_monitor_count() - current->jni_monitor_count()) > 0),
"Held monitor count and locks on stack invariant: " INT64_FORMAT " JNI: " INT64_FORMAT, (int64_t)current->held_monitor_count(), (int64_t)current->jni_monitor_count());
We already track whether a method has monitor byte codes while rewriting byte codes. This information is available in (ci)Method::has_monitor_bytecodes(). We could simply reuse this information either to set the nmethod::has_monitor flag (patch attached). This would avoid any issues in case not every byte code is parsed.