1 // natObject.cc - Implementation of the Object class.
3 /* Copyright (C) 1998, 1999, 2000 Red Hat, Inc.
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/lang/CloneNotSupportedException.h>
22 #include <java/lang/IllegalArgumentException.h>
23 #include <java/lang/IllegalMonitorStateException.h>
24 #include <java/lang/InterruptedException.h>
25 #include <java/lang/NullPointerException.h>
26 #include <java/lang/Class.h>
27 #include <java/lang/Cloneable.h>
28 #include <java/lang/Thread.h>
30 #define CloneableClass _CL_Q34java4lang9Cloneable
31 extern java::lang::Class CloneableClass
;
35 // This is used to represent synchronization information.
38 #if defined (_Jv_HaveCondDestroy) || defined (_Jv_HaveMutexDestroy)
39 // We only need to keep track of initialization state if we can
40 // possibly finalize this object.
43 _Jv_ConditionVariable_t condition
;
50 java::lang::Object::getClass (void)
52 _Jv_VTable
**dt
= (_Jv_VTable
**) this;
57 java::lang::Object::hashCode (void)
59 return _Jv_HashCode (this);
63 java::lang::Object::clone (void)
65 jclass klass
= getClass ();
69 // We also clone arrays here. If we put the array code into
70 // __JArray, then we'd have to figure out a way to find the array
71 // vtbl when creating a new array class. This is easier, if uglier.
74 __JArray
*array
= (__JArray
*) this;
75 jclass comp
= getClass()->getComponentType();
77 if (comp
->isPrimitive())
79 r
= _Jv_NewPrimArray (comp
, array
->length
);
80 eltsize
= comp
->size();
84 r
= _Jv_NewObjectArray (array
->length
, comp
, NULL
);
85 eltsize
= sizeof (jobject
);
87 // We can't use sizeof on __JArray because we must account for
88 // alignment of the element type.
89 size
= (_Jv_GetArrayElementFromElementType (array
, comp
) - (char *) array
90 + array
->length
* eltsize
);
94 if (! CloneableClass
.isAssignableFrom(klass
))
95 JvThrow (new CloneNotSupportedException
);
98 r
= JvAllocObject (klass
, size
);
101 memcpy ((void *) r
, (void *) this, size
);
107 // Synchronization code.
110 // This global is used to make sure that only one thread sets an
111 // object's `sync_info' field.
112 static _Jv_Mutex_t sync_mutex
;
114 // This macro is used to see if synchronization initialization is
116 #if defined (_Jv_HaveCondDestroy) || defined (_Jv_HaveMutexDestroy)
117 # define INIT_NEEDED(Obj) (! (Obj)->sync_info \
118 || ! ((_Jv_SyncInfo *) ((Obj)->sync_info))->init)
120 # define INIT_NEEDED(Obj) (! (Obj)->sync_info)
123 #if defined (_Jv_HaveCondDestroy) || defined (_Jv_HaveMutexDestroy)
124 // If we have to run a destructor for a sync_info member, then this
125 // function is registered as a finalizer for the sync_info.
127 finalize_sync_info (jobject obj
)
129 _Jv_SyncInfo
*si
= (_Jv_SyncInfo
*) obj
;
130 #if defined (_Jv_HaveCondDestroy)
131 _Jv_CondDestroy (&si
->condition
);
133 #if defined (_Jv_HaveMutexDestroy)
134 _Jv_MutexDestroy (&si
->mutex
);
140 // This is called to initialize the sync_info element of an object.
142 java::lang::Object::sync_init (void)
144 _Jv_MutexLock (&sync_mutex
);
145 // Check again to see if initialization is needed now that we have
147 if (INIT_NEEDED (this))
149 // We assume there are no pointers in the sync_info
152 // We always create a new sync_info, even if there is already
153 // one available. Any given object can only be finalized once.
154 // If we get here and sync_info is not null, then it has already
155 // been finalized. So if we just reinitialize the old one,
156 // we'll never be able to (re-)destroy the mutex and/or
157 // condition variable.
158 si
= (_Jv_SyncInfo
*) _Jv_AllocBytesChecked (sizeof (_Jv_SyncInfo
));
159 _Jv_MutexInit (&si
->mutex
);
160 _Jv_CondInit (&si
->condition
);
161 #if defined (_Jv_HaveCondDestroy) || defined (_Jv_HaveMutexDestroy)
162 // Register a finalizer.
164 _Jv_RegisterFinalizer (si
, finalize_sync_info
);
166 sync_info
= (jobject
) si
;
168 _Jv_MutexUnlock (&sync_mutex
);
172 java::lang::Object::notify (void)
174 if (INIT_NEEDED (this))
176 _Jv_SyncInfo
*si
= (_Jv_SyncInfo
*) sync_info
;
177 if (_Jv_CondNotify (&si
->condition
, &si
->mutex
))
178 JvThrow (new IllegalMonitorStateException(JvNewStringLatin1
179 ("current thread not owner")));
183 java::lang::Object::notifyAll (void)
185 if (INIT_NEEDED (this))
187 _Jv_SyncInfo
*si
= (_Jv_SyncInfo
*) sync_info
;
188 if (_Jv_CondNotifyAll (&si
->condition
, &si
->mutex
))
189 JvThrow (new IllegalMonitorStateException(JvNewStringLatin1
190 ("current thread not owner")));
194 java::lang::Object::wait (jlong timeout
, jint nanos
)
196 if (INIT_NEEDED (this))
198 if (timeout
< 0 || nanos
< 0 || nanos
> 999999)
199 JvThrow (new IllegalArgumentException
);
200 _Jv_SyncInfo
*si
= (_Jv_SyncInfo
*) sync_info
;
201 if (_Jv_CondWait (&si
->condition
, &si
->mutex
, timeout
, nanos
))
202 JvThrow (new IllegalMonitorStateException(JvNewStringLatin1
203 ("current thread not owner")));
204 if (Thread::interrupted())
205 JvThrow (new InterruptedException
);
209 // Some runtime code.
212 // This function is called at system startup to initialize the
215 _Jv_InitializeSyncMutex (void)
217 _Jv_MutexInit (&sync_mutex
);
221 _Jv_MonitorEnter (jobject obj
)
224 JvThrow (new java::lang::NullPointerException
);
225 if (INIT_NEEDED (obj
))
227 _Jv_SyncInfo
*si
= (_Jv_SyncInfo
*) obj
->sync_info
;
228 return _Jv_MutexLock (&si
->mutex
);
232 _Jv_MonitorExit (jobject obj
)
235 JvAssert (! INIT_NEEDED (obj
));
236 _Jv_SyncInfo
*si
= (_Jv_SyncInfo
*) obj
->sync_info
;
237 if (_Jv_MutexUnlock (&si
->mutex
))
238 JvThrow (new java::lang::IllegalMonitorStateException
);
243 _Jv_FinalizeObject (jobject obj
)
245 // Ignore exceptions. From section 12.6 of the Java Language Spec.
250 catch (java::lang::Throwable
*t
)