aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Malmberg <alexander@malmberg.org>2004-01-27 22:56:51 +0000
committerAndrew Pinski <pinskia@physics.uc.edu>2004-01-27 22:56:51 +0000
commit52995a18d245893409c812100d7aa39d3971c6da (patch)
treeebef194dfe9b0e6be8547b72f93f79a2374d0b90
parent676c51739a5823facb3846714de43537311128cb (diff)
2004-01-27 Alexander Malmberg <alexander@malmberg.org>
* selector.c: Rename register_selectors_from_list to __objc_register_selectors_from_list. Update caller. (__objc_register_selectors_from_list): Lock __objc_runtime_mutex while registering selectors. Use __sel_register_typed_name instead of sel_register_typed_name. Check for NULL method_name:s. (pool_alloc_selector): New function. (__sel_register_typed_name): Use pool_alloc_selector to allocate selector structures. * sendmsg.c (class_add_method_list): Use __objc_register_selectors_from_list. * objc/runtime.h: Add __objc_register_selectors_from_list. git-svn-id: https://gcc.gnu.org/svn/gcc/branches/libobjc-branch@76763 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--libobjc/ChangeLog.branch14
-rw-r--r--libobjc/objc/runtime.h1
-rw-r--r--libobjc/selector.c59
-rw-r--r--libobjc/sendmsg.c18
4 files changed, 63 insertions, 29 deletions
diff --git a/libobjc/ChangeLog.branch b/libobjc/ChangeLog.branch
index 6ab540517dd..5495b244686 100644
--- a/libobjc/ChangeLog.branch
+++ b/libobjc/ChangeLog.branch
@@ -1,3 +1,17 @@
+2004-01-27 Alexander Malmberg <alexander@malmberg.org>
+
+ * selector.c: Rename register_selectors_from_list to
+ __objc_register_selectors_from_list. Update caller.
+ (__objc_register_selectors_from_list): Lock __objc_runtime_mutex
+ while registering selectors. Use __sel_register_typed_name instead
+ of sel_register_typed_name. Check for NULL method_name:s.
+ (pool_alloc_selector): New function.
+ (__sel_register_typed_name): Use pool_alloc_selector to allocate
+ selector structures.
+ * sendmsg.c (class_add_method_list): Use
+ __objc_register_selectors_from_list.
+ * objc/runtime.h: Add __objc_register_selectors_from_list.
+
2004-01-25 Adam Fedor <fedor@gnu.org>
Nicola Pero <n.pero@mi.flashnet.it>
Andrew Pinski <pinskia@physics.uc.edu>
diff --git a/libobjc/objc/runtime.h b/libobjc/objc/runtime.h
index 72e79be30a7..edf8e5e71c3 100644
--- a/libobjc/objc/runtime.h
+++ b/libobjc/objc/runtime.h
@@ -49,6 +49,7 @@ extern void __objc_init_dispatch_tables(void); /* (objc-dispatch.c) */
extern void __objc_install_premature_dtable(Class); /* (objc-dispatch.c) */
extern void __objc_resolve_class_links(void); /* (objc-class.c) */
extern void __objc_register_selectors_from_class(Class); /* (objc-sel.c) */
+extern void __objc_register_selectors_from_list (MethodList_t); /* (selector.c) */
extern void __objc_update_dispatch_table_for_class (Class);/* (objc-msg.c) */
extern int __objc_init_thread_system(void); /* thread.c */
diff --git a/libobjc/selector.c b/libobjc/selector.c
index 06743b03ff4..ae16efda400 100644
--- a/libobjc/selector.c
+++ b/libobjc/selector.c
@@ -35,8 +35,6 @@ static struct sarray *__objc_selector_array = 0; /* uid -> sel !T:MUTEX */
static struct sarray *__objc_selector_names = 0; /* uid -> name !T:MUTEX */
static cache_ptr __objc_selector_hash = 0; /* name -> uid !T:MUTEX */
-static void register_selectors_from_list (MethodList_t);
-
/* Number of selectors stored in each of the above tables */
unsigned int __objc_selector_max_index = 0; /* !T:MUTEX */
@@ -60,7 +58,7 @@ __objc_register_selectors_from_class (Class class)
method_list = class->methods;
while (method_list)
{
- register_selectors_from_list (method_list);
+ __objc_register_selectors_from_list (method_list);
method_list = method_list->method_next;
}
}
@@ -70,21 +68,27 @@ __objc_register_selectors_from_class (Class class)
the record table. This is the routine that does the actual recording
work.
- This one is only called for Class objects. For categories,
- class_add_method_list is called.
+ The name and type pointers in the method list must be permanent and
+ immutable.
*/
-static void
-register_selectors_from_list (MethodList_t method_list)
+void
+__objc_register_selectors_from_list (MethodList_t method_list)
{
int i = 0;
+
+ objc_mutex_lock (__objc_runtime_mutex);
while (i < method_list->method_count)
{
Method_t method = &method_list->method_list[i];
- method->method_name
- = sel_register_typed_name ((const char *) method->method_name,
- method->method_types);
+ if (method->method_name)
+ {
+ method->method_name
+ = __sel_register_typed_name ((const char *) method->method_name,
+ method->method_types, 0, YES);
+ }
i += 1;
}
+ objc_mutex_unlock (__objc_runtime_mutex);
}
@@ -320,6 +324,35 @@ const char *sel_get_type (SEL selector)
/* The uninstalled dispatch table */
extern struct sarray *__objc_uninstalled_dtable;
+/* __sel_register_typed_name allocates lots of struct objc_selector:s
+ of 8 (16, if pointers are 64 bits) bytes at startup. To reduce the number
+ of malloc calls and memory lost to malloc overhead, we allocate
+ objc_selector:s in blocks here. This is only called from
+ __sel_register_typed_name, and __sel_register_typed_name may only be
+ called when __objc_runtime_mutex is locked.
+
+ Note that the objc_selector:s allocated from __sel_register_typed_name
+ are never freed.
+
+ 62 because 62 * sizeof (struct objc_selector) = 496 (992). This should
+ let malloc add some overhead and use a nice, round 512 (1024) byte chunk.
+ */
+#define SELECTOR_POOL_SIZE 62
+static struct objc_selector *selector_pool;
+static int selector_pool_left;
+
+static struct objc_selector *
+pool_alloc_selector(void)
+{
+ if (!selector_pool_left)
+ {
+ selector_pool = objc_malloc (sizeof (struct objc_selector)
+ * SELECTOR_POOL_SIZE);
+ selector_pool_left = SELECTOR_POOL_SIZE;
+ }
+ return &selector_pool[--selector_pool_left];
+}
+
/* Store the passed selector name in the selector record and return its
selector value (value returned by sel_get_uid).
Assumes that the calling function has locked down __objc_runtime_mutex. */
@@ -369,7 +402,7 @@ __sel_register_typed_name (const char *name, const char *types,
if (orig)
j = orig;
else
- j = objc_malloc (sizeof (struct objc_selector));
+ j = pool_alloc_selector ();
j->sel_id = (void *) i;
/* Can we use the pointer or must copy types? Don't copy if NULL */
@@ -388,7 +421,7 @@ __sel_register_typed_name (const char *name, const char *types,
if (orig)
j = orig;
else
- j = objc_malloc (sizeof (struct objc_selector));
+ j = pool_alloc_selector ();
j->sel_id = (void *) i;
/* Can we use the pointer or must copy types? Don't copy if NULL */
@@ -446,7 +479,7 @@ SEL
sel_register_typed_name (const char *name, const char *type)
{
SEL ret;
-
+
objc_mutex_lock (__objc_runtime_mutex);
/* Assume that name and type are not constant static memory and need to
be copied before put into a runtime structure. is_const == NO */
diff --git a/libobjc/sendmsg.c b/libobjc/sendmsg.c
index f8234b7ba12..9a58ca66806 100644
--- a/libobjc/sendmsg.c
+++ b/libobjc/sendmsg.c
@@ -465,28 +465,14 @@ __objc_update_dispatch_table_for_class (Class class)
This one is only called for categories. Class objects have their
methods installed right away, and their selectors are made into
- SEL's by the function __objc_register_selectors_from_class. */
+ SEL's by the function __objc_register_selectors_from_class. */
void
class_add_method_list (Class class, MethodList_t list)
{
- int i;
-
/* Passing of a linked list is not allowed. Do multiple calls. */
assert (! list->method_next);
- /* Check for duplicates. */
- for (i = 0; i < list->method_count; ++i)
- {
- Method_t method = &list->method_list[i];
-
- if (method->method_name) /* Sometimes these are NULL */
- {
- /* This is where selector names are transmogrified to SEL's */
- method->method_name =
- sel_register_typed_name ((const char *) method->method_name,
- method->method_types);
- }
- }
+ __objc_register_selectors_from_list(list);
/* Add the methods to the class's method list. */
list->method_next = class->methods;