I couldn't figure that out either, so I asked a friend who actually worked on this code and I came away feeling just a tad dirty but smarter. :)
The last three bits of the real address are always 000.
If you ask C's malloc for enough space to store a JS string, object, or float, the address that it gives you will be aligned on a 32-bit boundary, so the last three bits of the address will be 0. SpiderMonkey has it's own allocator, mostly because they do GC, but this allocator also guarantees that any address allocated for one of these types is aligned.
Because of this, the last three bits can always be used to store the type tag and then masked away to restore the proper 000 bits.
The last three bits of the real address are always 000.
If you ask C's malloc for enough space to store a JS string, object, or float, the address that it gives you will be aligned on a 32-bit boundary, so the last three bits of the address will be 0. SpiderMonkey has it's own allocator, mostly because they do GC, but this allocator also guarantees that any address allocated for one of these types is aligned.
Because of this, the last three bits can always be used to store the type tag and then masked away to restore the proper 000 bits.