OSDN Git Service

* Merged gcj-abi-2-dev-branch to trunk.
[pf3gnuchains/gcc-fork.git] / libjava / java / lang / natClassLoader.cc
index 5a0898a..dd5cd46 100644 (file)
@@ -18,6 +18,7 @@ details.  */
 
 #include <gcj/cni.h>
 #include <jvm.h>
+#include <execution.h>
 
 #include <java-threads.h>
 #include <java-interp.h>
@@ -33,6 +34,7 @@ details.  */
 #include <java/lang/ClassNotFoundException.h>
 #include <java/lang/ClassCircularityError.h>
 #include <java/lang/IncompatibleClassChangeError.h>
+#include <java/lang/ClassFormatError.h>
 #include <java/lang/VirtualMachineError.h>
 #include <java/lang/VMClassLoader.h>
 #include <java/lang/reflect/Modifier.h>
@@ -41,156 +43,6 @@ details.  */
 #include <java/io/Serializable.h>
 #include <java/lang/Cloneable.h>
 
-void
-_Jv_WaitForState (jclass klass, int state)
-{
-  if (klass->state >= state)
-    return;
-  
-  _Jv_MonitorEnter (klass) ;
-
-  if (klass->state == JV_STATE_COMPILED)
-    {
-      klass->state = JV_STATE_LOADED;
-      if (gcj::verbose_class_flag)
-       fprintf (stderr, "[Loaded (pre-compiled) %s]\n", klass->name->chars());
-    }
-  if (state == JV_STATE_LINKED)
-    {
-      // Must call _Jv_PrepareCompiledClass while holding the class
-      // mutex.
-#ifdef INTERPRETER
-      if (_Jv_IsInterpretedClass (klass))
-       _Jv_PrepareClass (klass);
-#endif
-      _Jv_PrepareCompiledClass (klass);
-      _Jv_MonitorExit (klass);
-      return;
-    }
-       
-  java::lang::Thread *self = java::lang::Thread::currentThread();
-
-  // this is similar to the strategy for class initialization.
-  // if we already hold the lock, just leave.
-  while (klass->state <= state
-        && klass->thread 
-        && klass->thread != self)
-    klass->wait ();
-
-  _Jv_MonitorExit (klass);
-
-  if (klass->state == JV_STATE_ERROR)
-    throw new java::lang::LinkageError;
-}
-
-typedef unsigned int uaddr __attribute__ ((mode (pointer)));
-
-/** This function does class-preparation for compiled classes.  
-    NOTE: It contains replicated functionality from
-    _Jv_ResolvePoolEntry, and this is intentional, since that function
-    lives in resolve.cc which is entirely conditionally compiled.
- */
-void
-_Jv_PrepareCompiledClass (jclass klass)
-{
-  jint state = klass->state;
-  if (state >= JV_STATE_LINKED)
-    return;
-
-  // Short-circuit, so that mutually dependent classes are ok.
-  klass->state = JV_STATE_LINKED;
-
-  _Jv_Constants *pool = &klass->constants;
-
-  // Resolve class constants first, since other constant pool
-  // entries may rely on these.
-  for (int index = 1; index < pool->size; ++index)
-    {
-      if (pool->tags[index] == JV_CONSTANT_Class)
-       {
-         _Jv_Utf8Const *name = pool->data[index].utf8;
-         
-         jclass found;
-         if (name->first() == '[')
-           found = _Jv_FindClassFromSignature (name->chars(),
-                                               klass->loader);
-         else
-           found = _Jv_FindClass (name, klass->loader);
-               
-         if (! found)
-           {
-             jstring str = name->toString();
-             throw new java::lang::NoClassDefFoundError (str);
-           }
-
-         pool->data[index].clazz = found;
-         pool->tags[index] |= JV_CONSTANT_ResolvedFlag;
-       }
-    }
-
-  // If superclass looks like a constant pool entry,
-  // resolve it now.
-  if ((uaddr) klass->superclass < pool->size)
-    klass->superclass = pool->data[(uaddr) klass->superclass].clazz;
-
-  // Likewise for interfaces.
-  for (int i = 0; i < klass->interface_count; i++)
-    if ((uaddr) klass->interfaces[i] < pool->size)
-      klass->interfaces[i] = pool->data[(uaddr) klass->interfaces[i]].clazz;
-
-  // Resolve the remaining constant pool entries.
-  for (int index = 1; index < pool->size; ++index)
-    {
-      if (pool->tags[index] == JV_CONSTANT_String)
-       {
-         jstring str;
-
-         str = _Jv_NewStringUtf8Const (pool->data[index].utf8);
-         pool->data[index].o = str;
-         pool->tags[index] |= JV_CONSTANT_ResolvedFlag;
-       }
-    }
-
-#ifdef INTERPRETER
-  // FIXME: although the comment up top says that this function is
-  // only called for compiled classes, it is actually called for every
-  // class.
-  if (! _Jv_IsInterpretedClass (klass))
-    {
-#endif /* INTERPRETER */
-      jfieldID f = JvGetFirstStaticField (klass);
-      for (int n = JvNumStaticFields (klass); n > 0; --n)
-       {
-         int mod = f->getModifiers ();
-         // If we have a static String field with a non-null initial
-         // value, we know it points to a Utf8Const.
-         _Jv_ResolveField(f, klass->loader);
-         if (f->getClass () == &java::lang::String::class$
-             && java::lang::reflect::Modifier::isStatic (mod))
-           {
-             jstring *strp = (jstring *) f->u.addr;
-             if (*strp)
-               *strp = _Jv_NewStringUtf8Const ((_Jv_Utf8Const *) *strp);
-           }
-         f = f->getNextField ();
-       }
-#ifdef INTERPRETER
-    }
-#endif /* INTERPRETER */
-
-  if (klass->isInterface ())
-    _Jv_LayoutInterfaceMethods (klass);
-
-  if (state == JV_STATE_COMPILED && gcj::verbose_class_flag)
-    fprintf (stderr, "[Loaded (pre-compiled) %s]\n",
-            klass->name->chars());
-
-  klass->notifyAll ();
-
-  _Jv_PushClass (klass);
-}
-
-
 //
 //  A single class can have many "initiating" class loaders,
 //  and a single "defining" class loader.  The Defining
@@ -221,6 +73,8 @@ static _Jv_LoaderInfo *initiated_classes[HASH_LEN];
 static jclass loaded_classes[HASH_LEN];
 
 // This is the root of a linked list of classes
+static jclass stack_head;
+
 
 \f
 
@@ -323,11 +177,6 @@ _Jv_RegisterClasses (const jclass *classes)
       jclass klass = *classes;
 
       (*_Jv_RegisterClassHook) (klass);
-
-      // registering a compiled class causes
-      // it to be immediately "prepared".  
-      if (klass->state == JV_STATE_NOTHING)
-       klass->state = JV_STATE_COMPILED;
     }
 }
 
@@ -341,11 +190,6 @@ _Jv_RegisterClasses_Counted (const jclass * classes, size_t count)
       jclass klass = classes[i];
 
       (*_Jv_RegisterClassHook) (klass);
-
-      // registering a compiled class causes
-      // it to be immediately "prepared".  
-      if (klass->state == JV_STATE_NOTHING)
-       klass->state = JV_STATE_COMPILED;
     }
 }
 
@@ -354,8 +198,10 @@ _Jv_RegisterClassHookDefault (jclass klass)
 {
   jint hash = HASH_UTF (klass->name);
 
-  jclass check_class = loaded_classes[hash];
-
+  // The BC ABI makes this check unnecessary: we always resolve all
+  // data references via the appropriate class loader, so the kludge
+  // that required this check has gone.
+#if 0
   // If the class is already registered, don't re-register it.
   while (check_class != NULL)
     {
@@ -381,7 +227,11 @@ _Jv_RegisterClassHookDefault (jclass klass)
 
       check_class = check_class->next;
     }
+#endif
 
+  // FIXME: this is really bogus!
+  if (! klass->engine)
+    klass->engine = &_Jv_soleCompiledEngine;
   klass->next = loaded_classes[hash];
   loaded_classes[hash] = klass;
 }
@@ -442,7 +292,7 @@ _Jv_FindClass (_Jv_Utf8Const *name, java::lang::ClassLoader *loader)
     {
       // we need classes to be in the hash while
       // we're loading, so that they can refer to themselves. 
-      _Jv_WaitForState (klass, JV_STATE_LOADED);
+      _Jv_Linker::wait_for_state (klass, JV_STATE_LOADED);
     }
 
   return klass;
@@ -555,7 +405,7 @@ _Jv_NewArrayClass (jclass element, java::lang::ClassLoader *loader,
   // cache one and reuse it. It is not necessary to synchronize this.
   if (!array_idt)
     {
-      _Jv_PrepareConstantTimeTables (array_class);
+      _Jv_Linker::wait_for_state(array_class, JV_STATE_PREPARED);
       array_idt = array_class->idt;
       array_depth = array_class->depth;
       array_ancestors = array_class->ancestors;
@@ -569,19 +419,19 @@ _Jv_NewArrayClass (jclass element, java::lang::ClassLoader *loader,
 
   using namespace java::lang::reflect;
   {
-    // Array classes are "abstract final"...
-    _Jv_ushort accflags = Modifier::FINAL | Modifier::ABSTRACT;
-    // ... and inherit accessibility from element type, per vmspec 5.3.3.2
-    accflags |= (element->accflags & Modifier::PUBLIC);
-    accflags |= (element->accflags & Modifier::PROTECTED);
-    accflags |= (element->accflags & Modifier::PRIVATE);      
+    // Array classes are "abstract final" and inherit accessibility
+    // from element type, per vmspec 5.3.3.2
+    _Jv_ushort accflags = (Modifier::FINAL | Modifier::ABSTRACT
+                          | (element->accflags
+                             & (Modifier::PUBLIC | Modifier::PROTECTED
+                                | Modifier::PRIVATE)));
     array_class->accflags = accflags;
   }
 
   // An array class has no visible instance fields. "length" is invisible to 
   // reflection.
 
-  // say this class is initialized and ready to go!
+  // Say this class is initialized and ready to go!
   array_class->state = JV_STATE_DONE;
 
   // vmspec, section 5.3.3 describes this
@@ -591,8 +441,6 @@ _Jv_NewArrayClass (jclass element, java::lang::ClassLoader *loader,
   element->arrayclass = array_class;
 }
 
-static jclass stack_head;
-
 // These two functions form a stack of classes.   When a class is loaded
 // it is pushed onto the stack by the class loader; this is so that
 // StackTrace can quickly determine which classes have been loaded.