# C/ObjC Block Byref Internals

In the last post, I mentioned that __block variable (here we named it block byref) will be retained if multiple blocks referenced it. Here are some sample code to show how runtime deals with reference counts.

In order to move the __block variable to the heap, the compiler must rewrite access to such a variable to be indirect through the structures forwarding pointer. For example:

would be rewritten to be:

As long as we know how block byref is structured, we can access the memory and dump it with internal function _Block_byref_dump.

The execution result is

\$ ./more_curious
Before local block:
byref data block 0x7fff6e8034f0 contents:
forwarding: 0x7fff6e8034f0
flags: 0x0
size: 32

After local block generated:
byref data block 0x7fff6e8034f0 contents:
forwarding: 0x7fff6e8034f0
flags: 0x0
size: 32

After first block copy:
byref data block 0x7fc191c13f60 contents:
forwarding: 0x7fc191c13f60
flags: 0x1000004
size: 32

After second block copy:
byref data block 0x7fc191c13f60 contents:
forwarding: 0x7fc191c13f60
flags: 0x1000006
size: 32

Execute block:
byref data block 0x7fc191c13f60 contents:
forwarding: 0x7fc191c13f60
flags: 0x1000004
size: 32

x is 2, &x is 0x7fc191c13f78
Execute block:
byref data block 0x7fc191c13f60 contents:
forwarding: 0x7fc191c13f60
flags: 0x1000002
size: 32

x is 3, &x is 0x7fc191c13f78


## What does it mean?

We can find some interesting things in this log:

1. Block byref flags and address doesn’t change until first copy.
2. After copy, the flag becomes 0x1000004. There’s a (1 << 24) flag in the front.
3. Block releases does decrease flag number in times of 2.

The (1 << 24) flag (the number one in 0x100xxxxx) means BLOCK_NEEDS_FREE in this enum:

So, flag changes until first copy makes sense, because block byref doesn’t need free until it is copied to heap.

The reference count is actually taken out from flags like so:

I didn’t find out why reference count is in times of two. The actual code that increase and decrease reference count is this:

OSAtomicCompareAndSwapInt is a function that can change value of a int thread and multiprocessor safe.

## Conclusion

Block seems magical at the first seen. With block we no longer have to do the function pointer + struct cast + void* tricks. Block automatically captures variables for us, and we can use __block storage qualifier to declare mutable ones. Behind the scene is really cool hack to make all this happen. However, it not quite easy to debug blocks and byrefs. We’d need to write some helper functions for gdb or lldb. These will be discussed in my next post.