From dd86e3be8a57b4e8df35d31d817e0434613562bd Mon Sep 17 00:00:00 2001
From: pinskia <pinskia@138bc75d-0d04-0410-961f-82ee72b054a4>
Date: Tue, 25 May 2004 19:10:54 +0000
Subject: [PATCH] 2004-05-25  Andrew Pinski  <pinskia@physics.uc.edu>

	Merge from the libobjc-branch
	2004-02-09  Andrew Pinski  <pinskia@physics.uc.edu>

		* Makefile.in (OBJC_H): Change objc-deps.h to objc-decls.h.

	2004-02-03  Andrew Pinski  <pinskia@physics.uc.edu>

		* Makefile.in (OBJC_H): Add objc-deps.h.

	2004-01-27  Nicola Pero  <n.pero@mi.flashnet.it>

		* Protocol.m ([-conformsTo:]): If the argument is nil, return NO.
		([-hash], [-isEqual:]): New methods.

	2004-01-27  Richard Frith-Macdonald <rfm@gnu.org>

		* sarray.c (sarray_free): Add a better comment.

	2004-01-27  Adam Fedor  <fedor@gnu.org>

		* hash.c (hash_add): Cast cachep to int.
		* selector.c (__sel_register_typed_name): Cast
		soffset_decode to int.

	2004-01-27  Alexander Malmberg  <alexander@malmberg.org>

		* selector.c: Rename register_selectors_from_list to
		__objc_register_selectors_from_list. Update caller.
		(__objc_register_selectors_from_list): Lock __objc_runtime_mutex
		while registering selectors. Use __sel_register_typed_name instead
		of sel_register_typed_name. Check for NULL method_name:s.
		(pool_alloc_selector): New function.
		(__sel_register_typed_name): Use pool_alloc_selector to allocate
		selector structures.
		* sendmsg.c (class_add_method_list): Use
		__objc_register_selectors_from_list.
		* objc/runtime.h: Add __objc_register_selectors_from_list.

	2004-01-25  Adam Fedor  <fedor@gnu.org>
	            Nicola Pero  <n.pero@mi.flashnet.it>
	            Andrew Pinski  <pinskia@physics.uc.edu>

		* objc/objc-decls.h: New file.
		* objc/objc-api.h (_objc_lookup_class): Mark as export.
		(_objc_load_callback): Likewise.
		(_objc_object_alloc): Likewise.
		(_objc_object_copy): Likewise.
		(_objc_object_dispose): Likewise.

	2004-01-25  Andrew Pinski  <pinskia@physics.uc.edu>

		* archive.c: s/__inline__/inline
		* sendmsg.c: Likewise.

		* encoding.c: Remove FIXME about the warning
		about unused variable.
		* sendmsg.c: Add a FIXME comment saying that
		this should be using libffi.

		* Makefile.in (LIBTOOL): Use @LIBTOOL@ now as it works.


git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@82253 138bc75d-0d04-0410-961f-82ee72b054a4
---
 libobjc/ChangeLog         | 64 +++++++++++++++++++++++++++++++++++++++
 libobjc/Makefile.in       |  5 ++-
 libobjc/Protocol.m        | 30 +++++++++++++++++-
 libobjc/archive.c         | 46 ++++++++++++++--------------
 libobjc/encoding.c        |  4 +--
 libobjc/hash.c            |  4 +--
 libobjc/objc/objc-api.h   | 29 +++++++++---------
 libobjc/objc/objc-decls.h | 47 ++++++++++++++++++++++++++++
 libobjc/objc/runtime.h    |  3 +-
 libobjc/sarray.c          |  6 ++--
 libobjc/selector.c        | 63 +++++++++++++++++++++++++++++---------
 libobjc/sendmsg.c         | 34 +++++++--------------
 12 files changed, 248 insertions(+), 87 deletions(-)
 create mode 100644 libobjc/objc/objc-decls.h

diff --git a/libobjc/ChangeLog b/libobjc/ChangeLog
index 898553311806..99f7769dd409 100644
--- a/libobjc/ChangeLog
+++ b/libobjc/ChangeLog
@@ -1,3 +1,67 @@
+2004-05-25  Andrew Pinski  <pinskia@physics.uc.edu>
+
+	Merge from the libobjc-branch
+	2004-02-09  Andrew Pinski  <pinskia@physics.uc.edu>
+	
+		* Makefile.in (OBJC_H): Change objc-deps.h to objc-decls.h.
+	
+	2004-02-03  Andrew Pinski  <pinskia@physics.uc.edu>
+	
+		* Makefile.in (OBJC_H): Add objc-deps.h.
+	
+	2004-01-27  Nicola Pero  <n.pero@mi.flashnet.it>
+	
+		* Protocol.m ([-conformsTo:]): If the argument is nil, return NO.
+		([-hash], [-isEqual:]): New methods.
+	
+	2004-01-27  Richard Frith-Macdonald <rfm@gnu.org>
+	
+		* sarray.c (sarray_free): Add a better comment.
+	
+	2004-01-27  Adam Fedor  <fedor@gnu.org>
+	
+		* hash.c (hash_add): Cast cachep to int.
+		* selector.c (__sel_register_typed_name): Cast
+		soffset_decode to int.
+	
+	2004-01-27  Alexander Malmberg  <alexander@malmberg.org>
+	
+		* selector.c: Rename register_selectors_from_list to
+		__objc_register_selectors_from_list. Update caller.
+		(__objc_register_selectors_from_list): Lock __objc_runtime_mutex
+		while registering selectors. Use __sel_register_typed_name instead
+		of sel_register_typed_name. Check for NULL method_name:s.
+		(pool_alloc_selector): New function.
+		(__sel_register_typed_name): Use pool_alloc_selector to allocate
+		selector structures.
+		* sendmsg.c (class_add_method_list): Use
+		__objc_register_selectors_from_list.
+		* objc/runtime.h: Add __objc_register_selectors_from_list.
+	
+	2004-01-25  Adam Fedor  <fedor@gnu.org>
+	            Nicola Pero  <n.pero@mi.flashnet.it>
+	            Andrew Pinski  <pinskia@physics.uc.edu>
+	
+		* objc/objc-decls.h: New file.
+		* objc/objc-api.h (_objc_lookup_class): Mark as export.
+		(_objc_load_callback): Likewise.
+		(_objc_object_alloc): Likewise.
+		(_objc_object_copy): Likewise.
+		(_objc_object_dispose): Likewise.
+	
+	2004-01-25  Andrew Pinski  <pinskia@physics.uc.edu>
+	
+		* archive.c: s/__inline__/inline
+		* sendmsg.c: Likewise. 
+	
+		* encoding.c: Remove FIXME about the warning
+		about unused variable.
+		* sendmsg.c: Add a FIXME comment saying that
+		this should be using libffi.
+	
+		* Makefile.in (LIBTOOL): Use @LIBTOOL@ now as it works.
+	
+
 2004-05-13  Andrew Pinski  <pinskia@physics.uc.edu>
 
 	* archive.c (objc_read_class): Initialize class_name.
diff --git a/libobjc/Makefile.in b/libobjc/Makefile.in
index c014a2dcfc81..28d22a4d6a77 100644
--- a/libobjc/Makefile.in
+++ b/libobjc/Makefile.in
@@ -79,8 +79,7 @@ ALL_CFLAGS = -I. -I$(srcdir) $(CPPFLAGS) $(DEFS) $(CFLAGS) $(WARN_CFLAGS) \
 # numbers.
 LIBOBJC_VERSION = @VERSION@
 LIBOBJC_GC_VERSION = @VERSION@
-# @LIBTOOL@ does not get it right, so we hack it in - FIXME
-LIBTOOL = ./libtool
+LIBTOOL = @LIBTOOL@
 LIBTOOL_COMPILE = $(LIBTOOL) --mode=compile
 LIBTOOL_LINK    = $(LIBTOOL) --mode=link 
 LIBTOOL_INSTALL = $(LIBTOOL) --mode=install
@@ -136,7 +135,7 @@ all: libobjc.la $(OBJC_BOEHM_GC)
 
 OBJC_H = hash.h objc-list.h sarray.h objc.h objc-api.h \
 	 NXConstStr.h Object.h Protocol.h encoding.h typedstream.h \
-	 thr.h
+	 thr.h objc-decls.h
 
 # Modules that comprise the runtime library.
 
diff --git a/libobjc/Protocol.m b/libobjc/Protocol.m
index 06a25acabbef..a18d544db404 100644
--- a/libobjc/Protocol.m
+++ b/libobjc/Protocol.m
@@ -1,5 +1,5 @@
 /* This file contains the implementation of class Protocol.
-   Copyright (C) 1993 Free Software Foundation, Inc.
+   Copyright (C) 1993, 2004 Free Software Foundation, Inc.
 
 This file is part of GCC. 
 
@@ -56,6 +56,9 @@ struct objc_method_description_list {
   size_t i;
   struct objc_protocol_list* proto_list;
 
+  if (aProtocolObject == nil)
+    return NO;
+
   if (!strcmp(aProtocolObject->protocol_name, self->protocol_name))
     return YES;
 
@@ -129,4 +132,29 @@ struct objc_method_description_list {
   return NULL;
 }
 
+- (unsigned) hash
+{
+  /* Compute a hash of the protocol_name; use the same hash algorithm
+   * that we use for class names; protocol names and class names are
+   * somewhat similar types of string spaces.
+   */
+  int hash = 0, index;
+  
+  for (index = 0; protocol_name[index] != '\0'; index++)
+    {
+      hash = (hash << 4) ^ (hash >> 28) ^ protocol_name[index];
+    }
+
+  hash = (hash ^ (hash >> 10) ^ (hash >> 20));
+
+  return hash;
+}
+
+- (BOOL) isEqual: (id)obj
+{
+  if (strcmp (protocol_name, [obj name]) == 0)
+    return YES;
+
+  return NO;
+}
 @end
diff --git a/libobjc/archive.c b/libobjc/archive.c
index f4245041fc56..b6a1ec359322 100644
--- a/libobjc/archive.c
+++ b/libobjc/archive.c
@@ -1,5 +1,5 @@
  /* GNU Objective C Runtime archiving
-   Copyright (C) 1993, 1995, 1996, 1997, 2002 Free Software Foundation, Inc.
+   Copyright (C) 1993, 1995, 1996, 1997, 2002, 2004 Free Software Foundation, Inc.
    Contributed by Kresten Krab Thorup
 
 This file is part of GCC.
@@ -62,7 +62,7 @@ const char *objc_skip_type (const char *type);
 static void __objc_finish_write_root_object (struct objc_typed_stream *);
 static void __objc_finish_read_root_object (struct objc_typed_stream *);
 
-static __inline__ int
+static inline int
 __objc_code_unsigned_char (unsigned char *buf, unsigned char val)
 {
   if ((val&_B_VALUE) == val)
@@ -87,7 +87,7 @@ objc_write_unsigned_char (struct objc_typed_stream *stream,
   return (*stream->write) (stream->physical, buf, len);
 }
 
-static __inline__ int
+static inline int
 __objc_code_char (unsigned char *buf, signed char val)
 {
   if (val >= 0)
@@ -108,7 +108,7 @@ objc_write_char (struct objc_typed_stream *stream, signed char value)
   return (*stream->write) (stream->physical, buf, len);
 }
 
-static __inline__ int
+static inline int
 __objc_code_unsigned_short (unsigned char *buf, unsigned short val)
 {
   if ((val&_B_VALUE) == val)
@@ -146,7 +146,7 @@ objc_write_unsigned_short (struct objc_typed_stream *stream,
   return (*stream->write) (stream->physical, buf, len);
 }
       
-static __inline__ int
+static inline int
 __objc_code_short (unsigned char *buf, short val)
 {
   int sign = (val < 0);
@@ -165,7 +165,7 @@ objc_write_short (struct objc_typed_stream *stream, short value)
 }
       
 
-static __inline__ int
+static inline int
 __objc_code_unsigned_int (unsigned char *buf, unsigned int val)
 {
   if ((val&_B_VALUE) == val)
@@ -202,7 +202,7 @@ objc_write_unsigned_int (struct objc_typed_stream *stream, unsigned int value)
   return (*stream->write) (stream->physical, buf, len);
 }
 
-static __inline__ int
+static inline int
 __objc_code_int (unsigned char *buf, int val)
 {
   int sign = (val < 0);
@@ -220,7 +220,7 @@ objc_write_int (struct objc_typed_stream *stream, int value)
   return (*stream->write) (stream->physical, buf, len);
 }
 
-static __inline__ int
+static inline int
 __objc_code_unsigned_long (unsigned char *buf, unsigned long val)
 {
   if ((val&_B_VALUE) == val)
@@ -258,7 +258,7 @@ objc_write_unsigned_long (struct objc_typed_stream *stream,
   return (*stream->write) (stream->physical, buf, len);
 }
 
-static __inline__ int
+static inline int
 __objc_code_long (unsigned char *buf, long val)
 {
   int sign = (val < 0);
@@ -350,7 +350,7 @@ objc_write_use_common (struct objc_typed_stream *stream, unsigned long key)
     }
 }
 
-static __inline__ int
+static inline int
 __objc_write_extension (struct objc_typed_stream *stream, unsigned char code)
 {
   if (code <= _B_VALUE)
@@ -366,7 +366,7 @@ __objc_write_extension (struct objc_typed_stream *stream, unsigned char code)
     }
 }
 
-__inline__ int
+inline int
 __objc_write_object (struct objc_typed_stream *stream, id object)
 {
   unsigned char buf = '\0';
@@ -431,7 +431,7 @@ objc_write_object (struct objc_typed_stream *stream, id object)
     }
 }
 
-__inline__ int
+inline int
 __objc_write_class (struct objc_typed_stream *stream, struct objc_class *class)
 {
   __objc_write_extension (stream, _BX_CLASS);
@@ -459,7 +459,7 @@ objc_write_class (struct objc_typed_stream *stream,
 }
 
 
-__inline__ int 
+inline int 
 __objc_write_selector (struct objc_typed_stream *stream, SEL selector)
 {
   const char *sel_name;
@@ -501,7 +501,7 @@ objc_write_selector (struct objc_typed_stream *stream, SEL selector)
 ** Read operations 
 */
 
-__inline__ int
+inline int
 objc_read_char (struct objc_typed_stream *stream, char *val)
 {
   unsigned char buf;
@@ -528,7 +528,7 @@ objc_read_char (struct objc_typed_stream *stream, char *val)
 }
 
 
-__inline__ int
+inline int
 objc_read_unsigned_char (struct objc_typed_stream *stream, unsigned char *val)
 {
   unsigned char buf;
@@ -549,7 +549,7 @@ objc_read_unsigned_char (struct objc_typed_stream *stream, unsigned char *val)
   return len;
 }
 
-__inline__ int
+inline int
 objc_read_short (struct objc_typed_stream *stream, short *value)
 {
   unsigned char buf[sizeof (short) + 1];
@@ -577,7 +577,7 @@ objc_read_short (struct objc_typed_stream *stream, short *value)
   return len;
 }
 
-__inline__ int
+inline int
 objc_read_unsigned_short (struct objc_typed_stream *stream,
 			  unsigned short *value)
 {
@@ -605,7 +605,7 @@ objc_read_unsigned_short (struct objc_typed_stream *stream,
 }
 
 
-__inline__ int
+inline int
 objc_read_int (struct objc_typed_stream *stream, int *value)
 {
   unsigned char buf[sizeof (int) + 1];
@@ -632,7 +632,7 @@ objc_read_int (struct objc_typed_stream *stream, int *value)
   return len;
 }
 
-__inline__ int
+inline int
 objc_read_long (struct objc_typed_stream *stream, long *value)
 {
   unsigned char buf[sizeof (long) + 1];
@@ -659,7 +659,7 @@ objc_read_long (struct objc_typed_stream *stream, long *value)
   return len;
 }
 
-__inline__ int
+inline int
 __objc_read_nbyte_uint (struct objc_typed_stream *stream,
 			unsigned int nbytes, unsigned int *val)
 {
@@ -678,7 +678,7 @@ __objc_read_nbyte_uint (struct objc_typed_stream *stream,
 }
   
 
-__inline__ int
+inline int
 objc_read_unsigned_int (struct objc_typed_stream *stream,
 			unsigned int *value)
 {
@@ -715,7 +715,7 @@ __objc_read_nbyte_ulong (struct objc_typed_stream *stream,
 }
   
 
-__inline__ int
+inline int
 objc_read_unsigned_long (struct objc_typed_stream *stream,
 			 unsigned long *value)
 {
@@ -733,7 +733,7 @@ objc_read_unsigned_long (struct objc_typed_stream *stream,
   return len;
 }
 
-__inline__ int
+inline int
 objc_read_string (struct objc_typed_stream *stream,
 		  char **string)
 {
diff --git a/libobjc/encoding.c b/libobjc/encoding.c
index 17bc8d4e2e14..4d45b4423dfa 100644
--- a/libobjc/encoding.c
+++ b/libobjc/encoding.c
@@ -1,5 +1,5 @@
 /* Encoding of types for Objective C.
-   Copyright (C) 1993, 1995, 1996, 1997, 1998, 2000, 2002
+   Copyright (C) 1993, 1995, 1996, 1997, 1998, 2000, 2002, 2004
    Free Software Foundation, Inc.
    Contributed by Kresten Krab Thorup
    Bitfield support by Ovidiu Predescu
@@ -84,8 +84,6 @@ Boston, MA 02111-1307, USA.  */
 
 /* Some ROUND_TYPE_ALIGN macros use TARGET_foo, and consequently
    target_flags.  Define a dummy entry here to so we don't die.  */
-/* ??? FIXME: As of 2002-06-21, the attribute `unused' doesn't seem to
-   eliminate the warning.  */
 static int __attribute__ ((__unused__)) target_flags = 0;
 
 
diff --git a/libobjc/hash.c b/libobjc/hash.c
index ac0da21fdee0..cbea81ad4248 100644
--- a/libobjc/hash.c
+++ b/libobjc/hash.c
@@ -1,5 +1,5 @@
 /* Hash tables for Objective C internal structures
-   Copyright (C) 1993, 1996, 1997 Free Software Foundation, Inc.
+   Copyright (C) 1993, 1996, 1997, 2004 Free Software Foundation, Inc.
 
 This file is part of GCC.
 
@@ -154,7 +154,7 @@ hash_add (cache_ptr *cachep, const void *key, void *value)
 			      (*cachep)->compare_func);
 
     DEBUG_PRINTF ("Expanding cache %#x from %d to %d\n",
-		  *cachep, (*cachep)->size, new->size);
+		  (int) *cachep, (*cachep)->size, new->size);
 
     /* Copy the nodes from the first hash table to the new one.  */
     while ((node1 = hash_next (*cachep, node1)))
diff --git a/libobjc/objc/objc-api.h b/libobjc/objc/objc-api.h
index dc8af068f0e7..52ad50a1213a 100644
--- a/libobjc/objc/objc-api.h
+++ b/libobjc/objc/objc-api.h
@@ -1,5 +1,5 @@
 /* GNU Objective-C Runtime API.
-   Copyright (C) 1993, 1995, 1996, 1997, 2002 Free Software Foundation, Inc.
+   Copyright (C) 1993, 1995, 1996, 1997, 2002, 2004 Free Software Foundation, Inc.
 
 This file is part of GCC.
 
@@ -30,6 +30,7 @@ Boston, MA 02111-1307, USA.  */
 #include "objc/objc.h"
 #include "objc/hash.h"
 #include "objc/thr.h"
+#include "objc/objc-decls.h"
 #include <stdio.h>
 #include <stdarg.h>
 
@@ -100,7 +101,7 @@ struct objc_method_description
 extern void objc_error(id object, int code, const char* fmt, ...);
 extern void objc_verror(id object, int code, const char* fmt, va_list ap);
 typedef BOOL (*objc_error_handler)(id, int code, const char *fmt, va_list ap);
-objc_error_handler objc_set_error_handler(objc_error_handler func);
+extern objc_error_handler objc_set_error_handler(objc_error_handler func);
 
 /*
 ** Error codes
@@ -361,7 +362,7 @@ retval_t objc_msg_sendv(id, SEL, arglist_t);
 ** This may e.g. try to load in the class using dynamic loading.
 ** The function is guaranteed to be passed a non-NULL name string.
 */
-extern Class (*_objc_lookup_class)(const char *name);
+objc_EXPORT Class (*_objc_lookup_class)(const char *name);
 
 /*
 ** This is a hook which is called by __objc_exec_class every time a class
@@ -369,14 +370,14 @@ extern Class (*_objc_lookup_class)(const char *name);
 ** dynamic loader determine the classes that have been loaded when
 ** an object file is dynamically linked in.
 */
-extern void (*_objc_load_callback)(Class class, Category* category);
+objc_EXPORT void (*_objc_load_callback)(Class class, Category* category);
 
 /*
 ** Hook functions for allocating, copying and disposing of instances
 */
-extern id (*_objc_object_alloc)(Class class);
-extern id (*_objc_object_copy)(id object);
-extern id (*_objc_object_dispose)(id object);
+objc_EXPORT id (*_objc_object_alloc)(Class class);
+objc_EXPORT id (*_objc_object_copy)(id object);
+objc_EXPORT id (*_objc_object_dispose)(id object);
 
 /*
 ** Standard functions for memory allocation and disposal.
@@ -412,19 +413,19 @@ objc_free(void *mem);
 ** Users should call the normal objc routines above for
 ** memory allocation and disposal within their programs.
 */
-extern void *(*_objc_malloc)(size_t);
-extern void *(*_objc_atomic_malloc)(size_t);
-extern void *(*_objc_valloc)(size_t);
-extern void *(*_objc_realloc)(void *, size_t);
-extern void *(*_objc_calloc)(size_t, size_t);
-extern void (*_objc_free)(void *);
+objc_EXPORT void *(*_objc_malloc)(size_t);
+objc_EXPORT void *(*_objc_atomic_malloc)(size_t);
+objc_EXPORT void *(*_objc_valloc)(size_t);
+objc_EXPORT void *(*_objc_realloc)(void *, size_t);
+objc_EXPORT void *(*_objc_calloc)(size_t, size_t);
+objc_EXPORT void (*_objc_free)(void *);
 
 /*
 **  Hook for method forwarding. This makes it easy to substitute a
 **  library, such as ffcall, that implements closures, thereby avoiding
 **  gcc's __builtin_apply problems.
 */
-extern IMP (*__objc_msg_forward)(SEL);
+objc_EXPORT IMP (*__objc_msg_forward)(SEL);
 
 Method_t class_get_class_method(MetaClass class, SEL aSel);
 
diff --git a/libobjc/objc/objc-decls.h b/libobjc/objc/objc-decls.h
new file mode 100644
index 000000000000..6d64c3bb52b1
--- /dev/null
+++ b/libobjc/objc/objc-decls.h
@@ -0,0 +1,47 @@
+/* GNU Objective-C Extern helpers for Win32.
+   Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option) any
+later version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING.  If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.  */
+
+/* As a special exception, if you link this library with files compiled
+   with GCC to produce an executable, this does not cause the resulting
+   executable to be covered by the GNU General Public License.  This
+   exception does not however invalidate any other reasons why the
+   executable file might be covered by the GNU General Public License. */
+
+#ifndef __objc_decls_INCLUDE_GNU
+#define __objc_decls_INCLUDE_GNU
+
+#if defined (_WIN32) || defined (__WIN32__) || defined (WIN32)
+
+#    ifdef DLL_EXPORT /* defined by libtool (if required) */
+#  define objc_EXPORT  __declspec(dllexport)
+#  define objc_DECLARE __declspec(dllexport)
+#else
+#  define objc_EXPORT  extern __declspec(dllimport)
+#  define objc_DECLARE extern __declspec(dllimport)
+#endif
+
+#else
+
+#  define objc_EXPORT  extern
+#  define objc_DECLARE 
+
+#endif
+
+#endif /* __objc_decls_INCLUDE_GNU */
diff --git a/libobjc/objc/runtime.h b/libobjc/objc/runtime.h
index 72e79be30a7f..17a3e5e9e768 100644
--- a/libobjc/objc/runtime.h
+++ b/libobjc/objc/runtime.h
@@ -1,5 +1,5 @@
 /* GNU Objective C Runtime internal declarations
-   Copyright (C) 1993, 1995, 1996, 1997, 2002 Free Software Foundation, Inc.
+   Copyright (C) 1993, 1995, 1996, 1997, 2002, 2004 Free Software Foundation, Inc.
    Contributed by Kresten Krab Thorup
 
 This file is part of GCC.
@@ -49,6 +49,7 @@ extern void __objc_init_dispatch_tables(void); /* (objc-dispatch.c) */
 extern void __objc_install_premature_dtable(Class); /* (objc-dispatch.c) */
 extern void __objc_resolve_class_links(void);  /* (objc-class.c) */
 extern void __objc_register_selectors_from_class(Class); /* (objc-sel.c) */
+extern void __objc_register_selectors_from_list (MethodList_t); /* (selector.c) */
 extern void __objc_update_dispatch_table_for_class (Class);/* (objc-msg.c) */
 
 extern int  __objc_init_thread_system(void);    /* thread.c */
diff --git a/libobjc/sarray.c b/libobjc/sarray.c
index c37633ba33e7..e7e69a9e8ce4 100644
--- a/libobjc/sarray.c
+++ b/libobjc/sarray.c
@@ -1,5 +1,5 @@
 /* Sparse Arrays for Objective C dispatch tables
-   Copyright (C) 1993, 1995, 1996, 2002 Free Software Foundation, Inc.
+   Copyright (C) 1993, 1995, 1996, 2002, 2004 Free Software Foundation, Inc.
 
 This file is part of GCC.
 
@@ -459,7 +459,9 @@ sarray_free (struct sarray *array) {
 
 #endif
   
-  /* If this is a copy, go ahead and decrement/deallocate the original */
+  /* If this is a copy of another array, we free it (which might just
+   * decrement its reference count so it will be freed when no longer in use).
+   */
   if (array->is_copy_of)
     sarray_free (array->is_copy_of);
 
diff --git a/libobjc/selector.c b/libobjc/selector.c
index 06743b03ff4e..5ff0d8c71e24 100644
--- a/libobjc/selector.c
+++ b/libobjc/selector.c
@@ -1,5 +1,5 @@
 /* GNU Objective C Runtime selector related functions
-   Copyright (C) 1993, 1995, 1996, 1997, 2002 Free Software Foundation, Inc.
+   Copyright (C) 1993, 1995, 1996, 1997, 2002, 2004 Free Software Foundation, Inc.
    Contributed by Kresten Krab Thorup
 
 This file is part of GCC.
@@ -35,8 +35,6 @@ static struct sarray *__objc_selector_array = 0; /* uid -> sel  !T:MUTEX */
 static struct sarray *__objc_selector_names = 0; /* uid -> name !T:MUTEX */
 static cache_ptr      __objc_selector_hash  = 0; /* name -> uid !T:MUTEX */
 
-static void register_selectors_from_list (MethodList_t);
-
 /* Number of selectors stored in each of the above tables */
 unsigned int __objc_selector_max_index = 0;     /* !T:MUTEX */
 
@@ -60,7 +58,7 @@ __objc_register_selectors_from_class (Class class)
   method_list = class->methods;
   while (method_list)
     {
-      register_selectors_from_list (method_list);
+      __objc_register_selectors_from_list (method_list);
       method_list = method_list->method_next;
     }
 }
@@ -70,21 +68,27 @@ __objc_register_selectors_from_class (Class class)
    the record table.  This is the routine that does the actual recording
    work.
 
-   This one is only called for Class objects.  For categories,
-   class_add_method_list is called.
+   The name and type pointers in the method list must be permanent and
+   immutable.
    */
-static void
-register_selectors_from_list (MethodList_t method_list)
+void
+__objc_register_selectors_from_list (MethodList_t method_list)
 {
   int i = 0;
+
+  objc_mutex_lock (__objc_runtime_mutex);
   while (i < method_list->method_count)
     {
       Method_t method = &method_list->method_list[i];
-      method->method_name 
-	= sel_register_typed_name ((const char *) method->method_name, 
-				   method->method_types);
+      if (method->method_name)
+	{
+	  method->method_name
+	    = __sel_register_typed_name ((const char *) method->method_name,
+					 method->method_types, 0, YES);
+	}
       i += 1;
     }
+  objc_mutex_unlock (__objc_runtime_mutex);
 }
 
 
@@ -320,6 +324,35 @@ const char *sel_get_type (SEL selector)
 /* The uninstalled dispatch table */
 extern struct sarray *__objc_uninstalled_dtable;
 
+/* __sel_register_typed_name allocates lots of struct objc_selector:s
+   of 8 (16, if pointers are 64 bits) bytes at startup. To reduce the number
+   of malloc calls and memory lost to malloc overhead, we allocate
+   objc_selector:s in blocks here. This is only called from
+   __sel_register_typed_name, and __sel_register_typed_name may only be
+   called when __objc_runtime_mutex is locked.
+
+   Note that the objc_selector:s allocated from __sel_register_typed_name
+   are never freed.
+
+   62 because 62 * sizeof (struct objc_selector) = 496 (992). This should
+   let malloc add some overhead and use a nice, round 512 (1024) byte chunk.
+   */
+#define SELECTOR_POOL_SIZE 62
+static struct objc_selector *selector_pool;
+static int selector_pool_left;
+
+static struct objc_selector *
+pool_alloc_selector(void)
+{
+  if (!selector_pool_left)
+    {
+      selector_pool = objc_malloc (sizeof (struct objc_selector)
+				   * SELECTOR_POOL_SIZE);
+      selector_pool_left = SELECTOR_POOL_SIZE;
+    }
+  return &selector_pool[--selector_pool_left];
+}
+
 /* Store the passed selector name in the selector record and return its
    selector value (value returned by sel_get_uid).
    Assumes that the calling function has locked down __objc_runtime_mutex. */
@@ -369,7 +402,7 @@ __sel_register_typed_name (const char *name, const char *types,
       if (orig)
 	j = orig;
       else
-	j = objc_malloc (sizeof (struct objc_selector));
+	j = pool_alloc_selector ();
 
       j->sel_id = (void *) i;
       /* Can we use the pointer or must copy types?  Don't copy if NULL */
@@ -388,7 +421,7 @@ __sel_register_typed_name (const char *name, const char *types,
       if (orig)
 	j = orig;
       else
-	j = objc_malloc (sizeof (struct objc_selector));
+	j = pool_alloc_selector ();
 	
       j->sel_id = (void *) i;
       /* Can we use the pointer or must copy types?  Don't copy if NULL */
@@ -402,7 +435,7 @@ __sel_register_typed_name (const char *name, const char *types,
     }
 
   DEBUG_PRINTF ("Record selector %s[%s] as: %ld\n", name, types, 
-		soffset_decode (i));
+		(long) soffset_decode (i));
   
   {
     int is_new = (l == 0);
@@ -446,7 +479,7 @@ SEL
 sel_register_typed_name (const char *name, const char *type)
 {
   SEL ret;
-    
+
   objc_mutex_lock (__objc_runtime_mutex);
   /* Assume that name and type are not constant static memory and need to
      be copied before put into a runtime structure.  is_const == NO */
diff --git a/libobjc/sendmsg.c b/libobjc/sendmsg.c
index 0214e77afcd8..f0b5bbb35c23 100644
--- a/libobjc/sendmsg.c
+++ b/libobjc/sendmsg.c
@@ -1,6 +1,6 @@
 /* GNU Objective C Runtime message lookup 
    Copyright (C) 1993, 1995, 1996, 1997, 1998,
-   2001, 2002 Free Software Foundation, Inc.
+   2001, 2002, 2004 Free Software Foundation, Inc.
    Contributed by Kresten Krab Thorup
 
 This file is part of GCC.
@@ -26,6 +26,8 @@ Boston, MA 02111-1307, USA.  */
    covered by the GNU General Public License.  */
 
 /* FIXME: This file has no business including tm.h.  */
+/* FIXME: This should be using libffi instead of __builtin_apply
+   and friends.  */
 
 #include "tconfig.h"
 #include "coretypes.h"
@@ -35,7 +37,7 @@ Boston, MA 02111-1307, USA.  */
 #include "encoding.h"
 #include "runtime-info.h"
 
-/* this is how we hack STRUCT_VALUE to be 1 or 0 */
+/* This is how we hack STRUCT_VALUE to be 1 or 0.   */
 #define gen_rtx(args...) 1
 #define gen_rtx_MEM(args...) 1
 #define gen_rtx_REG(args...) 1
@@ -83,7 +85,7 @@ Method_t search_for_method_in_list (MethodList_t list, SEL op);
 id nil_method (id, SEL);
 
 /* Given a selector, return the proper forwarding implementation. */
-__inline__
+inline
 IMP
 __objc_get_forward_imp (SEL sel)
 {
@@ -115,7 +117,7 @@ __objc_get_forward_imp (SEL sel)
 }
 
 /* Given a class and selector, return the selector's implementation.  */
-__inline__
+inline
 IMP
 get_imp (Class class, SEL sel)
 {
@@ -176,7 +178,7 @@ get_imp (Class class, SEL sel)
 /* Query if an object can respond to a selector, returns YES if the
 object implements the selector otherwise NO.  Does not check if the
 method can be forwarded. */
-__inline__
+inline
 BOOL
 __objc_responds_to (id object, SEL sel)
 {
@@ -201,7 +203,7 @@ __objc_responds_to (id object, SEL sel)
 /* This is the lookup function.  All entries in the table are either a 
    valid method *or* zero.  If zero then either the dispatch table
    needs to be installed or it doesn't exist and forwarding is attempted. */
-__inline__
+inline
 IMP
 objc_msg_lookup (id receiver, SEL op)
 {
@@ -463,28 +465,14 @@ __objc_update_dispatch_table_for_class (Class class)
 
    This one is only called for categories. Class objects have their
    methods installed right away, and their selectors are made into
-   SEL's by the function __objc_register_selectors_from_class. */ 
+   SEL's by the function __objc_register_selectors_from_class. */
 void
 class_add_method_list (Class class, MethodList_t list)
 {
-  int i;
-
   /* Passing of a linked list is not allowed.  Do multiple calls.  */
   assert (! list->method_next);
 
-  /* Check for duplicates.  */
-  for (i = 0; i < list->method_count; ++i)
-    {
-      Method_t method = &list->method_list[i];
-
-      if (method->method_name)  /* Sometimes these are NULL */
-	{
-	  /* This is where selector names are transmogrified to SEL's */
-	  method->method_name = 
-	    sel_register_typed_name ((const char *) method->method_name,
-				     method->method_types);
-	}
-    }
+  __objc_register_selectors_from_list(list);
 
   /* Add the methods to the class's method list.  */
   list->method_next = class->methods;
@@ -705,7 +693,7 @@ __objc_print_dtable_stats ()
 /* Returns the uninstalled dispatch table indicator.
  If a class' dispatch table points to __objc_uninstalled_dtable
  then that means it needs its dispatch table to be installed. */
-__inline__
+inline
 struct sarray *
 objc_get_uninstalled_dtable ()
 {
-- 
GitLab