throw new IllegalMonitorStateException();
throw new IllegalMonitorStateException("waiting on " + o);
  public static void wait (Object o) {    if (VM.BuildForEventLogging && VM.EventLoggingEnabled) { VM_EventLogger.logWaitBegin(); }    VM_Thread t = VM_Thread.getCurrentThread();    t.proxy = new VM_Proxy(t); // cache the proxy before obtaining lock    VM_Lock l = getHeavyLock(o);    if (l == null) l = inflate(o);    // this thread is supposed to own the lock on o    if (l.ownerId != VM_Magic.getThreadId())      throw new IllegalMonitorStateException();    // allow an entering thread a chance to get the lock    l.mutex.lock(); // until unlock(), thread-switching fatal    VM_Thread n = l.entering.dequeue();    if (n != null) n.scheduleHighPriority();    // squirrel away lock state in current thread    t.waitObject = l.lockedObject;    t.waitCount  = l.recursionCount;    // release l and simultaneously put t on l's waiting queue    l.ownerId = 0;    Throwable rethrow = null;    try {      t.yield(l.waiting, l.mutex); // thread-switching benign    } catch (Throwable thr) {      rethrow = thr; // An InterruptedException. We'll rethrow it after regaining the lock on o.    }    // regain lock    lock(o);    t.waitObject = null;              if (t.waitCount != 1) { // reset recursion count      l = getHeavyLock(o);      if (l == null) l = inflate(o);      l.recursionCount = t.waitCount;    }    if (rethrow != null) {      VM_Runtime.athrow(rethrow); // doesn't return    }    if (VM.BuildForEventLogging && VM.EventLoggingEnabled) { VM_EventLogger.logWaitEnd(); }  }