Commit 991d3e71 by Kresten Krab Thorup

Headerfiles reorganized

From-SVN: r4329
parent 84db222a
......@@ -61,11 +61,12 @@ libobjc.a: $(OBJC_O)
# ranlib is run in the parent directory's makefile.
OBJC_H = hash.h list.h sarray.h objc.h \
objc-api.h cache.h \
Object.h Protocol.h mutex.h
objc-api.h \
Object.h Protocol.h mutex.h \
typedstream.h
# copy objc headers to installation include directory
copy-headers: $(OBJC_H)
copy-headers:
-rm -fr $(incinstalldir)/objc
-mkdir $(incinstalldir)/objc
for file in $(OBJC_H); do \
......
......@@ -26,35 +26,8 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#ifndef __object_INCLUDE_GNU
#define __object_INCLUDE_GNU
#ifndef __objc_INCLUDE_GNU
/* This is the minimal set of definitions, which may be sufficient
for simple programs not interacting heavily with the runtime */
typedef char BOOL;
#define YES (BOOL)1
#define NO (BOOL)0
typedef void* SEL;
typedef struct objc_object {
struct objc_class* class_pointer;
} *id;
typedef id (*IMP)(id, SEL, ...);
typedef struct objc_class Class;
typedef struct objc_class MetaClass;
#define nil (id)0 /* id of Nil instance */
#define Nil (Class*)0 /* id of Nil class */
typedef char *STR; /* String alias */
@class Protocol;
typedef struct objc_typed_stream TypedStream;
typedef void* arglist_t;
#endif /* not __objc_INCLUDE_GNU */
#include <objc/objc.h>
#include <objc/typedstream.h>
/*
* All classes are derived from Object. As such,
......
......@@ -197,6 +197,9 @@ extern int errno;
}
}
if ([self superClass])
return [[self superClass] conformsTo: aProtocol];
else
return NO;
}
......
......@@ -31,6 +31,7 @@ You should have received a copy of the GNU General Public License along with
#ifndef __alpha__
#include "runtime.h"
#include "typedstream.h"
#define __objc_fatal(format, args...) \
{ fprintf(stderr, "archining: "); \
......@@ -606,7 +607,7 @@ objc_read_string (struct objc_typed_stream* stream,
case _B_SSTR:
{
int length = buf[0]&_B_VALUE;
(*string) = (char*)malloc(length+1);
(*string) = (char*)__objc_xmalloc(length+1);
if (key)
hash_add (&stream->stream_table, (void*)key, *string);
len = (*stream->read)(stream->physical, *string, length);
......@@ -626,7 +627,7 @@ objc_read_string (struct objc_typed_stream* stream,
unsigned int nbytes = buf[0]&_B_VALUE;
len = __objc_read_nbyte_uint(stream, nbytes, &nbytes);
if (len) {
(*string) = (char*)malloc(nbytes);
(*string) = (char*)__objc_xmalloc(nbytes);
if (key)
hash_add (&stream->stream_table, (void*)key, *string);
len = (*stream->read)(stream->physical, *string, buf[0]&_B_VALUE);
......@@ -1377,7 +1378,7 @@ objc_open_typed_stream (FILE* physical, int mode)
{
int fflush(FILE*);
TypedStream* s = (TypedStream*)malloc(sizeof(TypedStream));
TypedStream* s = (TypedStream*)__objc_xmalloc(sizeof(TypedStream));
s->mode = mode;
s->physical = physical;
......
......@@ -253,11 +253,7 @@ class_pose_as (Class* impostor, Class* super_class)
new_class->instance_size = super_class->instance_size;
new_class->ivars = super_class->ivars;
new_class->methods = impostor->methods;
#ifdef OBJC_SPARSE_LOOKUP
new_class->dtable = impostor->dtable;
#else
new_class->cache = impostor->cache;
#endif
/* Create the impostor meta class. */
new_meta_class->class_pointer = super_class->class_pointer->class_pointer;
......@@ -268,11 +264,7 @@ class_pose_as (Class* impostor, Class* super_class)
new_meta_class->instance_size = super_class->class_pointer->instance_size;
new_meta_class->ivars = super_class->class_pointer->ivars;
new_meta_class->methods = impostor->class_pointer->methods;
#ifdef OBJC_SPARSE_LOOKUP
new_meta_class->dtable = impostor->class_pointer->dtable;
#else
new_meta_class->cache = impostor->class_pointer->cache;
#endif
/* Now change super/subclass links of all related classes. This is rather
complex, since we have both super_class link, and subclass_list for the
......@@ -356,21 +348,3 @@ class_pose_as (Class* impostor, Class* super_class)
return new_class;
}
#ifdef OBJC_HASH_LOOKUP
__objc_class_hash_tables_size ()
{
node_ptr node;
Class* class1;
int total = 0;
for (node = hash_next (__objc_class_hash, NULL); node;
node = hash_next (__objc_class_hash, node))
{
Class* class1 = node->value;
total += (class1->cache->mask)*sizeof(struct objc_bucket);
total += sizeof(struct objc_cache);
}
return total;
}
#endif
......@@ -27,11 +27,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#ifndef __hash_INCLUDE_GNU
#define __hash_INCLUDE_GNU
#ifdef IN_GCC
#include "gstddef.h"
#else
#include <stddef.h>
#endif
/*
* This data structure is used to hold items
......
......@@ -29,9 +29,6 @@ You should have received a copy of the GNU General Public License along with
void objc_error(id object, const char* fmt, va_list);
void (*_objc_error)(id, const char*, va_list) = objc_error;
/* id (*_objc_object_alloc)(Class*) = 0; */
/* id (*_objc_object_dispose)(id) = 0; */
/* id (*_objc_object_copy)(id) = 0; */
void
objc_error(id object, const char* fmt, va_list ap)
......
......@@ -37,21 +37,34 @@ id (*_objc_object_copy)(id) = __objc_object_copy;
id
class_create_instance(Class* class)
{
id res = (*_objc_object_alloc)(class);
res->class_pointer = class;
return res;
id new = nil;
if (CLS_ISCLASS(class))
new = (*_objc_object_alloc)(class);
if (new!=nil)
new->class_pointer = class;
return new;
}
id
object_copy(id object)
{
if ((object!=nil)&&CLS_ISCLASS(object->class_pointer))
return (*_objc_object_copy)(object);
else
return nil;
}
id
object_dispose(id object)
{
return (*_objc_object_dispose)(object);
if ((object!=nil)&&CLS_ISCLASS(object->class_pointer))
{
if (_objc_object_dispose)
(*_objc_object_dispose)(object);
else
free(object);
}
return nil;
}
id __objc_object_alloc(Class* class)
......
......@@ -28,11 +28,10 @@ You should have received a copy of the GNU General Public License along with
#define __objc_runtime_INCLUDE_GNU
#include <stdio.h>
#include <memory.h>
#include <ctype.h>
#include "gstdarg.h" /* for varargs and va_list's */
#include "gstddef.h" /* so noone else will get system versions */
#include "stdarg.h" /* for varargs and va_list's */
#include "stddef.h" /* so noone else will get system versions */
#include "assert.h"
#include "objc/objc.h" /* core data types */
......
......@@ -26,7 +26,6 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#include "objc/sarray.h"
#include <stdio.h>
#include "assert.h"
#include <memory.h>
int nbuckets = 0;
int nindices = 0;
......
......@@ -39,11 +39,7 @@ extern const char* __objc_sparse2_id;
extern const char* __objc_sparse3_id;
#endif
#ifdef IN_GCC
#include "gstddef.h"
#else
#include <stddef.h>
#endif
extern int nbuckets; /* for stats */
extern int nindices;
......
......@@ -109,10 +109,8 @@ sel_is_mapped (SEL selector)
return ((idx > 0) && (idx <= __objc_selector_max_index));
}
#ifdef OBJC_SPARSE_LOOKUP
/* The uninstalled dispatch table */
extern struct sarray* __objc_uninstalled_dtable;
#endif
/* Store the passed selector name in the selector record and return its
selector value (value returned by sel_get_uid). */
......@@ -134,9 +132,7 @@ sel_register_name (const char *sel)
sarray_at_put_safe (__objc_selector_array, i, (void *) sel);
hash_add (&__objc_selector_hash, (void *) sel, (void *) i);
#ifdef OBJC_SPARSE_LOOKUP
sarray_realloc(__objc_uninstalled_dtable, __objc_selector_max_index+1);
#endif
return (SEL) i;
}
......
......@@ -25,23 +25,10 @@ You should have received a copy of the GNU General Public License along with
covered by the GNU General Public License. */
#include "runtime.h"
#include "sarray.h"
#ifdef OBJC_SPARSE_LOOKUP
const char* __objc_sparse_lookup_id = "Method lookup uses sparse arrays";
#endif
#ifdef OBJC_HASH_LOOKUP
const char* __objc_hash_lookup_id = "Method lookup uses hash caching";
#endif
#ifdef OBJC_HASH_LOOKUP
#include "objc/cache.h"
#endif
#ifdef OBJC_SPARSE_LOOKUP
/* The uninstalled dispatch table */
struct sarray* __objc_uninstalled_dtable = 0;
#endif
/* Send +initialize to class */
static void __objc_send_initialize(Class*);
......@@ -49,9 +36,7 @@ static void __objc_send_initialize(Class*);
static void __objc_install_dispatch_table_for_class (Class*);
/* Forward declare some functions */
#ifdef OBJC_SPARSE_LOOKUP
static void __objc_init_install_dtable(id, SEL);
#endif
static id __objc_missing_method(id, SEL, ...);
static Method_t search_for_method_in_hierarchy (Class* class, SEL sel);
static Method_t search_for_method_in_list(MethodList_t list, SEL op);
......@@ -67,14 +52,10 @@ nil_method(id receiver, SEL op, ...)
__inline__ IMP
get_imp (Class* class, SEL sel)
{
#ifdef OBJC_SPARSE_LOOKUP
void* res = sarray_get (class->dtable, (size_t) sel);
if(res == __objc_init_install_dtable)
__objc_install_dispatch_table_for_class (class);
return sarray_get (class->dtable, (size_t) sel);
#else
return cache_get (class, sel);
#endif
}
__inline__ BOOL
......@@ -91,11 +72,7 @@ __inline__ IMP
objc_msg_lookup(id receiver, SEL op)
{
if(receiver)
#ifdef OBJC_HASH_LOOKUP
return cache_get(receiver->class_pointer, op);
#else
return sarray_get(receiver->class_pointer->dtable, (sidx)op);
#endif
else
return nil_method;
}
......@@ -127,13 +104,10 @@ objc_msg_sendv(id object, SEL op, size_t frame_size, arglist_t arg_frame)
void __objc_init_dispatch_tables()
{
#ifdef OBJC_SPARSE_LOOKUP
__objc_uninstalled_dtable
= sarray_new(200, __objc_init_install_dtable);
#endif
}
#ifdef OBJC_SPARSE_LOOKUP
/* This one is a bit hairy. This function is installed in the
premature dispatch table, and thus called once for each class,
namely when the very first message is send to it. */
......@@ -187,18 +161,13 @@ allready_initialized:
__builtin_return (result);
}
#endif
/* Install dummy table for class which causes the first message to
that class (or instances hereof) to be initialized properly */
void __objc_install_premature_dtable(Class* class)
{
#ifdef OBJC_SPARSE_LOOKUP
assert(__objc_uninstalled_dtable);
class->dtable = __objc_uninstalled_dtable;
#else
class->cache = (Cache_t)__objc_xcalloc(1, sizeof(Cache));
#endif
}
/* Send +initialize to class if not already done */
......@@ -231,7 +200,6 @@ static void __objc_send_initialize(Class* class)
static void
__objc_install_dispatch_table_for_class (Class* class)
{
#ifdef OBJC_SPARSE_LOOKUP
Class* super;
MethodList_t mlist;
int counter;
......@@ -267,37 +235,21 @@ __objc_install_dispatch_table_for_class (Class* class)
counter -= 1;
}
}
#endif
}
void __objc_update_dispatch_table_for_class (Class* class)
{
Class* next;
#ifdef OBJC_SPARSE_LOOKUP
struct sarray* save;
#else
Cache_t save;
#endif
/* not yet installed -- skip it */
#ifdef OBJC_SPARSE_LOOKUP
if (class->dtable == __objc_uninstalled_dtable)
#else
if (class->cache->mask == 0)
#endif
return;
#ifdef OBJC_SPARSE_LOOKUP
save = class->dtable;
__objc_install_premature_dtable (class);
sarray_free (save);
#else
save = class->cache;
__objc_install_premature_dtable (class);
free(save);
#endif
if (class->subclass_list) /* Traverse subclasses */
for (next = class->subclass_list; next; next = next->sibling_class)
......@@ -474,108 +426,24 @@ void __objc_print_dtable_stats()
{
int total = 0;
printf("memory usage: (%s)\n",
#ifdef OBJC_SPARSE_LOOKUP
#ifdef OBJC_SPARSE2
"2-level sparse arrays"
#else
"3-level sparse arrays"
#endif
#else
"hash-cache"
#endif
);
#ifdef OBJC_SPARSE_LOOKUP
printf("arrays: %d = %d bytes\n", narrays, narrays*sizeof(struct sarray));
total += narrays*sizeof(struct sarray);
#ifdef OBJC_SPARSE3
printf("indices: %d = %d bytes\n", nindices, nindices*sizeof(struct sindex));
total += nindices*sizeof(struct sindex);
#endif
printf("buckets: %d = %d bytes\n", nbuckets, nbuckets*sizeof(struct sbucket));
total += nbuckets*sizeof(struct sbucket);
printf("idxtables: %d = %d bytes\n", idxsize, idxsize*sizeof(void*));
total += idxsize*sizeof(void*);
#else /* HASH_LOOKUP */
total = __objc_class_hash_tables_size ();
#endif
printf("-----------------------------------\n");
printf("total: %d bytes\n", total);
printf("===================================\n");
}
#ifdef OBJC_HASH_LOOKUP
static Cache_t __objc_cache_insert(Cache_t cache, SEL op, IMP imp);
static Cache_t
__objc_double_cache(Cache_t cache)
{
int i;
Cache_t newc = (Cache_t)__objc_xcalloc(1, sizeof(Cache)
+(sizeof(Cache)*2*(cache->mask+1)));
newc->occupied = cache->occupied;
newc->mask = ((cache->mask)<<1) | 1;
for(i=0; i <= cache->mask; i++)
newc = __objc_cache_insert(newc,
cache->buckets[i].method_selector,
cache->buckets[i].method_imp);
free(cache);
return newc;
}
static Cache_t
__objc_cache_insert(Cache_t cache, SEL op, IMP imp)
{
int index = ((size_t)op)&(cache)->mask;
if(op == 0)
return cache;
do
{
if((cache)->buckets[index].method_selector == 0)
{
(cache)->buckets[index].method_selector = op;
(cache)->buckets[index].method_imp = imp;
(cache)->occupied += 1;
return cache;
}
}
while (--index >= 0);
cache = __objc_double_cache(cache);
return __objc_cache_insert(cache, op, imp);
}
void*
__objc_cache_miss(Class* class, SEL op)
{
Method_t m;
Cache_t cache = class->cache;
if(!CLS_ISRESOLV(class))
__objc_resolve_class_links();
m = search_for_method_in_hierarchy(class, op);
if(!CLS_ISINITIALIZED(class))
if(CLS_ISMETA(class))
__objc_send_initialize(objc_get_class(class->name));
else
__objc_send_initialize(class);
if(m == NULL)
return __objc_missing_method;
if((cache->occupied+2)*2 > cache->mask)
class->cache = __objc_double_cache(cache);
class->cache = __objc_cache_insert(class->cache, op, m->method_imp);
return m->method_imp;
}
#endif
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