OSDN Git Service

bf38433a758bfa8d545b1995f7336690be6ebda3
[pf3gnuchains/gcc-fork.git] / libjava / java / lang / natObject.cc
1 // natObject.cc - Implementation of the Object class.
2
3 /* Copyright (C) 1998, 1999, 2000, 2001  Free Software Foundation
4
5    This file is part of libgcj.
6
7 This software is copyrighted work licensed under the terms of the
8 Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
9 details.  */
10
11 #include <config.h>
12
13 #include <string.h>
14
15 #pragma implementation "Object.h"
16
17 #include <gcj/cni.h>
18 #include <jvm.h>
19 #include <java/lang/Object.h>
20 #include <java-threads.h>
21 #include <java-signal.h>
22 #include <java/lang/CloneNotSupportedException.h>
23 #include <java/lang/IllegalArgumentException.h>
24 #include <java/lang/IllegalMonitorStateException.h>
25 #include <java/lang/InterruptedException.h>
26 #include <java/lang/NullPointerException.h>
27 #include <java/lang/Class.h>
28 #include <java/lang/Cloneable.h>
29 #include <java/lang/Thread.h>
30
31 #ifdef LOCK_DEBUG
32 #  include <stdio.h>
33 #endif
34
35 \f
36
37 // This is used to represent synchronization information.
38 struct _Jv_SyncInfo
39 {
40 #if defined (_Jv_HaveCondDestroy) || defined (_Jv_HaveMutexDestroy)
41   // We only need to keep track of initialization state if we can
42   // possibly finalize this object.
43   bool init;
44 #endif
45   _Jv_ConditionVariable_t condition;
46   _Jv_Mutex_t mutex;
47 };
48
49 \f
50
51 jclass
52 java::lang::Object::getClass (void)
53 {
54   _Jv_VTable **dt = (_Jv_VTable **) this;
55   return (*dt)->clas;
56 }
57
58 jint
59 java::lang::Object::hashCode (void)
60 {
61   return _Jv_HashCode (this);
62 }
63
64 jobject
65 java::lang::Object::clone (void)
66 {
67   jclass klass = getClass ();
68   jobject r;
69   jint size;
70
71   // We also clone arrays here.  If we put the array code into
72   // __JArray, then we'd have to figure out a way to find the array
73   // vtbl when creating a new array class.  This is easier, if uglier.
74   if (klass->isArray())
75     {
76       __JArray *array = (__JArray *) this;
77       jclass comp = getClass()->getComponentType();
78       jint eltsize;
79       if (comp->isPrimitive())
80         {
81           r = _Jv_NewPrimArray (comp, array->length);
82           eltsize = comp->size();
83         }
84       else
85         {
86           r = _Jv_NewObjectArray (array->length, comp, NULL);
87           eltsize = sizeof (jobject);
88         }
89       // We can't use sizeof on __JArray because we must account for
90       // alignment of the element type.
91       size = (_Jv_GetArrayElementFromElementType (array, comp) - (char *) array
92               + array->length * eltsize);
93     }
94   else
95     {
96       if (! java::lang::Cloneable::class$.isAssignableFrom(klass))
97         throw new CloneNotSupportedException;
98
99       size = klass->size();
100       r = JvAllocObject (klass, size);
101     }
102
103   memcpy ((void *) r, (void *) this, size);
104   return r;
105 }
106
107 void
108 _Jv_FinalizeObject (jobject obj)
109 {
110   // Ignore exceptions.  From section 12.6 of the Java Language Spec.
111   try
112     {
113       obj->finalize ();
114     }
115   catch (java::lang::Throwable *t)
116     {
117       // Ignore.
118     }
119 }
120
121
122 //
123 // Synchronization code.
124 //
125
126 #ifndef JV_HASH_SYNCHRONIZATION
127 // This global is used to make sure that only one thread sets an
128 // object's `sync_info' field.
129 static _Jv_Mutex_t sync_mutex;
130
131 // This macro is used to see if synchronization initialization is
132 // needed.
133 #if defined (_Jv_HaveCondDestroy) || defined (_Jv_HaveMutexDestroy)
134 #  define INIT_NEEDED(Obj) (! (Obj)->sync_info \
135                             || ! ((_Jv_SyncInfo *) ((Obj)->sync_info))->init)
136 #else
137 #  define INIT_NEEDED(Obj) (! (Obj)->sync_info)
138 #endif
139
140 #if defined (_Jv_HaveCondDestroy) || defined (_Jv_HaveMutexDestroy)
141 // If we have to run a destructor for a sync_info member, then this
142 // function is registered as a finalizer for the sync_info.
143 static void
144 finalize_sync_info (jobject obj)
145 {
146   _Jv_SyncInfo *si = (_Jv_SyncInfo *) obj;
147 #if defined (_Jv_HaveCondDestroy)
148   _Jv_CondDestroy (&si->condition);
149 #endif
150 #if defined (_Jv_HaveMutexDestroy)
151   _Jv_MutexDestroy (&si->mutex);
152 #endif
153   si->init = false;
154 }
155 #endif
156
157 // This is called to initialize the sync_info element of an object.
158 void
159 java::lang::Object::sync_init (void)
160 {
161   _Jv_MutexLock (&sync_mutex);
162   // Check again to see if initialization is needed now that we have
163   // the lock.
164   if (INIT_NEEDED (this))
165     {
166       // We assume there are no pointers in the sync_info
167       // representation.
168       _Jv_SyncInfo *si;
169       // We always create a new sync_info, even if there is already
170       // one available.  Any given object can only be finalized once.
171       // If we get here and sync_info is not null, then it has already
172       // been finalized.  So if we just reinitialize the old one,
173       // we'll never be able to (re-)destroy the mutex and/or
174       // condition variable.
175       si = (_Jv_SyncInfo *) _Jv_AllocBytes (sizeof (_Jv_SyncInfo));
176       _Jv_MutexInit (&si->mutex);
177       _Jv_CondInit (&si->condition);
178 #if defined (_Jv_HaveCondDestroy) || defined (_Jv_HaveMutexDestroy)
179       // Register a finalizer.
180       si->init = true;
181       _Jv_RegisterFinalizer (si, finalize_sync_info);
182 #endif
183       sync_info = (jobject) si;
184     }
185   _Jv_MutexUnlock (&sync_mutex);
186 }
187
188 void
189 java::lang::Object::notify (void)
190 {
191   if (__builtin_expect (INIT_NEEDED (this), false))
192     sync_init ();
193   _Jv_SyncInfo *si = (_Jv_SyncInfo *) sync_info;
194   if (__builtin_expect (_Jv_CondNotify (&si->condition, &si->mutex), false))
195     throw new IllegalMonitorStateException(JvNewStringLatin1 
196                                            ("current thread not owner"));
197 }
198
199 void
200 java::lang::Object::notifyAll (void)
201 {
202   if (__builtin_expect (INIT_NEEDED (this), false))
203     sync_init ();
204   _Jv_SyncInfo *si = (_Jv_SyncInfo *) sync_info;
205   if (__builtin_expect (_Jv_CondNotifyAll (&si->condition, &si->mutex), false))
206     throw new IllegalMonitorStateException(JvNewStringLatin1 
207                                            ("current thread not owner"));
208 }
209
210 void
211 java::lang::Object::wait (jlong timeout, jint nanos)
212 {
213   if (__builtin_expect (INIT_NEEDED (this), false))
214     sync_init ();
215   if (__builtin_expect (timeout < 0 || nanos < 0 || nanos > 999999, false))
216     throw new IllegalArgumentException;
217   _Jv_SyncInfo *si = (_Jv_SyncInfo *) sync_info;
218   switch (_Jv_CondWait (&si->condition, &si->mutex, timeout, nanos))
219     {
220       case _JV_NOT_OWNER:
221         throw new IllegalMonitorStateException (JvNewStringLatin1 
222                                                 ("current thread not owner"));
223       case _JV_INTERRUPTED:
224         if (Thread::interrupted ())
225           throw new InterruptedException;
226     }
227 }
228
229 //
230 // Some runtime code.
231 //
232
233 // This function is called at system startup to initialize the
234 // `sync_mutex'.
235 void
236 _Jv_InitializeSyncMutex (void)
237 {
238   _Jv_MutexInit (&sync_mutex);
239 }
240
241 void
242 _Jv_MonitorEnter (jobject obj)
243 {
244 #ifndef HANDLE_SEGV
245   if (__builtin_expect (! obj, false))
246     throw new java::lang::NullPointerException;
247 #endif
248   if (__builtin_expect (INIT_NEEDED (obj), false))
249     obj->sync_init ();
250   _Jv_SyncInfo *si = (_Jv_SyncInfo *) obj->sync_info;
251   _Jv_MutexLock (&si->mutex);
252   // FIXME: In the Windows case, this can return a nonzero error code.
253   // We should turn that into some exception ...
254 }
255
256 void
257 _Jv_MonitorExit (jobject obj)
258 {
259   JvAssert (obj);
260   JvAssert (! INIT_NEEDED (obj));
261   _Jv_SyncInfo *si = (_Jv_SyncInfo *) obj->sync_info;
262   if (__builtin_expect (_Jv_MutexUnlock (&si->mutex), false))
263     throw new java::lang::IllegalMonitorStateException;
264 }
265
266 #else /* JV_HASH_SYNCHRONIZATION */
267
268 // FIXME: We shouldn't be calling GC_register_finalizer directly.
269 #ifndef HAVE_BOEHM_GC
270 # error Hash synchronization currently requires boehm-gc
271 // That's actually a bit of a lie: It should also work with the null GC,
272 // probably even better than the alternative.
273 // To really support alternate GCs here, we would need to widen the
274 // interface to finalization, since we sometimes have to register a
275 // second finalizer for an object that already has one.
276 // We might also want to move the GC interface to a .h file, since
277 // the number of procedure call levels involved in some of these
278 // operations is already ridiculous, and would become worse if we
279 // went through the proper intermediaries.
280 #else
281 # include "gc.h"
282 #endif
283
284 // What follows currenly assumes a Linux-like platform.
285 // Some of it specifically assumes X86 or IA64 Linux, though that
286 // should be easily fixable.
287
288 // A Java monitor implemention based on a table of locks.
289 // Each entry in the table describes
290 // locks held for objects that hash to that location.
291 // This started out as a reimplementation of the technique used in SGIs JVM,
292 // for which we obtained permission from SGI.
293 // But in fact, this ended up quite different, though some ideas are
294 // still shared with the original.
295 // It was also influenced by some of the published IBM work,
296 // though it also differs in many ways from that.
297 // We could speed this up if we had a way to atomically update
298 // an entire cache entry, i.e. 2 contiguous words of memory.
299 // That would usually be the case with a 32 bit ABI on a 64 bit processor.
300 // But we don't currently go out of our way to target those.
301 // I don't know how to do much better with a N bit ABI on a processor
302 // that can atomically update only N bits at a time.
303 // Author: Hans-J. Boehm  (Hans_Boehm@hp.com, boehm@acm.org)
304
305 #include <assert.h>
306 #include <limits.h>
307 #include <unistd.h>     // for usleep, sysconf.
308 #include <sched.h>      // for sched_yield.
309 #include <gcj/javaprims.h>
310
311 typedef size_t obj_addr_t;      /* Integer type big enough for object   */
312                                 /* address.                             */
313
314 // The following should move to some standard place. Linux-threads
315 // already defines roughly these, as do more recent versions of boehm-gc.
316 // The problem is that neither exports them.
317
318 #if defined(__GNUC__) && defined(__i386__)
319   // Atomically replace *addr by new_val if it was initially equal to old.
320   // Return true if the comparison succeeded.
321   // Assumed to have acquire semantics, i.e. later memory operations
322   // cannot execute before the compare_and_swap finishes.
323   inline static bool
324   compare_and_swap(volatile obj_addr_t *addr,
325                                                 obj_addr_t old,
326                                                 obj_addr_t new_val) 
327   {
328     char result;
329     __asm__ __volatile__("lock; cmpxchgl %2, %0; setz %1"
330                 : "+m"(*(addr)), "=q"(result)
331                 : "r" (new_val), "a"(old)
332                 : "memory");
333     return (bool) result;
334   }
335
336   // Set *addr to new_val with release semantics, i.e. making sure
337   // that prior loads and stores complete before this
338   // assignment.
339   // On X86, the hardware shouldn't reorder reads and writes,
340   // so we just have to convince gcc not to do it either.
341   inline static void
342   release_set(volatile obj_addr_t *addr, obj_addr_t new_val)
343   {
344     __asm__ __volatile__(" " : : : "memory");
345     *(addr) = new_val;
346   }
347
348   // Compare_and_swap with release semantics instead of acquire semantics.
349   // On many architecture, the operation makes both guarantees, so the
350   // implementation can be the same.
351   inline static bool
352   compare_and_swap_release(volatile obj_addr_t *addr,
353                                                        obj_addr_t old,
354                                                        obj_addr_t new_val)
355   {
356     return compare_and_swap(addr, old, new_val);
357   }
358 #endif
359
360 #if defined(__GNUC__) && defined(__ia64__) && SIZEOF_VOID_P == 8
361   inline static bool
362   compare_and_swap(volatile obj_addr_t *addr,
363                                                 obj_addr_t old,
364                                                 obj_addr_t new_val) 
365   {
366     unsigned long oldval;
367     __asm__ __volatile__("mov ar.ccv=%4 ;; cmpxchg8.acq %0=%1,%2,ar.ccv"
368                 : "=r"(oldval), "=m"(*addr)
369                 : "r"(new_val), "1"(*addr), "r"(old) : "memory");
370     return (oldval == old);
371   }
372
373   // The fact that *addr is volatile should cause the compiler to
374   // automatically generate an st8.rel.
375   inline static void
376   release_set(volatile obj_addr_t *addr, obj_addr_t new_val)
377   {
378     __asm__ __volatile__(" " : : : "memory");
379     *(addr) = new_val;
380   }
381
382   inline static bool
383   compare_and_swap_release(volatile obj_addr_t *addr,
384                                                        obj_addr_t old,
385                                                        obj_addr_t new_val) 
386   {
387     unsigned long oldval;
388     __asm__ __volatile__("mov ar.ccv=%4 ;; cmpxchg8.rel %0=%1,%2,ar.ccv"
389                 : "=r"(oldval), "=m"(*addr)
390                 : "r"(new_val), "1"(*addr), "r"(old) : "memory");
391     return (oldval == old);
392   }
393 #endif
394
395 #if defined(__GNUC__) && defined(__alpha__)
396   inline static bool
397   compare_and_swap(volatile obj_addr_t *addr,
398                                                 obj_addr_t old,
399                                                 obj_addr_t new_val) 
400   {
401     unsigned long oldval;
402     char result;
403     __asm__ __volatile__(
404         "1:ldq_l %0, %1\n\t" \
405         "cmpeq %0, %5, %2\n\t" \
406         "beq %2, 2f\n\t" \
407         "mov %3, %0\n\t" \
408         "stq_c %0, %1\n\t" \
409         "bne %0, 2f\n\t" \
410         "br 1b\n\t" \
411         "2:mb"
412                 : "=&r"(oldval), "=m"(*addr), "=&r"(result)
413                 : "r" (new_val), "m"(*addr), "r"(old) : "memory");
414     return (bool) result;
415   }
416
417   inline static void
418   release_set(volatile obj_addr_t *addr, obj_addr_t new_val)
419   {
420     __asm__ __volatile__("mb" : : : "memory");
421     *(addr) = new_val;
422   }
423
424   inline static bool
425   compare_and_swap_release(volatile obj_addr_t *addr,
426                                                        obj_addr_t old,
427                                                        obj_addr_t new_val)
428   {
429     return compare_and_swap(addr, old, new_val);
430   }
431 #endif
432
433 // Try to determine whether we are on a multiprocessor, i.e. whether
434 // spinning may be profitable.
435 // This should really use a suitable autoconf macro.
436 // False is the conservative answer, though the right one is much better.
437 static bool
438 is_mp()
439 {
440 #ifdef _SC_NPROCESSORS_ONLN
441   long nprocs = sysconf(_SC_NPROCESSORS_ONLN);
442   return (nprocs > 1);
443 #else
444   return false;
445 #endif
446 }
447
448 // A call to keep_live(p) forces p to be accessible to the GC
449 // at this point.
450 inline static void
451 keep_live(obj_addr_t p)
452 {
453     __asm__ __volatile__("" : : "rm"(p) : "memory");
454 }
455
456
457 // Each hash table entry holds a single preallocated "lightweight" lock.
458 // In addition, it holds a chain of "heavyweight" locks.  Lightweight
459 // locks do not support Object.wait(), and are converted to heavyweight
460 // status in response to contention.  Unlike the SGI scheme, both
461 // ligtweight and heavyweight locks in one hash entry can be simultaneously
462 // in use.  (The SGI scheme requires that we be able to acquire a heavyweight
463 // lock on behalf of another thread, and can thus convert a lock we don't
464 // hold to heavyweight status.  Here we don't insist on that, and thus
465 // let the original holder of the lighweight lock keep it.)
466
467 struct heavy_lock {
468   void * reserved_for_gc;
469   struct heavy_lock *next;      // Hash chain link.
470                                 // Traced by GC.
471   void * old_client_data;       // The only other field traced by GC.
472   GC_finalization_proc old_finalization_proc;
473   obj_addr_t address;           // Object to which this lock corresponds.
474                                 // Should not be traced by GC.
475                                 // Cleared as heavy_lock is destroyed.
476                                 // Together with the rest of the hevy lock
477                                 // chain, this is protected by the lock
478                                 // bit in the hash table entry to which
479                                 // the chain is attached.
480   _Jv_SyncInfo si;
481   // The remaining fields save prior finalization info for
482   // the object, which we needed to replace in order to arrange
483   // for cleanup of the lock structure.
484 };
485
486 #ifdef LOCK_DEBUG
487 void
488 print_hl_list(heavy_lock *hl)
489 {
490     heavy_lock *p = hl;
491     for (; 0 != p; p = p->next)
492       fprintf (stderr, "(hl = %p, addr = %p)", p, (void *)(p -> address));
493 }
494 #endif /* LOCK_DEBUG */
495
496 #if defined (_Jv_HaveCondDestroy) || defined (_Jv_HaveMutexDestroy)
497 // If we have to run a destructor for a sync_info member, then this
498 // function could be registered as a finalizer for the sync_info.
499 // In fact, we now only invoke it explicitly.
500 static inline void
501 heavy_lock_finalization_proc (heavy_lock *hl)
502 {
503 #if defined (_Jv_HaveCondDestroy)
504   _Jv_CondDestroy (&hl->si.condition);
505 #endif
506 #if defined (_Jv_HaveMutexDestroy)
507   _Jv_MutexDestroy (&hl->si.mutex);
508 #endif
509   hl->si.init = false;
510 }
511 #endif /* defined (_Jv_HaveCondDestroy) || defined (_Jv_HaveMutexDestroy) */
512
513 // We convert the lock back to lightweight status when
514 // we exit, so that a single contention episode doesn't doom the lock
515 // forever.  But we also need to make sure that lock structures for dead
516 // objects are eventually reclaimed.  We do that in a an additional
517 // finalizer on the underlying object.
518 // Note that if the corresponding object is dead, it is safe to drop
519 // the heavy_lock structure from its list.  It is not necessarily
520 // safe to deallocate it, since the unlock code could still be running.
521
522 struct hash_entry {
523   volatile obj_addr_t address;  // Address of object for which lightweight
524                                 // k is held.
525                                 // We assume the 3 low order bits are zero.
526                                 // With the Boehm collector and bitmap
527                                 // allocation, objects of size 4 bytes are
528                                 // broken anyway.  Thus this is primarily
529                                 // a constraint on statically allocated
530                                 // objects used for synchronization.
531                                 // This allows us to use the low order
532                                 // bits as follows:
533 #   define LOCKED       1       // This hash entry is locked, and its
534                                 // state may be invalid.
535                                 // The lock protects both the hash_entry
536                                 // itself (except for the light_count
537                                 // and light_thr_id fields, which
538                                 // are protected by the lightweight
539                                 // lock itself), and any heavy_monitor
540                                 // structures attached to it.
541 #   define HEAVY        2       // There may be heavyweight locks
542                                 // associated with this cache entry.
543                                 // The lightweight entry is still valid,
544                                 // if the leading bits of the address
545                                 // field are nonzero.
546                                 // Set if heavy_count is > 0 .
547                                 // Stored redundantly so a single
548                                 // compare-and-swap works in the easy case.
549 #   define REQUEST_CONVERSION 4 // The lightweight lock is held.  But
550                                 // one or more other threads have tried
551                                 // to acquire the lock, and hence request
552                                 // conversion to heavyweight status.
553 #   define FLAGS (LOCKED | HEAVY | REQUEST_CONVERSION)
554   volatile _Jv_ThreadId_t light_thr_id;
555                                 // Thr_id of holder of lightweight lock.
556                                 // Only updated by lightweight lock holder.
557                                 // Must be recognizably invalid if the
558                                 // lightweight lock is not held.
559 #   define INVALID_THREAD_ID 0  // Works for Linux?
560                                 // If zero doesn't work, we have to
561                                 // initialize lock table.
562   volatile unsigned short light_count;
563                                 // Number of times the lightweight lock
564                                 // is held minus one.  Zero if lightweight
565                                 // lock is not held.
566   unsigned short heavy_count;   // Total number of times heavyweight locks
567                                 // associated with this hash entry are held
568                                 // or waiting to be acquired.
569                                 // Threads in wait() are included eventhough
570                                 // they have temporarily released the lock.
571   struct heavy_lock * heavy_locks;
572                                 // Chain of heavy locks.  Protected
573                                 // by lockbit for he.  Locks may
574                                 // remain allocated here even if HEAVY
575                                 // is not set and heavy_count is 0.
576                                 // If a lightweight and heavyweight lock
577                                 // correspond to the same address, the
578                                 // lightweight lock is the right one.
579 };
580
581 #ifndef JV_SYNC_TABLE_SZ
582 # define JV_SYNC_TABLE_SZ 2048
583 #endif
584
585 hash_entry light_locks[JV_SYNC_TABLE_SZ];
586
587 #define JV_SYNC_HASH(p) (((long)p ^ ((long)p >> 10)) % JV_SYNC_TABLE_SZ)
588
589 // Note that the light_locks table is scanned conservatively by the
590 // collector.  It is essential the the heavy_locks field is scanned.
591 // Currently the address field may or may not cause the associated object
592 // to be retained, depending on whether flag bits are set.
593 // This means that we can conceivable get an unexpected deadlock if
594 // 1) Object at address A is locked.
595 // 2) The client drops A without unlocking it.
596 // 3) Flag bits in the address entry are set, so the collector reclaims
597 //    the object at A.
598 // 4) A is reallocated, and an attempt is made to lock the result.
599 // This could be fixed by scanning light_locks in a more customized
600 // manner that ignores the flag bits.  But it can only happen with hand
601 // generated semi-illegal .class files, and then it doesn't present a
602 // security hole.
603
604 #ifdef LOCK_DEBUG
605   void print_he(hash_entry *he)
606   {
607      fprintf(stderr, "lock hash entry = %p, index = %d, address = 0x%lx\n"
608                      "\tlight_thr_id = 0x%lx, light_count = %d, "
609                      "heavy_count = %d\n\theavy_locks:", he,
610                      he - light_locks, he -> address, he -> light_thr_id,
611                      he -> light_count, he -> heavy_count);
612      print_hl_list(he -> heavy_locks);
613      fprintf(stderr, "\n");
614   }
615 #endif /* LOCK_DEBUG */
616
617 static bool mp = false; // Known multiprocesssor.
618
619 // Wait for roughly 2^n units, touching as little memory as possible.
620 static void
621 spin(unsigned n)
622 {
623   const unsigned MP_SPINS = 10;
624   const unsigned YIELDS = 4;
625   const unsigned SPINS_PER_UNIT = 30;
626   const unsigned MIN_SLEEP_USECS = 2001; // Shorter times spin under Linux.
627   const unsigned MAX_SLEEP_USECS = 200000;
628   static unsigned spin_limit = 0;
629   static unsigned yield_limit = YIELDS;
630   static bool spin_initialized = false;
631
632   if (!spin_initialized)
633     {
634       mp = is_mp();
635       if (mp)
636         {
637           spin_limit = MP_SPINS;
638           yield_limit = MP_SPINS + YIELDS;
639         }
640       spin_initialized = true;
641     }
642   if (n < spin_limit)
643     {
644       unsigned i = SPINS_PER_UNIT << n;
645       for (; i > 0; --i)
646         __asm__ __volatile__("");
647     }
648   else if (n < yield_limit)
649     {
650       sched_yield();
651     }
652   else
653     {
654       unsigned duration = MIN_SLEEP_USECS << (n - yield_limit);
655       if (n >= 15 + yield_limit || duration > MAX_SLEEP_USECS)
656         duration = MAX_SLEEP_USECS;
657       usleep(duration);
658     }
659 }
660
661 // Wait for a hash entry to become unlocked.
662 static void
663 wait_unlocked (hash_entry *he)
664 {
665   unsigned i = 0;
666   while (he -> address & LOCKED)
667     spin (i++);
668 }
669
670 // Return the heavy lock for addr if it was already allocated.
671 // The client passes in the appropriate hash_entry.
672 // We hold the lock for he.
673 static inline heavy_lock *
674 find_heavy (obj_addr_t addr, hash_entry *he)
675 {
676   heavy_lock *hl = he -> heavy_locks;
677   while (hl != 0 && hl -> address != addr) hl = hl -> next;
678   return hl;
679 }
680
681 // Unlink the heavy lock for the given address from its hash table chain.
682 // Dies miserably and conspicuously if it's not there, since that should
683 // be impossible.
684 static inline void
685 unlink_heavy (obj_addr_t addr, hash_entry *he)
686 {
687   heavy_lock **currentp = &(he -> heavy_locks);
688   while ((*currentp) -> address != addr)
689     currentp = &((*currentp) -> next);
690   *currentp = (*currentp) -> next;
691 }
692
693 // Finalization procedure for objects that have associated heavy-weight
694 // locks.  This may replace the real finalization procedure.
695 static void
696 heavy_lock_obj_finalization_proc (void *obj, void *cd)
697 {
698   heavy_lock *hl = (heavy_lock *)cd;
699   obj_addr_t addr = (obj_addr_t)obj;
700   hash_entry *he = light_locks + JV_SYNC_HASH(addr);
701   obj_addr_t he_address = (he -> address & ~LOCKED);
702
703   // Acquire lock bit immediately.  It's possible that the hl was already
704   // destroyed while we were waiting for the finalizer to run.  If it
705   // was, the address field was set to zero.  The address filed access is
706   // protected by the lock bit to ensure that we do this exactly once.
707   // The lock bit also protects updates to the objects finalizer.
708   while (!compare_and_swap(&(he -> address), he_address, he_address|LOCKED ))
709     {
710       // Hash table entry is currently locked.  We can't safely 
711       // touch the list of heavy locks.  
712       wait_unlocked(he);
713       he_address = (he -> address & ~LOCKED);
714     }
715   if (0 == hl -> address)
716     {
717       // remove_all_heavy destroyed hl, and took care of the real finalizer.
718       release_set(&(he -> address), he_address);
719       return;
720     }
721   assert(hl -> address == addr);
722   GC_finalization_proc old_finalization_proc = hl -> old_finalization_proc;
723   if (old_finalization_proc != 0)
724     {
725       // We still need to run a real finalizer.  In an idealized
726       // world, in which people write thread-safe finalizers, that is
727       // likely to require synchronization.  Thus we reregister
728       // ourselves as the only finalizer, and simply run the real one.
729       // Thus we don't clean up the lock yet, but we're likely to do so
730       // on the next GC cycle.
731       // It's OK if remove_all_heavy actually destroys the heavy lock,
732       // since we've updated old_finalization_proc, and thus the user's
733       // finalizer won't be rerun.
734       void * old_client_data = hl -> old_client_data;
735       hl -> old_finalization_proc = 0;
736       hl -> old_client_data = 0;
737 #     ifdef HAVE_BOEHM_GC
738         GC_REGISTER_FINALIZER_NO_ORDER(obj, heavy_lock_obj_finalization_proc, cd, 0, 0);
739 #     endif
740       release_set(&(he -> address), he_address);
741       old_finalization_proc(obj, old_client_data);
742     }
743   else
744     {
745       // The object is really dead, although it's conceivable that
746       // some thread may still be in the process of releasing the
747       // heavy lock.  Unlink it and, if necessary, register a finalizer
748       // to destroy sync_info.
749       unlink_heavy(addr, he);
750       hl -> address = 0;        // Don't destroy it again.
751       release_set(&(he -> address), he_address);
752 #     if defined (_Jv_HaveCondDestroy) || defined (_Jv_HaveMutexDestroy)
753         // Make sure lock is not held and then destroy condvar and mutex.
754         _Jv_MutexLock(&(hl->si.mutex));
755         _Jv_MutexUnlock(&(hl->si.mutex));
756         heavy_lock_finalization_proc (hl);
757 #     endif
758     }
759 }
760
761 // We hold the lock on he, and heavy_count is 0.
762 // Release the lock by replacing the address with new_address_val.
763 // Remove all heavy locks on the list.  Note that the only possible way
764 // in which a lock may still be in use is if it's in the process of
765 // being unlocked.
766 static void
767 remove_all_heavy (hash_entry *he, obj_addr_t new_address_val)
768 {
769   assert(he -> heavy_count == 0);
770   assert(he -> address & LOCKED);
771   heavy_lock *hl = he -> heavy_locks;
772   he -> heavy_locks = 0;
773   // We would really like to release the lock bit here.  Unfortunately, that
774   // Creates a race between or finalizer removal, and the potential
775   // reinstallation of a new finalizer as a new heavy lock is created.
776   // This may need to be revisited.
777   for(; 0 != hl; hl = hl->next)
778     {
779       obj_addr_t obj = hl -> address;
780       assert(0 != obj); // If this was previously finalized, it should no
781                         // longer appear on our list.
782       hl -> address = 0; // Finalization proc might still see it after we
783                          // finish.
784       GC_finalization_proc old_finalization_proc = hl -> old_finalization_proc;
785       void * old_client_data = hl -> old_client_data;
786 #     ifdef HAVE_BOEHM_GC
787         // Remove our finalization procedure.
788         // Reregister the clients if applicable.
789           GC_REGISTER_FINALIZER_NO_ORDER((GC_PTR)obj, old_finalization_proc,
790                                          old_client_data, 0, 0);
791           // Note that our old finalization procedure may have been
792           // previously determined to be runnable, and may still run.
793           // FIXME - direct dependency on boehm GC.
794 #     endif
795 #     if defined (_Jv_HaveCondDestroy) || defined (_Jv_HaveMutexDestroy)
796         // Wait for a possible lock holder to finish unlocking it.
797         // This is only an issue if we have to explicitly destroy the mutex
798         // or possibly if we have to destroy a condition variable that is
799         // still being notified.
800           _Jv_MutexLock(&(hl->si.mutex));
801           _Jv_MutexUnlock(&(hl->si.mutex));
802           heavy_lock_finalization_proc (hl);
803 #     endif
804     }
805   release_set(&(he -> address), new_address_val);
806 }
807
808 // We hold the lock on he and heavy_count is 0.
809 // We release it by replacing the address field with new_address_val.
810 // Remove all heavy locks on the list if the list is sufficiently long.
811 // This is called periodically to avoid very long lists of heavy locks.
812 // This seems to otherwise become an issue with SPECjbb, for example.
813 static inline void
814 maybe_remove_all_heavy (hash_entry *he, obj_addr_t new_address_val)
815 {
816   static const int max_len = 5;
817   heavy_lock *hl = he -> heavy_locks;
818
819   for (int i = 0; i < max_len; ++i)
820     {
821       if (0 == hl) 
822         {
823           release_set(&(he -> address), new_address_val);
824           return;
825         }
826       hl = hl -> next;
827     }
828   remove_all_heavy(he, new_address_val);
829 }
830
831 // Allocate a new heavy lock for addr, returning its address.
832 // Assumes we already have the hash_entry locked, and there
833 // is currently no lightweight or allocated lock for addr.
834 // We register a finalizer for addr, which is responsible for
835 // removing the heavy lock when addr goes away, in addition
836 // to the responsibilities of any prior finalizer.
837 // This unfortunately holds the lock bit for the hash entry while it
838 // allocates two objects (on for the finalizer).
839 // It would be nice to avoid that somehow ...
840 static heavy_lock *
841 alloc_heavy(obj_addr_t addr, hash_entry *he)
842 {
843   heavy_lock * hl = (heavy_lock *) _Jv_AllocTraceTwo(sizeof (heavy_lock));
844   
845   hl -> address = addr;
846   _Jv_MutexInit (&(hl -> si.mutex));
847   _Jv_CondInit (&(hl -> si.condition));
848 # if defined (_Jv_HaveCondDestroy) || defined (_Jv_HaveMutexDestroy)
849     hl->si.init = true;  // needed ?
850 # endif
851   hl -> next = he -> heavy_locks;
852   he -> heavy_locks = hl;
853   // FIXME: The only call that cheats and goes directly to the GC interface.
854 # ifdef HAVE_BOEHM_GC
855     GC_REGISTER_FINALIZER_NO_ORDER(
856                           (void *)addr, heavy_lock_obj_finalization_proc,
857                           hl, &hl->old_finalization_proc,
858                           &hl->old_client_data);
859 # endif /* HAVE_BOEHM_GC */
860   return hl;
861 }
862
863 // Return the heavy lock for addr, allocating if necessary.
864 // Assumes we have the cache entry locked, and there is no lightweight
865 // lock for addr.
866 static heavy_lock *
867 get_heavy(obj_addr_t addr, hash_entry *he)
868 {
869   heavy_lock *hl = find_heavy(addr, he);
870   if (0 == hl)
871     hl = alloc_heavy(addr, he);
872   return hl;
873 }
874
875 void
876 _Jv_MonitorEnter (jobject obj)
877 {
878   obj_addr_t addr = (obj_addr_t)obj;
879   obj_addr_t address;
880   unsigned hash = JV_SYNC_HASH(addr);
881   hash_entry * he = light_locks + hash;
882   _Jv_ThreadId_t self = _Jv_ThreadSelf();
883   unsigned count;
884   const unsigned N_SPINS = 18;
885
886   // We need to somehow check that addr is not NULL on the fast path.
887   // A very predictable
888   // branch on a register value is probably cheaper than dereferencing addr.
889   // We could also permanently lock the NULL entry in the hash table.
890   // But it's not clear that's cheaper either.
891   if (__builtin_expect(!addr, false))
892     throw new java::lang::NullPointerException;
893    
894   assert(!(addr & FLAGS));
895 retry:
896   if (__builtin_expect(compare_and_swap(&(he -> address),
897                                         0, addr),true))
898     {
899       assert(he -> light_thr_id == INVALID_THREAD_ID);
900       assert(he -> light_count == 0);
901       he -> light_thr_id = self;
902       // Count fields are set correctly.  Heavy_count was also zero,
903       // but can change asynchronously.
904       // This path is hopefully both fast and the most common.
905       return;
906     }
907   address = he -> address;
908   if ((address & ~(HEAVY | REQUEST_CONVERSION)) == addr)
909     {
910       if (he -> light_thr_id == self)
911         {
912           // We hold the lightweight lock, and it's for the right
913           // address.
914           count = he -> light_count;
915           if (count == USHRT_MAX)
916             {
917               // I think most JVMs don't check for this.
918               // But I'm not convinced I couldn't turn this into a security
919               // hole, even with a 32 bit counter.
920               throw new java::lang::IllegalMonitorStateException(
921                 JvNewStringLatin1("maximum monitor nesting level exceeded")); 
922             }
923           he -> light_count = count + 1;
924           return;
925         }
926       else
927         {
928           // Lightweight lock is held, but by somone else.
929           // Spin a few times.  This avoids turning this into a heavyweight
930           // lock if the current holder is about to release it.
931           for (unsigned int i = 0; i < N_SPINS; ++i)
932             {
933               if ((he -> address & ~LOCKED) != (address & ~LOCKED)) goto retry;
934               spin(i);
935             }
936           address &= ~LOCKED;
937           if (!compare_and_swap(&(he -> address), address, address | LOCKED ))
938             {
939               wait_unlocked(he);      
940               goto retry;
941             }
942           heavy_lock *hl = get_heavy(addr, he);
943           ++ (he -> heavy_count);
944           // The hl lock acquisition can't block for long, since it can
945           // only be held by other threads waiting for conversion, and
946           // they, like us, drop it quickly without blocking.
947           _Jv_MutexLock(&(hl->si.mutex));
948           assert(he -> address == address | LOCKED );
949           release_set(&(he -> address), (address | REQUEST_CONVERSION | HEAVY));
950                                 // release lock on he
951           while ((he -> address & ~FLAGS) == (address & ~FLAGS))
952             {
953               // Once converted, the lock has to retain heavyweight
954               // status, since heavy_count > 0 . 
955               _Jv_CondWait (&(hl->si.condition), &(hl->si.mutex), 0, 0);
956             }
957           keep_live(addr);
958                 // Guarantee that hl doesn't get unlinked by finalizer.
959                 // This is only an issue if the client fails to release
960                 // the lock, which is unlikely.
961           assert(he -> address & HEAVY);
962           // Lock has been converted, we hold the heavyweight lock,
963           // heavy_count has been incremented.
964           return;
965         }
966     }
967   obj_addr_t was_heavy = (address & HEAVY);
968   address &= ~LOCKED;
969   if (!compare_and_swap(&(he -> address), address, (address | LOCKED )))
970     {
971       wait_unlocked(he);
972       goto retry;
973     }
974   if ((address & ~(HEAVY | REQUEST_CONVERSION)) == 0)
975     {
976       // Either was_heavy is true, or something changed out from under us,
977       // since the initial test for 0 failed.
978       assert(!(address & REQUEST_CONVERSION));
979         // Can't convert a nonexistent lightweight lock.
980       heavy_lock *hl;
981       hl = (was_heavy? find_heavy(addr, he) : 0);
982       if (0 == hl)
983         {
984           // It is OK to use the lighweight lock, since either the
985           // heavyweight lock does not exist, or none of the
986           // heavyweight locks currently exist.  Future threads
987           // trying to acquire the lock will see the lightweight
988           // one first and use that.
989           he -> light_thr_id = self;  // OK, since nobody else can hold
990                                       // light lock or do this at the same time.
991           assert(he -> light_count == 0);
992           assert(was_heavy == (he -> address & HEAVY));
993           release_set(&(he -> address), (addr | was_heavy));
994         }
995       else
996         {
997           // Must use heavy lock.
998           ++ (he -> heavy_count);
999           assert(0 == (address & ~HEAVY));
1000           release_set(&(he -> address), HEAVY);
1001           _Jv_MutexLock(&(hl->si.mutex));
1002           keep_live(addr);
1003         }
1004       return;
1005     }
1006   // Lightweight lock is held, but does not correspond to this object.
1007   // We hold the lock on the hash entry, and he -> address can't
1008   // change from under us.  Neither can the chain of heavy locks.
1009     {
1010       assert(0 == he -> heavy_count || (address & HEAVY));
1011       heavy_lock *hl = get_heavy(addr, he);
1012       ++ (he -> heavy_count);
1013       release_set(&(he -> address), address | HEAVY);
1014       _Jv_MutexLock(&(hl->si.mutex));
1015       keep_live(addr);
1016     }
1017 }
1018
1019
1020 void
1021 _Jv_MonitorExit (jobject obj)
1022 {
1023   obj_addr_t addr = (obj_addr_t)obj;
1024   _Jv_ThreadId_t self = _Jv_ThreadSelf();
1025   unsigned hash = JV_SYNC_HASH(addr);
1026   hash_entry * he = light_locks + hash;
1027   _Jv_ThreadId_t light_thr_id;
1028   unsigned count;
1029   obj_addr_t address;
1030
1031 retry:
1032   light_thr_id = he -> light_thr_id;
1033   // Unfortunately, it turns out we always need to read the address
1034   // first.  Even if we are going to update it with compare_and_swap,
1035   // we need to reset light_thr_id, and that's not safe unless we know
1036   // that we hold the lock.
1037   address = he -> address;
1038   // First the (relatively) fast cases:
1039   if (__builtin_expect(light_thr_id == self, true))
1040     // Above must fail if addr == 0 .
1041     {
1042       count = he -> light_count;
1043       if (__builtin_expect((address & ~HEAVY) == addr, true))
1044         {
1045           if (count != 0)
1046             {
1047               // We held the lightweight lock all along.  Thus the values
1048               // we saw for light_thr_id and light_count must have been valid. 
1049               he -> light_count = count - 1;
1050               return;
1051             }
1052           else
1053             {
1054               // We hold the lightweight lock once.
1055               he -> light_thr_id = INVALID_THREAD_ID;
1056               if (compare_and_swap_release(&(he -> address), address,
1057                                            address & HEAVY))
1058                 return;
1059               else
1060                 {
1061                   he -> light_thr_id = light_thr_id; // Undo prior damage.
1062                   goto retry;
1063                 }
1064             }
1065         }
1066       // else lock is not for this address, conversion is requested,
1067       // or the lock bit in the address field is set.
1068     }
1069   else
1070     {
1071       if (__builtin_expect(!addr, false))
1072         throw new java::lang::NullPointerException;
1073       if ((address & ~(HEAVY | REQUEST_CONVERSION)) == addr)
1074         {
1075 #         ifdef LOCK_DEBUG
1076             fprintf(stderr, "Lightweight lock held by other thread\n\t"
1077                             "light_thr_id = 0x%lx, self = 0x%lx, "
1078                             "address = 0x%lx, pid = %d\n",
1079                             light_thr_id, self, address, getpid());
1080             print_he(he);
1081             for(;;) {}
1082 #         endif
1083           // Someone holds the lightweight lock for this object, and
1084           // it can't be us.
1085           throw new java::lang::IllegalMonitorStateException(
1086                         JvNewStringLatin1("current thread not owner"));
1087         }
1088       else
1089         count = he -> light_count;
1090     }
1091   if (address & LOCKED)
1092     {
1093       wait_unlocked(he);
1094       goto retry;
1095     }
1096   // Now the unlikely cases.
1097   // We do know that:
1098   // - Address is set, and doesn't contain the LOCKED bit.
1099   // - If address refers to the same object as addr, then he -> light_thr_id
1100   //   refers to this thread, and count is valid.
1101   // - The case in which we held the lightweight lock has been
1102   //   completely handled, except for the REQUEST_CONVERSION case.
1103   //   
1104   if ((address & ~FLAGS) == addr)
1105     {
1106       // The lightweight lock is assigned to this object.
1107       // Thus we must be in the REQUEST_CONVERSION case.
1108       if (0 != count)
1109         {
1110           // Defer conversion until we exit completely.
1111           he -> light_count = count - 1;
1112           return;
1113         }
1114       assert(he -> light_thr_id == self);
1115       assert(address & REQUEST_CONVERSION);
1116       // Conversion requested
1117       // Convert now.
1118       if (!compare_and_swap(&(he -> address), address, address | LOCKED))
1119         goto retry;
1120       heavy_lock *hl = find_heavy(addr, he);
1121       assert (0 != hl);
1122                 // Requestor created it.
1123       he -> light_count = 0;
1124       assert(he -> heavy_count > 0);
1125                 // was incremented by requestor.
1126       _Jv_MutexLock(&(hl->si.mutex));
1127         // Release the he lock after acquiring the mutex.
1128         // Otherwise we can accidentally
1129         // notify a thread that has already seen a heavyweight
1130         // lock.
1131       he -> light_thr_id = INVALID_THREAD_ID;
1132       release_set(&(he -> address), HEAVY);
1133                 // lightweight lock now unused.
1134       _Jv_CondNotifyAll(&(hl->si.condition), &(hl->si.mutex));
1135       _Jv_MutexUnlock(&(hl->si.mutex));
1136       // heavy_count was already incremented by original requestor.
1137       keep_live(addr);
1138       return;
1139     }
1140   // lightweight lock not for this object.
1141   assert(!(address & LOCKED));
1142   assert((address & ~FLAGS) != addr);
1143   if (!compare_and_swap(&(he -> address), address, address | LOCKED))
1144         goto retry;
1145   heavy_lock *hl = find_heavy(addr, he);
1146   if (NULL == hl)
1147     {
1148 #     ifdef LOCK_DEBUG
1149         fprintf(stderr, "Failed to find heavyweight lock for addr 0x%lx"
1150                         " pid = %d\n", addr, getpid());
1151         print_he(he);
1152         for(;;) {}
1153 #     endif
1154       throw new java::lang::IllegalMonitorStateException(
1155                         JvNewStringLatin1("current thread not owner"));
1156     }
1157   assert(address & HEAVY);
1158   count = he -> heavy_count;
1159   assert(count > 0);
1160   --count;
1161   he -> heavy_count = count;
1162   if (0 == count)
1163     {
1164       const unsigned test_freq = 16;  // Power of 2
1165       static volatile unsigned counter = 0;
1166       unsigned my_counter = counter;
1167
1168       counter = my_counter + 1;
1169       if (my_counter%test_freq == 0)
1170         {
1171           // Randomize the interval length a bit.
1172             counter = my_counter + (my_counter >> 4) % (test_freq/2);
1173           // Unlock mutex first, to avoid self-deadlock, or worse.
1174           _Jv_MutexUnlock(&(hl->si.mutex));
1175           maybe_remove_all_heavy(he, address &~HEAVY);
1176                                 // release lock bit, preserving
1177                                 // REQUEST_CONVERSION
1178                                 // and object address.
1179         }
1180       else
1181         {
1182           release_set(&(he -> address), address &~HEAVY);
1183           _Jv_MutexUnlock(&(hl->si.mutex));
1184                         // Unlock after releasing the lock bit, so that
1185                         // we don't switch to another thread prematurely.
1186         }
1187     } 
1188   else
1189     {
1190       release_set(&(he -> address), address);
1191       _Jv_MutexUnlock(&(hl->si.mutex));
1192     }
1193   keep_live(addr);
1194 }     
1195
1196 // The rest of these are moderately thin veneers on _Jv_Cond ops.
1197 // The current version of Notify might be able to make the pthread
1198 // call AFTER releasing the lock, thus saving some context switches??
1199
1200 void
1201 java::lang::Object::wait (jlong timeout, jint nanos)
1202 {
1203   obj_addr_t addr = (obj_addr_t)this;
1204   _Jv_ThreadId_t self = _Jv_ThreadSelf();
1205   unsigned hash = JV_SYNC_HASH(addr);
1206   hash_entry * he = light_locks + hash;
1207   unsigned count;
1208   obj_addr_t address;
1209   heavy_lock *hl;
1210     
1211   if (__builtin_expect (timeout < 0 || nanos < 0 || nanos > 999999, false))
1212     throw new IllegalArgumentException;
1213 retry:
1214   address = he -> address;
1215   address &= ~LOCKED;
1216   if (!compare_and_swap(&(he -> address), address, address | LOCKED))
1217     {
1218       wait_unlocked(he);
1219       goto retry;
1220     }
1221   // address does not have the lock bit set.  We hold the lock on he.
1222   if ((address & ~FLAGS) == addr)
1223     {
1224       // Convert to heavyweight.
1225         if (he -> light_thr_id != self)
1226           {
1227 #           ifdef LOCK_DEBUG
1228               fprintf(stderr, "Found wrong lightweight lock owner in wait "
1229                               "address = 0x%lx pid = %d\n", address, getpid());
1230               print_he(he);
1231               for(;;) {}
1232 #           endif
1233             release_set(&(he -> address), address);
1234             throw new IllegalMonitorStateException (JvNewStringLatin1 
1235                           ("current thread not owner"));
1236           }
1237         count = he -> light_count;
1238         hl = get_heavy(addr, he);
1239         he -> light_count = 0;
1240         he -> heavy_count += count + 1;
1241         for (unsigned i = 0; i <= count; ++i)
1242           _Jv_MutexLock(&(hl->si.mutex));
1243         // Again release the he lock after acquiring the mutex.
1244         he -> light_thr_id = INVALID_THREAD_ID;
1245         release_set(&(he -> address), HEAVY);  // lightweight lock now unused.
1246         if (address & REQUEST_CONVERSION)
1247           _Jv_CondNotify (&(hl->si.condition), &(hl->si.mutex));
1248     }
1249   else /* We should hold the heavyweight lock. */
1250     {
1251       hl = find_heavy(addr, he);
1252       release_set(&(he -> address), address);
1253       if (0 == hl)
1254         {
1255 #         ifdef LOCK_DEBUG
1256             fprintf(stderr, "Couldn't find heavy lock in wait "
1257                             "addr = 0x%lx pid = %d\n", addr, getpid());
1258             print_he(he);
1259             for(;;) {}
1260 #         endif
1261           throw new IllegalMonitorStateException (JvNewStringLatin1 
1262                           ("current thread not owner"));
1263         }
1264       assert(address & HEAVY);
1265     }
1266   switch (_Jv_CondWait (&(hl->si.condition), &(hl->si.mutex), timeout, nanos))
1267     {
1268       case _JV_NOT_OWNER:
1269         throw new IllegalMonitorStateException (JvNewStringLatin1 
1270                           ("current thread not owner"));        
1271       case _JV_INTERRUPTED:
1272         if (Thread::interrupted ())
1273           throw new InterruptedException;        
1274     }
1275 }
1276
1277 void
1278 java::lang::Object::notify (void)
1279 {
1280   obj_addr_t addr = (obj_addr_t)this;
1281   _Jv_ThreadId_t self = _Jv_ThreadSelf();
1282   unsigned hash = JV_SYNC_HASH(addr);
1283   hash_entry * he = light_locks + hash;
1284   heavy_lock *hl;
1285   obj_addr_t address;
1286   int result;
1287
1288 retry:
1289   address = ((he -> address) & ~LOCKED);
1290   if (!compare_and_swap(&(he -> address), address, address | LOCKED))
1291     {
1292       wait_unlocked(he);
1293       goto retry;
1294     }
1295   if ((address & ~FLAGS) == addr && he -> light_thr_id == self)
1296     {
1297       // We hold lightweight lock.  Since it has not
1298       // been inflated, there are no waiters.
1299       release_set(&(he -> address), address);   // unlock
1300       return;
1301     }
1302   hl = find_heavy(addr, he);
1303   // Hl can't disappear since we point to the underlying object.
1304   // It's important that we release the lock bit before the notify, since
1305   // otherwise we will try to wake up thee target while we still hold the
1306   // bit.  This results in lock bit contention, which we don't handle
1307   // terribly well.
1308   release_set(&(he -> address), address); // unlock
1309   if (0 == hl)
1310     {
1311       throw new IllegalMonitorStateException(JvNewStringLatin1 
1312                                               ("current thread not owner"));
1313       return;
1314     }
1315   result = _Jv_CondNotify(&(hl->si.condition), &(hl->si.mutex));
1316   keep_live(addr);
1317   if (__builtin_expect (result, 0))
1318     throw new IllegalMonitorStateException(JvNewStringLatin1 
1319                                               ("current thread not owner"));
1320 }
1321
1322 void
1323 java::lang::Object::notifyAll (void)
1324 {
1325   obj_addr_t addr = (obj_addr_t)this;
1326   _Jv_ThreadId_t self = _Jv_ThreadSelf();
1327   unsigned hash = JV_SYNC_HASH(addr);
1328   hash_entry * he = light_locks + hash;
1329   heavy_lock *hl;
1330   obj_addr_t address;
1331   int result;
1332
1333 retry:
1334   address = (he -> address) & ~LOCKED;
1335   if (!compare_and_swap(&(he -> address), address, address | LOCKED))
1336     {
1337       wait_unlocked(he);
1338       goto retry;
1339     }
1340   hl = find_heavy(addr, he);
1341   if ((address & ~FLAGS) == addr && he -> light_thr_id == self)
1342     {
1343       // We hold lightweight lock.  Since it has not
1344       // been inflated, there are no waiters.
1345       release_set(&(he -> address), address);   // unlock
1346       return;
1347     }
1348   release_set(&(he -> address), address); // unlock
1349   if (0 == hl)
1350     {
1351       throw new IllegalMonitorStateException(JvNewStringLatin1 
1352                                               ("current thread not owner"));
1353     }
1354   result = _Jv_CondNotifyAll(&(hl->si.condition), &(hl->si.mutex));
1355   if (__builtin_expect (result, 0))
1356     throw new IllegalMonitorStateException(JvNewStringLatin1 
1357                                               ("current thread not owner"));
1358 }
1359
1360 // This is declared in Java code and in Object.h.
1361 // It should never be called with JV_HASH_SYNCHRONIZATION
1362 void
1363 java::lang::Object::sync_init (void)
1364 {
1365   throw new IllegalMonitorStateException(JvNewStringLatin1 
1366                                               ("internal error: sync_init"));
1367 }
1368
1369 // This is called on startup and declared in Object.h.
1370 // For now we just make it a no-op.
1371 void
1372 _Jv_InitializeSyncMutex (void)
1373 {
1374 }
1375
1376 #endif /* JV_HASH_SYNCHRONIZATION */
1377