Gcc 3.1.0 pre-release's Objective C support bits from the FSF anoncvs repo

on 9-May-2002 15:57:15 EDT.
This commit is contained in:
David E. O'Brien 2002-05-09 22:50:04 +00:00
parent e3f07fb2c3
commit 641c89aab9
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/vendor/gcc/dist/; revision=96297
22 changed files with 3834 additions and 580 deletions

View file

@ -1,38 +1,291 @@
Fri Mar 16 12:46:19 GMT 2001 Bernd Schmidt (bernds@redhat.com)
2002-05-08 Alexandre Oliva <aoliva@redhat.com>
* gcc-2.95.3 Released.
* configure.in (ORIGINAL_LD_FOR_MULTILIBS): Preserve LD at
script entry, and set LD to it when configuring multilibs.
* configure: Rebuilt.
2001-01-11 Joseph S. Myers <jsm28@cam.ac.uk>
2002-04-19 David O'Brien <obrien@FreeBSD.org>
* encoding.c (MAX, MIN, ROUNDING): #undef before defining.
2002-04-09 Hans-Peter Nilsson <hp@bitrange.com>
PR objc/6107
* objc/objc-api.h (struct objc_protocol_list): Change type of
member count from int to size_t.
2002-02-11 Franz Sirl <Franz.Sirl-kernel@lauterbach.com>
PR libobjc/4039
* aclocal.m4: Replace with version copied from libstdc++-v3.
* configure.in: Update for changes to aclocal and Makefile.
* configure: Regenerate.
* Makefile.in: Correct install of multilibs and shared libs, use
INSTALL_DATA for include files.
Mon Dec 17 17:02:12 2001 Nicola Pero <nicola@brainstorm.co.uk>
* init.c (__objc_exec_class): Fixed bug in the loop on unclaimed
categories - when an unclaimed category was found, the loop was
doing two steps forward instead of one, so that in certain cases
it was failing to properly load all the categories. (Reported
with fix by Alexander Malmberg <alexander@malmberg.org>).
2001-11-14 Aldy Hernandez <aldyh@redhat.com>
* encoding.c: Add target_flags.
2001-11-07 Aldy Hernandez <aldyh@redhat.com>
* objc/objc-api.h (_C_VECTOR): New.
* encoding.c (VECTOR_TYPE): New.
Mon Oct 29 21:29:21 2001 Nicola Pero <n.pero@mi.flashnet.it>
* class.c: Rewritten the class table to use optimized, lock-free
lookup. This more than doubles the speed of class method
invocations. (class_table_setup), (class_table_insert),
(class_table_replace), (class_table_get_safe),
(class_table_next), (class_table_print),
(class_table_print_histogram): New functions.
(__objc_init_class_tables): Use class_table_setup.
(__objc_add_class_to_hash): Use class_table_get_safe and
class_table_insert. (objc_lookup_class), (objc_get_class): Do not
assert the existence of the table; do not lock the runtime; use
class_table_get_safe. (objc_next_class): Use class_table_next.
(__objc_resolve_class_links): Use class_table_next.
(class_pose_as): Use class_table_replace.
2001-09-10 Ovidiu Predescu <ovidiu@cup.hp.com>
* gc.c: Removed the DEBUG declaration.
Wed Jul 18 12:48:56 2001 Nicola Pero <n.pero@mi.flashnet.it>
* thr.c (objc_mutex_lock): Invoke __objc_thread_id directly,
rather than through objc_thread_id, to save a function call.
(objc_mutex_trylock, objc_mutex_unlock, objc_condition_wait):
Ditto.
Mon Jul 16 12:15:00 2001 Nicola Pero <n.pero@mi.flashnet.it>
* objc/objc-api.h (object_is_class): Fixed - buggy code was trying
to cast an id to a Class, which can not be done. Make the check
by using CLS_ISMETA on the class pointer instead.
(object_is_meta_class): Similar fix.
2001-06-09 Alexandre Oliva <aoliva@redhat.com>, Stephen L Moshier <moshier@mediaone.net>
* configure.in (AC_EXEEXT): Work around in case it expands to
nothing, as in autoconf 2.50.
* acinclude.m4: Likewise.
* configure: Rebuilt.
2001-06-08 Nicola Pero <n.pero@mi.flashnet.it>
* THREADS: Explain that when we compile libobjc inside GCC, we
always use thr-objc.c as a backend, which uses GCC's thread code.
2001-06-06 Richard Frith-Macdonald <rrfm@gnu.org>
* init.c (__objc_send_message_in_list): When setting a new entry
in __objc_load_methods use the method IMP as key, but check to see
if the method is in the hashtable by looking at the IMP also.
Also ... call the method after adding it to the hashtable rather
than before ... thus preventing an obscure possibility of infinite
recursion if a +load method itself loads a subclass.
2001-05-25 Ovidiu Predescu <ovidiu@cup.hp.com>
* init.c (__objc_send_message_in_list): When setting a new entry
in __objc_load_methods use the method name as key, not the method
IMP (reported by Richard Frith-Macdonald <richard@brainstorm.co.uk>).
2001-05-09 Joseph S. Myers <jsm28@cam.ac.uk>
* objc-features.texi: Move to ../gcc/objc.texi.
* fdl.texi: Remove.
* Makefile.in: Don't generate documentation from
objc-features.texi.
2001-05-01 Mark Mitchell <mark@codesourcery.com>
* fdl.texi: New file.
* objc-features.texi: Simplify.
* Makefile.in: Adjust accordingly.
2001-04-30 Mark Mitchell <mark@codesourcery.com>
* objc-features.texi: Use the GFDL.
Wed Mar 21 04:44:58 EST 2001 John Wehle (john@feith.com)
* encoding.c (REAL_TYPE): Define.
2001-03-19 David Edelsohn <edelsohn@gnu.org>
* encoding.c (TYPE_MODE): Define.
2001-03-14 Nicola Pero <n.pero@mi.flashnet.it>
* thr.c (objc_thread_add): New function.
(objc_thread_remove): Ditto.
* objc/thr.h: Declare them.
* libobjc.def: Mention them.
2001-02-28 Ovidiu Predescu <ovidiu@cup.hp.com>
* objc-features.texi: Document the @compatibility_alias compiler
directive (description from Nicola Pero <n.pero@mi.flashnet.it>).
Fri Feb 23 18:12:00 2001 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
* sendmsg.c (__objc_forward): Delete strlen() declaration.
2001-02-08 Geoffrey Keating <geoffk@redhat.com>
* configure.in: Don't run AC_PROG_CC_WORKS or AC_EXEEXT, because
we're not interested in the result and they might fail.
* configure: Regenerated.
2001-01-12 Joseph S. Myers <jsm28@cam.ac.uk>
* objc-features.texi: Use @email.
2001-01-12 Joseph S. Myers <jsm28@cam.ac.uk>
* sendmsg.c (__objc_print_dtable_stats): Don't use #ifdef inside
printf.
2000-01-11 Richard Earnshaw <rearnsha@arm.com>
* encoding.c (STRUCTURE_SIZE_BOUNDARY): Redefine in a way that
determines the value dynamically.
Wed Jan 3 00:49:10 2001 Ovidiu Predescu <ovidiu@cup.hp.com>
* sendmsg.c: Added __objc_msg_forward, a hook that allows external
libraries to provide a function that returns the real forwarding
function. This can alleviate problems __builtin_apply() and
friends have on various platforms. (Solution suggested by Helge
Hess.)
* objc/objc-api.h: Define __objc_msg_forward.
* sendmsg.c: Define gen_rtx_REG.
2000-12-06 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
* thr-rtems.c: New file. Stub to compile.
2000-09-06 Alexandre Oliva <aoliva@redhat.com>
* configure: Rebuilt with new libtool.m4.
Tue Aug 15 00:38:56 2000 Ovidiu Predescu <ovidiu@cup.hp.com>
* configure.in: Create a config.h file. Check for <sched.h>.
* configure: Regenerate.
* config.h.in: Check for <sched.h>.
2000-08-14 Zack Weinberg <zack@wolery.cumb.org>
* configure: Regenerate after change to ../libtool.m4.
2000-08-14 Andreas Schwab <schwab@suse.de>
* objc-features.texi (Top): Move @menu at end of node.
2000-08-11 Manfred Hollstein <manfredh@redhat.com>
* objc-features.texi: Move @node Top before @menu.
Sun Aug 6 23:27:49 2000 Ovidiu Predescu <ovidiu@cup.hp.com>
* objc-features.texi: Documented the new -fconstant-string-class
option.
Sun Aug 6 22:51:16 2000 Ovidiu Predescu <ovidiu@cup.hp.com>
* thr-posix.c: Integrated Chris Ball's <cball@fmco.com> changes to
improve the Posix thread support for Objective-C.
2000-08-04 Zack Weinberg <zack@wolery.cumb.org>
* aclocal.m4: Replace copy of ../libtool.m4 with
sinclude(../libtool.m4).
Fri Jul 28 08:58:02 2000 Nicola Pero <nicola@brainstorm.co.uk>
* configure.in: Added libtool support; build shared libraries
if --enable-shared was passed on command line.
* Makefile.in: Modified most compilation commands to use libtool.
* aclocal.m4: New symbolic link to the ../libtool.m4, from the
libtool distribution.
Sat Jul 29 00:10:21 2000 Ovidiu Predescu <ovidiu@cup.hp.com>
* sarray.c, Object.m: Removed the explicit prototypes for strlen
and memcpy on 64-bit platforms (Suggested by Rodney Brown
<rdb@cup.hp.com>).
2000-05-12 H.J. Lu (hjl@gnu.org)
* Makefile.in (GTHREAD_FLAGS): New.
(ALL_CFLAGS): Add $(GTHREAD_FLAGS).
(OBJC_THREAD_FILE): Changed to thr-objc.
* configure.in (GTHREAD_FLAGS): New, check and replace it for
Makefile.
(OBJC_THREAD_FILE): Removed.
* thr-objc.c: New.
2000-07-13 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
* objc/hash.h: Include string.h.
2000-04-15 David Edelsohn <edelsohn@gnu.org>
* Object.m (strlen): 64-bit PowerPC is a 64bit platform as well.
2000-04-12 Jakub Jelinek <jakub@redhat.com>
* Object.m (strlen): Provide prototype on all 64bit platforms,
not only alpha.
* sarray.c (memcpy): Likewise.
* encoding.c (objc_layout_finish_structure): Don't use
ROUND_TYPE_ALIGN on sparc.
* encoding.c (objc_layout_structure_next_member): Do the whole
procedure even for the first member, so that we get correct
alignment.
2000-03-29 Zack Weinberg <zack@wolery.cumb.org>
* objc/Protocol.h, objc/objc-list.h: Change #endif labels to
comments.
Sun Oct 24 23:54:10 PDT 1999 Jeff Law (law@cygnus.com)
2000-02-23 Zack Weinberg <zack@wolery.cumb.org>
* gcc-2.95.2 Released.
* Makefile.in: Add -DIN_TARGET_LIBS to ALL_CFLAGS.
Mon Aug 16 01:29:24 PDT 1999 Jeff Law (law@cygnus.com)
Thu Sep 23 07:19:12 1999 Chris Ball <cball@fmco.com>
* gcc-2.95.1 Released.
* thr-posix.c (__objc_mutex_deallocate): made deallocate work.
Tue Sep 21 07:47:10 1999 Jeffrey A Law (law@cygnus.com)
* Makefile.in (gc.o, gc_gc.o): Do not pass -fgnu-runtime to
the compiler when building C code.
Fri Aug 6 23:32:29 1999 Daniel Jacobowitz <drow@drow.them.org>
* Makefile.in (FLAGS_TO_PASS): Include prefix, exec_prefix,
libdir, libsubdir and tooldir.
Wed Jul 28 21:39:31 PDT 1999 Jeff Law (law@cygnus.com)
* gcc-2.95 Released.
Sun Jul 25 23:40:51 PDT 1999 Jeff Law (law@cygnus.com)
* gcc-2.95 Released.
Mon Jun 21 05:40:15 1999 John David Anglin <dave@hiauly1>
* init.c (__objc_force_linking): Make global.

View file

@ -1,5 +1,5 @@
#Makefile for GNU Objective C runtime library.
#Copyright (C) 1993, 95-97, 1998 Free Software Foundation, Inc.
#Copyright (C) 1993, 95-98, 1999, 2001 Free Software Foundation, Inc.
#This file is part of GNU CC.
@ -23,20 +23,27 @@
#worthless.
SHELL = /bin/sh
MAKEOVERRIDES=
#### Start of system configuration section. ####
srcdir = @srcdir@
VPATH = @srcdir@
srcdir = @glibcpp_srcdir@
VPATH = @glibcpp_srcdir@
prefix = @prefix@
exec_prefix = @exec_prefix@
target_alias = @target_alias@
gcc_version = @gcc_version@
gcc_version_trigger = @gcc_version_trigger@
top_srcdir = @top_srcdir@
toplevel_srcdir = @toplevel_srcdir@
toolexecdir = @glibcpp_toolexecdir@
glibcpp_toolexecdir = @glibcpp_toolexecdir@
glibcpp_toolexeclibdir = @glibcpp_toolexeclibdir@
top_builddir = .
libdir = $(exec_prefix)/lib
libsubdir = $(libdir)/gcc-lib/$(target_alias)/$(gcc_version)
incinstalldir = $(libsubdir)/include
# Multilib support variables.
MULTISRCTOP =
@ -60,7 +67,24 @@ RANLIB = @RANLIB@
CC = @CC@
CFLAGS = @CFLAGS@
ALL_CFLAGS = -I. -I$(srcdir) $(CPPFLAGS) $(DEFS) $(CFLAGS) -DIN_GCC
GTHREAD_FLAGS=@GTHREAD_FLAGS@
ALL_CFLAGS = -I. -I$(srcdir) $(CPPFLAGS) $(DEFS) $(CFLAGS) \
$(GTHREAD_FLAGS) -DIN_GCC -DIN_TARGET_LIBS
# Libtool
# The following strings describe the version of the obj-C library
# begin compiled and compatibility issues.
# Please refer to Libtool documentation about how to manage these
# numbers.
LIBOBJC_VERSION = 1:0:0
LIBOBJC_GC_VERSION = 1:0:0
# @LIBTOOL@ does not get it right, so we hack it in - FIXME
LIBTOOL = ./libtool
LIBTOOL_COMPILE = $(LIBTOOL) --mode=compile
LIBTOOL_LINK = $(LIBTOOL) --mode=link
LIBTOOL_INSTALL = $(LIBTOOL) --mode=install
LIBTOOL_CLEAN = $(LIBTOOL) --mode=clean
#LIBTOOL_UNINSTALL = $(LIBTOOL) --mode=uninstall
#
# Define the cc1obj in terms of the CC that is passed on from higher
@ -75,16 +99,17 @@ INCLUDES = -I$(srcdir)/objc -I$(srcdir)/$(MULTISRCTOP)../gcc \
-I$(srcdir)/$(MULTISRCTOP)../include
OBJC_GCFLAGS=-DOBJC_WITH_GC=1
OBJC_THREAD_FILE=thr-@OBJC_THREAD_FILE@
OBJC_THREAD_FILE=thr-objc
OBJC_BOEHM_GC=@OBJC_BOEHM_GC@
.SUFFIXES:
.SUFFIXES: .c .m .o
.SUFFIXES: .c .m .lo
.c.o:
$(CC) -c $(ALL_CFLAGS) $(INCLUDES) $<
.c.lo:
$(LIBTOOL_COMPILE) $(CC) -c $(ALL_CFLAGS) $(INCLUDES) $<
.m.o:
$(CC) -c $(ALL_CFLAGS) $(INCLUDES) $<
.m.lo:
$(LIBTOOL_COMPILE) $(CC) -c $(ALL_CFLAGS) $(INCLUDES) $<
# Flags to pass to a recursive make.
FLAGS_TO_PASS = \
@ -99,6 +124,7 @@ FLAGS_TO_PASS = \
"INSTALL_DATA=$(INSTALL_DATA)" \
"INSTALL_PROGRAM=$(INSTALL_PROGRAM)" \
"LDFLAGS=$(LDFLAGS)" \
"LIBTOOL=$(LIBTOOL)" \
"LOADLIBES=$(LOADLIBES)" \
"PICFLAG=$(PICFLAG)" \
"RANLIB=$(RANLIB)" \
@ -109,7 +135,7 @@ FLAGS_TO_PASS = \
"libsubdir=$(libsubdir)" \
"tooldir=$(tooldir)"
all: libobjc.a @OBJC_BOEHM_GC@
all: libobjc.la $(OBJC_BOEHM_GC)
$(MULTIDO) $(FLAGS_TO_PASS) multi-do DO=all
# User-visible header files.
@ -120,111 +146,136 @@ OBJC_H = hash.h objc-list.h sarray.h objc.h objc-api.h \
# Modules that comprise the runtime library.
OBJS = archive.o class.o encoding.o gc.o hash.o init.o linking.o \
misc.o nil_method.o NXConstStr.o Object.o objects.o \
Protocol.o sarray.o selector.o sendmsg.o thr.o \
$(OBJC_THREAD_FILE).o
OBJS = archive.lo class.lo encoding.lo gc.lo hash.lo init.lo linking.lo \
misc.lo nil_method.lo NXConstStr.lo Object.lo objects.lo \
Protocol.lo sarray.lo selector.lo sendmsg.lo thr.lo \
$(OBJC_THREAD_FILE).lo
OBJS_GC = archive_gc.o class_gc.o encoding_gc.o gc_gc.o hash_gc.o \
init_gc.o linking_gc.o misc_gc.o nil_method_gc.o \
NXConstStr_gc.o Object_gc.o objects_gc.o Protocol_gc.o \
sarray_gc.o selector_gc.o sendmsg_gc.o thr_gc.o \
$(OBJC_THREAD_FILE)_gc.o
OBJS_GC = archive_gc.lo class_gc.lo encoding_gc.lo gc_gc.lo hash_gc.lo \
init_gc.lo linking_gc.lo misc_gc.lo nil_method_gc.lo \
NXConstStr_gc.lo Object_gc.lo objects_gc.lo Protocol_gc.lo \
sarray_gc.lo selector_gc.lo sendmsg_gc.lo thr_gc.lo \
$(OBJC_THREAD_FILE)_gc.lo
runtime-info.h:
echo "" > tmp-runtime
echo "/* This file is automatically generated */" > $@
$(CC1OBJ) -print-objc-runtime-info tmp-runtime >> $@
rm -f tmp-runtime
echo "" > tmp-runtime
echo "/* This file is automatically generated */" > $@
$(CC1OBJ) -print-objc-runtime-info tmp-runtime >> $@
rm -f tmp-runtime
archive_gc.o: archive.c
$(CC) -c -o $@ $(ALL_CFLAGS) $(OBJC_GCFLAGS) $(INCLUDES) $<
archive_gc.lo: archive.c
$(LIBTOOL_COMPILE) $(CC) -c -o $@ $(ALL_CFLAGS) $(OBJC_GCFLAGS) \
$(INCLUDES) $<
class_gc.o: class.c
$(CC) -c -o $@ $(ALL_CFLAGS) $(OBJC_GCFLAGS) $(INCLUDES) $<
class_gc.lo: class.c
$(LIBTOOL_COMPILE) $(CC) -c -o $@ $(ALL_CFLAGS) $(OBJC_GCFLAGS) \
$(INCLUDES) $<
encoding_gc.o: encoding.c
$(CC) -c -o $@ $(ALL_CFLAGS) $(OBJC_GCFLAGS) $(INCLUDES) $<
encoding_gc.lo: encoding.c
$(LIBTOOL_COMPILE) $(CC) -c -o $@ $(ALL_CFLAGS) $(OBJC_GCFLAGS) \
$(INCLUDES) $<
gc.o: gc.c
$(CC) -fgnu-runtime -c -o $@ $(ALL_CFLAGS) $(INCLUDES) $<
gc.lo: gc.c
$(LIBTOOL_COMPILE) $(CC) -c -o $@ $(ALL_CFLAGS) $(INCLUDES) $<
gc_gc.o: gc.c
$(CC) -fgnu-runtime -c -o $@ $(ALL_CFLAGS) $(OBJC_GCFLAGS) \
$(INCLUDES) $<
gc_gc.lo: gc.c
$(LIBTOOL_COMPILE) $(CC) -c -o $@ $(ALL_CFLAGS) $(OBJC_GCFLAGS) \
$(INCLUDES) $<
hash_gc.o: hash.c
$(CC) -c -o $@ $(ALL_CFLAGS) $(OBJC_GCFLAGS) $(INCLUDES) $<
hash_gc.lo: hash.c
$(LIBTOOL_COMPILE) $(CC) -c -o $@ $(ALL_CFLAGS) $(OBJC_GCFLAGS) \
$(INCLUDES) $<
init_gc.o: init.c
$(CC) -c -o $@ $(ALL_CFLAGS) $(OBJC_GCFLAGS) $(INCLUDES) $<
init_gc.lo: init.c
$(LIBTOOL_COMPILE) $(CC) -c -o $@ $(ALL_CFLAGS) $(OBJC_GCFLAGS) \
$(INCLUDES) $<
linking.o: linking.m
$(CC) -fgnu-runtime -c -o $@ $(ALL_CFLAGS) $(INCLUDES) $<
linking.lo: linking.m
$(LIBTOOL_COMPILE) $(CC) -fgnu-runtime -c -o $@ $(ALL_CFLAGS) \
$(INCLUDES) $<
linking_gc.o: linking.m
$(CC) -fgnu-runtime -c -o $@ $(ALL_CFLAGS) $(OBJC_GCFLAGS) \
$(INCLUDES) $<
linking_gc.lo: linking.m
$(LIBTOOL_COMPILE) $(CC) -fgnu-runtime -c -o $@ $(ALL_CFLAGS) \
$(OBJC_GCFLAGS) $(INCLUDES) $<
misc_gc.o: misc.c
$(CC) -c -o $@ $(ALL_CFLAGS) $(OBJC_GCFLAGS) $(INCLUDES) $<
misc_gc.lo: misc.c
$(LIBTOOL_COMPILE) $(CC) -c $(ALL_CFLAGS) -o $@ $(OBJC_GCFLAGS) \
$(INCLUDES) $<
nil_method_gc.o: nil_method.c
$(CC) -c -o $@ $(ALL_CFLAGS) $(OBJC_GCFLAGS) $(INCLUDES) $<
nil_method_gc.lo: nil_method.c
$(LIBTOOL_COMPILE) $(CC) -c $(ALL_CFLAGS) -o $@ $(OBJC_GCFLAGS) \
$(INCLUDES) $<
NXConstStr.o: NXConstStr.m
$(CC) -fgnu-runtime -c -o $@ $(ALL_CFLAGS) $(INCLUDES) $<
NXConstStr.lo: NXConstStr.m
$(LIBTOOL_COMPILE) $(CC) -fgnu-runtime -c -o $@ $(ALL_CFLAGS) \
$(INCLUDES) $<
NXConstStr_gc.o: NXConstStr.m
$(CC) -fgnu-runtime -c -o $@ $(ALL_CFLAGS) $(OBJC_GCFLAGS) \
$(INCLUDES) $<
NXConstStr_gc.lo: NXConstStr.m
$(LIBTOOL_COMPILE) $(CC) -fgnu-runtime -c -o $@ $(ALL_CFLAGS) \
$(OBJC_GCFLAGS) $(INCLUDES) $<
Object.o: Object.m
$(CC) -fgnu-runtime -c -o $@ $(ALL_CFLAGS) $(INCLUDES) $<
Object.lo: Object.m
$(LIBTOOL_COMPILE) $(CC) -fgnu-runtime -c -o $@ $(ALL_CFLAGS) \
$(INCLUDES) $<
Object_gc.o: Object.m
$(CC) -fgnu-runtime -c -o $@ $(ALL_CFLAGS) $(OBJC_GCFLAGS) \
$(INCLUDES) $<
Object_gc.lo: Object.m
$(LIBTOOL_COMPILE) $(CC) -fgnu-runtime -c -o $@ $(ALL_CFLAGS) \
$(OBJC_GCFLAGS) $(INCLUDES) $<
objects_gc.o: objects.c
$(CC) -c -o $@ $(ALL_CFLAGS) $(OBJC_GCFLAGS) $(INCLUDES) $<
objects_gc.lo: objects.c
$(LIBTOOL_COMPILE) $(CC) -c $(ALL_CFLAGS) -o $@ $(OBJC_GCFLAGS) \
$(INCLUDES) $<
Protocol.o: Protocol.m
$(CC) -fgnu-runtime -c -o $@ $(ALL_CFLAGS) $(INCLUDES) $<
Protocol.lo: Protocol.m
$(LIBTOOL_COMPILE) $(CC) -fgnu-runtime -c -o $@ $(ALL_CFLAGS) \
$(INCLUDES) $<
Protocol_gc.o: Protocol.m
$(CC) -fgnu-runtime -c -o $@ $(ALL_CFLAGS) $(OBJC_GCFLAGS) \
$(INCLUDES) $<
Protocol_gc.lo: Protocol.m
$(LIBTOOL_COMPILE) $(CC) -fgnu-runtime -c -o $@ $(ALL_CFLAGS) \
$(OBJC_GCFLAGS) $(INCLUDES) $<
sarray_gc.o: sarray.c
$(CC) -c -o $@ $(ALL_CFLAGS) $(OBJC_GCFLAGS) $(INCLUDES) $<
sarray_gc.lo: sarray.c
$(LIBTOOL_COMPILE) $(CC) -c -o $@ $(ALL_CFLAGS) $(OBJC_GCFLAGS) \
$(INCLUDES) $<
selector_gc.o: selector.c
$(CC) -c -o $@ $(ALL_CFLAGS) $(OBJC_GCFLAGS) $(INCLUDES) $<
selector_gc.lo: selector.c
$(LIBTOOL_COMPILE) $(CC) -c -o $@ $(ALL_CFLAGS) $(OBJC_GCFLAGS) \
$(INCLUDES) $<
sendmsg.o: sendmsg.c runtime-info.h
$(CC) -c -o $@ $(ALL_CFLAGS) $(INCLUDES) $<
sendmsg.lo: sendmsg.c runtime-info.h
$(LIBTOOL_COMPILE) $(CC) -c -o $@ $(ALL_CFLAGS) $(INCLUDES) $<
sendmsg_gc.o: sendmsg.c runtime-info.h
$(CC) -c -o $@ $(ALL_CFLAGS) $(OBJC_GCFLAGS) $(INCLUDES) $<
sendmsg_gc.lo: sendmsg.c runtime-info.h
$(LIBTOOL_COMPILE) $(CC) -c -o $@ $(ALL_CFLAGS) $(OBJC_GCFLAGS) \
$(INCLUDES) $<
thr_gc.o: thr.c
$(CC) -c -o $@ $(ALL_CFLAGS) $(OBJC_GCFLAGS) $(INCLUDES) $<
thr_gc.lo: thr.c
$(LIBTOOL_COMPILE) $(CC) -c -o $@ $(ALL_CFLAGS) $(OBJC_GCFLAGS) \
$(INCLUDES) $<
$(OBJC_THREAD_FILE)_gc.o: $(OBJC_THREAD_FILE).c
$(CC) -c -o $@ $(ALL_CFLAGS) $(OBJC_GCFLAGS) $(INCLUDES) $<
$(OBJC_THREAD_FILE)_gc.lo: $(OBJC_THREAD_FILE).c
$(LIBTOOL_COMPILE) $(CC) -c -o $@ $(ALL_CFLAGS) $(OBJC_GCFLAGS) \
$(INCLUDES) $<
doc: info dvi html
libobjc.a: $(OBJS)
$(AR) $(AR_FLAGS) $@ $(OBJS)
$(RANLIB) $@
libobjc.la: $(OBJS)
$(LIBTOOL_LINK) $(CC) -o $@ $(OBJS) \
-rpath $(glibcpp_toolexeclibdir) \
-version-info $(LIBOBJC_VERSION)
libobjc_gc.a: $(OBJS_GC)
$(AR) $(AR_FLAGS) $@ $(OBJS_GC)
$(RANLIB) $@
libobjc_gc.la: $(OBJS_GC)
$(LIBTOOL_LINK) $(CC) -o $@ $(OBJS_GC) \
-rpath $(glibcpp_toolexeclibdir) \
-version-info $(LIBOBJC_GC_VERSION)
libobjc_s.a: libobjc.a
#
# FIXME -- The following part does not fit in the libtool context.
# Libtool is supposed to [going to] be able to create a win 32 DLL
# without extra code but since I don't have a win machine to test
# if it already works, I leave the old code here.
#
libobjc_s.a: libobjc.la
mv libobjc.a libobjc_s.a
# Create a relocatable DLL
@ -241,19 +292,15 @@ libobjc.dll: libobjc_s.a libobjc_entry.o
-o libobjc.dll libobjc_s.a libobjc_entry.o -lkernel32
$(DLLTOOL) --dllname libobjc.dll --def $(srcdir)/libobjc.def \
--output-lib libobjc.a
#
#
#
#
#
info: objc-features.info
dvi: objc-features.dvi
html: objc-features_toc.html
objc-features.info: $(srcdir)/objc-features.texi
makeinfo $(srcdir)/objc-features.texi
objc-features.dvi: $(srcdir)/objc-features.texi
texi2dvi $(srcdir)/objc-features.texi
objc-features_toc.html: objc-features.texi
texi2html -split_node $(srcdir)/objc-features.texi
info:
dvi:
html:
Makefile: Makefile.in config.status
$(SHELL) config.status
@ -267,43 +314,31 @@ ${srcdir}/configure: configure.in
rm -f config.cache
cd ${srcdir} && autoconf
install: install-libs copy-headers
install: install-libs install-headers
install-libs: installdirs
-if test -f libobjc.a ; then \
rm -f $(libsubdir)/libobjc.a; \
$(INSTALL_DATA) libobjc.a $(libsubdir)/libobjc.a; \
chmod a-x $(libsubdir)/libobjc.a; \
else true; fi
-if test -f libobjc_gc.a ; then \
rm -f $(libsubdir)/libobjc_gc.a; \
$(INSTALL_DATA) libobjc_gc.a $(libsubdir)/libobjc_gc.a; \
chmod a-x $(libsubdir)/libobjc_gc.a; \
else true; fi
-if test -f libobjc_s.a ; then \
rm -f $(libsubdir)/libobjc_s.a; \
$(INSTALL_DATA) libobjc_s.a $(libsubdir)/libobjc_s.a; \
chmod a-x $(libsubdir)/libobjc_s.a; \
else true; fi
-if test -f libobjc.dll ; then \
rm -f $(bindir)/libobjc.dll; \
$(INSTALL_DATA) libobjc.dll $(bindir)/libobjc.dll; \
else true; fi
$(SHELL) $(toplevel_srcdir)/mkinstalldirs $(glibcpp_toolexeclibdir)
$(LIBTOOL_INSTALL) $(INSTALL) libobjc.la $(glibcpp_toolexeclibdir);
if [ "$(OBJC_BOEHM_GC)" ]; then \
$(LIBTOOL_INSTALL) $(INSTALL) libobjc_gc.la \
$(glibcpp_toolexeclibdir);\
fi
$(MULTIDO) $(FLAGS_TO_PASS) multi-do DO="$@"
@-$(LIBTOOL) --mode=finish $(glibcpp_toolexeclibdir)
# Copy Objective C headers to installation include directory.
copy-headers:
-rm -rf $(incinstalldir)/objc
-mkdir $(incinstalldir)/objc
install-headers:
$(SHELL) $(toplevel_srcdir)/mkinstalldirs $(libsubdir)/include/objc
for file in $(OBJC_H); do \
realfile=$(srcdir)/objc/$${file}; \
cp $${realfile} $(incinstalldir)/objc; \
chmod a+r $(incinstalldir)/objc/$${file}; \
$(INSTALL_DATA) $${realfile} $(libsubdir)/include/objc; \
done
check uninstall install-strip dist installcheck installdirs:
mostlyclean:
-rm -f runtime-info.h tmp-runtime.s *.o libobjc* xforward \
-$(LIBTOOL_CLEAN) rm -f libobjc.la libobjc_gc.la *.lo
-rm -f runtime-info.h tmp-runtime.s *.o *.lo libobjc* xforward \
fflags *.aux *.cp *.dvi *.fn *.info *.ky *.log *.pg \
*.toc *.tp *.vr *.html libobj.exp
@$(MULTICLEAN) multi-clean DO=mostlyclean

View file

@ -320,10 +320,6 @@ extern int errno;
object_get_class_name(self), sel_get_name(aSel)];
}
#ifdef __alpha__
extern size_t strlen(const char*);
#endif
- error:(const char *)aString, ...
{
#define FMT "error: %s (%s)\n%s\n"

View file

@ -102,30 +102,33 @@ high degree of portability across platforms.
The backend is composed of a file with the necessary code to map the ObjC
thread and mutex to a platform specific implementation. For example, the
file thr-solaris.c contains the implementation for Solaris. When you
configure GCC, it attempts to pick an appropriate backend file for the
target platform; however, you can override this choice by assign the
OBJC_THREAD_FILE make variable to the basename of the backend file. This
is especially useful on platforms which have multiple thread libraries.
For example:
make OBJC_THREAD_FILE=thr-posix
would indicate that the generic posix backend file, thr-posix.c, should be
compiled with the ObjC runtime library. If your platform does not support
threads then you should specify the OBJC_THREAD_FILE=thr-single backend file
to compile the ObjC runtime library without thread or mutex support; note
that programs which rely upon the ObjC thread and mutex functions will
compile and link correctly but attempting to create a thread or mutex will
result in an error.
file thr-solaris.c contains the implementation for Solaris.
If you are compiling libobjc as part of GCC, the thr-objc.c backend is
always used; this backend uses GCC's gthread code. The thread system
is automatically configured when GCC is configured. Important: make
sure you configure GCC using `--enable-threads' if you want threads !
If you want to compile libobjc standalone, then you would need to
modify the configure.in and makefiles for it; and you need to pick an
appropriate backend file for the target platform; you make this choice
by assigning the OBJC_THREAD_FILE make variable to the basename of the
backend file. For example, OBJC_THREAD_FILE=thr-posix would indicate
that the generic posix backend file, thr-posix.c, should be compiled
with the ObjC runtime library. If your platform does not support
threads then you should specify the OBJC_THREAD_FILE=thr-single
backend file to compile the ObjC runtime library without thread or
mutex support; note that programs which rely upon the ObjC thread and
mutex functions will compile and link correctly but attempting to
create a thread or mutex will result in an error.
It is questionable whether it is really necessary to have both a
frontend and backend function for all available functionality. On the
one hand, it provides a clear, consistent differentiation between what
is public and what is private with the downside of having the overhead
of multiple functions calls. For example, the function to have a thread
yield the processor is objc_thread_yield; in the current implementation
this produces a function call set:
of multiple functions calls. For example, the function to have a
thread yield the processor is objc_thread_yield; in the current
implementation this produces a function call set:
objc_thread_yield() -> __objc_thread_yield() -> system yield function

224
contrib/libobjc/aclocal.m4 vendored Normal file
View file

@ -0,0 +1,224 @@
dnl Copyright (C) 1994, 1995-8, 1999, 2001 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
dnl with or without modifications, as long as this notice is preserved.
dnl This program is distributed in the hope that it will be useful,
dnl but WITHOUT ANY WARRANTY, to the extent permitted by law; without
dnl even the implied warranty of MERCHANTABILITY or FITNESS FOR A
dnl PARTICULAR PURPOSE.
dnl
dnl Initialize configure bits.
dnl
dnl GLIBCPP_CONFIGURE
AC_DEFUN(GLIBCPP_CONFIGURE, [
dnl Default to --enable-multilib
AC_ARG_ENABLE(multilib,
[ --enable-multilib build hella library versions (default)],
[case "${enableval}" in
yes) multilib=yes ;;
no) multilib=no ;;
*) AC_MSG_ERROR(bad value ${enableval} for multilib option) ;;
esac], [multilib=yes])dnl
# When building with srcdir == objdir, links to the source files will
# be created in directories within the target_subdir. We have to
# adjust toplevel_srcdir accordingly, so that configure finds
# install-sh and other auxiliary files that live in the top-level
# source directory.
if test "${srcdir}" = "."; then
if test -z "${with_target_subdir}"; then
toprel=".."
else
if test "${with_target_subdir}" != "."; then
toprel="${with_multisrctop}../.."
else
toprel="${with_multisrctop}.."
fi
fi
else
toprel=".."
fi
AC_CONFIG_AUX_DIR(${srcdir}/$toprel)
toplevel_srcdir=\${top_srcdir}/$toprel
AC_SUBST(toplevel_srcdir)
# Export build and source directories.
# These need to be absolute paths, yet at the same time need to
# canonicalize only relative paths, because then amd will not unmount
# drives. Thus the use of PWDCMD: set it to 'pawd' or 'amq -w' if using amd.
glibcpp_builddir=`pwd`
case $srcdir in
[\\/$]* | ?:[\\/]*) glibcpp_srcdir=${srcdir} ;;
*) glibcpp_srcdir=`cd "$srcdir" && ${PWDCMD-pwd} || echo "$srcdir"` ;;
esac
AC_SUBST(glibcpp_builddir)
AC_SUBST(glibcpp_srcdir)
dnl This is here just to satisfy automake.
ifelse(not,equal,[AC_CONFIG_AUX_DIR(..)])
# Will set LN_S to either 'ln -s' or 'ln'. With autoconf 2.50+, can also
# be 'cp -p' if linking isn't available.
#ac_cv_prog_LN_S='cp -p'
AC_PROG_LN_S
# We use these options to decide which functions to include.
AC_ARG_WITH(target-subdir,
[ --with-target-subdir=SUBDIR
configuring in a subdirectory])
AC_ARG_WITH(cross-host,
[ --with-cross-host=HOST configuring with a cross compiler])
# Never versions of autoconf add an underscore to these functions.
# Prevent future problems ...
ifdef([AC_PROG_CC_G],[],[define([AC_PROG_CC_G],defn([_AC_PROG_CC_G]))])
ifdef([AC_PROG_CC_GNU],[],[define([AC_PROG_CC_GNU],defn([_AC_PROG_CC_GNU]))])
ifdef([AC_PROG_CXX_G],[],[define([AC_PROG_CXX_G],defn([_AC_PROG_CXX_G]))])
ifdef([AC_PROG_CXX_GNU],[],[define([AC_PROG_CXX_GNU],defn([_AC_PROG_CXX_GNU]))])
# AC_PROG_CC
# FIXME: We temporarily define our own version of AC_PROG_CC. This is
# copied from autoconf 2.12, but does not call AC_PROG_CC_WORKS. We
# are probably using a cross compiler, which will not be able to fully
# link an executable. This should really be fixed in autoconf
# itself.
AC_DEFUN(LIB_AC_PROG_CC,
[AC_BEFORE([$0], [AC_PROG_CPP])dnl
dnl Fool anybody using AC_PROG_CC.
AC_PROVIDE([AC_PROG_CC])
AC_CHECK_PROG(CC, gcc, gcc)
if test -z "$CC"; then
AC_CHECK_PROG(CC, cc, cc, , , /usr/ucb/cc)
test -z "$CC" && AC_MSG_ERROR([no acceptable cc found in \$PATH])
fi
AC_PROG_CC_GNU
if test $ac_cv_prog_gcc = yes; then
GCC=yes
dnl Check whether -g works, even if CFLAGS is set, in case the package
dnl plays around with CFLAGS (such as to build both debugging and
dnl normal versions of a library), tasteless as that idea is.
ac_test_CFLAGS="${CFLAGS+set}"
ac_save_CFLAGS="$CFLAGS"
CFLAGS=
AC_PROG_CC_G
if test "$ac_test_CFLAGS" = set; then
CFLAGS="$ac_save_CFLAGS"
elif test $ac_cv_prog_cc_g = yes; then
CFLAGS="-g -O2"
else
CFLAGS="-O2"
fi
else
GCC=
test "${CFLAGS+set}" = set || CFLAGS="-g"
fi
])
LIB_AC_PROG_CC
AC_CHECK_TOOL(AS, as)
AC_CHECK_TOOL(AR, ar)
AC_CHECK_TOOL(RANLIB, ranlib, ranlib-not-found-in-path-error)
AC_PROG_INSTALL
# We need AC_EXEEXT to keep automake happy in cygnus mode. However,
# at least currently, we never actually build a program, so we never
# need to use $(EXEEXT). Moreover, the test for EXEEXT normally
# fails, because we are probably configuring with a cross compiler
# which can't create executables. So we include AC_EXEEXT to keep
# automake happy, but we don't execute it, since we don't care about
# the result.
if false; then
# autoconf 2.50 runs AC_EXEEXT by default, and the macro expands
# to nothing, so nothing would remain between `then' and `fi' if it
# were not for the `:' below.
:
AC_EXEEXT
fi
])
dnl
dnl GLIBCPP_EXPORT_INSTALL_INFO
dnl calculates gxx_install_dir
dnl exports glibcpp_toolexecdir
dnl exports glibcpp_toolexeclibdir
dnl exports glibcpp_prefixdir
dnl
dnl Assumes cross_compiling bits already done, and with_cross_host in
dnl particular
dnl
dnl GLIBCPP_EXPORT_INSTALL_INFO
AC_DEFUN(GLIBCPP_EXPORT_INSTALL_INFO, [
# Assumes glibcpp_builddir, glibcpp_srcdir are alreay set up and
# exported correctly in GLIBCPP_CONFIGURE.
glibcpp_toolexecdir=no
glibcpp_toolexeclibdir=no
glibcpp_prefixdir=${prefix}
AC_MSG_CHECKING([for interface version number])
libstdcxx_interface=$INTERFACE
AC_MSG_RESULT($libstdcxx_interface)
# Process the option "--enable-version-specific-runtime-libs"
AC_MSG_CHECKING([for --enable-version-specific-runtime-libs])
AC_ARG_ENABLE(version-specific-runtime-libs,
[ --enable-version-specific-runtime-libs Specify that runtime libraries should be installed in a compiler-specific directory ],
[case "$enableval" in
yes) version_specific_libs=yes ;;
no) version_specific_libs=no ;;
*) AC_MSG_ERROR([Unknown argument to enable/disable version-specific libs]);;
esac],
version_specific_libs=no)dnl
# Option set, now we can test it.
AC_MSG_RESULT($version_specific_libs)
gcc_version_trigger=${srcdir}/../gcc/version.c
gcc_version_full=`grep version_string ${gcc_version_trigger} | sed -e 's/.*\"\([[^ \"]]*\)[[ \"]].*/\1/'`
gcc_version=`echo ${gcc_version_full} | sed -e 's/\([^ ]*\) .*/\1/'`
AC_SUBST(gcc_version)
AC_SUBST(gcc_version_trigger)
if test $version_specific_libs = yes; then
# Need the gcc compiler version to know where to install libraries
# and header files if --enable-version-specific-runtime-libs option
# is selected.
changequote(,)dnl
glibcpp_toolexecdir='$(libdir)/gcc-lib/$(target_alias)'
glibcpp_toolexeclibdir='$(toolexecdir)/'${gcc_version}'$(MULTISUBDIR)'
changequote([,])dnl
fi
# Calculate glibcpp_toolexecdir, glibcpp_toolexeclibdir
# Install a library built with a cross compiler in tooldir, not libdir.
if test x"$glibcpp_toolexecdir" = x"no"; then
if test -n "$with_cross_host" &&
test x"$with_cross_host" != x"no"; then
glibcpp_toolexecdir='$(exec_prefix)/$(target_alias)'
glibcpp_toolexeclibdir='$(toolexecdir)/lib$(MULTISUBDIR)'
else
glibcpp_toolexecdir='$(libdir)/gcc-lib/$(target_alias)'
glibcpp_toolexeclibdir='$(libdir)$(MULTISUBDIR)'
fi
fi
AC_SUBST(glibcpp_prefixdir)
AC_SUBST(glibcpp_toolexecdir)
AC_SUBST(glibcpp_toolexeclibdir)
])
sinclude(../libtool.m4)
dnl The lines below arrange for aclocal not to bring an installed
dnl libtool.m4 into aclocal.m4, while still arranging for automake to
dnl add a definition of LIBTOOL to Makefile.in.
ifelse(,,,[AC_SUBST(LIBTOOL)
AC_DEFUN([AM_PROG_LIBTOOL])
AC_DEFUN([AC_LIBTOOL_DLOPEN])
AC_DEFUN([AC_PROG_LD])
])

View file

@ -1,7 +1,10 @@
/* GNU Objective C Runtime class related functions
Copyright (C) 1993, 1995, 1996, 1997 Free Software Foundation, Inc.
Copyright (C) 1993, 1995, 1996, 1997, 2001 Free Software Foundation, Inc.
Contributed by Kresten Krab Thorup and Dennis Glatting.
Lock-free class table code designed and written from scratch by
Nicola Pero, 2001.
This file is part of GNU CC.
GNU CC is free software; you can redistribute it and/or modify it under the
@ -23,44 +26,411 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
however invalidate any other reasons why the executable file might be
covered by the GNU General Public License. */
#include "runtime.h" /* the kitchen sink */
/*
The code in this file critically affects class method invocation
speed. This long preamble comment explains why, and the issues
involved.
One of the traditional weaknesses of the GNU Objective-C runtime is
that class method invocations are slow. The reason is that when you
write
array = [NSArray new];
this gets basically compiled into the equivalent of
array = [(objc_get_class ("NSArray")) new];
objc_get_class returns the class pointer corresponding to the string
`NSArray'; and because of the lookup, the operation is more
complicated and slow than a simple instance method invocation.
Most high performance Objective-C code (using the GNU Objc runtime)
I had the opportunity to read (or write) work around this problem by
caching the class pointer:
Class arrayClass = [NSArray class];
... later on ...
array = [arrayClass new];
array = [arrayClass new];
array = [arrayClass new];
In this case, you always perform a class lookup (the first one), but
then all the [arrayClass new] methods run exactly as fast as an
instance method invocation. It helps if you have many class method
invocations to the same class.
The long-term solution to this problem would be to modify the
compiler to output tables of class pointers corresponding to all the
class method invocations, and to add code to the runtime to update
these tables - that should in the end allow class method invocations
to perform precisely as fast as instance method invocations, because
no class lookup would be involved. I think the Apple Objective-C
runtime uses this technique. Doing this involves synchronized
modifications in the runtime and in the compiler.
As a first medicine to the problem, I [NP] have redesigned and
rewritten the way the runtime is performing class lookup. This
doesn't give as much speed as the other (definitive) approach, but
at least a class method invocation now takes approximately 4.5 times
an instance method invocation on my machine (it would take approx 12
times before the rewriting), which is a lot better.
One of the main reason the new class lookup is so faster is because
I implemented it in a way that can safely run multithreaded without
using locks - a so-called `lock-free' data structure. The atomic
operation is pointer assignment. The reason why in this problem
lock-free data structures work so well is that you never remove
classes from the table - and the difficult thing with lock-free data
structures is freeing data when is removed from the structures. */
#include "runtime.h" /* the kitchen sink */
#include "sarray.h"
/* The table of classname->class. Used for objc_lookup_class and friends */
static cache_ptr __objc_class_hash = 0; /* !T:MUTEX */
#include <objc/objc.h>
#include <objc/objc-api.h>
#include <objc/thr.h>
/* This is a hook which is called by objc_get_class and
objc_lookup_class if the runtime is not able to find the class.
This may e.g. try to load in the class using dynamic loading */
/* We use a table which maps a class name to the corresponding class
* pointer. The first part of this file defines this table, and
* functions to do basic operations on the table. The second part of
* the file implements some higher level Objective-C functionality for
* classes by using the functions provided in the first part to manage
* the table. */
/**
** Class Table Internals
**/
/* A node holding a class */
typedef struct class_node
{
struct class_node *next; /* Pointer to next entry on the list.
NULL indicates end of list. */
const char *name; /* The class name string */
int length; /* The class name string length */
Class pointer; /* The Class pointer */
} *class_node_ptr;
/* A table containing classes is a class_node_ptr (pointing to the
first entry in the table - if it is NULL, then the table is
empty). */
/* We have 1024 tables. Each table contains all class names which
have the same hash (which is a number between 0 and 1023). To look
up a class_name, we compute its hash, and get the corresponding
table. Once we have the table, we simply compare strings directly
till we find the one which we want (using the length first). The
number of tables is quite big on purpose (a normal big application
has less than 1000 classes), so that you shouldn't normally get any
collisions, and get away with a single comparison (which we can't
avoid since we need to know that you have got the right thing). */
#define CLASS_TABLE_SIZE 1024
#define CLASS_TABLE_MASK 1023
static class_node_ptr class_table_array[CLASS_TABLE_SIZE];
/* The table writing mutex - we lock on writing to avoid conflicts
between different writers, but we read without locks. That is
possible because we assume pointer assignment to be an atomic
operation. */
static objc_mutex_t __class_table_lock = NULL;
/* CLASS_TABLE_HASH is how we compute the hash of a class name. It is
a macro - *not* a function - arguments *are* modified directly.
INDEX should be a variable holding an int;
HASH should be a variable holding an int;
CLASS_NAME should be a variable holding a (char *) to the class_name.
After the macro is executed, INDEX contains the length of the
string, and HASH the computed hash of the string; CLASS_NAME is
untouched. */
#define CLASS_TABLE_HASH(INDEX, HASH, CLASS_NAME) \
HASH = 0; \
for (INDEX = 0; CLASS_NAME[INDEX] != '\0'; INDEX++) \
{ \
HASH = (HASH << 4) ^ (HASH >> 28) ^ CLASS_NAME[INDEX]; \
} \
\
HASH = (HASH ^ (HASH >> 10) ^ (HASH >> 20)) & CLASS_TABLE_MASK;
/* Setup the table. */
static void
class_table_setup ()
{
/* Start - nothing in the table. */
memset (class_table_array, 0, sizeof(class_node_ptr) * CLASS_TABLE_SIZE);
/* The table writing mutex. */
__class_table_lock = objc_mutex_allocate ();
}
/* Insert a class in the table (used when a new class is registered). */
static void
class_table_insert (const char *class_name, Class class_pointer)
{
int hash, length;
class_node_ptr new_node;
/* Find out the class name's hash and length. */
CLASS_TABLE_HASH (length, hash, class_name);
/* Prepare the new node holding the class. */
new_node = objc_malloc (sizeof (struct class_node));
new_node->name = class_name;
new_node->length = length;
new_node->pointer = class_pointer;
/* Lock the table for modifications. */
objc_mutex_lock (__class_table_lock);
/* Insert the new node in the table at the beginning of the table at
class_table_array[hash]. */
new_node->next = class_table_array[hash];
class_table_array[hash] = new_node;
objc_mutex_unlock (__class_table_lock);
}
/* Replace a class in the table (used only by poseAs:). */
static void
class_table_replace (Class old_class_pointer, Class new_class_pointer)
{
int hash;
class_node_ptr node;
objc_mutex_lock (__class_table_lock);
hash = 0;
node = class_table_array[hash];
while (hash < CLASS_TABLE_SIZE)
{
if (node == NULL)
{
hash++;
if (hash < CLASS_TABLE_SIZE)
{
node = class_table_array[hash];
}
}
else
{
Class class1 = node->pointer;
if (class1 == old_class_pointer)
{
node->pointer = new_class_pointer;
}
node = node->next;
}
}
objc_mutex_unlock (__class_table_lock);
}
/* Get a class from the table. This does not need mutex protection.
Currently, this function is called each time you call a static
method, this is why it must be very fast. */
static inline Class
class_table_get_safe (const char *class_name)
{
class_node_ptr node;
int length, hash;
/* Compute length and hash. */
CLASS_TABLE_HASH (length, hash, class_name);
node = class_table_array[hash];
if (node != NULL)
{
do
{
if (node->length == length)
{
/* Compare the class names. */
int i;
for (i = 0; i < length; i++)
{
if ((node->name)[i] != class_name[i])
{
break;
}
}
if (i == length)
{
/* They are equal! */
return node->pointer;
}
}
}
while ((node = node->next) != NULL);
}
return Nil;
}
/* Enumerate over the class table. */
struct class_table_enumerator
{
int hash;
class_node_ptr node;
};
static Class
class_table_next (struct class_table_enumerator **e)
{
struct class_table_enumerator *enumerator = *e;
class_node_ptr next;
if (enumerator == NULL)
{
*e = objc_malloc (sizeof (struct class_table_enumerator));
enumerator = *e;
enumerator->hash = 0;
enumerator->node = NULL;
next = class_table_array[enumerator->hash];
}
else
{
next = enumerator->node->next;
}
if (next != NULL)
{
enumerator->node = next;
return enumerator->node->pointer;
}
else
{
enumerator->hash++;
while (enumerator->hash < CLASS_TABLE_SIZE)
{
next = class_table_array[enumerator->hash];
if (next != NULL)
{
enumerator->node = next;
return enumerator->node->pointer;
}
enumerator->hash++;
}
/* Ok - table finished - done. */
objc_free (enumerator);
return Nil;
}
}
#if 0 /* DEBUGGING FUNCTIONS */
/* Debugging function - print the class table. */
void
class_table_print ()
{
int i;
for (i = 0; i < CLASS_TABLE_SIZE; i++)
{
class_node_ptr node;
printf ("%d:\n", i);
node = class_table_array[i];
while (node != NULL)
{
printf ("\t%s\n", node->name);
node = node->next;
}
}
}
/* Debugging function - print an histogram of number of classes in
function of hash key values. Useful to evaluate the hash function
in real cases. */
void
class_table_print_histogram ()
{
int i, j;
int counter = 0;
for (i = 0; i < CLASS_TABLE_SIZE; i++)
{
class_node_ptr node;
node = class_table_array[i];
while (node != NULL)
{
counter++;
node = node->next;
}
if (((i + 1) % 50) == 0)
{
printf ("%4d:", i + 1);
for (j = 0; j < counter; j++)
{
printf ("X");
}
printf ("\n");
counter = 0;
}
}
printf ("%4d:", i + 1);
for (j = 0; j < counter; j++)
{
printf ("X");
}
printf ("\n");
}
#endif /* DEBUGGING FUNCTIONS */
/**
** Objective-C runtime functions
**/
/* From now on, the only access to the class table data structure
should be via the class_table_* functions. */
/* This is a hook which is called by objc_get_class and
objc_lookup_class if the runtime is not able to find the class.
This may e.g. try to load in the class using dynamic loading. */
Class (*_objc_lookup_class)(const char* name) = 0; /* !T:SAFE */
/* True when class links has been resolved */
/* True when class links has been resolved. */
BOOL __objc_class_links_resolved = NO; /* !T:UNUSED */
/* Initial number of buckets size of class hash table. */
#define CLASS_HASH_SIZE 32
void __objc_init_class_tables()
{
/* Allocate the class hash table */
if(__objc_class_hash)
/* Allocate the class hash table. */
if(__class_table_lock)
return;
objc_mutex_lock(__objc_runtime_mutex);
__objc_class_hash
= hash_new (CLASS_HASH_SIZE,
(hash_func_type) hash_string,
(compare_func_type) compare_strings);
class_table_setup ();
objc_mutex_unlock(__objc_runtime_mutex);
}
/* This function adds a class to the class hash table, and assigns the
class a number, unless it's already known */
/* This function adds a class to the class hash table, and assigns the
class a number, unless it's already known. */
void
__objc_add_class_to_hash(Class class)
{
@ -68,14 +438,14 @@ __objc_add_class_to_hash(Class class)
objc_mutex_lock(__objc_runtime_mutex);
/* make sure the table is there */
assert(__objc_class_hash);
/* Make sure the table is there. */
assert(__class_table_lock);
/* make sure it's not a meta class */
/* Make sure it's not a meta class. */
assert(CLS_ISCLASS(class));
/* Check to see if the class is already in the hash table. */
h_class = hash_value_for_key (__objc_class_hash, class->name);
h_class = class_table_get_safe (class->name);
if (!h_class)
{
/* The class isn't in the hash table. Add the class and assign a class
@ -86,7 +456,7 @@ __objc_add_class_to_hash(Class class)
CLS_SETNUMBER(class->class_pointer, class_number);
++class_number;
hash_add (&__objc_class_hash, class->name, class);
class_table_insert (class->name, class);
}
objc_mutex_unlock(__objc_runtime_mutex);
@ -94,19 +464,12 @@ __objc_add_class_to_hash(Class class)
/* Get the class object for the class named NAME. If NAME does not
identify a known class, the hook _objc_lookup_class is called. If
this fails, nil is returned */
this fails, nil is returned. */
Class objc_lookup_class (const char* name)
{
Class class;
objc_mutex_lock(__objc_runtime_mutex);
/* Make sure the class hash table exists. */
assert (__objc_class_hash);
class = hash_value_for_key (__objc_class_hash, name);
objc_mutex_unlock(__objc_runtime_mutex);
class = class_table_get_safe (name);
if (class)
return class;
@ -119,20 +482,13 @@ Class objc_lookup_class (const char* name)
/* Get the class object for the class named NAME. If NAME does not
identify a known class, the hook _objc_lookup_class is called. If
this fails, an error message is issued and the system aborts */
this fails, an error message is issued and the system aborts. */
Class
objc_get_class (const char *name)
{
Class class;
objc_mutex_lock(__objc_runtime_mutex);
/* Make sure the class hash table exists. */
assert (__objc_class_hash);
class = hash_value_for_key (__objc_class_hash, name);
objc_mutex_unlock(__objc_runtime_mutex);
class = class_table_get_safe (name);
if (class)
return class;
@ -144,7 +500,7 @@ objc_get_class (const char *name)
return class;
objc_error(nil, OBJC_ERR_BAD_CLASS,
"objc runtime: cannot find class %s\n", name);
"objc runtime: cannot find class %s\n", name);
return 0;
}
@ -166,44 +522,42 @@ objc_get_meta_class(const char *name)
Class
objc_next_class(void **enum_state)
{
Class class;
objc_mutex_lock(__objc_runtime_mutex);
/* Make sure the table is there. */
assert(__class_table_lock);
/* make sure the table is there */
assert(__objc_class_hash);
*(node_ptr*)enum_state =
hash_next(__objc_class_hash, *(node_ptr*)enum_state);
class = class_table_next ((struct class_table_enumerator **)enum_state);
objc_mutex_unlock(__objc_runtime_mutex);
if (*(node_ptr*)enum_state)
return (*(node_ptr*)enum_state)->value;
return (Class)0;
return class;
}
/* Resolve super/subclass links for all classes. The only thing we
can be sure of is that the class_pointer for class objects point
to the right meta class objects */
/* Resolve super/subclass links for all classes. The only thing we
can be sure of is that the class_pointer for class objects point to
the right meta class objects. */
void __objc_resolve_class_links()
{
node_ptr node;
struct class_table_enumerator *es = NULL;
Class object_class = objc_get_class ("Object");
Class class1;
assert(object_class);
objc_mutex_lock(__objc_runtime_mutex);
/* Assign subclass links */
for (node = hash_next (__objc_class_hash, NULL); node;
node = hash_next (__objc_class_hash, node))
/* Assign subclass links. */
while ((class1 = class_table_next (&es)))
{
Class class1 = node->value;
/* Make sure we have what we think we have. */
assert (CLS_ISCLASS(class1));
assert (CLS_ISMETA(class1->class_pointer));
/* The class_pointer of all meta classes point to Object's meta class. */
/* The class_pointer of all meta classes point to Object's meta
class. */
class1->class_pointer->class_pointer = object_class->class_pointer;
if (!(CLS_ISRESOLV(class1)))
@ -221,11 +575,11 @@ void __objc_resolve_class_links()
DEBUG_PRINTF ("making class connections for: %s\n",
class1->name);
/* assign subclass links for superclass */
/* Assign subclass links for superclass. */
class1->sibling_class = a_super_class->subclass_list;
a_super_class->subclass_list = class1;
/* Assign subclass links for meta class of superclass */
/* Assign subclass links for meta class of superclass. */
if (a_super_class->class_pointer)
{
class1->class_pointer->sibling_class
@ -234,8 +588,8 @@ void __objc_resolve_class_links()
= class1->class_pointer;
}
}
else /* a root class, make its meta object */
/* be a subclass of Object */
else /* A root class, make its meta object be a subclass of
Object. */
{
class1->class_pointer->sibling_class
= object_class->subclass_list;
@ -244,11 +598,10 @@ void __objc_resolve_class_links()
}
}
/* Assign superclass links */
for (node = hash_next (__objc_class_hash, NULL); node;
node = hash_next (__objc_class_hash, node))
/* Assign superclass links. */
es = NULL;
while ((class1 = class_table_next (&es)))
{
Class class1 = node->value;
Class sub_class;
for (sub_class = class1->subclass_list; sub_class;
sub_class = sub_class->sibling_class)
@ -269,13 +622,10 @@ void __objc_resolve_class_links()
Class
class_pose_as (Class impostor, Class super_class)
{
node_ptr node;
Class class1;
if (!CLS_ISRESOLV (impostor))
__objc_resolve_class_links ();
/* preconditions */
/* Preconditions */
assert (impostor);
assert (super_class);
assert (impostor->super_class == super_class);
@ -286,73 +636,64 @@ class_pose_as (Class impostor, Class super_class)
{
Class *subclass = &(super_class->subclass_list);
/* move subclasses of super_class to impostor */
/* Move subclasses of super_class to impostor. */
while (*subclass)
{
Class nextSub = (*subclass)->sibling_class;
Class nextSub = (*subclass)->sibling_class;
if (*subclass != impostor)
{
Class sub = *subclass;
if (*subclass != impostor)
{
Class sub = *subclass;
/* classes */
sub->sibling_class = impostor->subclass_list;
sub->super_class = impostor;
impostor->subclass_list = sub;
/* Classes */
sub->sibling_class = impostor->subclass_list;
sub->super_class = impostor;
impostor->subclass_list = sub;
/* It will happen that SUB is not a class object if it is
the top of the meta class hierarchy chain. (root
meta-class objects inherit their class object) If that is
the case... don't mess with the meta-meta class. */
if (CLS_ISCLASS (sub))
{
/* meta classes */
CLASSOF (sub)->sibling_class =
CLASSOF (impostor)->subclass_list;
CLASSOF (sub)->super_class = CLASSOF (impostor);
CLASSOF (impostor)->subclass_list = CLASSOF (sub);
}
}
/* It will happen that SUB is not a class object if it is
the top of the meta class hierarchy chain (root
meta-class objects inherit their class object). If
that is the case... don't mess with the meta-meta
class. */
if (CLS_ISCLASS (sub))
{
/* Meta classes */
CLASSOF (sub)->sibling_class =
CLASSOF (impostor)->subclass_list;
CLASSOF (sub)->super_class = CLASSOF (impostor);
CLASSOF (impostor)->subclass_list = CLASSOF (sub);
}
}
*subclass = nextSub;
*subclass = nextSub;
}
/* set subclasses of superclass to be impostor only */
/* Set subclasses of superclass to be impostor only. */
super_class->subclass_list = impostor;
CLASSOF (super_class)->subclass_list = CLASSOF (impostor);
/* set impostor to have no sibling classes */
/* Set impostor to have no sibling classes. */
impostor->sibling_class = 0;
CLASSOF (impostor)->sibling_class = 0;
}
/* check relationship of impostor and super_class is kept. */
/* Check relationship of impostor and super_class is kept. */
assert (impostor->super_class == super_class);
assert (CLASSOF (impostor)->super_class == CLASSOF (super_class));
/* This is how to update the lookup table. Regardless of
what the keys of the hashtable is, change all values that are
superclass into impostor. */
/* This is how to update the lookup table. Regardless of what the
keys of the hashtable is, change all values that are superclass
into impostor. */
objc_mutex_lock(__objc_runtime_mutex);
for (node = hash_next (__objc_class_hash, NULL); node;
node = hash_next (__objc_class_hash, node))
{
class1 = (Class)node->value;
if (class1 == super_class)
{
node->value = impostor; /* change hash table value */
}
}
class_table_replace (super_class, impostor);
objc_mutex_unlock(__objc_runtime_mutex);
/* next, we update the dispatch tables... */
/* Next, we update the dispatch tables... */
__objc_update_dispatch_table_for_class (CLASSOF (impostor));
__objc_update_dispatch_table_for_class (impostor);
return impostor;
}

View file

@ -0,0 +1,2 @@
/* Define this if you have the <sched.h> header file */
#undef HAVE_SCHED_H

File diff suppressed because it is too large Load diff

View file

@ -1,5 +1,5 @@
# Process this file with autoconf to produce a configure script.
# Copyright (C) 1995, 1997, 1998, 1999 Free Software Foundation, Inc.
# Copyright (C) 1995, 1997, 1998, 1999, 2002 Free Software Foundation, Inc.
# Contributed by Dave Love (d.love@dl.ac.uk).
#
#This file is part of GNU Objective C.
@ -21,20 +21,20 @@
AC_PREREQ(2.13)
AC_INIT(objc/objc.h)
#AC_CONFIG_HEADER(config.h)
AC_CONFIG_HEADER(config.h)
if test "${srcdir}" = "." ; then
if test "${with_target_subdir}" != "." ; then
topsrcdir=${with_multisrctop}../..
else
topsrcdir=${with_multisrctop}..
fi
else
topsrcdir=${srcdir}/..
fi
dnl This is needed for a multilibbed build in the source tree so
dnl that install-sh and config.sub get found.
AC_CONFIG_AUX_DIR($topsrcdir)
# This works around the fact that libtool configuration may change LD
# for this particular configuration, but some shells, instead of
# keeping the changes in LD private, export them just because LD is
# exported.
ORIGINAL_LD_FOR_MULTILIBS=$LD
AC_CANONICAL_SYSTEM
target_alias=${target_alias-$target}
AC_SUBST(target_alias)
GLIBCPP_CONFIGURE(.)
GLIBCPP_EXPORT_INSTALL_INFO
# If the language specific compiler does not exist, but the "gcc" directory
# does, we do not build anything. Note, $r is set by the top-level Makefile.
@ -65,10 +65,16 @@ then
fi
dnl Checks for programs.
# For ObjC we'll set CC to point at the built gcc, but this will get it into
# the makefiles
AC_PROG_CC
# Disable shared libs by default
AC_DISABLE_SHARED
# Enable Win32 DLL on MS Windows - FIXME
AC_LIBTOOL_WIN32_DLL
AC_PROG_LIBTOOL
dnl These should be inherited in the recursive make, but ensure they are
dnl defined:
test "$AR" || AR=ar
AC_SUBST(AR)
if test "$RANLIB"; then :
@ -77,8 +83,7 @@ else
AC_PROG_RANLIB
fi
AC_PROG_INSTALL
dnl Checks for libraries.
AC_PROG_MAKE_SET
dnl Checks for header files.
# Sanity check for the cross-compilation case:
@ -91,17 +96,19 @@ the Objective C runtime system. If necessary, install gcc now with
AC_HEADER_STDC
# Determine the name of the GCC thread file.
AC_CHECK_HEADERS(sched.h)
AC_CACHE_CHECK([for thread file],objc_cv_thread_file,
# Determine CFLAGS for gthread.
AC_CACHE_CHECK([for gthread cflags],objc_cv_gthread_flags,
[if test -f "$r"/gcc/Makefile
then
objc_cv_thread_file=`grep \^GCC_THREAD_FILE "$r"/gcc/Makefile | awk -F= '{ print $2 }'`
objc_cv_gthread_flags=`grep \^GTHREAD_FLAGS "$r"/gcc/Makefile | awk -F= '{ print $2 }'`
else
AC_MSG_ERROR([not found])
fi])
OBJC_THREAD_FILE=$objc_cv_thread_file
AC_SUBST(OBJC_THREAD_FILE)
GTHREAD_FLAGS=$objc_cv_gthread_flags
AC_SUBST(GTHREAD_FLAGS)
AC_ARG_ENABLE(objc-gc,
[ --enable-objc-gc enable the use of Boehm's garbage collector with
@ -109,7 +116,7 @@ AC_ARG_ENABLE(objc-gc,
if [[[ x$enable_objc_gc = xno ]]]; then
OBJC_BOEHM_GC=''
else
OBJC_BOEHM_GC=libobjc_gc.a
OBJC_BOEHM_GC=libobjc_gc.la
fi,
OBJC_BOEHM_GC='')
AC_SUBST(OBJC_BOEHM_GC)
@ -117,12 +124,13 @@ AC_SUBST(OBJC_BOEHM_GC)
# We need multilib support, but only if configuring for the target.
AC_OUTPUT(Makefile,
[test -z "$CONFIG_HEADERS" || echo timestamp > stamp-h
[test -z "$CONFIG_HEADERS" || echo timestamp > stamp-h
if test -n "$CONFIG_FILES"; then
if test -n "${with_target_subdir}"; then
# FIXME: We shouldn't need to set ac_file
ac_file=Makefile
. ${topsrcdir}/config-ml.in
LD="${ORIGINAL_LD_FOR_MULTILIBS}"
. ${toplevel_srcdir}/config-ml.in
fi
fi],
srcdir=${srcdir}
@ -131,10 +139,11 @@ target=${target}
with_target_subdir=${with_target_subdir}
with_multisubdir=${with_multisubdir}
ac_configure_args="--enable-multilib ${ac_configure_args}"
toplevel_srcdir=${toplevel_srcdir}
CONFIG_SHELL=${CONFIG_SHELL-/bin/sh}
topsrcdir=${topsrcdir}
)
dnl Local Variables:
dnl comment-start: "dnl "
dnl comment-end: ""

View file

@ -1,5 +1,5 @@
/* Encoding of types for Objective C.
Copyright (C) 1993, 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
Copyright (C) 1993, 1995, 1996, 1997, 1998, 2000 Free Software Foundation, Inc.
Contributed by Kresten Krab Thorup
Bitfield support by Ovidiu Predescu
@ -30,14 +30,17 @@ Boston, MA 02111-1307, USA. */
#include "objc-api.h"
#include "encoding.h"
#undef MAX
#define MAX(X, Y) \
({ typeof(X) __x = (X), __y = (Y); \
(__x > __y ? __x : __y); })
#undef MIN
#define MIN(X, Y) \
({ typeof(X) __x = (X), __y = (Y); \
(__x < __y ? __x : __y); })
#undef ROUND
#define ROUND(V, A) \
({ typeof(V) __v=(V); typeof(A) __a=(A); \
__a*((__v+__a-1)/__a); })
@ -46,22 +49,37 @@ Boston, MA 02111-1307, USA. */
/* Various hacks for objc_layout_record. These are used by the target
macros. */
#define TREE_CODE(TYPE) *TYPE
#define TREE_TYPE(TREE) TREE
#define TREE_CODE(TYPE) *(TYPE)
#define TREE_TYPE(TREE) (TREE)
#define RECORD_TYPE _C_STRUCT_B
#define UNION_TYPE _C_UNION_B
#define QUAL_UNION_TYPE _C_UNION_B
#define ARRAY_TYPE _C_ARY_B
#define REAL_TYPE _C_DBL
#define VECTOR_TYPE _C_VECTOR
#define TYPE_FIELDS(TYPE) objc_skip_typespec (TYPE)
#define DECL_MODE(TYPE) *(TYPE)
#define DECL_MODE(TYPE) *(TYPE)
#define TYPE_MODE(TYPE) *(TYPE)
#define DFmode _C_DBL
#define get_inner_array_type(TYPE) ((TYPE) + 1)
/* Some ports (eg ARM) allow the structure size boundary to be
selected at compile-time. We override the normal definition with
one that has a constant value for this compilation. */
#undef STRUCTURE_SIZE_BOUNDARY
#define STRUCTURE_SIZE_BOUNDARY (BITS_PER_UNIT * sizeof (struct{char a;}))
/* Some ROUND_TYPE_ALIGN macros use TARGET_foo, and consequently
target_flags. Define a dummy entry here to so we don't die. */
static int target_flags = 0;
static inline int
atoi (const char* str)
@ -724,9 +742,7 @@ objc_layout_structure (const char *type,
layout->record_size = 0;
layout->record_align = BITS_PER_UNIT;
#ifdef STRUCTURE_SIZE_BOUNDARY
layout->record_align = MAX (layout->record_align, STRUCTURE_SIZE_BOUNDARY);
#endif
}
@ -743,15 +759,6 @@ objc_layout_structure_next_member (struct objc_struct_layout *layout)
/* The current type without the type qualifiers */
const char *type;
#if 1
if (layout->prev_type == NULL)
{
layout->prev_type = layout->type;
layout->type = objc_skip_typespec (layout->prev_type);
return YES;
}
#endif
/* Add the size of the previous field to the size of the record. */
if (layout->prev_type)
{
@ -760,7 +767,6 @@ objc_layout_structure_next_member (struct objc_struct_layout *layout)
if (*type != _C_BFLD)
layout->record_size += objc_sizeof_type (type) * BITS_PER_UNIT;
else {
desired_align = 1;
/* Get the bitfield's type */
for (bfld_type = type + 1;
isdigit(*bfld_type);
@ -878,7 +884,7 @@ void objc_layout_finish_structure (struct objc_struct_layout *layout,
in the record type. Round it up to a multiple of the record's
alignment. */
#ifdef ROUND_TYPE_ALIGN
#if defined(ROUND_TYPE_ALIGN) && !defined(__sparc__)
layout->record_align = ROUND_TYPE_ALIGN (layout->original_type,
1,
layout->record_align);

View file

@ -324,12 +324,13 @@ __objc_generate_gc_type_description (Class class)
if (current + 1 == type_size)
class_structure_type = objc_realloc (class_structure_type, ++type_size);
strcat (class_structure_type + current, "}");
// printf ("type description for '%s' is %s\n", class->name, class_structure_type);
#ifdef DEBUG
printf ("type description for '%s' is %s\n", class->name, class_structure_type);
#endif
__objc_gc_type_description_from_type (mask, class_structure_type);
objc_free (class_structure_type);
#define DEBUG 1
#ifdef DEBUG
printf (" mask for '%s', type '%s' (bits %d, mask size %d) is:",
class_structure_type, class->name, bits_no, size);

View file

@ -313,16 +313,16 @@ __objc_send_message_in_list (MethodList_t method_list, Class class, SEL op)
Method_t mth = &method_list->method_list[i];
if (mth->method_name && sel_eq (mth->method_name, op)
&& !hash_is_key_in_hash (__objc_load_methods, mth->method_name))
&& !hash_is_key_in_hash (__objc_load_methods, mth->method_imp))
{
/* The method was found and wasn't previously executed. */
(*mth->method_imp) ((id)class, mth->method_name);
/* Add this method into the +load hash table */
hash_add (&__objc_load_methods, mth->method_imp, mth->method_imp);
DEBUG_PRINTF ("sending +load in class: %s\n", class->name);
/* The method was found and wasn't previously executed. */
(*mth->method_imp) ((id)class, mth->method_name);
break;
}
}
@ -599,9 +599,7 @@ __objc_exec_class (Module_t module)
/* Scan the unclaimed category hash. Attempt to attach any unclaimed
categories to objects. */
for (cell = &unclaimed_categories;
*cell;
({ if (*cell) cell = &(*cell)->tail; }))
for (cell = &unclaimed_categories; *cell; )
{
Category_t category = (*cell)->head;
Class class = objc_lookup_class (category->class_name);
@ -630,6 +628,8 @@ __objc_exec_class (Module_t module)
only done for root classes. */
__objc_register_instance_methods_to_class(class);
}
else
cell = &(*cell)->tail;
}
if (unclaimed_proto_list && objc_lookup_class ("Protocol"))

View file

@ -45,6 +45,8 @@ objc_thread_id
objc_thread_set_data
objc_thread_set_priority
objc_thread_yield
objc_thread_add
objc_thread_remove
__objc_class_name_Object
__objc_class_name_Protocol
__objc_class_name_NXConstantString

View file

@ -29,6 +29,7 @@ Boston, MA 02111-1307, USA. */
#define __hash_INCLUDE_GNU
#include <stddef.h>
#include <string.h>
#include <objc/objc.h>
/*

View file

@ -1,5 +1,5 @@
/* GNU Objective-C Runtime API.
Copyright (C) 1993, 1995, 1996, 1997 Free Software Foundation, Inc.
Copyright (C) 1993, 1995, 1996, 1997, 2002 Free Software Foundation, Inc.
This file is part of GNU CC.
@ -75,6 +75,7 @@ struct objc_method_description
#define _C_UNION_E ')'
#define _C_STRUCT_B '{'
#define _C_STRUCT_E '}'
#define _C_VECTOR '!'
/*
@ -260,7 +261,7 @@ typedef struct objc_method_list {
struct objc_protocol_list {
struct objc_protocol_list *next;
int count;
size_t count;
Protocol *list[1];
};
@ -414,6 +415,13 @@ extern void *(*_objc_realloc)(void *, size_t);
extern void *(*_objc_calloc)(size_t, size_t);
extern 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);
Method_t class_get_class_method(MetaClass class, SEL aSel);
Method_t class_get_instance_method(Class class, SEL aSel);
@ -571,21 +579,23 @@ object_get_super_class
}
static inline BOOL
object_is_class(id object)
object_is_class (id object)
{
return CLS_ISCLASS((Class)object);
return ((object != nil) && CLS_ISMETA (object->class_pointer));
}
static inline BOOL
object_is_instance (id object)
{
return ((object != nil) && CLS_ISCLASS (object->class_pointer));
}
static inline BOOL
object_is_instance(id object)
object_is_meta_class (id object)
{
return (object!=nil)&&CLS_ISCLASS(object->class_pointer);
}
static inline BOOL
object_is_meta_class(id object)
{
return CLS_ISMETA((Class)object);
return ((object != nil)
&& !object_is_instance (object)
&& !object_is_class (object));
}
struct sarray*

View file

@ -96,6 +96,8 @@ int objc_thread_get_priority(void);
void * objc_thread_get_data(void);
int objc_thread_set_data(void *value);
objc_thread_t objc_thread_id(void);
void objc_thread_add(void);
void objc_thread_remove(void);
/*
Use this to set the hook function that will be called when the

View file

@ -44,10 +44,6 @@ const char* __objc_sparse2_id = "2 level sparse indices";
const char* __objc_sparse3_id = "3 level sparse indices";
#endif
#ifdef __alpha__
const void *memcpy (void*, const void*, size_t);
#endif
/* This function removes any structures left over from free operations
that were not safe in a multi-threaded environment. */
void

View file

@ -1,5 +1,6 @@
/* GNU Objective C Runtime message lookup
Copyright (C) 1993, 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
Copyright (C) 1993, 1995, 1996, 1997, 1998,
2001 Free Software Foundation, Inc.
Contributed by Kresten Krab Thorup
This file is part of GNU CC.
@ -33,6 +34,7 @@ Boston, MA 02111-1307, USA. */
/* 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
#define rtx int
#if !defined(STRUCT_VALUE) || STRUCT_VALUE == 0
@ -44,6 +46,11 @@ Boston, MA 02111-1307, USA. */
/* The uninstalled dispatch table */
struct sarray* __objc_uninstalled_dtable = 0; /* !T:MUTEX */
/* Hook for method forwarding. If it is set, is invoked to return a
function that performs the real forwarding. Otherwise the libgcc
based functions (__builtin_apply and friends) are used. */
IMP (*__objc_msg_forward)(SEL) = NULL;
/* Send +initialize to class */
static void __objc_send_initialize(Class);
@ -76,18 +83,27 @@ __inline__
IMP
__objc_get_forward_imp (SEL sel)
{
const char *t = sel->sel_types;
if (t && (*t == '[' || *t == '(' || *t == '{')
#ifdef OBJC_MAX_STRUCT_BY_VALUE
&& objc_sizeof_type(t) > OBJC_MAX_STRUCT_BY_VALUE
#endif
)
return (IMP)__objc_block_forward;
else if (t && (*t == 'f' || *t == 'd'))
return (IMP)__objc_double_forward;
if (__objc_msg_forward)
{
IMP result;
if ((result = __objc_msg_forward (sel)))
return result;
}
else
return (IMP)__objc_word_forward;
{
const char *t = sel->sel_types;
if (t && (*t == '[' || *t == '(' || *t == '{')
#ifdef OBJC_MAX_STRUCT_BY_VALUE
&& objc_sizeof_type(t) > OBJC_MAX_STRUCT_BY_VALUE
#endif
)
return (IMP)__objc_block_forward;
else if (t && (*t == 'f' || *t == 'd'))
return (IMP)__objc_double_forward;
else
return (IMP)__objc_word_forward;
}
}
/* Given a class and selector, return the selector's implementation. */
@ -581,7 +597,6 @@ __objc_forward (id object, SEL sel, arglist_t args)
/* The object doesn't recognize the method. Check for responding to
error:. If it does then sent it. */
{
size_t strlen (const char*);
char msg[256 + strlen ((const char*)sel_get_name (sel))
+ strlen ((const char*)object->class_pointer->name)];

181
contrib/libobjc/thr-objc.c Normal file
View file

@ -0,0 +1,181 @@
/* GNU Objective C Runtime Thread Interface.
Copyright (C) 1999 Free Software Foundation, Inc.
This file is part of GNU CC.
GNU CC 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.
GNU CC 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 GNU CC; 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. */
#define _LIBOBJC
#include "tconfig.h"
#include "defaults.h"
#include <objc/thr.h>
#include "runtime.h"
#include <gthr.h>
/* Backend initialization functions */
/* Initialize the threads subsystem. */
int
__objc_init_thread_system(void)
{
return __gthread_objc_init_thread_system ();
}
/* Close the threads subsystem. */
int
__objc_close_thread_system(void)
{
return __gthread_objc_close_thread_system ();
}
/* Backend thread functions */
/* Create a new thread of execution. */
objc_thread_t
__objc_thread_detach(void (*func)(void *), void *arg)
{
return __gthread_objc_thread_detach (func, arg);
}
/* Set the current thread's priority. */
int
__objc_thread_set_priority(int priority)
{
return __gthread_objc_thread_set_priority (priority);
}
/* Return the current thread's priority. */
int
__objc_thread_get_priority(void)
{
return __gthread_objc_thread_get_priority ();
}
/* Yield our process time to another thread. */
void
__objc_thread_yield(void)
{
__gthread_objc_thread_yield ();
}
/* Terminate the current thread. */
int
__objc_thread_exit(void)
{
return __gthread_objc_thread_exit ();
}
/* Returns an integer value which uniquely describes a thread. */
objc_thread_t
__objc_thread_id(void)
{
return __gthread_objc_thread_id ();
}
/* Sets the thread's local storage pointer. */
int
__objc_thread_set_data(void *value)
{
return __gthread_objc_thread_set_data (value);
}
/* Returns the thread's local storage pointer. */
void *
__objc_thread_get_data(void)
{
return __gthread_objc_thread_get_data ();
}
/* Backend mutex functions */
/* Allocate a mutex. */
int
__objc_mutex_allocate(objc_mutex_t mutex)
{
return __gthread_objc_mutex_allocate (mutex);
}
/* Deallocate a mutex. */
int
__objc_mutex_deallocate(objc_mutex_t mutex)
{
return __gthread_objc_mutex_deallocate (mutex);
}
/* Grab a lock on a mutex. */
int
__objc_mutex_lock(objc_mutex_t mutex)
{
return __gthread_objc_mutex_lock (mutex);
}
/* Try to grab a lock on a mutex. */
int
__objc_mutex_trylock(objc_mutex_t mutex)
{
return __gthread_objc_mutex_trylock (mutex);
}
/* Unlock the mutex */
int
__objc_mutex_unlock(objc_mutex_t mutex)
{
return __gthread_objc_mutex_unlock (mutex);
}
/* Backend condition mutex functions */
/* Allocate a condition. */
int
__objc_condition_allocate(objc_condition_t condition)
{
return __gthread_objc_condition_allocate (condition);
}
/* Deallocate a condition. */
int
__objc_condition_deallocate(objc_condition_t condition)
{
return __gthread_objc_condition_deallocate (condition);
}
/* Wait on the condition */
int
__objc_condition_wait(objc_condition_t condition, objc_mutex_t mutex)
{
return __gthread_objc_condition_wait (condition, mutex);
}
/* Wake up all threads waiting on this condition. */
int
__objc_condition_broadcast(objc_condition_t condition)
{
return __gthread_objc_condition_broadcast (condition);
}
/* Wake up one thread waiting on this condition. */
int
__objc_condition_signal(objc_condition_t condition)
{
return __gthread_objc_condition_signal (condition);
}
/* End of File */

View file

@ -2,6 +2,7 @@
Copyright (C) 1996, 1997 Free Software Foundation, Inc.
Contributed by Galen C. Hunt (gchunt@cs.rochester.edu)
Modified for Linux/Pthreads by Kai-Uwe Sattler (kus@iti.cs.uni-magdeburg.de)
Modified for posix compliance by Chris Ball (cball@fmco.com)
This file is part of GNU CC.
@ -31,6 +32,7 @@ Boston, MA 02111-1307, USA. */
/* Key structure for maintaining thread specific storage */
static pthread_key_t _objc_thread_storage;
static pthread_attr_t _objc_thread_attribs;
/* Backend initialization functions */
@ -39,14 +41,34 @@ int
__objc_init_thread_system(void)
{
/* Initialize the thread storage key */
return pthread_key_create(&_objc_thread_storage, NULL);
if (pthread_key_create(&_objc_thread_storage, NULL) == 0)
{
/*
* The normal default detach state for threads is PTHREAD_CREATE_JOINABLE
* which causes threads to not die when you think they should.
*/
if (pthread_attr_init(&_objc_thread_attribs) == 0)
{
if (pthread_attr_setdetachstate(&_objc_thread_attribs,
PTHREAD_CREATE_DETACHED) == 0)
return 0;
}
}
return -1;
}
/* Close the threads subsystem. */
int
__objc_close_thread_system(void)
{
return 0;
if (pthread_key_delete(_objc_thread_storage) == 0)
{
if (pthread_attr_destroy(&_objc_thread_attribs) == 0)
return 0;
}
return -1;
}
/* Backend thread functions */
@ -57,20 +79,50 @@ __objc_thread_detach(void (*func)(void *arg), void *arg)
{
objc_thread_t thread_id;
pthread_t new_thread_handle;
if ( !(pthread_create(&new_thread_handle, NULL, (void *)func, arg)) )
thread_id = *(objc_thread_t *)&new_thread_handle;
if (!(pthread_create(&new_thread_handle, &_objc_thread_attribs,
(void *)func, arg)))
thread_id = *(objc_thread_t *)&new_thread_handle;
else
thread_id = NULL;
return thread_id;
}
/* Set the current thread's priority. */
/* Set the current thread's priority.
*
* Be aware that the default schedpolicy often disallows thread priorities.
*/
int
__objc_thread_set_priority(int priority)
{
/* Not implemented yet */
pthread_t thread_id = pthread_self();
int policy;
struct sched_param params;
int priority_min, priority_max;
if (pthread_getschedparam(thread_id, &policy, &params) == 0)
{
if ((priority_max = sched_get_priority_max(policy)) != 0)
return -1;
if ((priority_min = sched_get_priority_min(policy)) != 0)
return -1;
if (priority > priority_max)
priority = priority_max;
else if (priority < priority_min)
priority = priority_min;
params.sched_priority = priority;
/*
* The solaris 7 and several other man pages incorrectly state that
* this should be a pointer to policy but pthread.h is universally
* at odds with this.
*/
if (pthread_setschedparam(thread_id, policy, &params) == 0)
return 0;
}
return -1;
}
@ -78,8 +130,13 @@ __objc_thread_set_priority(int priority)
int
__objc_thread_get_priority(void)
{
/* Not implemented yet */
return -1;
int policy;
struct sched_param params;
if (pthread_getschedparam(pthread_self(), &policy, &params) == 0)
return params.sched_priority;
else
return -1;
}
/* Yield our process time to another thread. */
@ -113,7 +170,10 @@ __objc_thread_id(void)
int
__objc_thread_set_data(void *value)
{
return pthread_setspecific(_objc_thread_storage, value);
if (pthread_setspecific(_objc_thread_storage, value) == 0)
return 0;
else
return -1;
}
/* Returns the thread's local storage pointer. */
@ -145,6 +205,19 @@ __objc_mutex_allocate(objc_mutex_t mutex)
int
__objc_mutex_deallocate(objc_mutex_t mutex)
{
int count = 1;
/*
* Posix Threads specifically require that the thread be unlocked for
* pthread_mutex_destroy to work.
*/
while (count)
{
if ((count = pthread_mutex_unlock((pthread_mutex_t*)mutex->backend)) < 0)
return -1;
}
if (pthread_mutex_destroy((pthread_mutex_t *)mutex->backend))
return -1;
@ -157,21 +230,30 @@ __objc_mutex_deallocate(objc_mutex_t mutex)
int
__objc_mutex_lock(objc_mutex_t mutex)
{
return pthread_mutex_lock((pthread_mutex_t *)mutex->backend);
if (pthread_mutex_lock((pthread_mutex_t *)mutex->backend) == 0)
return 0;
else
return -1;
}
/* Try to grab a lock on a mutex. */
int
__objc_mutex_trylock(objc_mutex_t mutex)
{
return pthread_mutex_trylock((pthread_mutex_t *)mutex->backend);
if (pthread_mutex_trylock((pthread_mutex_t *)mutex->backend) == 0)
return 0;
else
return -1;
}
/* Unlock the mutex */
int
__objc_mutex_unlock(objc_mutex_t mutex)
{
return pthread_mutex_unlock((pthread_mutex_t *)mutex->backend);
if (pthread_mutex_unlock((pthread_mutex_t *)mutex->backend) == 0)
return 0;
else
return -1;
}
/* Backend condition mutex functions */
@ -208,22 +290,29 @@ __objc_condition_deallocate(objc_condition_t condition)
int
__objc_condition_wait(objc_condition_t condition, objc_mutex_t mutex)
{
return pthread_cond_wait((pthread_cond_t *)condition->backend,
(pthread_mutex_t *)mutex->backend);
if (pthread_cond_wait((pthread_cond_t *)condition->backend,
(pthread_mutex_t *)mutex->backend) == 0)
return 0;
else
return -1;
}
/* Wake up all threads waiting on this condition. */
int
__objc_condition_broadcast(objc_condition_t condition)
{
return pthread_cond_broadcast((pthread_cond_t *)condition->backend);
if (pthread_cond_broadcast((pthread_cond_t *)condition->backend) == 0)
return 0;
else
return -1;
}
/* Wake up one thread waiting on this condition. */
int
__objc_condition_signal(objc_condition_t condition)
{
return pthread_cond_signal((pthread_cond_t *)condition->backend);
if (pthread_cond_signal((pthread_cond_t *)condition->backend) == 0)
return 0;
else
return -1;
}
/* End of File */

194
contrib/libobjc/thr-rtems.c Normal file
View file

@ -0,0 +1,194 @@
/* GNU Objective C Runtime Thread Implementation
Copyright (C) 1996, 1997 Free Software Foundation, Inc.
Contributed by Galen C. Hunt (gchunt@cs.rochester.edu)
Renamed from thr-vxworks.c to thr-rtems.c by
Ralf Corsepius (corsepiu@faw.uni-ulm.de)
This file is part of GNU CC.
GNU CC 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.
GNU CC 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
GNU CC; 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. */
#include <objc/thr.h>
#include "runtime.h"
/* Thread local storage for a single thread */
static void *thread_local_storage = NULL;
/* Backend initialization functions */
/* Initialize the threads subsystem. */
int
__objc_init_thread_system(void)
{
/* No thread support available */
return -1;
}
/* Close the threads subsystem. */
int
__objc_close_thread_system(void)
{
/* No thread support available */
return -1;
}
/* Backend thread functions */
/* Create a new thread of execution. */
objc_thread_t
__objc_thread_detach(void (*func)(void *arg), void *arg)
{
/* No thread support available */
return NULL;
}
/* Set the current thread's priority. */
int
__objc_thread_set_priority(int priority)
{
/* No thread support available */
return -1;
}
/* Return the current thread's priority. */
int
__objc_thread_get_priority(void)
{
return OBJC_THREAD_INTERACTIVE_PRIORITY;
}
/* Yield our process time to another thread. */
void
__objc_thread_yield(void)
{
return;
}
/* Terminate the current thread. */
int
__objc_thread_exit(void)
{
/* No thread support available */
/* Should we really exit the program */
/* exit(&__objc_thread_exit_status); */
return -1;
}
/* Returns an integer value which uniquely describes a thread. */
objc_thread_t
__objc_thread_id(void)
{
/* No thread support, use 1. */
return (objc_thread_t)1;
}
/* Sets the thread's local storage pointer. */
int
__objc_thread_set_data(void *value)
{
thread_local_storage = value;
return 0;
}
/* Returns the thread's local storage pointer. */
void *
__objc_thread_get_data(void)
{
return thread_local_storage;
}
/* Backend mutex functions */
/* Allocate a mutex. */
int
__objc_mutex_allocate(objc_mutex_t mutex)
{
return 0;
}
/* Deallocate a mutex. */
int
__objc_mutex_deallocate(objc_mutex_t mutex)
{
return 0;
}
/* Grab a lock on a mutex. */
int
__objc_mutex_lock(objc_mutex_t mutex)
{
/* There can only be one thread, so we always get the lock */
return 0;
}
/* Try to grab a lock on a mutex. */
int
__objc_mutex_trylock(objc_mutex_t mutex)
{
/* There can only be one thread, so we always get the lock */
return 0;
}
/* Unlock the mutex */
int
__objc_mutex_unlock(objc_mutex_t mutex)
{
return 0;
}
/* Backend condition mutex functions */
/* Allocate a condition. */
int
__objc_condition_allocate(objc_condition_t condition)
{
return 0;
}
/* Deallocate a condition. */
int
__objc_condition_deallocate(objc_condition_t condition)
{
return 0;
}
/* Wait on the condition */
int
__objc_condition_wait(objc_condition_t condition, objc_mutex_t mutex)
{
return 0;
}
/* Wake up all threads waiting on this condition. */
int
__objc_condition_broadcast(objc_condition_t condition)
{
return 0;
}
/* Wake up one thread waiting on this condition. */
int
__objc_condition_signal(objc_condition_t condition)
{
return 0;
}
/* End of File */

View file

@ -318,7 +318,7 @@ objc_mutex_lock(objc_mutex_t mutex)
return -1;
/* If we already own the lock then increment depth */
thread_id = objc_thread_id();
thread_id = __objc_thread_id();
if (mutex->owner == thread_id)
return ++mutex->depth;
@ -350,7 +350,7 @@ objc_mutex_trylock(objc_mutex_t mutex)
return -1;
/* If we already own the lock then increment depth */
thread_id = objc_thread_id();
thread_id = __objc_thread_id();
if (mutex->owner == thread_id)
return ++mutex->depth;
@ -385,7 +385,7 @@ objc_mutex_unlock(objc_mutex_t mutex)
return -1;
/* If another thread owns the lock then abort */
thread_id = objc_thread_id();
thread_id = __objc_thread_id();
if (mutex->owner != thread_id)
return -1;
@ -477,7 +477,7 @@ objc_condition_wait(objc_condition_t condition, objc_mutex_t mutex)
return -1;
/* Make sure we are owner of mutex */
thread_id = objc_thread_id();
thread_id = __objc_thread_id();
if (mutex->owner != thread_id)
return -1;
@ -531,4 +531,33 @@ objc_condition_signal(objc_condition_t condition)
return __objc_condition_signal(condition);
}
/* Make the objc thread system aware that a thread which is managed
(started, stopped) by external code could access objc facilities
from now on. This is used when you are interfacing with some
external non-objc-based environment/system - you must call
objc_thread_add() before an alien thread makes any calls to
Objective-C. Do not cause the _objc_became_multi_threaded hook to
be executed. */
void
objc_thread_add(void)
{
objc_mutex_lock(__objc_runtime_mutex);
__objc_is_multi_threaded = 1;
__objc_runtime_threads_alive++;
objc_mutex_unlock(__objc_runtime_mutex);
}
/* Make the objc thread system aware that a thread managed (started,
stopped) by some external code will no longer access objc and thus
can be forgotten by the objc thread system. Call
objc_thread_remove() when your alien thread is done with making
calls to Objective-C. */
void
objc_thread_remove(void)
{
objc_mutex_lock(__objc_runtime_mutex);
__objc_runtime_threads_alive--;
objc_mutex_unlock(__objc_runtime_mutex);
}
/* End of File */