Commit d8bb17c8 by Ovidiu Predescu Committed by Jeff Law

Boehm GC support for ObjC from Ovidiu Predescu.

From-SVN: r22199
parent d636ae0b
Thu Sep 3 00:37:55 1998 Ovidiu Predescu <ovidiu@aracnet.com>
Added support for the Boehm's garbage collector.
* configure.in: Handle --enable-objc-gc.
* configure: Rebuilt.
* Makefile.in (CHECK_TARGETS): Add check-objc.
(check-objc): New rule.
* objc/Make-lang.in: Build a different Objective-C library that
runs with the Boehm's collector.
* objc/encoding.c (objc_round_acc_size_for_types): New function.
* objc/encoding.c: Correctly compute the size of compound types in
the presence of bitfields. Skip the variable name of the type if
any. Added support for long long.
* objc/encoding.h (_C_GCINVISIBLE): New specifier.
(_F_GCINVISIBLE): New mask.
* objc/gc.c: New file. Compute the type memory mask associated with
a class based on the runtime information.
* objc/misc.c: Added the hooks that use the Boehm's collector
allocation functions.
* objc/objc-act.c (build_class_template): Generate a new class
member (gc_object_type) to hold the class' type memory mask.
(build_shared_structure_initializer): Initialize the new member to
NULL.
(encode_complete_bitfield): New function. Generate the new
encoding.
(encode_field_decl): Generate the new encoding only for the GNU
runtime.
* objc/objc-api.h (_C_LNG_LNG, _C_ULNG_LNG): New specifiers for the
long long types.
(class_get_gc_object_type): New function to mark a pointer instance
variable as a weak pointer.
* objc/objc-features.texi: New file.
* objc/objc.h (gc_object_type): New class member.
* objc/objects.c (class_create_instance): Create a typed memory
object when compiled with Boehm's collector support.
* objc/sendmsg.c (__objc_init_install_dtable): Call
__objc_send_initialize instead of setting the initialize flag.
(__objc_send_initialize): Call __objc_generate_gc_type_description
to generate the class type memory mask. Rewrite the code that
sends the +initialize so that it is called only once (bug report
and fix from Ronald Pijnacker <Ronald.Pijnacker@best.ms.philips.com>).
* testsuite/objc: New testsuite for Objective-C type encoding.
* testsuite/lib/objc-torture.exp: New file.
* testsuite/lib/objc.exp: New file.
Wed Sep 2 14:47:36 1998 Jim Wilson <wilson@cygnus.com>
* jump.c (jump_optimize): In if/then/else transformations, add
......
......@@ -246,6 +246,7 @@ lang_specs_files=@lang_specs_files@
lang_options_files=@lang_options_files@
lang_tree_files=@lang_tree_files@
GCC_THREAD_FILE=@thread_file@
OBJC_BOEHM_GC=@objc_boehm_gc@
GTHREAD_FLAGS=@gthread_flags@
# Be prepared for gcc2 merges.
gcc_version=@gcc_version@
......@@ -2574,7 +2575,7 @@ site.exp: ./config.status Makefile
-e '1,/^## All variables above are.*##/ d' >> site.exp
-@rm -f ./tmp?
CHECK_TARGETS = check-gcc check-g++ check-g77
CHECK_TARGETS = check-gcc check-g++ check-g77 check-objc
check: $(CHECK_TARGETS)
......@@ -2617,6 +2618,16 @@ check-g77: testsuite/site.exp
export TCL_LIBRARY ; fi ; \
$(RUNTEST) --tool g77 $(RUNTESTFLAGS)
check-objc: testsuite/site.exp
-rootme=`pwd`; export rootme; \
srcdir=`cd ${srcdir}; pwd` ; export srcdir ; \
cd testsuite; \
EXPECT=${EXPECT} ; export EXPECT ; \
if [ -f $${rootme}/../expect/expect ] ; then \
TCL_LIBRARY=$${srcdir}/../tcl/library ; \
export TCL_LIBRARY ; fi ; \
$(RUNTEST) --tool objc $(RUNTESTFLAGS)
# These exist for maintenance purposes.
# Update the tags table.
......
......@@ -173,6 +173,16 @@ case x${enable_threads_flag} in
;;
esac
AC_ARG_ENABLE(objc-gc,
[ --enable-objc-gc enable the use of Boehm's garbage collector with
the GNU Objective-C runtime.],
if [[[ x$enable_objc_gc = xno ]]]; then
objc_boehm_gc=''
else
objc_boehm_gc=1
fi,
objc_boehm_gc='')
# Determine the host, build, and target systems
AC_CANONICAL_SYSTEM
......@@ -3822,6 +3832,7 @@ AC_SUBST(lang_specs_files)
AC_SUBST(lang_options_files)
AC_SUBST(lang_tree_files)
AC_SUBST(thread_file)
AC_SUBST(objc_boehm_gc)
AC_SUBST(gcc_version)
AC_SUBST(gcc_version_trigger)
AC_SUBST(local_prefix)
......
......@@ -119,6 +119,7 @@ OBJC_O = objc/hash.o objc/sarray.o \
objc/NXConstStr.o objc/Object.o \
objc/Protocol.o objc/nil_method.o \
objc/thr.o objc/linking.o \
objc/gc.o \
objc/$(OBJC_THREAD_FILE).o
objc/hash.o: $(srcdir)/objc/hash.c $(GCC_PASSES)
......@@ -172,11 +173,74 @@ objc/nil_method.o: $(srcdir)/objc/nil_method.c $(GCC_PASSES)
objc/linking.o: $(srcdir)/objc/linking.m $(GCC_PASSES)
$(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) \
-fgnu-runtime -c $(srcdir)/objc/linking.m -o $@
objc/gc.o: $(srcdir)/objc/gc.c $(GCC_PASSES)
$(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) \
-fgnu-runtime -c $(srcdir)/objc/gc.c -o $@
objc/libobjc_entry.o: $(srcdir)/objc/libobjc_entry.c $(GCC_PASSES)
$(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) \
-c $(srcdir)/objc/libobjc_entry.c -o $@
objc/hash_gc.o: $(srcdir)/objc/hash.c $(GCC_PASSES)
$(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) \
-c $(srcdir)/objc/hash.c -o $@
objc/sarray_gc.o: $(srcdir)/objc/sarray.c $(GCC_PASSES)
$(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) \
-c $(srcdir)/objc/sarray.c -o $@
objc/class_gc.o: $(srcdir)/objc/class.c $(GCC_PASSES)
$(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) \
-c $(srcdir)/objc/class.c -o $@
objc/sendmsg_gc.o: $(srcdir)/objc/sendmsg.c $(GCC_PASSES) objc/runtime-info.h
$(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) -Iobjc \
-c $(srcdir)/objc/sendmsg.c -o $@
objc/init_gc.o: $(srcdir)/objc/init.c $(GCC_PASSES)
$(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) \
-c $(srcdir)/objc/init.c -o $@
objc/archive_gc.o: $(srcdir)/objc/archive.c $(GCC_PASSES)
$(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) \
-c $(srcdir)/objc/archive.c -o $@
objc/encoding_gc.o: $(srcdir)/objc/encoding.c $(GCC_PASSES)
$(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) \
-c $(srcdir)/objc/encoding.c -o $@
objc/selector_gc.o: $(srcdir)/objc/selector.c $(GCC_PASSES)
$(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) \
-c $(srcdir)/objc/selector.c -o $@
objc/objects_gc.o: $(srcdir)/objc/objects.c $(GCC_PASSES)
$(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) \
-c $(srcdir)/objc/objects.c -o $@
objc/misc_gc.o: $(srcdir)/objc/misc.c $(GCC_PASSES)
$(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) \
-c $(srcdir)/objc/misc.c -o $@
objc/NXConstStr_gc.o: $(srcdir)/objc/NXConstStr.m $(GCC_PASSES)
$(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) \
-fgnu-runtime -c $(srcdir)/objc/NXConstStr.m -o $@
objc/Object_gc.o: $(srcdir)/objc/Object.m $(GCC_PASSES)
$(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) \
-fgnu-runtime -c $(srcdir)/objc/Object.m -o $@
objc/Protocol_gc.o: $(srcdir)/objc/Protocol.m $(GCC_PASSES)
$(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) \
-fgnu-runtime -c $(srcdir)/objc/Protocol.m -o $@
objc/thr_gc.o: $(srcdir)/objc/thr.h $(srcdir)/objc/thr.c $(GCC_PASSES)
$(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) \
-c $(srcdir)/objc/thr.c -o $@
objc/$(OBJC_THREAD_FILE)_gc.o: $(srcdir)/objc/$(OBJC_THREAD_FILE).c $(GCC_PASSES)
$(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) \
-c $(srcdir)/objc/$(OBJC_THREAD_FILE).c -o $@
objc/nil_method_gc.o: $(srcdir)/objc/nil_method.c $(GCC_PASSES)
$(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) \
-c $(srcdir)/objc/nil_method.c -o $@
objc/linking_gc.o: $(srcdir)/objc/linking.m $(GCC_PASSES)
$(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) \
-fgnu-runtime -c $(srcdir)/objc/linking.m -o $@
objc/gc_gc.o: $(srcdir)/objc/gc.c $(GCC_PASSES)
$(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) \
-fgnu-runtime -c $(srcdir)/objc/gc.c -o $@
objc/libobjc_entry_gc.o: $(srcdir)/objc/libobjc_entry.c $(GCC_PASSES)
$(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) \
-c $(srcdir)/objc/libobjc_entry.c -o $@
$(OBJC_O): $(GCC_PASSES) cc1obj$(exeext)
# Build the Objective C runtime library.
......@@ -185,6 +249,17 @@ libobjc.a: cc1obj$(exeext) specs stmp-int-hdrs libgcc2.ready \
-rm -f libobjc.a
$(AR) $(AR_FLAGS) libobjc.a $(OBJC_O)
-if $(RANLIB_TEST) ; then $(RANLIB) libobjc.a; else true; fi
-if [ "$(OBJC_BOEHM_GC)" != "" ]; then \
make libobjc_gc.a GCC_CFLAGS="$(GCC_CFLAGS) -DOBJC_WITH_GC=1" \
OBJC_O=`echo $(OBJC_O) | sed 's/.o /_gc.o /g'`; \
fi
# Build the garbage collected Objective C runtime library.
libobjc_gc.a: cc1obj specs stmp-int-hdrs libgcc2.ready \
$(USE_COLLECT2) $(EXTRA_PARTS) $(OBJC_O)
-rm -f libobjc_gc.a
$(AR) $(AR_FLAGS) libobjc_gc.a $(OBJC_O)
-if $(RANLIB_TEST) ; then $(RANLIB) libobjc_gc.a; else true; fi
libobjc_s.a: libobjc.a
mv libobjc.a libobjc_s.a
......@@ -236,6 +311,13 @@ objc.install-normal: installdirs
(cd $(libsubdir); $(RANLIB) libobjc.a); else true; fi; \
chmod a-x $(libsubdir)/libobjc.a; \
else true; fi
-if [ -f libobjc_gc.a ] ; then \
rm -f $(libsubdir)/libobjc_gc.a; \
$(INSTALL_DATA) libobjc_gc.a $(libsubdir)/libobjc_gc.a; \
if $(RANLIB_TEST) ; then \
(cd $(libsubdir); $(RANLIB) libobjc_gc.a); else true; fi; \
chmod a-x $(libsubdir)/libobjc_gc.a; \
else true; fi
-if [ -f libobjc_s.a ] ; then \
rm -f $(libsubdir)/libobjc_s.a; \
$(INSTALL_DATA) libobjc_s.a $(libsubdir)/libobjc_s.a; \
......@@ -263,7 +345,7 @@ objc.mostlyclean:
-rm -f tmp-objc-prs.y
-rm -f objc/*$(objext) objc/xforward objc/fflags
-rm -f objc/runtime-info.h
-rm -f libobjc.a libobjc_s.a libobjc.dll
-rm -f libobjc.a libobjc_gc.a libobjc_s.a libobjc.dll
-rm -f libobjc.base libobjc.exp
objc.clean: objc.mostlyclean
-rm -rf objc-headers
......@@ -282,19 +364,19 @@ objc.maintainer-clean:
objc.stage1: stage1-start
-mv objc/*$(objext) stage1/objc
-mv cc1obj$(exeext) stage1
-mv libobjc.a stage1
-mv libobjc.a libobjc_gc.a stage1
objc.stage2: stage2-start
-mv objc/*$(objext) stage2/objc
-mv cc1obj$(exeext) stage2
-mv libobjc.a stage2
-mv libobjc.a libobjc_gc.a stage2
objc.stage3: stage3-start
-mv objc/*$(objext) stage3/objc
-mv cc1obj$(exeext) stage3
-mv libobjc.a stage3
-mv libobjc.a libobjc_gc.a stage3
objc.stage4: stage4-start
-mv objc/*$(objext) stage4/objc
-mv cc1obj$(exeext) stage4
-mv libobjc.a stage4
-mv libobjc.a libobjc_gc.a stage4
#
# Maintenance hooks:
......
......@@ -81,8 +81,23 @@ copy-headers:
Makefile: $(srcdir)/Makefile.in $(srcdir)/../configure
cd ..; $(SHELL) config.status
doc: info dvi html
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
mostlyclean:
-rm -f *.o libobjc.a xforward fflags
-rm -f *.o libobjc* xforward fflags *.aux *.cp *.dvi *.fn *.info \
*.ky *.log *.pg *.toc *.tp *.vr *.html
clean: mostlyclean
distclean: mostlyclean
extraclean: mostlyclean
......
......@@ -32,26 +32,28 @@ Boston, MA 02111-1307, USA. */
#include <ctype.h>
#include "objc/objc-api.h"
#define _C_CONST 'r'
#define _C_IN 'n'
#define _C_INOUT 'N'
#define _C_OUT 'o'
#define _C_BYCOPY 'O'
#define _C_ONEWAY 'V'
#define _F_CONST 0x01
#define _F_IN 0x01
#define _F_OUT 0x02
#define _F_INOUT 0x03
#define _F_BYCOPY 0x04
#define _F_ONEWAY 0x08
#define _C_CONST 'r'
#define _C_IN 'n'
#define _C_INOUT 'N'
#define _C_OUT 'o'
#define _C_BYCOPY 'O'
#define _C_ONEWAY 'V'
#define _C_GCINVISIBLE '!'
#define _F_CONST 0x01
#define _F_IN 0x01
#define _F_OUT 0x02
#define _F_INOUT 0x03
#define _F_BYCOPY 0x04
#define _F_ONEWAY 0x08
#define _F_GCINVISIBLE 0x10
int objc_aligned_size (const char* type);
int objc_sizeof_type (const char* type);
int objc_alignof_type (const char* type);
int objc_aligned_size (const char* type);
int objc_promoted_size (const char* type);
const char* objc_skip_type_qualifiers (const char* type);
const char* objc_skip_typespec (const char* type);
const char* objc_skip_offset (const char* type);
......@@ -72,4 +74,24 @@ char* method_get_nth_argument (struct objc_method* m,
unsigned objc_get_type_qualifiers (const char* type);
struct objc_struct_layout
{
const char *original_type;
const char *type;
const char *prev_type;
unsigned int record_size;
unsigned int record_align;
};
void objc_layout_structure (const char *type,
struct objc_struct_layout *layout);
BOOL objc_layout_structure_next_member (struct objc_struct_layout *layout);
void objc_layout_finish_structure (struct objc_struct_layout *layout,
unsigned int *size,
unsigned int *align);
void objc_layout_structure_get_info (struct objc_struct_layout *layout,
unsigned int *offset,
unsigned int *align,
const char **type);
#endif /* __encoding_INCLUDE_GNU */
This diff is collapsed. Click to expand it.
/* GNU Objective C Runtime Miscellaneous
Copyright (C) 1993, 1994, 1995, 1996, 1997 Free Software Foundation, Inc.
Contrbuted by Kresten Krab Thorup
Contributed by Kresten Krab Thorup
This file is part of GNU CC.
......@@ -144,9 +144,37 @@ objc_free(void *mem)
** Users should call the normal objc routines above for
** memory allocation and disposal within their programs.
*/
#if OBJC_WITH_GC
#include <gc.h>
static void *GC_calloc (size_t nelem, size_t size)
{
void* p = GC_malloc (nelem * size);
if (!p)
objc_error (nil, OBJC_ERR_MEMORY, "Virtual memory exhausted!\n");
memset (p, 0, nelem * size);
return p;
}
static void noFree (void* p) {}
void *(*_objc_malloc)(size_t) = GC_malloc;
void *(*_objc_atomic_malloc)(size_t) = GC_malloc_atomic;
void *(*_objc_valloc)(size_t) = GC_malloc;
void *(*_objc_realloc)(void *, size_t) = GC_realloc;
void *(*_objc_calloc)(size_t, size_t) = GC_calloc;
void (*_objc_free)(void *) = noFree;
#else
void *(*_objc_malloc)(size_t) = malloc;
void *(*_objc_atomic_malloc)(size_t) = malloc;
void *(*_objc_valloc)(size_t) = malloc;
void *(*_objc_realloc)(void *, size_t) = realloc;
void *(*_objc_calloc)(size_t, size_t) = calloc;
void (*_objc_free)(void *) = free;
#endif
......@@ -3380,6 +3380,7 @@ build_selector_template ()
struct objc_class *sibling_class;
}
struct objc_protocol_list *protocols;
void *gc_object_type;
}; */
static void
......@@ -3515,6 +3516,21 @@ build_class_template ()
decl_specs, NULL_TREE);
chainon (field_decl_chain, field_decl);
/* void *sel_id; */
decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_VOID]);
field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sel_id"));
field_decl
= grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
chainon (field_decl_chain, field_decl);
/* void *gc_object_type; */
decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_VOID]);
field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("gc_object_type"));
field_decl
= grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
chainon (field_decl_chain, field_decl);
finish_struct (objc_class_template, field_decl_chain, NULL_TREE);
}
......@@ -4287,6 +4303,7 @@ build_category_initializer (type, cat_name, class_name,
struct objc_class *sibling_class;
}
struct objc_protocol_list *protocols;
void *gc_object_type;
}; */
static tree
......@@ -4377,6 +4394,9 @@ build_shared_structure_initializer (type, isa, super, name, size, status,
initlist = tree_cons (NULL_TREE, expr, initlist);
}
/* gc_object_type = NULL */
initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
return build_constructor (type, nreverse (initlist));
}
......@@ -6819,6 +6839,62 @@ encode_type (type, curtype, format)
}
static void
encode_complete_bitfield (int position, tree type, int size)
{
enum tree_code code = TREE_CODE (type);
char buffer[40];
char charType = '?';
if (code == INTEGER_TYPE)
{
if (TREE_INT_CST_LOW (TYPE_MIN_VALUE (type)) == 0
&& TREE_INT_CST_HIGH (TYPE_MIN_VALUE (type)) == 0)
{
/* Unsigned integer types. */
if (TYPE_MODE (type) == QImode)
charType = 'C';
else if (TYPE_MODE (type) == HImode)
charType = 'S';
else if (TYPE_MODE (type) == SImode)
{
if (type == long_unsigned_type_node)
charType = 'L';
else
charType = 'I';
}
else if (TYPE_MODE (type) == DImode)
charType = 'Q';
}
else
/* Signed integer types. */
{
if (TYPE_MODE (type) == QImode)
charType = 'c';
else if (TYPE_MODE (type) == HImode)
charType = 's';
else if (TYPE_MODE (type) == SImode)
{
if (type == long_integer_type_node)
charType = 'l';
else
charType = 'i';
}
else if (TYPE_MODE (type) == DImode)
charType = 'q';
}
}
else
abort ();
sprintf (buffer, "b%d%c%d", position, charType, size);
obstack_grow (&util_obstack, buffer, strlen (buffer));
}
static void
encode_field_decl (field_decl, curtype, format)
tree field_decl;
int curtype;
......@@ -6826,18 +6902,36 @@ encode_field_decl (field_decl, curtype, format)
{
tree type;
/* If this field is obviously a bitfield, or is a bitfield that has been
type = TREE_TYPE (field_decl);
/* If this field is obviously a bitfield, or is a bitfield that has been
clobbered to look like a ordinary integer mode, go ahead and generate
the bitfield typing information. */
type = TREE_TYPE (field_decl);
if (DECL_BIT_FIELD (field_decl))
encode_bitfield (DECL_FIELD_SIZE (field_decl), format);
else if (TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST
&& DECL_FIELD_SIZE (field_decl)
&& TYPE_MODE (type) > DECL_MODE (field_decl))
encode_bitfield (DECL_FIELD_SIZE (field_decl), format);
if (flag_next_runtime)
{
if (DECL_BIT_FIELD (field_decl))
encode_bitfield (DECL_FIELD_SIZE (field_decl), format);
else if (TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST
&& DECL_FIELD_SIZE (field_decl)
&& TYPE_MODE (type) > DECL_MODE (field_decl))
encode_bitfield (DECL_FIELD_SIZE (field_decl), format);
else
encode_type (TREE_TYPE (field_decl), curtype, format);
}
else
encode_type (TREE_TYPE (field_decl), curtype, format);
{
if (DECL_BIT_FIELD (field_decl)
|| (TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST
&& DECL_FIELD_SIZE (field_decl)
&& TYPE_MODE (type) > DECL_MODE (field_decl)))
{
encode_complete_bitfield (TREE_INT_CST_LOW (DECL_FIELD_BITPOS (field_decl)),
DECL_BIT_FIELD_TYPE (field_decl),
DECL_FIELD_SIZE (field_decl));
}
else
encode_type (TREE_TYPE (field_decl), curtype, format);
}
}
static tree
......
......@@ -59,6 +59,8 @@ struct objc_method_description
#define _C_UINT 'I'
#define _C_LNG 'l'
#define _C_ULNG 'L'
#define _C_LNG_LNG 'q'
#define _C_ULNG_LNG 'Q'
#define _C_FLT 'f'
#define _C_DBL 'd'
#define _C_BFLD 'b'
......@@ -495,6 +497,17 @@ class_set_version(Class class, long version)
class->version = version;
}
static inline void *
class_get_gc_object_type (Class class)
{
return CLS_ISCLASS(class) ? class->gc_object_type : NULL;
}
/* Mark the instance variable as innaccessible to the garbage collector */
extern void class_ivar_set_gcinvisible (Class class,
const char* ivarname,
BOOL gcInvisible);
static inline IMP
method_get_imp(Method_t method)
{
......
......@@ -126,6 +126,7 @@ struct objc_class {
struct objc_class* sibling_class;
struct objc_protocol_list *protocols; /* Protocols conformed to */
void* gc_object_type;
};
#ifndef __OBJC__
......
......@@ -25,8 +25,13 @@ Boston, MA 02111-1307, USA. */
covered by the GNU General Public License. */
#include "../tconfig.h" /* include defs of bzero for target */
#include "objc.h"
#include "runtime.h" /* the kitchen sink */
#if OBJC_WITH_GC
# include <gc.h>
#endif
id __objc_object_alloc(Class);
id __objc_object_dispose(id);
id __objc_object_copy(id);
......@@ -39,8 +44,16 @@ id
class_create_instance(Class class)
{
id new = nil;
#if OBJC_WITH_GC
if (CLS_ISCLASS(class))
new = (id)GC_malloc_explicitly_typed (class->instance_size,
class->gc_object_type);
#else
if (CLS_ISCLASS(class))
new = (*_objc_object_alloc)(class);
#endif
if (new!=nil)
{
memset (new, 0, class->instance_size);
......
......@@ -244,10 +244,7 @@ __objc_init_install_dtable(id receiver, SEL op)
/* Install real dtable for factory methods */
__objc_install_dispatch_table_for_class (receiver->class_pointer);
if (strcmp (sel_get_name (op), "initialize"))
__objc_send_initialize((Class)receiver);
else
CLS_SETINITIALIZED((Class)receiver);
__objc_send_initialize((Class)receiver);
}
objc_mutex_unlock(__objc_runtime_mutex);
}
......@@ -273,36 +270,36 @@ __objc_send_initialize(Class class)
{
CLS_SETINITIALIZED(class);
CLS_SETINITIALIZED(class->class_pointer);
/* Create the garbage collector type memory description */
__objc_generate_gc_type_description (class);
if(class->super_class)
__objc_send_initialize(class->super_class);
{
SEL op = sel_register_name ("initialize");
Class tmpclass = class;
IMP imp = 0;
while (!imp && tmpclass) {
MethodList_t method_list = tmpclass->class_pointer->methods;
while(!imp && method_list) {
int i;
Method_t method;
for (i=0;i<method_list->method_count;i++) {
method = &(method_list->method_list[i]);
if (method->method_name
&& method->method_name->sel_id == op->sel_id) {
imp = method->method_imp;
break;
}
}
SEL op = sel_register_name ("initialize");
IMP imp = 0;
MethodList_t method_list = class->class_pointer->methods;
while (method_list) {
int i;
Method_t method;
for (i = 0; i< method_list->method_count; i++) {
method = &(method_list->method_list[i]);
if (method->method_name
&& method->method_name->sel_id == op->sel_id) {
imp = method->method_imp;
break;
}
}
method_list = method_list->method_next;
if (imp)
break;
}
method_list = method_list->method_next;
tmpclass = tmpclass->super_class;
}
if (imp)
(*imp)((id)class, op);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment