#! /bin/sh -e
# DP: libobjc update taken from the 3.4.1 release.
dir=
if [ $# -eq 3 -a "$2" = '-d' ]; then
pdir="-d $3"
dir="$3/"
elif [ $# -ne 1 ]; then
echo >&2 "`basename $0`: script expects -patch|-unpatch as argument"
exit 1
fi
case "$1" in
-patch)
patch $pdir -f --no-backup-if-mismatch -p1 < $0
;;
-unpatch)
patch $pdir -f --no-backup-if-mismatch -R -p1 < $0
;;
*)
echo >&2 "`basename $0`: script expects -patch|-unpatch as argument"
exit 1
esac
exit 0
libobjc:
2004-03-01 Michael Matz <matz@suse.de>
* Makefile.in (ALL_CFLAGS): Add -fno-strict-aliasing.
2004-01-14 Adam Fedor <fedor@gnu.org>
PR libobjc/12155
* selector.c (__objc_register_instance_methods_to_class): Free
new_list if not used.
2004-01-09 Andrew Ruder <aeruder@ksu.edu>
PR libobjc/11904
* sarray.c (sarray_free): Free array->is_copy_of latter.
2003-10-24 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
* Makefile.in (runtime-info.h): Remove -Wp.
2003-10-21 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
* Makefile.in (CC1OBJ): Remove.
(runtime-info.h): Invoke $(CC) so all MULTIFLAGS are handled
correctly.
Use .m extension for temporary file.
Remove assembler temp file.
2003-10-20 Joseph S. Myers <jsm@polyomino.org.uk>
* objc/hash.h (hash_string): Don't use a cast as an lvalue.
2003-10-17 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
* Makefile.in (runtime-info.h): Use MULTIFLAGS.
Thu Jul 10 10:27:43 2003 Nicola Pero <n.pero@mi.flashnet.it>
libobjc/9969
* sendmsg.c (get_imp): Fixed rare threading problem.
(__objc_responds_to): Similar fixes.
(objc_msg_lookup): Similar fixes.
(__objc_init_install_dtable): Lock the runtime before checking if the
table is installed.
Tue May 13 14:56:03 2003 Richard Frith-Macdonald <rfm@gnu.org>
Nicola Pero <n.pero@mi.flashnet.it>
libobjc/10742
* init.c (class_superclass_of_class): New function.
(create_tree_of_subclasses_inherited_from): Use it.
(__objc_tree_insert_class): Likewise.
(class_is_subclass_of_class): Likewise.
2003-04-11 David Chad <davidc@freebsd.org>
Loren J. Rittle <ljrittle@acm.org>
libobjc/8562
* objc/hash.h (hash_string): Constify correctly.
(compare_ptrs): Use direct compare.
* objc/objc-list.h (list_nth): Rename index to indx to avoid shadow.
* objc/sarray.h: Global rename index to indx to avoid shadow.
diff -ur --exclude=CVS gcc-3.3/libobjc/Makefile.in gcc-3.4/libobjc/Makefile.in
--- gcc-3.3/libobjc/Makefile.in 2003-01-26 12:29:56.000000000 +0100
+++ gcc-3.4/libobjc/Makefile.in 2004-03-02 00:28:01.000000000 +0100
@@ -70,7 +71,7 @@
WARN_CFLAGS = -W -Wall -Wwrite-strings -Wstrict-prototypes
GTHREAD_FLAGS=@GTHREAD_FLAGS@
ALL_CFLAGS = -I. -I$(srcdir) $(CPPFLAGS) $(DEFS) $(CFLAGS) $(WARN_CFLAGS) \
- $(GTHREAD_FLAGS) -DIN_GCC -DIN_TARGET_LIBS
+ $(GTHREAD_FLAGS) -DIN_GCC -DIN_TARGET_LIBS -fno-strict-aliasing
# Libtool
# The following strings describe the version of the obj-C library
@@ -87,14 +88,6 @@
LIBTOOL_CLEAN = $(LIBTOOL) --mode=clean
#LIBTOOL_UNINSTALL = $(LIBTOOL) --mode=uninstall
-#
-# Define the cc1obj in terms of the CC that is passed on from higher
-# level make. This is needed to make sure we can create runtime-info.h
-# when doing canadian cross builds where running ../../gcc/cc1obj
-# does not make any sense.
-#
-CC1OBJ = `$(CC) -print-prog-name=cc1obj`
-
INCLUDES = -I$(srcdir)/objc -I$(srcdir)/$(MULTISRCTOP)../gcc \
-I$(srcdir)/$(MULTISRCTOP)../gcc/config -I$(MULTIBUILDTOP)../../gcc \
-I$(srcdir)/$(MULTISRCTOP)../include
@@ -160,10 +153,10 @@
$(OBJC_THREAD_FILE)_gc.lo
runtime-info.h:
- echo "" > tmp-runtime
+ echo "" > tmp-runtime.m
echo "/* This file is automatically generated */" > $@
- $(CC1OBJ) -print-objc-runtime-info tmp-runtime >> $@
- rm -f tmp-runtime
+ $(CC) $(MULTIFLAGS) -print-objc-runtime-info -S tmp-runtime.m >> $@
+ rm -f tmp-runtime.m tmp-runtime.s
archive_gc.lo: archive.c
$(LIBTOOL_COMPILE) $(CC) -c -o $@ $(ALL_CFLAGS) $(OBJC_GCFLAGS) \
diff -ur --exclude=CVS gcc-3.3/libobjc/init.c gcc-3.4/libobjc/init.c
--- gcc-3.3/libobjc/init.c 2002-07-02 21:42:27.000000000 +0200
+++ gcc-3.4/libobjc/init.c 2003-05-24 09:47:56.000000000 +0200
@@ -99,6 +99,50 @@
should not be destroyed during the execution of the program. */
static cache_ptr __objc_load_methods = NULL;
+/* This function is used when building the class tree used to send
+ ordinately the +load message to all classes needing it. The tree
+ is really needed so that superclasses will get the message before
+ subclasses.
+
+ This tree will contain classes which are being loaded (or have just
+ being loaded), and whose super_class pointers have not yet been
+ resolved. This implies that their super_class pointers point to a
+ string with the name of the superclass; when the first message is
+ sent to the class (/an object of that class) the class links will
+ be resolved, which will replace the super_class pointers with
+ pointers to the actual superclasses.
+
+ Unfortunately, the tree might also contain classes which had been
+ loaded previously, and whose class links have already been
+ resolved.
+
+ This function returns the superclass of a class in both cases, and
+ can be used to build the determine the class relationships while
+ building the tree.
+*/
+static Class class_superclass_of_class (Class class)
+{
+ char *super_class_name;
+
+ /* If the class links have been resolved, use the resolved
+ * links. */
+ if (CLS_ISRESOLV (class))
+ return class->super_class;
+
+ /* Else, 'class' has not yet been resolved. This means that its
+ * super_class pointer is really the name of the super class (rather
+ * than a pointer to the actual superclass). */
+ super_class_name = (char *)class->super_class;
+
+ /* Return Nil for a root class. */
+ if (super_class_name == NULL)
+ return Nil;
+
+ /* Lookup the superclass of non-root classes. */
+ return objc_lookup_class (super_class_name);
+}
+
+
/* Creates a tree of classes whose topmost class is directly inherited
from `upper' and the bottom class in this tree is
`bottom_class'. The classes in this tree are super classes of
@@ -127,9 +171,7 @@
tree = objc_calloc (1, sizeof (objc_class_tree));
tree->class = superclass;
tree->subclasses = list_cons (prev, tree->subclasses);
- superclass = (superclass->super_class ?
- objc_lookup_class ((char *) superclass->super_class)
- : Nil);
+ superclass = class_superclass_of_class (superclass);
prev = tree;
}
@@ -157,10 +199,7 @@
DEBUG_PRINTF ("1. class %s was previously inserted\n", class->name);
return tree;
}
- else if ((class->super_class ?
- objc_lookup_class ((char *) class->super_class)
- : Nil)
- == tree->class)
+ else if (class_superclass_of_class (class) == tree->class)
{
/* If class is a direct subclass of tree->class then add class to the
list of subclasses. First check to see if it wasn't already
@@ -370,9 +409,7 @@
{
if (class == superclass)
return YES;
- class = (class->super_class ?
- objc_lookup_class ((char *) class->super_class)
- : Nil);
+ class = class_superclass_of_class (class);
}
return NO;
diff -ur --exclude=CVS gcc-3.3/libobjc/objc/hash.h gcc-3.4/libobjc/objc/hash.h
--- gcc-3.3/libobjc/objc/hash.h 2004-03-02 03:18:17.000000000 +0100
+++ gcc-3.4/libobjc/objc/hash.h 2003-10-20 23:53:26.000000000 +0200
@@ -187,7 +187,7 @@
static inline int
compare_ptrs (const void *k1, const void *k2)
{
- return ! (k1 - k2);
+ return (k1 == k2);
}
diff -ur --exclude=CVS gcc-3.3/libobjc/objc/objc-list.h gcc-3.4/libobjc/objc/objc-list.h
--- gcc-3.3/libobjc/objc/objc-list.h 2000-03-29 22:19:06.000000000 +0200
+++ gcc-3.4/libobjc/objc/objc-list.h 2003-05-24 09:47:56.000000000 +0200
@@ -64,9 +64,9 @@
larger than the list length, NULL is returned */
static inline void*
-list_nth(int index, struct objc_list* list)
+list_nth(int indx, struct objc_list* list)
{
- while(index-- != 0)
+ while(indx-- != 0)
{
if(list->tail)
list = list->tail;
diff -ur --exclude=CVS gcc-3.3/libobjc/objc/sarray.h gcc-3.4/libobjc/objc/sarray.h
--- gcc-3.3/libobjc/objc/sarray.h 1998-10-07 04:21:54.000000000 +0200
+++ gcc-3.4/libobjc/objc/sarray.h 2003-05-24 09:47:56.000000000 +0200
@@ -146,8 +146,8 @@
void sarray_free(struct sarray*);
struct sarray* sarray_lazy_copy(struct sarray*);
void sarray_realloc(struct sarray*, int new_size);
-void sarray_at_put(struct sarray*, sidx index, void* elem);
-void sarray_at_put_safe(struct sarray*, sidx index, void* elem);
+void sarray_at_put(struct sarray*, sidx indx, void* elem);
+void sarray_at_put_safe(struct sarray*, sidx indx, void* elem);
struct sarray* sarray_hard_copy(struct sarray*); /* ... like the name? */
void sarray_remove_garbage(void);
@@ -156,10 +156,10 @@
#ifdef PRECOMPUTE_SELECTORS
/* Transform soffset values to ints and vica verca */
static inline unsigned int
-soffset_decode(sidx index)
+soffset_decode(sidx indx)
{
union sofftype x;
- x.idx = index;
+ x.idx = indx;
#ifdef OBJC_SPARSE3
return x.off.eoffset
+ (x.off.boffset*BUCKET_SIZE)
@@ -186,9 +186,9 @@
#else /* not PRECOMPUTE_SELECTORS */
static inline size_t
-soffset_decode(sidx index)
+soffset_decode(sidx indx)
{
- return index;
+ return indx;
}
static inline sidx
@@ -198,13 +198,13 @@
}
#endif /* not PRECOMPUTE_SELECTORS */
-/* Get element from the Sparse array `array' at offset `index' */
+/* Get element from the Sparse array `array' at offset `indx' */
-static inline void* sarray_get(struct sarray* array, sidx index)
+static inline void* sarray_get(struct sarray* array, sidx indx)
{
#ifdef PRECOMPUTE_SELECTORS
union sofftype x;
- x.idx = index;
+ x.idx = indx;
#ifdef OBJC_SPARSE3
return
array->
@@ -217,19 +217,19 @@
#else /* not PRECOMPUTE_SELECTORS */
#ifdef OBJC_SPARSE3
return array->
- indices[index/INDEX_CAPACITY]->
- buckets[(index/BUCKET_SIZE)%INDEX_SIZE]->
- elems[index%BUCKET_SIZE];
+ indices[indx/INDEX_CAPACITY]->
+ buckets[(indx/BUCKET_SIZE)%INDEX_SIZE]->
+ elems[indx%BUCKET_SIZE];
#else /* OBJC_SPARSE2 */
- return array->buckets[index/BUCKET_SIZE]->elems[index%BUCKET_SIZE];
+ return array->buckets[indx/BUCKET_SIZE]->elems[indx%BUCKET_SIZE];
#endif /* not OBJC_SPARSE3 */
#endif /* not PRECOMPUTE_SELECTORS */
}
-static inline void* sarray_get_safe(struct sarray* array, sidx index)
+static inline void* sarray_get_safe(struct sarray* array, sidx indx)
{
- if(soffset_decode(index) < array->capacity)
- return sarray_get(array, index);
+ if(soffset_decode(indx) < array->capacity)
+ return sarray_get(array, indx);
else
return (array->empty_bucket->elems[0]);
}
diff -ur --exclude=CVS gcc-3.3/libobjc/sarray.c gcc-3.4/libobjc/sarray.c
--- gcc-3.3/libobjc/sarray.c 2002-07-02 21:42:44.000000000 +0200
+++ gcc-3.4/libobjc/sarray.c 2004-01-10 09:09:36.000000000 +0100
@@ -402,9 +402,6 @@
#else
old_buckets = array->buckets;
#endif
-
- if ((array->is_copy_of) && ((array->is_copy_of->ref_count - 1) == 0))
- sarray_free (array->is_copy_of);
/* Free all entries that do not point to empty_bucket */
for (counter = 0; counter <= old_max_index; counter++ ) {
@@ -462,6 +459,10 @@
#endif
+ /* If this is a copy, go ahead and decrement/deallocate the original */
+ if (array->is_copy_of)
+ sarray_free (array->is_copy_of);
+
/* free array */
sarray_free_garbage (array);
}
diff -ur --exclude=CVS gcc-3.3/libobjc/selector.c gcc-3.4/libobjc/selector.c
--- gcc-3.3/libobjc/selector.c 2002-07-02 21:42:44.000000000 +0200
+++ gcc-3.4/libobjc/selector.c 2004-01-15 17:22:01.000000000 +0100
@@ -148,6 +148,8 @@
new_list->method_next = class->class_pointer->methods;
class->class_pointer->methods = new_list;
}
+ else
+ objc_free(new_list);
__objc_update_dispatch_table_for_class (class->class_pointer);
}
diff -ur --exclude=CVS gcc-3.3/libobjc/sendmsg.c gcc-3.4/libobjc/sendmsg.c
--- gcc-3.3/libobjc/sendmsg.c 2002-09-12 19:29:58.000000000 +0200
+++ gcc-3.4/libobjc/sendmsg.c 2003-07-10 20:24:56.000000000 +0200
@@ -115,6 +119,14 @@
IMP
get_imp (Class class, SEL sel)
{
+ /* In a vanilla implementation we would first check if the dispatch
+ table is installed. Here instead, to get more speed in the
+ standard case (that the dispatch table is installed) we first try
+ to get the imp using brute force. Only if that fails, we do what
+ we should have been doing from the very beginning, that is, check
+ if the dispatch table needs to be installed, install it if it's
+ not installed, and retrieve the imp from the table if it's
+ installed. */
void *res = sarray_get_safe (class->dtable, (size_t) sel->sel_id);
if (res == 0)
{
@@ -123,7 +135,16 @@
{
/* The dispatch table needs to be installed. */
objc_mutex_lock (__objc_runtime_mutex);
- __objc_install_dispatch_table_for_class (class);
+
+ /* Double-checked locking pattern: Check
+ __objc_uninstalled_dtable again in case another thread
+ installed the dtable while we were waiting for the lock
+ to be released. */
+ if (class->dtable == __objc_uninstalled_dtable)
+ {
+ __objc_install_dispatch_table_for_class (class);
+ }
+
objc_mutex_unlock (__objc_runtime_mutex);
/* Call ourselves with the installed dispatch table
and get the real method */
@@ -131,10 +152,22 @@
}
else
{
- /* The dispatch table has been installed so the
- method just doesn't exist for the class.
- Return the forwarding implementation. */
- res = __objc_get_forward_imp (sel);
+ /* The dispatch table has been installed. */
+
+ /* Get the method from the dispatch table (we try to get it
+ again in case another thread has installed the dtable just
+ after we invoked sarray_get_safe, but before we checked
+ class->dtable == __objc_uninstalled_dtable).
+ */
+ res = sarray_get_safe (class->dtable, (size_t) sel->sel_id);
+ if (res == 0)
+ {
+ /* The dispatch table has been installed, and the method
+ is not in the dispatch table. So the method just
+ doesn't exist for the class. Return the forwarding
+ implementation. */
+ res = __objc_get_forward_imp (sel);
+ }
}
}
return res;
@@ -153,7 +186,10 @@
if (object->class_pointer->dtable == __objc_uninstalled_dtable)
{
objc_mutex_lock (__objc_runtime_mutex);
- __objc_install_dispatch_table_for_class (object->class_pointer);
+ if (object->class_pointer->dtable == __objc_uninstalled_dtable)
+ {
+ __objc_install_dispatch_table_for_class (object->class_pointer);
+ }
objc_mutex_unlock (__objc_runtime_mutex);
}
@@ -188,10 +224,19 @@
}
else
{
- /* The dispatch table has been installed so the
- method just doesn't exist for the class.
- Attempt to forward the method. */
- result = __objc_get_forward_imp (op);
+ /* The dispatch table has been installed. Check again
+ if the method exists (just in case the dispatch table
+ has been installed by another thread after we did the
+ previous check that the method exists).
+ */
+ result = sarray_get_safe (receiver->class_pointer->dtable,
+ (sidx)op->sel_id);
+ if (result == 0)
+ {
+ /* If the method still just doesn't exist for the
+ class, attempt to forward the method. */
+ result = __objc_get_forward_imp (op);
+ }
}
}
return result;
@@ -235,13 +280,16 @@
static void
__objc_init_install_dtable (id receiver, SEL op __attribute__ ((__unused__)))
{
+ objc_mutex_lock (__objc_runtime_mutex);
+
/* This may happen, if the programmer has taken the address of a
method before the dtable was initialized... too bad for him! */
if (receiver->class_pointer->dtable != __objc_uninstalled_dtable)
- return;
-
- objc_mutex_lock (__objc_runtime_mutex);
-
+ {
+ objc_mutex_unlock (__objc_runtime_mutex);
+ return;
+ }
+
if (CLS_ISCLASS (receiver->class_pointer))
{
/* receiver is an ordinary object */