aboutsummaryrefslogtreecommitdiff
path: root/libjava/java/lang/natObject.cc
diff options
context:
space:
mode:
Diffstat (limited to 'libjava/java/lang/natObject.cc')
-rw-r--r--libjava/java/lang/natObject.cc241
1 files changed, 241 insertions, 0 deletions
diff --git a/libjava/java/lang/natObject.cc b/libjava/java/lang/natObject.cc
new file mode 100644
index 0000000..7b26769
--- /dev/null
+++ b/libjava/java/lang/natObject.cc
@@ -0,0 +1,241 @@
+// natObject.cc - Implementation of the Object class.
+
+/* Copyright (C) 1998, 1999 Cygnus Solutions
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+#include <config.h>
+
+#include <string.h>
+
+#pragma implementation "Object.h"
+
+#include <cni.h>
+#include <jvm.h>
+#include <java/lang/Object.h>
+#include <java-threads.h>
+#include <java/lang/CloneNotSupportedException.h>
+#include <java/lang/IllegalArgumentException.h>
+#include <java/lang/IllegalMonitorStateException.h>
+#include <java/lang/InterruptedException.h>
+#include <java/lang/NullPointerException.h>
+#include <java/lang/Class.h>
+#include <java/lang/Cloneable.h>
+#include <java/lang/Thread.h>
+
+#define CloneableClass _CL_Q34java4lang9Cloneable
+extern java::lang::Class CloneableClass;
+
+
+
+// This is used to represent synchronization information.
+struct _Jv_SyncInfo
+{
+#if defined (_Jv_HaveCondDestroy) || defined (_Jv_HaveMutexDestroy)
+ // We only need to keep track of initialization state if we can
+ // possibly finalize this object.
+ bool init;
+#endif
+ _Jv_ConditionVariable_t condition;
+ _Jv_Mutex_t mutex;
+};
+
+
+
+jclass
+java::lang::Object::getClass (void)
+{
+ _Jv_VTable **dt = (_Jv_VTable **) this;
+ return (*dt)->clas;
+}
+
+jint
+java::lang::Object::hashCode (void)
+{
+ return _Jv_HashCode (this);
+}
+
+jobject
+java::lang::Object::clone (void)
+{
+ jclass klass = getClass ();
+ jobject r;
+ jint size;
+
+ // We also clone arrays here. If we put the array code into
+ // __JArray, then we'd have to figure out a way to find the array
+ // vtbl when creating a new array class. This is easier, if uglier.
+ if (klass->isArray())
+ {
+ __JArray *array = (__JArray *) this;
+ jclass comp = getClass()->getComponentType();
+ jint eltsize;
+ if (comp->isPrimitive())
+ {
+ r = _Jv_NewPrimArray (comp, array->length);
+ eltsize = comp->size();
+ }
+ else
+ {
+ r = _Jv_NewObjectArray (array->length, comp, NULL);
+ eltsize = sizeof (jobject);
+ }
+ size = sizeof (__JArray) + array->length * eltsize;
+ }
+ else
+ {
+ if (! CloneableClass.isAssignableFrom(klass))
+ JvThrow (new CloneNotSupportedException);
+
+ size = klass->size();
+ r = JvAllocObject (klass, size);
+ }
+
+ memcpy ((void *) r, (void *) this, size);
+ return r;
+}
+
+
+//
+// Synchronization code.
+//
+
+// This global is used to make sure that only one thread sets an
+// object's `sync_info' field.
+static _Jv_Mutex_t sync_mutex;
+
+// This macro is used to see if synchronization initialization is
+// needed.
+#if defined (_Jv_HaveCondDestroy) || defined (_Jv_HaveMutexDestroy)
+# define INIT_NEEDED(Obj) (! (Obj)->sync_info \
+ || ! ((_Jv_SyncInfo *) ((Obj)->sync_info))->init)
+#else
+# define INIT_NEEDED(Obj) (! (Obj)->sync_info)
+#endif
+
+#if defined (_Jv_HaveCondDestroy) || defined (_Jv_HaveMutexDestroy)
+// If we have to run a destructor for a sync_info member, then this
+// function is registered as a finalizer for the sync_info.
+static void
+finalize_sync_info (jobject obj)
+{
+ _Jv_SyncInfo *si = (_Jv_SyncInfo *) obj;
+#if defined (_Jv_HaveCondDestroy)
+ _Jv_CondDestroy (&si->condition);
+#endif
+#if defined (_Jv_HaveMutexDestroy)
+ _Jv_MutexDestroy (&si->mutex);
+#endif
+ si->init = false;
+}
+#endif
+
+// This is called to initialize the sync_info element of an object.
+void
+java::lang::Object::sync_init (void)
+{
+ _Jv_MutexLock (&sync_mutex);
+ // Check again to see if initialization is needed now that we have
+ // the lock.
+ if (INIT_NEEDED (this))
+ {
+ // We assume there are no pointers in the sync_info
+ // representation.
+ _Jv_SyncInfo *si;
+ // We always create a new sync_info, even if there is already
+ // one available. Any given object can only be finalized once.
+ // If we get here and sync_info is not null, then it has already
+ // been finalized. So if we just reinitialize the old one,
+ // we'll never be able to (re-)destroy the mutex and/or
+ // condition variable.
+ si = (_Jv_SyncInfo *) _Jv_AllocBytes (sizeof (_Jv_SyncInfo));
+ // FIXME: what if si == NULL?
+ _Jv_MutexInit (&si->mutex);
+ _Jv_CondInit (&si->condition);
+#if defined (_Jv_HaveCondDestroy) || defined (_Jv_HaveMutexDestroy)
+ // Register a finalizer.
+ si->init = true;
+ _Jv_RegisterFinalizer (si, finalize_sync_info);
+#endif
+ sync_info = (jobject) si;
+ }
+ _Jv_MutexUnlock (&sync_mutex);
+}
+
+void
+java::lang::Object::notify (void)
+{
+ if (INIT_NEEDED (this))
+ sync_init ();
+ _Jv_SyncInfo *si = (_Jv_SyncInfo *) sync_info;
+ if (_Jv_CondNotify (&si->condition, &si->mutex))
+ JvThrow (new IllegalMonitorStateException);
+}
+
+void
+java::lang::Object::notifyAll (void)
+{
+ if (INIT_NEEDED (this))
+ sync_init ();
+ _Jv_SyncInfo *si = (_Jv_SyncInfo *) sync_info;
+ if (_Jv_CondNotifyAll (&si->condition, &si->mutex))
+ JvThrow (new IllegalMonitorStateException);
+}
+
+void
+java::lang::Object::wait (jlong timeout, jint nanos)
+{
+ if (INIT_NEEDED (this))
+ sync_init ();
+ if (timeout < 0 || nanos < 0 || nanos > 999999)
+ JvThrow (new IllegalArgumentException);
+ _Jv_SyncInfo *si = (_Jv_SyncInfo *) sync_info;
+ if (_Jv_CondWait (&si->condition, &si->mutex, timeout, nanos))
+ JvThrow (new IllegalMonitorStateException);
+ if (Thread::interrupted())
+ JvThrow (new InterruptedException);
+}
+
+//
+// Some runtime code.
+//
+
+// This function is called at system startup to initialize the
+// `sync_mutex'.
+void
+_Jv_InitializeSyncMutex (void)
+{
+ _Jv_MutexInit (&sync_mutex);
+}
+
+jint
+_Jv_MonitorEnter (jobject obj)
+{
+ if (! obj)
+ JvThrow (new java::lang::NullPointerException);
+ if (INIT_NEEDED (obj))
+ obj->sync_init ();
+ _Jv_SyncInfo *si = (_Jv_SyncInfo *) obj->sync_info;
+ return _Jv_MutexLock (&si->mutex);
+}
+
+jint
+_Jv_MonitorExit (jobject obj)
+{
+ JvAssert (obj);
+ JvAssert (! INIT_NEEDED (obj));
+ _Jv_SyncInfo *si = (_Jv_SyncInfo *) obj->sync_info;
+ if (_Jv_MutexUnlock (&si->mutex))
+ JvThrow (new java::lang::IllegalMonitorStateException);
+ return 0;
+}
+
+void
+_Jv_FinalizeObject (jobject obj)
+{
+ java::lang::Object::hack12_6(obj);
+}