Back to Fluent Bit

Boxing

lib/nghttp2-1.65.0/third-party/mruby/doc/internal/boxing.md

5.0.43.3 KB
Original Source

Boxing

The mruby objects and data are represented by C data type mrb_value. There are three options how to pack the data values in the mrb_value.

  • Word Boxing
  • NaN Boxing
  • No Boxing

Word Boxing

Word boxing packs the Ruby data in a word, which is a natural integer size that equals to the size of pointers (intptr_t). Word boxing can be specified by MRB_WORD_BOXING, and it's default configuration for most platforms.

Some values (called immediate values, e.g. integers, booleans, symbols, etc.) are directly packed in the word. The other data types are represented by pointers to the heap allocated structures.

The Word boxing packing bit patterns are like following:

TypesBit Pattern
objectxxxxxxxx xxxxxxxx xxxxxxxx xxxxx000
fixnumxxxxxxxx xxxxxxxx xxxxxxxx xxxxxxx1
nil00000000 00000000 00000000 00000000
true00000000 00000000 00000000 00001100
false00000000 00000000 00000000 00000100
undef00000000 00000000 00000000 00010100
symbolxxxxxxxx xxxxxxxx xxxxxxxx xxxxxx10

On 64-bit platforms (unless MRB_WORDBOX_NO_FLOAT_TRUNCATE), float values are also packed in the mrb_value. In that case, we drop least significant 2 bits from mantissa. If you need full precision for floating-point numbers, define MRB_WORDBOX_NO_FLOAT_TRUNCATE.

NaN Boxing

NaN boxing packs the Ruby data in a floating-point numbers, which represent NaN (Not a Number) values. Under IEEE753 definitions every value that exponent is all set are considered as NaN. That means NaN can represent 2^51 values. NaN boxing is a teaching to pack the values in those NaN representation. In theory, 64 bit pointers are too big to fit in NaN, but practically most OS use only 48 bits at most for pointers (except for some OS e.g. Solaris).

The NaN boxing packing bit patterns are like following:

TypesBit Pattern
floatSEEEEEEE EEEEFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF
+/-infS1111111 11110000 00000000 00000000 00000000 00000000 00000000 00000000
nan01111111 11111000 00000000 00000000 00000000 00000000 00000000 00000000
fixnum01111111 11111001 00000000 00000000 IIIIIIII IIIIIIII IIIIIIII IIIIIIII
symbol01111111 11111110 00000000 00000000 SSSSSSSS SSSSSSSS SSSSSSSS SSSSSSSS
misc01111111 11111111 00000000 00000000 00000000 00000000 00TTTTTT 0000MMMM
object01111111 11111100 PPPPPPPP PPPPPPPP PPPPPPPP PPPPPPPP PPPPPPPP PPPPPP00
ptr01111111 11111100 PPPPPPPP PPPPPPPP PPPPPPPP PPPPPPPP PPPPPPPP PPPPPP01
nil00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000

The object values appear far more frequently than floating-point numbers, so we offset the value so that object pointers are unchanged. This technique is called "favor pointer".

No Boxing

No boxing represents mrb_value by the C struct with type and the value union. This is the most portable (but inefficient) representation. No boxing can be specified by MRB_NO_BOXING, and it's default for debugging configuration (e.g. host-debug).