Page MenuHomePhabricator

Relax the rules around objc_alloc and objc_alloc_init optimizations.
ClosedPublic

Authored by MadCoder on Dec 18 2019, 5:22 PM.

Details

Summary

Today the optimization is limited to:

  • [ClassName alloc]
  • [self alloc] when within a class method

However it means that when code is written this way:

@interface MyObject
- (id)copyWithZone:(NSZone *)zone
{
    return [[self.class alloc] _initWith...];
}

@end

... then the optimization doesn't kick in and +[NSObject alloc] ends up in IMP caches where it could have been avoided. It turns out that +alloc -> +[NSObject alloc] is the most cached SEL/IMP pair in the entire platform which is rather silly).

There's two theoretical risks allowing this optimization:

  1. if the receiver is nil (which it can't be today), but it turns out that objc_alloc()/objc_alloc_init() cope with a nil receiver,
  2. if the Class type for the receiver is a lie. However, for such a code to work today (and not fail witn an unrecognized selector anyway) you'd have to have implemented the -alloc instance method.

    Fortunately, objc_alloc() doesn't assume that the receiver is a Class, it basically starts with a test that is similar to if (receiver->isa->bits & hasDefaultAWZ) { /* fastpath */ }. This bit is only set on metaclasses by the runtime, so if an instance is passed to this function by accident, its isa will fail this test, and objc_alloc() will gracefully fallback to objc_msgSend().

    The one thing objc_alloc() doesn't support is tagged pointer instances. None of the tagged pointer classes implement an instance method called 'alloc' (actually there's a single class in the entire Apple codebase that has such a method).

Radar-Id: rdar://problem/58058316

Diff Detail

Event Timeline

MadCoder created this revision.Dec 18 2019, 5:22 PM
MadCoder edited the summary of this revision. (Show Details)Dec 18 2019, 5:24 PM
MadCoder edited the summary of this revision. (Show Details)Dec 18 2019, 5:37 PM
MadCoder edited the summary of this revision. (Show Details)
MadCoder edited the summary of this revision. (Show Details)
ahatanak added inline comments.Jan 13 2020, 4:00 PM
clang/test/CodeGenObjC/objc-alloc-init.m
30–33

Can you add a test case for [[self class] alloc] to test the code in tryGenerateSpecializedMessageSend?

MadCoder marked an inline comment as done.Jan 14 2020, 8:56 AM
MadCoder added inline comments.
clang/test/CodeGenObjC/objc-alloc-init.m
30–33

isn't it what meth2 is doing?

ahatanak added inline comments.Jan 14 2020, 9:32 AM
clang/test/CodeGenObjC/objc-alloc-init.m
30–33

Ah, right. I didn't see the NOT_OPTIMIZED line.

This revision is now accepted and ready to land.Jan 14 2020, 9:43 AM
MadCoder marked 2 inline comments as done.Jan 14 2020, 2:36 PM
This revision was automatically updated to reflect the committed changes.