OSDN Git Service

gcc/testsuite/
[pf3gnuchains/gcc-fork.git] / libobjc / class.c
1 /* GNU Objective C Runtime class related functions
2    Copyright (C) 1993, 1995, 1996, 1997, 2001, 2002, 2009, 2010
3      Free Software Foundation, Inc.
4    Contributed by Kresten Krab Thorup and Dennis Glatting.
5
6    Lock-free class table code designed and written from scratch by
7    Nicola Pero, 2001.
8
9 This file is part of GCC.
10
11 GCC is free software; you can redistribute it and/or modify it under the
12 terms of the GNU General Public License as published by the Free Software
13 Foundation; either version 3, or (at your option) any later version.
14
15 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
16 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
17 FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
18 details.
19
20 Under Section 7 of GPL version 3, you are granted additional
21 permissions described in the GCC Runtime Library Exception, version
22 3.1, as published by the Free Software Foundation.
23
24 You should have received a copy of the GNU General Public License and
25 a copy of the GCC Runtime Library Exception along with this program;
26 see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
27 <http://www.gnu.org/licenses/>.  */
28
29 /* The code in this file critically affects class method invocation
30   speed.  This long preamble comment explains why, and the issues
31   involved.
32
33   One of the traditional weaknesses of the GNU Objective-C runtime is
34   that class method invocations are slow.  The reason is that when you
35   write
36   
37   array = [NSArray new];
38   
39   this gets basically compiled into the equivalent of 
40   
41   array = [(objc_get_class ("NSArray")) new];
42   
43   objc_get_class returns the class pointer corresponding to the string
44   `NSArray'; and because of the lookup, the operation is more
45   complicated and slow than a simple instance method invocation.
46   
47   Most high performance Objective-C code (using the GNU Objc runtime)
48   I had the opportunity to read (or write) work around this problem by
49   caching the class pointer:
50   
51   Class arrayClass = [NSArray class];
52   
53   ... later on ...
54   
55   array = [arrayClass new];
56   array = [arrayClass new];
57   array = [arrayClass new];
58   
59   In this case, you always perform a class lookup (the first one), but
60   then all the [arrayClass new] methods run exactly as fast as an
61   instance method invocation.  It helps if you have many class method
62   invocations to the same class.
63   
64   The long-term solution to this problem would be to modify the
65   compiler to output tables of class pointers corresponding to all the
66   class method invocations, and to add code to the runtime to update
67   these tables - that should in the end allow class method invocations
68   to perform precisely as fast as instance method invocations, because
69   no class lookup would be involved.  I think the Apple Objective-C
70   runtime uses this technique.  Doing this involves synchronized
71   modifications in the runtime and in the compiler.
72   
73   As a first medicine to the problem, I [NP] have redesigned and
74   rewritten the way the runtime is performing class lookup.  This
75   doesn't give as much speed as the other (definitive) approach, but
76   at least a class method invocation now takes approximately 4.5 times
77   an instance method invocation on my machine (it would take approx 12
78   times before the rewriting), which is a lot better.
79
80   One of the main reason the new class lookup is so faster is because
81   I implemented it in a way that can safely run multithreaded without
82   using locks - a so-called `lock-free' data structure.  The atomic
83   operation is pointer assignment.  The reason why in this problem
84   lock-free data structures work so well is that you never remove
85   classes from the table - and the difficult thing with lock-free data
86   structures is freeing data when is removed from the structures.  */
87
88 #include "objc-private/common.h"
89 #include "objc-private/error.h"
90 #include "objc/runtime.h"
91 #include "objc/thr.h"
92 #include "objc-private/module-abi-8.h"  /* For CLS_ISCLASS and similar.  */
93 #include "objc-private/runtime.h"       /* the kitchen sink */
94 #include "objc-private/sarray.h"        /* For sarray_put_at_safe.  */
95 #include "objc-private/selector.h"      /* For sarray_put_at_safe.  */
96 #include <string.h>                     /* For memset */
97
98 /* We use a table which maps a class name to the corresponding class
99    pointer.  The first part of this file defines this table, and
100    functions to do basic operations on the table.  The second part of
101    the file implements some higher level Objective-C functionality for
102    classes by using the functions provided in the first part to manage
103    the table. */
104
105 /**
106  ** Class Table Internals
107  **/
108
109 /* A node holding a class */
110 typedef struct class_node
111 {
112   struct class_node *next;      /* Pointer to next entry on the list.
113                                    NULL indicates end of list. */
114   
115   const char *name;             /* The class name string */
116   int length;                   /* The class name string length */
117   Class pointer;                /* The Class pointer */
118   
119 } *class_node_ptr;
120
121 /* A table containing classes is a class_node_ptr (pointing to the
122    first entry in the table - if it is NULL, then the table is
123    empty). */
124
125 /* We have 1024 tables.  Each table contains all class names which
126    have the same hash (which is a number between 0 and 1023).  To look
127    up a class_name, we compute its hash, and get the corresponding
128    table.  Once we have the table, we simply compare strings directly
129    till we find the one which we want (using the length first).  The
130    number of tables is quite big on purpose (a normal big application
131    has less than 1000 classes), so that you shouldn't normally get any
132    collisions, and get away with a single comparison (which we can't
133    avoid since we need to know that you have got the right thing).  */
134 #define CLASS_TABLE_SIZE 1024
135 #define CLASS_TABLE_MASK 1023
136
137 static class_node_ptr class_table_array[CLASS_TABLE_SIZE];
138
139 /* The table writing mutex - we lock on writing to avoid conflicts
140    between different writers, but we read without locks.  That is
141    possible because we assume pointer assignment to be an atomic
142    operation.  TODO: This is only true under certain circumstances,
143    which should be clarified.  */
144 static objc_mutex_t __class_table_lock = NULL;
145
146 /* CLASS_TABLE_HASH is how we compute the hash of a class name.  It is
147    a macro - *not* a function - arguments *are* modified directly.
148
149    INDEX should be a variable holding an int;
150    HASH should be a variable holding an int;
151    CLASS_NAME should be a variable holding a (char *) to the class_name.  
152
153    After the macro is executed, INDEX contains the length of the
154    string, and HASH the computed hash of the string; CLASS_NAME is
155    untouched.  */
156
157 #define CLASS_TABLE_HASH(INDEX, HASH, CLASS_NAME)          \
158   HASH = 0;                                                  \
159   for (INDEX = 0; CLASS_NAME[INDEX] != '\0'; INDEX++)        \
160     {                                                        \
161       HASH = (HASH << 4) ^ (HASH >> 28) ^ CLASS_NAME[INDEX]; \
162     }                                                        \
163                                                              \
164   HASH = (HASH ^ (HASH >> 10) ^ (HASH >> 20)) & CLASS_TABLE_MASK;
165
166 /* Setup the table.  */
167 static void
168 class_table_setup (void)
169 {
170   /* Start - nothing in the table.  */
171   memset (class_table_array, 0, sizeof (class_node_ptr) * CLASS_TABLE_SIZE);
172
173   /* The table writing mutex.  */
174   __class_table_lock = objc_mutex_allocate ();
175 }
176
177
178 /* Insert a class in the table (used when a new class is
179    registered).  */
180 static void 
181 class_table_insert (const char *class_name, Class class_pointer)
182 {
183   int hash, length;
184   class_node_ptr new_node;
185
186   /* Find out the class name's hash and length.  */
187   CLASS_TABLE_HASH (length, hash, class_name);
188   
189   /* Prepare the new node holding the class.  */
190   new_node = objc_malloc (sizeof (struct class_node));
191   new_node->name = class_name;
192   new_node->length = length;
193   new_node->pointer = class_pointer;
194
195   /* Lock the table for modifications.  */
196   objc_mutex_lock (__class_table_lock);
197   
198   /* Insert the new node in the table at the beginning of the table at
199      class_table_array[hash].  */
200   new_node->next = class_table_array[hash];
201   class_table_array[hash] = new_node;
202   
203   objc_mutex_unlock (__class_table_lock);
204 }
205
206 /* Get a class from the table.  This does not need mutex protection.
207    Currently, this function is called each time you call a static
208    method, this is why it must be very fast.  */
209 static inline Class 
210 class_table_get_safe (const char *class_name)
211 {
212   class_node_ptr node;  
213   int length, hash;
214
215   /* Compute length and hash.  */
216   CLASS_TABLE_HASH (length, hash, class_name);
217   
218   node = class_table_array[hash];
219   
220   if (node != NULL)
221     {
222       do
223         {
224           if (node->length == length)
225             {
226               /* Compare the class names.  */
227               int i;
228
229               for (i = 0; i < length; i++)
230                 {
231                   if ((node->name)[i] != class_name[i]) 
232                     break;
233                 }
234               
235               if (i == length)
236                 {
237                   /* They are equal!  */
238                   return node->pointer;
239                 }
240             }
241         }
242       while ((node = node->next) != NULL);
243     }
244
245   return Nil;
246 }
247
248 /* Enumerate over the class table.  */
249 struct class_table_enumerator
250 {
251   int hash;
252   class_node_ptr node;
253 };
254
255
256 static Class
257 class_table_next (struct class_table_enumerator **e)
258 {
259   struct class_table_enumerator *enumerator = *e;
260   class_node_ptr next;
261   
262   if (enumerator == NULL)
263     {
264        *e = objc_malloc (sizeof (struct class_table_enumerator));
265       enumerator = *e;
266       enumerator->hash = 0;
267       enumerator->node = NULL;
268
269       next = class_table_array[enumerator->hash];
270     }
271   else
272     next = enumerator->node->next;
273   
274   if (next != NULL)
275     {
276       enumerator->node = next;
277       return enumerator->node->pointer;
278     }
279   else 
280     {
281       enumerator->hash++;
282      
283       while (enumerator->hash < CLASS_TABLE_SIZE)
284         {
285           next = class_table_array[enumerator->hash];
286           if (next != NULL)
287             {
288               enumerator->node = next;
289               return enumerator->node->pointer;
290             }
291           enumerator->hash++;
292         }
293       
294       /* Ok - table finished - done.  */
295       objc_free (enumerator);
296       return Nil;
297     }
298 }
299
300 #if 0 /* DEBUGGING FUNCTIONS */
301 /* Debugging function - print the class table.  */
302 void
303 class_table_print (void)
304 {
305   int i;
306   
307   for (i = 0; i < CLASS_TABLE_SIZE; i++)
308     {
309       class_node_ptr node;
310       
311       printf ("%d:\n", i);
312       node = class_table_array[i];
313       
314       while (node != NULL)
315         {
316           printf ("\t%s\n", node->name);
317           node = node->next;
318         }
319     }
320 }
321
322 /* Debugging function - print an histogram of number of classes in
323    function of hash key values.  Useful to evaluate the hash function
324    in real cases.  */
325 void
326 class_table_print_histogram (void)
327 {
328   int i, j;
329   int counter = 0;
330   
331   for (i = 0; i < CLASS_TABLE_SIZE; i++)
332     {
333       class_node_ptr node;
334       
335       node = class_table_array[i];
336       
337       while (node != NULL)
338         {
339           counter++;
340           node = node->next;
341         }
342       if (((i + 1) % 50) == 0)
343         {
344           printf ("%4d:", i + 1);
345           for (j = 0; j < counter; j++)
346             printf ("X");
347
348           printf ("\n");
349           counter = 0;
350         }
351     }
352   printf ("%4d:", i + 1);
353   for (j = 0; j < counter; j++)
354     printf ("X");
355
356   printf ("\n");
357 }
358 #endif /* DEBUGGING FUNCTIONS */
359
360 /**
361  ** Objective-C runtime functions
362  **/
363
364 /* From now on, the only access to the class table data structure
365    should be via the class_table_* functions.  */
366
367 /* This is a hook which is called by objc_get_class and
368    objc_lookup_class if the runtime is not able to find the class.
369    This may e.g. try to load in the class using dynamic loading.
370
371    This hook was a public, global variable in the Traditional GNU
372    Objective-C Runtime API (objc/objc-api.h).  The modern GNU
373    Objective-C Runtime API (objc/runtime.h) provides the
374    objc_setGetUnknownClassHandler() function instead.
375 */
376 Class (*_objc_lookup_class) (const char *name) = 0;      /* !T:SAFE */
377
378 /* The handler currently in use.  PS: if both
379    __obj_get_unknown_class_handler and _objc_lookup_class are defined,
380    __objc_get_unknown_class_handler is called first.  */
381 static objc_get_unknown_class_handler
382 __objc_get_unknown_class_handler = NULL;
383
384 objc_get_unknown_class_handler
385 objc_setGetUnknownClassHandler (objc_get_unknown_class_handler 
386                                 new_handler)
387 {
388   objc_get_unknown_class_handler old_handler 
389     = __objc_get_unknown_class_handler;
390   __objc_get_unknown_class_handler = new_handler;
391   return old_handler;
392 }
393
394
395 /* True when class links has been resolved.  */     
396 BOOL __objc_class_links_resolved = NO;                  /* !T:UNUSED */
397
398
399 void
400 __objc_init_class_tables (void)
401 {
402   /* Allocate the class hash table.  */
403   
404   if (__class_table_lock)
405     return;
406   
407   objc_mutex_lock (__objc_runtime_mutex);
408   
409   class_table_setup ();
410
411   objc_mutex_unlock (__objc_runtime_mutex);
412 }  
413
414 /* This function adds a class to the class hash table, and assigns the
415    class a number, unless it's already known.  Return 'YES' if the
416    class was added.  Return 'NO' if the class was already known.  */
417 BOOL
418 __objc_add_class_to_hash (Class class)
419 {
420   Class existing_class;
421
422   objc_mutex_lock (__objc_runtime_mutex);
423
424   /* Make sure the table is there.  */
425   assert (__class_table_lock);
426
427   /* Make sure it's not a meta class.  */
428   assert (CLS_ISCLASS (class));
429
430   /* Check to see if the class is already in the hash table.  */
431   existing_class = class_table_get_safe (class->name);
432
433   if (existing_class)
434     {
435       objc_mutex_unlock (__objc_runtime_mutex);
436       return NO;      
437     }
438   else
439     {
440       /* The class isn't in the hash table.  Add the class and assign
441          a class number.  */
442       static unsigned int class_number = 1;
443       
444       CLS_SETNUMBER (class, class_number);
445       CLS_SETNUMBER (class->class_pointer, class_number);
446
447       ++class_number;
448       class_table_insert (class->name, class);
449
450       objc_mutex_unlock (__objc_runtime_mutex);
451       return YES;
452     }
453 }
454
455 Class
456 objc_getClass (const char *name)
457 {
458   Class class;
459
460   if (name == NULL)
461     return Nil;
462
463   class = class_table_get_safe (name);
464   
465   if (class)
466     return class;
467
468   if (__objc_get_unknown_class_handler)
469     return (*__objc_get_unknown_class_handler) (name);
470
471   if (_objc_lookup_class)
472     return (*_objc_lookup_class) (name);
473
474   return Nil;
475 }
476
477 Class
478 objc_lookUpClass (const char *name)
479 {
480   if (name == NULL)
481     return Nil;
482   else
483     return class_table_get_safe (name);
484 }
485
486 Class
487 objc_getMetaClass (const char *name)
488 {
489   Class class = objc_getClass (name);
490
491   if (class)
492     return class->class_pointer;
493   else
494     return Nil;
495 }
496
497 Class
498 objc_getRequiredClass (const char *name)
499 {
500   Class class = objc_getClass (name);
501
502   if (class)
503     return class;
504   else
505     _objc_abort ("objc_getRequiredClass ('%s') failed: class not found\n", name);
506 }
507
508 int
509 objc_getClassList (Class *returnValue, int maxNumberOfClassesToReturn)
510 {
511   /* Iterate over all entries in the table.  */
512   int hash, count = 0;
513
514   for (hash = 0; hash < CLASS_TABLE_SIZE; hash++)
515     {
516       class_node_ptr node = class_table_array[hash];
517       
518       while (node != NULL)
519         {
520           if (returnValue)
521             {
522               if (count < maxNumberOfClassesToReturn)
523                 returnValue[count] = node->pointer;
524               else
525                 return count;
526             }
527           count++;
528           node = node->next;
529         }
530     }
531   
532   return count;
533 }
534
535 Class
536 objc_allocateClassPair (Class super_class, const char *class_name, size_t extraBytes)
537 {
538   Class new_class;
539   Class new_meta_class;
540
541   if (class_name == NULL)
542     return Nil;
543
544   if (objc_getClass (class_name))
545     return Nil;
546
547   if (super_class)
548     {
549       /* If you want to build a hierarchy of classes, you need to
550          build and register them one at a time.  The risk is that you
551          are able to cause confusion by registering a subclass before
552          the superclass or similar.  */
553       if (CLS_IS_IN_CONSTRUCTION (super_class))
554         return Nil;
555     }
556
557   /* Technically, we should create the metaclass first, then use
558      class_createInstance() to create the class.  That complication
559      would be relevant if we had class variables, but we don't, so we
560      just ignore it and create everything directly and assume all
561      classes have the same size.  */
562   new_class = objc_calloc (1, sizeof (struct objc_class) + extraBytes);
563   new_meta_class = objc_calloc (1, sizeof (struct objc_class) + extraBytes);
564
565   /* We create an unresolved class, similar to one generated by the
566      compiler.  It will be resolved later when we register it.
567
568      Note how the metaclass details are not that important; when the
569      class is resolved, the ones that matter will be fixed up.  */
570   new_class->class_pointer = new_meta_class;
571   new_meta_class->class_pointer = 0;
572
573   if (super_class)
574     {
575       /* Force the name of the superclass in place of the link to the
576          actual superclass, which will be put there when the class is
577          resolved.  */
578       const char *super_class_name = class_getName (super_class);
579       new_class->super_class = (void *)super_class_name;
580       new_meta_class->super_class = (void *)super_class_name;
581     }
582   else
583     {
584       new_class->super_class = (void *)0;
585       new_meta_class->super_class = (void *)0;
586     }
587
588   new_class->name = objc_malloc (strlen (class_name) + 1);
589   strcpy ((char*)new_class->name, class_name);
590   new_meta_class->name = new_class->name;
591
592   new_class->version = 0;
593   new_meta_class->version = 0;
594
595   new_class->info = _CLS_CLASS | _CLS_IN_CONSTRUCTION;
596   new_meta_class->info = _CLS_META | _CLS_IN_CONSTRUCTION;
597
598   if (super_class)
599     new_class->instance_size = super_class->instance_size;
600   else
601     new_class->instance_size = 0;
602   new_meta_class->instance_size = sizeof (struct objc_class);
603
604   return new_class;
605 }
606
607 void
608 objc_registerClassPair (Class class_)
609 {
610   if (class_ == Nil)
611     return;
612
613   if ((! CLS_ISCLASS (class_)) || (! CLS_IS_IN_CONSTRUCTION (class_)))
614     return;
615
616   if ((! CLS_ISMETA (class_->class_pointer)) || (! CLS_IS_IN_CONSTRUCTION (class_->class_pointer)))
617     return;
618
619   objc_mutex_lock (__objc_runtime_mutex);
620
621   if (objc_getClass (class_->name))
622     {
623       objc_mutex_unlock (__objc_runtime_mutex);
624       return;
625     }
626
627   CLS_SET_NOT_IN_CONSTRUCTION (class_);
628   CLS_SET_NOT_IN_CONSTRUCTION (class_->class_pointer);
629
630   __objc_init_class (class_);
631
632   /* Resolve class links immediately.  No point in waiting.  */
633   __objc_resolve_class_links ();
634
635   objc_mutex_unlock (__objc_runtime_mutex);
636 }
637
638 void
639 objc_disposeClassPair (Class class_)
640 {
641   if (class_ == Nil)
642     return;
643
644   if ((! CLS_ISCLASS (class_)) || (! CLS_IS_IN_CONSTRUCTION (class_)))
645     return;
646
647   if ((! CLS_ISMETA (class_->class_pointer)) || (! CLS_IS_IN_CONSTRUCTION (class_->class_pointer)))
648     return;
649
650   /* Undo any class_addIvar().  */
651   if (class_->ivars)
652     {
653       int i;
654       for (i = 0; i < class_->ivars->ivar_count; i++)
655         {
656           struct objc_ivar *ivar = &(class_->ivars->ivar_list[i]);
657
658           objc_free ((char *)ivar->ivar_name);
659           objc_free ((char *)ivar->ivar_type);
660         }
661       
662       objc_free (class_->ivars);
663     }
664
665   /* Undo any class_addMethod().  */
666   if (class_->methods)
667     {
668       struct objc_method_list *list = class_->methods;
669       while (list)
670         {
671           int i;
672           struct objc_method_list *next = list->method_next;
673
674           for (i = 0; i < list->method_count; i++)
675             {
676               struct objc_method *method = &(list->method_list[i]);
677
678               objc_free ((char *)method->method_name);
679               objc_free ((char *)method->method_types);
680             }
681
682           objc_free (list);
683           list = next;
684         }
685     }
686
687   /* Undo any class_addProtocol().  */
688   if (class_->protocols)
689     {
690       struct objc_protocol_list *list = class_->protocols;
691       while (list)
692         {
693           struct objc_protocol_list *next = list->next;
694
695           objc_free (list);
696           list = next;
697         }
698     }
699   
700   /* Undo any class_addMethod() on the meta-class.  */
701   if (class_->class_pointer->methods)
702     {
703       struct objc_method_list *list = class_->class_pointer->methods;
704       while (list)
705         {
706           int i;
707           struct objc_method_list *next = list->method_next;
708
709           for (i = 0; i < list->method_count; i++)
710             {
711               struct objc_method *method = &(list->method_list[i]);
712
713               objc_free ((char *)method->method_name);
714               objc_free ((char *)method->method_types);
715             }
716
717           objc_free (list);
718           list = next;
719         }
720     }
721
722   /* Undo objc_allocateClassPair().  */
723   objc_free ((char *)(class_->name));
724   objc_free (class_->class_pointer);
725   objc_free (class_);
726 }
727
728 /* Traditional GNU Objective-C Runtime API.  Important: this method is
729    called automatically by the compiler while messaging (if using the
730    traditional ABI), so it is worth keeping it fast; don't make it
731    just a wrapper around objc_getClass().  */
732 /* Note that this is roughly equivalent to objc_getRequiredClass().  */
733 /* Get the class object for the class named NAME.  If NAME does not
734    identify a known class, the hook _objc_lookup_class is called.  If
735    this fails, an error message is issued and the system aborts.  */
736 Class
737 objc_get_class (const char *name)
738 {
739   Class class;
740
741   class = class_table_get_safe (name);
742
743   if (class)
744     return class;
745
746   if (__objc_get_unknown_class_handler)
747     class = (*__objc_get_unknown_class_handler) (name);
748
749   if ((!class)  &&  _objc_lookup_class)
750     class = (*_objc_lookup_class) (name);
751
752   if (class)
753     return class;
754   
755   _objc_abort ("objc runtime: cannot find class %s\n", name);
756
757   return 0;
758 }
759
760 /* This is used by the compiler too.  */
761 Class
762 objc_get_meta_class (const char *name)
763 {
764   return objc_get_class (name)->class_pointer;
765 }
766
767 /* This is not used by GCC, but the clang compiler seems to use it
768    when targetting the GNU runtime.  That's wrong, but we have it to
769    be compatible.  */
770 Class
771 objc_lookup_class (const char *name)
772 {
773   return objc_getClass (name);
774 }
775
776 /* This is used when the implementation of a method changes.  It goes
777    through all classes, looking for the ones that have these methods
778    (either method_a or method_b; method_b can be NULL), and reloads
779    the implementation for these.  You should call this with the
780    runtime mutex already locked.  */
781 void
782 __objc_update_classes_with_methods (struct objc_method *method_a, struct objc_method *method_b)
783 {
784   int hash;
785
786   /* Iterate over all classes.  */
787   for (hash = 0; hash < CLASS_TABLE_SIZE; hash++)
788     {
789       class_node_ptr node = class_table_array[hash];
790       
791       while (node != NULL)
792         {
793           /* We execute this loop twice: the first time, we iterate
794              over all methods in the class (instance methods), while
795              the second time we iterate over all methods in the meta
796              class (class methods).  */
797           Class class = Nil;
798           BOOL done = NO;
799
800           while (done == NO)
801             {
802               struct objc_method_list * method_list;
803
804               if (class == Nil)
805                 {
806                   /* The first time, we work on the class.  */
807                   class = node->pointer;
808                 }
809               else
810                 {
811                   /* The second time, we work on the meta class.  */
812                   class = class->class_pointer;
813                   done = YES;
814                 }
815
816               method_list = class->methods;
817
818               while (method_list)
819                 {
820                   int i;
821                   
822                   for (i = 0; i < method_list->method_count; ++i)
823                     {
824                       struct objc_method *method = &method_list->method_list[i];
825                       
826                       /* If the method is one of the ones we are
827                          looking for, update the implementation.  */
828                       if (method == method_a)
829                         sarray_at_put_safe (class->dtable,
830                                             (sidx) method_a->method_name->sel_id,
831                                             method_a->method_imp);
832                       
833                       if (method == method_b)
834                         {
835                           if (method_b != NULL)
836                             sarray_at_put_safe (class->dtable,
837                                                 (sidx) method_b->method_name->sel_id,
838                                                 method_b->method_imp);
839                         }
840                     }
841                   
842                   method_list = method_list->method_next;
843                 }
844             }
845           node = node->next;
846         }
847     }
848 }
849
850 /* Resolve super/subclass links for all classes.  The only thing we
851    can be sure of is that the class_pointer for class objects point to
852    the right meta class objects.  */
853 void
854 __objc_resolve_class_links (void)
855 {
856   struct class_table_enumerator *es = NULL;
857   Class object_class = objc_get_class ("Object");
858   Class class1;
859
860   assert (object_class);
861
862   objc_mutex_lock (__objc_runtime_mutex);
863
864   /* Assign subclass links.  */
865   while ((class1 = class_table_next (&es)))
866     {
867       /* Make sure we have what we think we have.  */
868       assert (CLS_ISCLASS (class1));
869       assert (CLS_ISMETA (class1->class_pointer));
870
871       /* The class_pointer of all meta classes point to Object's meta
872          class.  */
873       class1->class_pointer->class_pointer = object_class->class_pointer;
874
875       if (! CLS_ISRESOLV (class1))
876         {
877           CLS_SETRESOLV (class1);
878           CLS_SETRESOLV (class1->class_pointer);
879               
880           if (class1->super_class)
881             {   
882               Class a_super_class 
883                 = objc_get_class ((char *) class1->super_class);
884               
885               assert (a_super_class);
886               
887               DEBUG_PRINTF ("making class connections for: %s\n",
888                             class1->name);
889               
890               /* Assign subclass links for superclass.  */
891               class1->sibling_class = a_super_class->subclass_list;
892               a_super_class->subclass_list = class1;
893               
894               /* Assign subclass links for meta class of superclass.  */
895               if (a_super_class->class_pointer)
896                 {
897                   class1->class_pointer->sibling_class
898                     = a_super_class->class_pointer->subclass_list;
899                   a_super_class->class_pointer->subclass_list 
900                     = class1->class_pointer;
901                 }
902             }
903           else /* A root class, make its meta object be a subclass of
904                   Object.  */
905             {
906               class1->class_pointer->sibling_class 
907                 = object_class->subclass_list;
908               object_class->subclass_list = class1->class_pointer;
909             }
910         }
911     }
912
913   /* Assign superclass links.  */
914    es = NULL;
915    while ((class1 = class_table_next (&es)))
916     {
917       Class sub_class;
918       for (sub_class = class1->subclass_list; sub_class;
919            sub_class = sub_class->sibling_class)
920         {
921           sub_class->super_class = class1;
922           if (CLS_ISCLASS (sub_class))
923             sub_class->class_pointer->super_class = class1->class_pointer;
924         }
925     }
926
927   objc_mutex_unlock (__objc_runtime_mutex);
928 }
929
930 const char *
931 class_getName (Class class_)
932 {
933   if (class_ == Nil)
934     return "nil";
935
936   return class_->name;
937 }
938
939 BOOL
940 class_isMetaClass (Class class_)
941 {
942   /* CLS_ISMETA includes the check for Nil class_.  */
943   return CLS_ISMETA (class_);
944 }
945
946 /* Even inside libobjc it may be worth using class_getSuperclass
947    instead of accessing class_->super_class directly because it
948    resolves the class links if needed.  If you access
949    class_->super_class directly, make sure to deal with the situation
950    where the class is not resolved yet!  */
951 Class
952 class_getSuperclass (Class class_)
953 {
954   if (class_ == Nil)
955     return Nil;
956
957   /* Classes that are in construction are not resolved, and still have
958      the class name (instead of a class pointer) in the
959      class_->super_class field.  In that case we need to lookup the
960      superclass name to return the superclass.  We can not resolve the
961      class until it is registered.  */
962   if (CLS_IS_IN_CONSTRUCTION (class_))
963     {
964       if (CLS_ISMETA (class_))
965         return object_getClass ((id)objc_lookUpClass ((const char *)(class_->super_class)));
966       else
967         return objc_lookUpClass ((const char *)(class_->super_class));
968     }
969
970   /* If the class is not resolved yet, super_class would point to a
971      string (the name of the super class) as opposed to the actual
972      super class.  In that case, we need to resolve the class links
973      before we can return super_class.  */
974   if (! CLS_ISRESOLV (class_))
975     __objc_resolve_class_links ();
976   
977   return class_->super_class;
978 }
979
980 int
981 class_getVersion (Class class_)
982 {
983   if (class_ == Nil)
984     return 0;
985
986   return (int)(class_->version);
987 }
988
989 void
990 class_setVersion (Class class_, int version)
991 {
992   if (class_ == Nil)
993     return;
994
995   class_->version = version;
996 }
997
998 size_t
999 class_getInstanceSize (Class class_)
1000 {
1001   if (class_ == Nil)
1002     return 0;
1003
1004   return class_->instance_size;
1005 }
1006