public void leave(ThreadInfo ti) { // <2do> - that's not really enough, we might have suspicious bytecode that fails // to release locks acquired by monitor_enter (e.g. by not having a handler that // monitor_exits & re-throws). That's probably shifted into the bytecode verifier // in the future (i.e. outside JPF), but maybe we should add an explicit test here // and report an error if the code does asymmetric locking (according to the specs, // VMs are allowed to silently fix this, so it might run on some and fail on others) if (isSynchronized()) { ElementInfo ei = getBlockedObject(ti, false); ei.unlock(ti); if (isStatic() && isClinit()) { // we just released the lock on the class object, returning from a clinit // now we can consider this class to be initialized. // NOTE this is still part of the RETURN insn of clinit, so ClassInfo.isInitialized // is protected ci.setInitialized(); } } ti.getVM().notifyMethodExited(ti, this); }