Make base::WeakPtr::Get() fast

It was previously calling WeakReference::is_valid() which was an out-of-line
method. That means code like

  if (my_weak_ptr)
    my_weak_ptr->foo();

would do two calls to is_valid(), plus tests and branching.

The is_valid() method showed up as one of the most frequently called non-inline
functions during browser start-up on Windows (about 1M calls).

is_valid() was also inefficient because it had to do a null-pointer check on
flag_, as well as checking if the flag was marked valid.

This patch removes the null-pointer check by using a sentinel object instead of
a nullptr. And instead of storing a bool in the flag, it stores a pointer-sized
bitmask 0 or ~0, so it can be AND'ed with the pointer value and conveniently
setting EFLAGS so that the code above just becomes a few loads, AND, branch,
and call. (The size of Flag is unchanged; it grows into the padding only.)

This is expected to reduce the binary size by ~48KB on Android, and increase it
by 79KB on x64 Linux -- something that's paid for by the split-out refactorings
to WeakPtr and WeakPtrFactory.

Exposing the SequenceChecker calls in inline functions caused the
MessageLoopTestType*.Nesting test to overflow on Win64 dcheck release builds,
which is why this patch also lowers the recursion depth there.

BUG=728324

Review-Url: https://codereview.chromium.org/2963623002
Cr-Commit-Position: refs/heads/master@{#483427}


CrOS-Libchrome-Original-Commit: 526f714c9ae172c3b16581b7e11eb035fd14274e
3 files changed
tree: 2555c2fb7634a10b59a3aa8d96b62b3bb5e1f7eb
  1. base/
  2. build/
  3. components/
  4. dbus/
  5. device/
  6. ipc/
  7. mojo/
  8. testing/
  9. third_party/
  10. ui/