[all-commits] [llvm/llvm-project] d18fbf: Relax the rules around objc_alloc and objc_alloc_i...

Pierre Habouzit via All-commits all-commits at lists.llvm.org
Tue Jan 14 19:48:44 PST 2020


  Branch: refs/heads/master
  Home:   https://github.com/llvm/llvm-project
  Commit: d18fbfc09720009c0dc6a1ddf315402ee0a7751d
      https://github.com/llvm/llvm-project/commit/d18fbfc09720009c0dc6a1ddf315402ee0a7751d
  Author: Pierre Habouzit <phabouzit at apple.com>
  Date:   2020-01-14 (Tue, 14 Jan 2020)

  Changed paths:
    M clang/lib/CodeGen/CGObjC.cpp
    M clang/test/CodeGenObjC/objc-alloc-init.m

  Log Message:
  -----------
  Relax the rules around objc_alloc and objc_alloc_init optimizations.

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 `Clas` 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).

Differential Revision: https://reviews.llvm.org/D71682
Radar-Id: rdar://problem/58058316
Reviewed-By: Akira Hatanaka
Signed-off-by: Pierre Habouzit <phabouzit at apple.com>




More information about the All-commits mailing list