News for hackers. Stuff that matters.
Re:Dissecting objc_msgSend on ARM64 by dfox on Saturday July 01, 2017 @05:36PM (#14679169)
Having lookup instead of send as the primitive operation also allows you to generate code like this for the call site:

    ({
      static SEL last_isa = NULL;
      static IMP last_imp = NULL;
      if (object->isa != isa){
        last_isa = object->isa;
        last_imp = lookup(object->isa, sel);
      }
      last_isa(object, selector, arguments...);
    })
(modulo the fact that you cannot generate this by dumb string substitution without compiler extension like gcc's ({...}))

Smalltalk/X takes this to the extreme by compiling all sends into code like:

    {
       static struct cache = {.imp = &magic_global_method, .class=NULL}
       cache->imp(&cache, object, selector, arguments...);
    }
And generates something like this into every method prologue:

    if (cache && self->isa != cache->class){
      cache->class = self->isa;
      cache->imp = lookup(object, selector);
      return cache->imp(NULL, object, selector, arguments...)
    }
It looks convoluted and uses one additional word of stack space per call, but does not contain any unpredictable indirect branches in the fast path (and in fact reduces overall code size as it can be expected that there are many more sends than methods).
Re:Dissecting objc_msgSend on ARM64 by mikeash on Saturday July 01, 2017 @08:46PM (#14680074)
That is very cool. Can this approach be made thread safe while still being fast?
Re:Dissecting objc_msgSend on ARM64 by dfox on Sunday July 02, 2017 @09:40AM (#14682440)
It is safe as long as everything that can get into the cache starts with the validity checking prologue and there is only one thread. Making this thread-safe is probably non-trivial.