Skip to content

Instantly share code, notes, and snippets.

@jonathanmarvens
Last active August 29, 2015 13:59
Show Gist options
  • Save jonathanmarvens/10708143 to your computer and use it in GitHub Desktop.
Save jonathanmarvens/10708143 to your computer and use it in GitHub Desktop.

In the general sense, a VALUE is just a C pointer to a Ruby object data type. We use VALUEs in the C code like we would use objects in the Ruby code.

some_function(VALUE arg_object)
{
  some_method(arg_object);
}

One would expect that the VALUE is just a typedef to a C pointer and there’s a lookup table as to which object it represents, and this would be partially correct. However, there’s also some trickery involved.

Instead of implementing the VALUE as a pointer, Ruby implements it as an unsigned long. It just so happens that sizeof(void *) == sizeof(long) at least on the platforms I’m familiar with. After all, what is a pointer? It’s just an n-byte int that represents a memory address.

But because of this, there’s some tricks Ruby can perform.

First, for performance purposes, Ruby doesn’t use the VALUE as a pointer in every instance. For Fixnums, Ruby stores the number value directly in the VALUE itself. That keeps us from having to keep a lookup table of every possible Fixnum in the system.

The trick lies in the fact that pointers are aligned in 4 byte chunks (8 bytes on 64 bit systems). For example, if there was an object stored at 0×0000F000, then the next would be one stored at 0×0000F004. This jump from 0 to 4 in the lower nibble is important. Expanding out as bits, it is: 0000 and 0100. This means that if we use the VALUE as a pointer, the lowest two bits will always be 0s.

Ruby uses this to its advantage. It will tuck a 1 in the lowest bit and then use the rest of the space (31 bits) to store a Fixnum. One of the bits will be used for the sign, so a Ruby Fixnum can be up to 30 bits in length.

Ruby uses the other bit to help distinguish other common types, like false, true, and nil. Symbols and their IDs are also stored with this bit on, so Ruby recognizes it as a special instance and interprets accordingly.

The rest of the time a VALUE is a good old fashioned memory address, which points to an object structure in memory.

Useful VALUE diagram

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment