OSDN Git Service

2fa3f49ef1b30359733a79e36f283c2dea8db9ae
[pf3gnuchains/gcc-fork.git] / libjava / java / lang / natClassLoader.cc
1 // natClassLoader.cc - Implementation of java.lang.ClassLoader native methods.
2
3 /* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005  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 /* Author: Kresten Krab Thorup <krab@gnu.org>  */
12
13 #include <config.h>
14
15 #include <stdlib.h>
16 #include <stdio.h>
17 #include <string.h>
18
19 #include <gcj/cni.h>
20 #include <jvm.h>
21 #include <execution.h>
22
23 #include <java-threads.h>
24 #include <java-interp.h>
25
26 #include <java/lang/Character.h>
27 #include <java/lang/Thread.h>
28 #include <java/lang/ClassLoader.h>
29 #include <java/lang/InternalError.h>
30 #include <java/lang/IllegalAccessError.h>
31 #include <java/lang/LinkageError.h>
32 #include <java/lang/NoClassDefFoundError.h>
33 #include <java/lang/ClassNotFoundException.h>
34 #include <java/lang/ClassCircularityError.h>
35 #include <java/lang/IncompatibleClassChangeError.h>
36 #include <java/lang/ClassFormatError.h>
37 #include <java/lang/VirtualMachineError.h>
38 #include <java/lang/VMClassLoader.h>
39 #include <java/lang/reflect/Modifier.h>
40 #include <java/lang/Runtime.h>
41 #include <java/lang/StringBuffer.h>
42 #include <java/io/Serializable.h>
43 #include <java/lang/Cloneable.h>
44 #include <java/util/HashMap.h>
45 #include <gnu/gcj/runtime/BootClassLoader.h>
46
47 // Size of local hash table.
48 #define HASH_LEN 1013
49
50 // Hash function for Utf8Consts.
51 #define HASH_UTF(Utf) ((Utf)->hash16() % HASH_LEN)
52
53 static jclass loaded_classes[HASH_LEN];
54
55 // This records classes which will be registered with the system class
56 // loader when it is initialized.
57 static jclass system_class_list;
58
59 // This is used as the value of system_class_list after we have
60 // initialized the system class loader; it lets us know that we should
61 // no longer pay attention to the system abi flag.
62 #define SYSTEM_LOADER_INITIALIZED ((jclass) -1)
63
64 // This is the root of a linked list of classes
65 static jclass stack_head;
66
67 // While bootstrapping we keep a list of classes we found, so that we
68 // can register their packages.  There aren't many of these so we
69 // just keep a small buffer here and abort if we overflow.
70 #define BOOTSTRAP_CLASS_LIST_SIZE 20
71 static jclass bootstrap_class_list[BOOTSTRAP_CLASS_LIST_SIZE];
72 static int bootstrap_index;
73
74
75 \f
76
77 jclass
78 java::lang::ClassLoader::loadClassFromSig(jstring name)
79 {
80   int len = _Jv_GetStringUTFLength (name);
81   char sig[len + 1];
82   _Jv_GetStringUTFRegion (name, 0, name->length(), sig);
83   return _Jv_FindClassFromSignature(sig, this);
84 }
85
86 \f
87
88 // This tries to find a class in our built-in cache.  This cache is
89 // used only for classes which are linked in to the executable or
90 // loaded via dlopen().
91 jclass
92 _Jv_FindClassInCache (_Jv_Utf8Const *name)
93 {
94   JvSynchronize sync (&java::lang::Class::class$);
95   jint hash = HASH_UTF (name);
96
97   jclass klass;
98   for (klass = loaded_classes[hash]; klass; klass = klass->next_or_version)
99     {
100       if (_Jv_equalUtf8Consts (name, klass->name))
101         break;
102     }
103
104   return klass;
105 }
106
107 void
108 _Jv_UnregisterClass (jclass the_class)
109 {
110   JvSynchronize sync (&java::lang::Class::class$);
111   jint hash = HASH_UTF(the_class->name);
112
113   jclass *klass = &(loaded_classes[hash]);
114   for ( ; *klass; klass = &((*klass)->next_or_version))
115     {
116       if (*klass == the_class)
117         {
118           *klass = (*klass)->next_or_version;
119           break;
120         }
121     }
122 }
123
124 // Register an initiating class loader for a given class.
125 void
126 _Jv_RegisterInitiatingLoader (jclass klass, java::lang::ClassLoader *loader)
127 {
128   if (! loader)
129     loader = java::lang::VMClassLoader::bootLoader;
130   loader->loadedClasses->put(klass->name->toString(), klass);
131 }
132
133 // If we found an error while defining an interpreted class, we must
134 // go back and unregister it.
135 void
136 _Jv_UnregisterInitiatingLoader (jclass klass, java::lang::ClassLoader *loader)
137 {
138   if (! loader)
139     loader = java::lang::VMClassLoader::bootLoader;
140   loader->loadedClasses->remove(klass->name->toString());
141 }
142
143 // This function is called many times during startup, before main() is
144 // run.  At that point in time we know for certain we are running 
145 // single-threaded, so we don't need to lock when adding classes to the 
146 // class chain.  At all other times, the caller should synchronize on
147 // Class::class$.
148 void
149 _Jv_RegisterClasses (const jclass *classes)
150 {
151   for (; *classes; ++classes)
152     {
153       jclass klass = *classes;
154
155       if (_Jv_CheckABIVersion ((unsigned long) klass->next_or_version))
156         (*_Jv_RegisterClassHook) (klass);
157     }
158 }
159
160 // This is a version of _Jv_RegisterClasses that takes a count.
161 void
162 _Jv_RegisterClasses_Counted (const jclass * classes, size_t count)
163 {
164   size_t i;
165   for (i = 0; i < count; i++)
166     {
167       jclass klass = classes[i];
168
169       if (_Jv_CheckABIVersion ((unsigned long) klass->next_or_version))
170         (*_Jv_RegisterClassHook) (klass);
171     }
172 }
173
174 void
175 _Jv_RegisterClassHookDefault (jclass klass)
176 {
177   // This is bogus, but there doesn't seem to be a better place to do
178   // it.
179   if (! klass->engine)
180     klass->engine = &_Jv_soleCompiledEngine;
181
182   if (system_class_list != SYSTEM_LOADER_INITIALIZED)
183     {
184       unsigned long abi = (unsigned long) klass->next_or_version;
185       if (! _Jv_ClassForBootstrapLoader (abi))
186         {
187           klass->next_or_version = system_class_list;
188           system_class_list = klass;
189           return;
190         }
191     }
192
193   jint hash = HASH_UTF (klass->name);
194
195   // If the class is already registered, don't re-register it.
196   for (jclass check_class = loaded_classes[hash];
197        check_class != NULL;
198        check_class = check_class->next_or_version)
199     {
200       if (check_class == klass)
201         {
202           // If you get this, it means you have the same class in two
203           // different libraries.
204 #define TEXT "Duplicate class registration: "
205           // We size-limit MESSAGE so that you can't trash the stack.
206           char message[200];
207           strcpy (message, TEXT);
208           strncpy (message + sizeof (TEXT) - 1, klass->name->chars(),
209                    sizeof (message) - sizeof (TEXT));
210           message[sizeof (message) - 1] = '\0';
211           if (! gcj::runtimeInitialized)
212             JvFail (message);
213           else
214             {
215               java::lang::String *str = JvNewStringLatin1 (message);
216               throw new java::lang::VirtualMachineError (str);
217             }
218         }
219     }
220
221   klass->next_or_version = loaded_classes[hash];
222   loaded_classes[hash] = klass;
223 }
224
225 // A pointer to a function that actually registers a class.
226 // Normally _Jv_RegisterClassHookDefault, but could be some other function
227 // that registers the class in e.g. a ClassLoader-local table.
228 // Should synchronize on Class:class$ while setting/restore this variable.
229
230 void (*_Jv_RegisterClassHook) (jclass cl) = _Jv_RegisterClassHookDefault;
231
232 void
233 _Jv_RegisterClass (jclass klass)
234 {
235   jclass classes[2];
236   classes[0] = klass;
237   classes[1] = NULL;
238   _Jv_RegisterClasses (classes);
239 }
240
241 // This is used during initialization to register all compiled-in
242 // classes that are not part of the core with the system class loader.
243 void
244 _Jv_CopyClassesToSystemLoader (java::lang::ClassLoader *loader)
245 {
246   for (jclass klass = system_class_list;
247        klass;
248        klass = klass->next_or_version)
249     {
250       klass->loader = loader;
251       loader->loadedClasses->put(klass->name->toString(), klass);
252     }
253   system_class_list = SYSTEM_LOADER_INITIALIZED;
254 }
255
256 jclass
257 _Jv_FindClass (_Jv_Utf8Const *name, java::lang::ClassLoader *loader)
258 {
259   // See if the class was already loaded by this loader.  This handles
260   // initiating loader checks, as we register classes with their
261   // initiating loaders.
262
263   java::lang::ClassLoader *boot = java::lang::VMClassLoader::bootLoader;
264   java::lang::ClassLoader *real = loader;
265   if (! real)
266     real = boot;
267   jstring sname = name->toString();
268   // We might still be bootstrapping the VM, in which case there
269   // won't be a bootstrap class loader yet.
270   jclass klass = real ? real->findLoadedClass (sname) : NULL;
271
272   if (! klass)
273     {
274       if (loader)
275         {
276           // Load using a user-defined loader, jvmspec 5.3.2.
277           // Note that we explicitly must call the single-argument form.
278           klass = loader->loadClass(sname);
279
280           // If "loader" delegated the loadClass operation to another
281           // loader, explicitly register that it is also an initiating
282           // loader of the given class.
283           java::lang::ClassLoader *delegate = (loader == boot
284                                                ? NULL
285                                                : loader);
286           if (klass && klass->getClassLoaderInternal () != delegate)
287             _Jv_RegisterInitiatingLoader (klass, loader);
288         }
289       else if (boot)
290         {
291           // Load using the bootstrap loader jvmspec 5.3.1.
292           klass = java::lang::VMClassLoader::loadClass (sname, false); 
293
294           // Register that we're an initiating loader.
295           if (klass)
296             _Jv_RegisterInitiatingLoader (klass, 0);
297         }
298       else
299         {
300           // Not even a bootstrap loader, try the built-in cache.
301           klass = _Jv_FindClassInCache (name);
302
303           if (klass)
304             {
305               bool found = false;
306               for (int i = 0; i < bootstrap_index; ++i)
307                 {
308                   if (bootstrap_class_list[i] == klass)
309                     {
310                       found = true;
311                       break;
312                     }
313                 }
314               if (! found)
315                 {
316                   if (bootstrap_index == BOOTSTRAP_CLASS_LIST_SIZE)
317                     abort ();
318                   bootstrap_class_list[bootstrap_index++] = klass;
319                 }
320             }
321         }
322     }
323   else
324     {
325       // We need classes to be in the hash while we're loading, so
326       // that they can refer to themselves.
327       _Jv_Linker::wait_for_state (klass, JV_STATE_LOADED);
328     }
329
330   return klass;
331 }
332
333 void
334 _Jv_RegisterBootstrapPackages ()
335 {
336   for (int i = 0; i < bootstrap_index; ++i)
337     java::lang::VMClassLoader::definePackageForNative(bootstrap_class_list[i]->getName());
338 }
339
340 jclass
341 _Jv_NewClass (_Jv_Utf8Const *name, jclass superclass,
342               java::lang::ClassLoader *loader)
343 {
344   jclass ret = (jclass) _Jv_AllocObject (&java::lang::Class::class$);
345   ret->name = name;
346   ret->superclass = superclass;
347   ret->loader = loader;
348
349   _Jv_RegisterClass (ret);
350
351   return ret;
352 }
353
354 static _Jv_IDispatchTable *array_idt = NULL;
355 static jshort array_depth = 0;
356 static jclass *array_ancestors = NULL;
357
358 // Create a class representing an array of ELEMENT and store a pointer to it
359 // in element->arrayclass. LOADER is the ClassLoader which _initiated_ the 
360 // instantiation of this array. ARRAY_VTABLE is the vtable to use for the new 
361 // array class. This parameter is optional.
362 void
363 _Jv_NewArrayClass (jclass element, java::lang::ClassLoader *loader,
364                    _Jv_VTable *array_vtable)
365 {
366   JvSynchronize sync (element);
367
368   _Jv_Utf8Const *array_name;
369   int len;
370
371   if (element->arrayclass)
372     return;
373
374   if (element->isPrimitive())
375     {
376       if (element == JvPrimClass (void))
377         throw new java::lang::ClassNotFoundException ();
378       len = 3;
379     }
380   else
381     len = element->name->len() + 5;
382
383   {
384     char signature[len];
385     int index = 0;
386     signature[index++] = '[';
387     // Compute name of array class.
388     if (element->isPrimitive())
389       {
390         signature[index++] = (char) element->method_count;
391       }
392     else
393       {
394         size_t length = element->name->len();
395         const char *const name = element->name->chars();
396         if (name[0] != '[')
397           signature[index++] = 'L';
398         memcpy (&signature[index], name, length);
399         index += length;
400         if (name[0] != '[')
401           signature[index++] = ';';
402       }      
403     array_name = _Jv_makeUtf8Const (signature, index);
404   }
405
406   // Create new array class.
407   jclass array_class = _Jv_NewClass (array_name, &java::lang::Object::class$,
408                                      element->loader);
409
410   // Note that `vtable_method_count' doesn't include the initial
411   // gc_descr slot.
412   JvAssert (java::lang::Object::class$.vtable_method_count
413             == NUM_OBJECT_METHODS);
414   int dm_count = java::lang::Object::class$.vtable_method_count;
415
416   // Create a new vtable by copying Object's vtable.
417   _Jv_VTable *vtable;
418   if (array_vtable)
419     vtable = array_vtable;
420   else
421     vtable = _Jv_VTable::new_vtable (dm_count);
422   vtable->clas = array_class;
423   vtable->gc_descr = java::lang::Object::class$.vtable->gc_descr;
424   for (int i = 0; i < dm_count; ++i)
425     vtable->set_method (i, java::lang::Object::class$.vtable->get_method (i));
426
427   array_class->vtable = vtable;
428   array_class->vtable_method_count
429     = java::lang::Object::class$.vtable_method_count;
430
431   // Stash the pointer to the element type.
432   array_class->methods = (_Jv_Method *) element;
433
434   // Register our interfaces.
435   static jclass interfaces[] =
436     {
437       &java::lang::Cloneable::class$,
438       &java::io::Serializable::class$
439     };
440   array_class->interfaces = interfaces;
441   array_class->interface_count = sizeof interfaces / sizeof interfaces[0];
442
443   // Since all array classes have the same interface dispatch table, we can 
444   // cache one and reuse it. It is not necessary to synchronize this.
445   if (!array_idt)
446     {
447       _Jv_Linker::wait_for_state(array_class, JV_STATE_PREPARED);
448       array_idt = array_class->idt;
449       array_depth = array_class->depth;
450       array_ancestors = array_class->ancestors;
451     }
452   else
453     {
454       array_class->idt = array_idt;
455       array_class->depth = array_depth;
456       array_class->ancestors = array_ancestors;
457     }
458
459   using namespace java::lang::reflect;
460   {
461     // Array classes are "abstract final" and inherit accessibility
462     // from element type, per vmspec 5.3.3.2
463     _Jv_ushort accflags = (Modifier::FINAL | Modifier::ABSTRACT
464                            | (element->accflags
465                               & (Modifier::PUBLIC | Modifier::PROTECTED
466                                  | Modifier::PRIVATE)));
467     array_class->accflags = accflags;
468   }
469
470   // An array class has no visible instance fields. "length" is invisible to 
471   // reflection.
472
473   // Say this class is initialized and ready to go!
474   array_class->state = JV_STATE_DONE;
475
476   // vmspec, section 5.3.3 describes this
477   if (element->loader != loader)
478     _Jv_RegisterInitiatingLoader (array_class, loader);
479
480   element->arrayclass = array_class;
481 }
482
483 // These two functions form a stack of classes.   When a class is loaded
484 // it is pushed onto the stack by the class loader; this is so that
485 // StackTrace can quickly determine which classes have been loaded.
486
487 jclass
488 _Jv_PopClass (void)
489 {
490   JvSynchronize sync (&java::lang::Class::class$);
491   if (stack_head)
492     {
493       jclass tmp = stack_head;
494       stack_head = tmp->chain;
495       return tmp;
496     }
497   return NULL;
498 }
499
500 void
501 _Jv_PushClass (jclass k)
502 {
503   JvSynchronize sync (&java::lang::Class::class$);
504   jclass tmp = stack_head;
505   stack_head = k;
506   k->chain = tmp;
507 }