Improve the efficiency of NSObject's methodSignatureForSelector by:

- Moving the linear search over all of the method lists in the class hierarchy to the end.  If we found the type info in the protocol list, we were throwing this info away.  Doing something expensive and then discarding the result is generally not a good idea.

- Replacing the linear search of the method lists with a dtable lookup on libobjc2.  The type info for methods is part of the slot, so we only need to do the expensive search at all on the old runtime.  With libobjc2, type info lookup costs as little as IMP lookup, so doing things the slow way is not required.



git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@31231 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
David Chisnall 2010-09-02 15:17:46 +00:00
parent 1b43c3a615
commit e58ea125de

View file

@ -1465,8 +1465,7 @@ objc_create_block_classes_as_subclasses_of(Class super) __attribute__((weak));
*/
- (NSMethodSignature*) methodSignatureForSelector: (SEL)aSelector
{
const char *types;
struct objc_method *mth;
const char *types = NULL;
Class c;
if (0 == aSelector)
@ -1475,14 +1474,14 @@ objc_create_block_classes_as_subclasses_of(Class super) __attribute__((weak));
}
c = (GSObjCIsInstance(self) ? object_getClass(self) : (Class)self);
mth = GSGetMethod(c, aSelector, GSObjCIsInstance(self), YES);
if (mth == 0)
// Do a fast lookup to see if the method is implemented at all. If it isn't,
// we can give up without doing a very expensive linear search through every
// method list in the class hierarchy.
if (!class_respondsToSelector(c, aSelector))
{
return nil; // Method not implemented
}
types = mth->method_types;
/*
* If there are protocols that this class conforms to,
* the method may be listed in a protocol with more
@ -1526,6 +1525,19 @@ objc_create_block_classes_as_subclasses_of(Class super) __attribute__((weak));
}
}
if (types == 0)
{
#ifdef __GNUSTEP_RUNTIME__
struct objc_slot* objc_get_slot(Class cls, SEL selector);
struct objc_slot *slot = objc_get_slot(c, aSelector);
types = slot->types;
#else
struct objc_method *mth =
GSGetMethod(c, aSelector, GSObjCIsInstance(self), YES);
types = mth->method_types;
#endif
}
if (types == 0)
{
return nil;