1 // natObject.cc - Implementation of the Object class.
3 /* Copyright (C) 1998, 1999, 2000 Free Software Foundation
5 This file is part of libgcj.
7 This software is copyrighted work licensed under the terms of the
8 Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
15 #pragma implementation "Object.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>
31 #define CloneableClass _CL_Q34java4lang9Cloneable
32 extern java::lang::Class CloneableClass;
36 // This is used to represent synchronization information.
39 #if defined (_Jv_HaveCondDestroy) || defined (_Jv_HaveMutexDestroy)
40 // We only need to keep track of initialization state if we can
41 // possibly finalize this object.
44 _Jv_ConditionVariable_t condition;
51 java::lang::Object::getClass (void)
53 _Jv_VTable **dt = (_Jv_VTable **) this;
58 java::lang::Object::hashCode (void)
60 return _Jv_HashCode (this);
64 java::lang::Object::clone (void)
66 jclass klass = getClass ();
70 // We also clone arrays here. If we put the array code into
71 // __JArray, then we'd have to figure out a way to find the array
72 // vtbl when creating a new array class. This is easier, if uglier.
75 __JArray *array = (__JArray *) this;
76 jclass comp = getClass()->getComponentType();
78 if (comp->isPrimitive())
80 r = _Jv_NewPrimArray (comp, array->length);
81 eltsize = comp->size();
85 r = _Jv_NewObjectArray (array->length, comp, NULL);
86 eltsize = sizeof (jobject);
88 // We can't use sizeof on __JArray because we must account for
89 // alignment of the element type.
90 size = (_Jv_GetArrayElementFromElementType (array, comp) - (char *) array
91 + array->length * eltsize);
95 if (! CloneableClass.isAssignableFrom(klass))
96 JvThrow (new CloneNotSupportedException);
99 r = JvAllocObject (klass, size);
102 memcpy ((void *) r, (void *) this, size);
108 // Synchronization code.
111 // This global is used to make sure that only one thread sets an
112 // object's `sync_info' field.
113 static _Jv_Mutex_t sync_mutex;
115 // This macro is used to see if synchronization initialization is
117 #if defined (_Jv_HaveCondDestroy) || defined (_Jv_HaveMutexDestroy)
118 # define INIT_NEEDED(Obj) (! (Obj)->sync_info \
119 || ! ((_Jv_SyncInfo *) ((Obj)->sync_info))->init)
121 # define INIT_NEEDED(Obj) (! (Obj)->sync_info)
124 #if defined (_Jv_HaveCondDestroy) || defined (_Jv_HaveMutexDestroy)
125 // If we have to run a destructor for a sync_info member, then this
126 // function is registered as a finalizer for the sync_info.
128 finalize_sync_info (jobject obj)
130 _Jv_SyncInfo *si = (_Jv_SyncInfo *) obj;
131 #if defined (_Jv_HaveCondDestroy)
132 _Jv_CondDestroy (&si->condition);
134 #if defined (_Jv_HaveMutexDestroy)
135 _Jv_MutexDestroy (&si->mutex);
141 // This is called to initialize the sync_info element of an object.
143 java::lang::Object::sync_init (void)
145 _Jv_MutexLock (&sync_mutex);
146 // Check again to see if initialization is needed now that we have
148 if (INIT_NEEDED (this))
150 // We assume there are no pointers in the sync_info
153 // We always create a new sync_info, even if there is already
154 // one available. Any given object can only be finalized once.
155 // If we get here and sync_info is not null, then it has already
156 // been finalized. So if we just reinitialize the old one,
157 // we'll never be able to (re-)destroy the mutex and/or
158 // condition variable.
159 si = (_Jv_SyncInfo *) _Jv_AllocBytesChecked (sizeof (_Jv_SyncInfo));
160 _Jv_MutexInit (&si->mutex);
161 _Jv_CondInit (&si->condition);
162 #if defined (_Jv_HaveCondDestroy) || defined (_Jv_HaveMutexDestroy)
163 // Register a finalizer.
165 _Jv_RegisterFinalizer (si, finalize_sync_info);
167 sync_info = (jobject) si;
169 _Jv_MutexUnlock (&sync_mutex);
173 java::lang::Object::notify (void)
175 if (__builtin_expect (INIT_NEEDED (this), 0))
177 _Jv_SyncInfo *si = (_Jv_SyncInfo *) sync_info;
178 if (__builtin_expect (_Jv_CondNotify (&si->condition, &si->mutex), 0))
179 JvThrow (new IllegalMonitorStateException(JvNewStringLatin1
180 ("current thread not owner")));
184 java::lang::Object::notifyAll (void)
186 if (__builtin_expect (INIT_NEEDED (this), 0))
188 _Jv_SyncInfo *si = (_Jv_SyncInfo *) sync_info;
189 if (__builtin_expect (_Jv_CondNotifyAll (&si->condition, &si->mutex), 0))
190 JvThrow (new IllegalMonitorStateException(JvNewStringLatin1
191 ("current thread not owner")));
195 java::lang::Object::wait (jlong timeout, jint nanos)
197 if (__builtin_expect (INIT_NEEDED (this), 0))
199 if (__builtin_expect (timeout < 0 || nanos < 0 || nanos > 999999, 0))
200 JvThrow (new IllegalArgumentException);
201 _Jv_SyncInfo *si = (_Jv_SyncInfo *) sync_info;
202 switch (_Jv_CondWait (&si->condition, &si->mutex, timeout, nanos))
205 JvThrow (new IllegalMonitorStateException (JvNewStringLatin1
206 ("current thread not owner")));
207 case _JV_INTERRUPTED:
208 if (Thread::interrupted ())
209 JvThrow (new InterruptedException);
214 // Some runtime code.
217 // This function is called at system startup to initialize the
220 _Jv_InitializeSyncMutex (void)
222 _Jv_MutexInit (&sync_mutex);
226 _Jv_MonitorEnter (jobject obj)
229 if (__builtin_expect (! obj, 0))
230 JvThrow (new java::lang::NullPointerException);
232 if (__builtin_expect (INIT_NEEDED (obj), 0))
234 _Jv_SyncInfo *si = (_Jv_SyncInfo *) obj->sync_info;
235 return _Jv_MutexLock (&si->mutex);
239 _Jv_MonitorExit (jobject obj)
242 JvAssert (! INIT_NEEDED (obj));
243 _Jv_SyncInfo *si = (_Jv_SyncInfo *) obj->sync_info;
244 if (__builtin_expect (_Jv_MutexUnlock (&si->mutex), 0))
245 JvThrow (new java::lang::IllegalMonitorStateException);
250 _Jv_FinalizeObject (jobject obj)
252 // Ignore exceptions. From section 12.6 of the Java Language Spec.
257 catch (java::lang::Throwable *t)