mirror of git://gcc.gnu.org/git/gcc.git
In libobjc/: 2010-12-21 Nicola Pero <nicola.pero@meta-innovation.com>
In libobjc/: 2010-12-21 Nicola Pero <nicola.pero@meta-innovation.com> PR libobjc/45953 * selector.c (__sel_register_typed_name): When registering a new selector with the same name as an existing one, reuse the existing name string. Also updated types, casts and comments in the whole function. In gcc/testsuite/: 2010-12-21 Nicola Pero <nicola.pero@meta-innovation.com> PR libobjc/45953 * objc.dg/libobjc-selector-1.m: New test. From-SVN: r168115
This commit is contained in:
parent
cb227aa9ab
commit
c75534d1e6
|
@ -1,3 +1,8 @@
|
||||||
|
2010-12-21 Nicola Pero <nicola.pero@meta-innovation.com>
|
||||||
|
|
||||||
|
PR libobjc/45953
|
||||||
|
* objc.dg/libobjc-selector-1.m: New test.
|
||||||
|
|
||||||
2010-12-21 Jakub Jelinek <jakub@redhat.com>
|
2010-12-21 Jakub Jelinek <jakub@redhat.com>
|
||||||
|
|
||||||
PR middle-end/45852
|
PR middle-end/45852
|
||||||
|
|
|
@ -0,0 +1,39 @@
|
||||||
|
/* Test a little inefficiency that was fixed in libobjc when dealing
|
||||||
|
with selectors (PR libobjc/45953). */
|
||||||
|
|
||||||
|
/* { dg-do run } */
|
||||||
|
/* { dg-skip-if "" { *-*-* } { "-fnext-runtime" } { "" } } */
|
||||||
|
|
||||||
|
/* To get the modern GNU Objective-C Runtime API, you include
|
||||||
|
objc/runtime.h. */
|
||||||
|
#include <objc/runtime.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
/* Test that registering a new selector, with the same name but a
|
||||||
|
different type than the previous one, does not change the original
|
||||||
|
name string. It is actually fine to change it (there is no
|
||||||
|
guarantee that it won't change), except for runtime performance /
|
||||||
|
memory consumption, since changing it means that the runtime is
|
||||||
|
doing an unneeded objc_malloc()/strcpy(), which is inefficient. */
|
||||||
|
|
||||||
|
int main (void)
|
||||||
|
{
|
||||||
|
SEL selector_1;
|
||||||
|
SEL selector_2;
|
||||||
|
const char *name_1;
|
||||||
|
const char *name_2;
|
||||||
|
|
||||||
|
/* These method type strings may well be invalid. Please don't use
|
||||||
|
them as examples. They are irrelevant for this test; any string
|
||||||
|
will do. */
|
||||||
|
selector_1 = sel_registerTypedName ("method", "v@:");
|
||||||
|
name_1 = sel_getName (selector_1);
|
||||||
|
|
||||||
|
selector_2 = sel_registerTypedName ("method", "i@:");
|
||||||
|
name_2 = sel_getName (selector_1);
|
||||||
|
|
||||||
|
if (name_1 != name_2)
|
||||||
|
abort ();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -1,3 +1,11 @@
|
||||||
|
2010-12-21 Nicola Pero <nicola.pero@meta-innovation.com>
|
||||||
|
|
||||||
|
PR libobjc/45953
|
||||||
|
* selector.c (__sel_register_typed_name): When registering a new
|
||||||
|
selector with the same name as an existing one, reuse the existing
|
||||||
|
name string. Also updated types, casts and comments in the whole
|
||||||
|
function.
|
||||||
|
|
||||||
2010-12-21 Nicola Pero <nicola.pero@meta-innovation.com>
|
2010-12-21 Nicola Pero <nicola.pero@meta-innovation.com>
|
||||||
|
|
||||||
* objc-private/module-abi-8.h (struct objc_symtab): Declare 'refs'
|
* objc-private/module-abi-8.h (struct objc_symtab): Declare 'refs'
|
||||||
|
|
|
@ -451,17 +451,19 @@ __sel_register_typed_name (const char *name, const char *types,
|
||||||
i = (sidx) objc_hash_value_for_key (__objc_selector_hash, name);
|
i = (sidx) objc_hash_value_for_key (__objc_selector_hash, name);
|
||||||
if (soffset_decode (i) != 0)
|
if (soffset_decode (i) != 0)
|
||||||
{
|
{
|
||||||
for (l = (struct objc_list *) sarray_get_safe (__objc_selector_array, i);
|
/* There are already selectors with that name. Examine them to
|
||||||
|
see if the one we're registering already exists. */
|
||||||
|
for (l = (struct objc_list *)sarray_get_safe (__objc_selector_array, i);
|
||||||
l; l = l->tail)
|
l; l = l->tail)
|
||||||
{
|
{
|
||||||
SEL s = (SEL) l->head;
|
SEL s = (SEL)l->head;
|
||||||
if (types == 0 || s->sel_types == 0)
|
if (types == 0 || s->sel_types == 0)
|
||||||
{
|
{
|
||||||
if (s->sel_types == types)
|
if (s->sel_types == types)
|
||||||
{
|
{
|
||||||
if (orig)
|
if (orig)
|
||||||
{
|
{
|
||||||
orig->sel_id = (void *) i;
|
orig->sel_id = (void *)i;
|
||||||
return orig;
|
return orig;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -472,79 +474,93 @@ __sel_register_typed_name (const char *name, const char *types,
|
||||||
{
|
{
|
||||||
if (orig)
|
if (orig)
|
||||||
{
|
{
|
||||||
orig->sel_id = (void *) i;
|
orig->sel_id = (void *)i;
|
||||||
return orig;
|
return orig;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/* A selector with this specific name/type combination does not
|
||||||
|
exist yet. We need to register it. */
|
||||||
if (orig)
|
if (orig)
|
||||||
j = orig;
|
j = orig;
|
||||||
else
|
else
|
||||||
j = pool_alloc_selector ();
|
j = pool_alloc_selector ();
|
||||||
|
|
||||||
j->sel_id = (void *) i;
|
j->sel_id = (void *)i;
|
||||||
/* Can we use the pointer or must copy types? Don't copy if
|
/* Can we use the pointer or must we copy types ? Don't copy if
|
||||||
NULL. */
|
NULL. */
|
||||||
if ((is_const) || (types == 0))
|
if ((is_const) || (types == 0))
|
||||||
j->sel_types = (const char *) types;
|
j->sel_types = types;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
j->sel_types = (char *) objc_malloc (strlen (types) + 1);
|
j->sel_types = (char *)objc_malloc (strlen (types) + 1);
|
||||||
strcpy ((char *) j->sel_types, types);
|
strcpy ((char *)j->sel_types, types);
|
||||||
}
|
}
|
||||||
l = (struct objc_list *) sarray_get_safe (__objc_selector_array, i);
|
l = (struct objc_list *)sarray_get_safe (__objc_selector_array, i);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
/* There are no other selectors with this name registered in the
|
||||||
|
runtime tables. */
|
||||||
|
const char *new_name;
|
||||||
|
|
||||||
|
/* Determine i. */
|
||||||
__objc_selector_max_index += 1;
|
__objc_selector_max_index += 1;
|
||||||
i = soffset_encode (__objc_selector_max_index);
|
i = soffset_encode (__objc_selector_max_index);
|
||||||
|
|
||||||
|
/* Prepare the selector. */
|
||||||
if (orig)
|
if (orig)
|
||||||
j = orig;
|
j = orig;
|
||||||
else
|
else
|
||||||
j = pool_alloc_selector ();
|
j = pool_alloc_selector ();
|
||||||
|
|
||||||
j->sel_id = (void *) i;
|
j->sel_id = (void *)i;
|
||||||
/* Can we use the pointer or must copy types? Don't copy if
|
/* Can we use the pointer or must we copy types ? Don't copy if
|
||||||
NULL. */
|
NULL. */
|
||||||
if ((is_const) || (types == 0))
|
if (is_const || (types == 0))
|
||||||
j->sel_types = (const char *) types;
|
j->sel_types = types;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
j->sel_types = (char *) objc_malloc (strlen (types) + 1);
|
j->sel_types = (char *)objc_malloc (strlen (types) + 1);
|
||||||
strcpy ((char *) j->sel_types, types);
|
strcpy ((char *)j->sel_types, types);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Since this is the first selector with this name, we need to
|
||||||
|
register the correspondence between 'i' (the sel_id) and
|
||||||
|
'name' (the actual string) in __objc_selector_names and
|
||||||
|
__objc_selector_hash. */
|
||||||
|
|
||||||
|
/* Can we use the pointer or must we copy name ? Don't copy if
|
||||||
|
NULL. (FIXME: Can the name really be NULL here ?) */
|
||||||
|
if (is_const || (name == 0))
|
||||||
|
new_name = name;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
new_name = (char *)objc_malloc (strlen (name) + 1);
|
||||||
|
strcpy ((char *)new_name, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This maps the sel_id to the name. */
|
||||||
|
sarray_at_put_safe (__objc_selector_names, i, (void *)new_name);
|
||||||
|
|
||||||
|
/* This maps the name to the sel_id. */
|
||||||
|
objc_hash_add (&__objc_selector_hash, (void *)new_name, (void *)i);
|
||||||
|
|
||||||
l = 0;
|
l = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
DEBUG_PRINTF ("Record selector %s[%s] as: %ld\n", name, types,
|
DEBUG_PRINTF ("Record selector %s[%s] as: %ld\n", name, types,
|
||||||
(long) soffset_decode (i));
|
(long)soffset_decode (i));
|
||||||
|
|
||||||
{
|
/* Now add the selector to the list of selectors with that id. */
|
||||||
int is_new = (l == 0);
|
l = list_cons ((void *)j, l);
|
||||||
const char *new_name;
|
sarray_at_put_safe (__objc_selector_array, i, (void *)l);
|
||||||
|
|
||||||
/* Can we use the pointer or must copy name? Don't copy if
|
|
||||||
NULL. */
|
|
||||||
if ((is_const) || (name == 0))
|
|
||||||
new_name = name;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
new_name = (char *) objc_malloc (strlen (name) + 1);
|
|
||||||
strcpy ((char *) new_name, name);
|
|
||||||
}
|
|
||||||
|
|
||||||
l = list_cons ((void *) j, l);
|
|
||||||
sarray_at_put_safe (__objc_selector_names, i, (void *) new_name);
|
|
||||||
sarray_at_put_safe (__objc_selector_array, i, (void *) l);
|
|
||||||
if (is_new)
|
|
||||||
objc_hash_add (&__objc_selector_hash, (void *) new_name, (void *) i);
|
|
||||||
}
|
|
||||||
|
|
||||||
sarray_realloc (__objc_uninstalled_dtable, __objc_selector_max_index + 1);
|
sarray_realloc (__objc_uninstalled_dtable, __objc_selector_max_index + 1);
|
||||||
|
|
||||||
return (SEL) j;
|
return (SEL)j;
|
||||||
}
|
}
|
||||||
|
|
||||||
SEL
|
SEL
|
||||||
|
|
Loading…
Reference in New Issue