How OCaml Represents Values in Memory

A practical tour of immediate integers, heap blocks, runtime tags and variant constructors, illustrated with OCaml's Obj module.

チャンネル
Jane Street
公開日
2024年12月20日
動画
12:43
読了時間
3 分
スライド
5
原文
英語
YouTube で開く
スクロールすると動画は右下に小さくなって再生を続けます。字幕は閲覧言語に合わせて切り替わります。
閲覧言語2 言語で読めます
この記事はまだ日本語に翻訳されていないため、英語の原文を表示しています。
要約

30 秒でわかる

A Jane Street language-team engineer explains the conventional OCaml value layout. Using interactive examples, the speaker shows how tagged integers, block headers and tags let the runtime and garbage collector distinguish values and interpret heap blocks.

  1. 1Immediate valuesUnit and false are represented as integer zero, true as one, and characters by their byte codes.
  2. 2One bit distinguishes valuesAligned pointers have a zero low bit; immediate integers use a one, leaving 63 bits for integer representation on the layout shown.
  3. 3Block headersThe header records a block's size, garbage-collector color and tag.
  4. 4Special tags for raw dataBoxed floats and strings use tags that prevent their contents from being scanned as ordinary pointers.
  5. 5Variants use two numbering schemesConstructors without payloads are immediate integers; payload-carrying constructors use the block tag.

ポイント

  1. Unit, booleans, characters and integers use immediate integer representations.
  2. Compound structures such as tuples and records are represented by heap blocks in the examples.
  3. On the 64-bit layout shown, the low bit distinguishes immediate integers from aligned block pointers.
  4. Block headers include a size, garbage-collector color bits and a tag.
  5. Tags distinguish non-scannable blocks such as boxed floats and strings, and also identify payload-carrying variant constructors.
  6. Payload-free and payload-carrying variant constructors are numbered independently.
全文

チャプターごとに整えた全文を読む

文字起こしのみ
01

Immediate values and compound structures

The speaker introduces immediate values and uses Obj to inspect their representations. Arrays, tuples and records demonstrate boxed blocks.

I work on the OCaml language team at Jane Street. Earlier videos in this series discussed modes such as locality; another area of development is the kind system, which can express properties including memory layout. Before discussing unboxed types, I want to explain OCaml's conventional value representation.

The first category is immediate values. Unit has just one value, written (), and is commonly used when a computation performs an effect rather than returning meaningful information. Booleans, characters, and signed integers are also immediate types.

These values are represented as OCaml integers. To inspect them, I write a helper that checks a value's representation and uses Obj.magic, an unsafe reinterpretation, to view it as an integer. Unit and false are represented as 0, true as 1; a character gives its byte code, and an integer gives itself.

Inspecting immediate representations
スライド 1 / 5Inspecting immediate representationsThe REPL defines a helper using Obj.repr and Obj.magic and inspects the unit value.

Values can also be composed into structures: a list or array can contain elements of one type, a tuple can contain different types, and a record can name fields with their own types. Unlike the immediate types, these compound values are boxed and represented by heap-allocated blocks.

A second helper uses Obj.repr to view the runtime representation, checks that it is a block, and calls Obj.size. In the examples, a four-element array has size four words, a triple has size three, and a two-field record has size two. Obj.repr is an identity operation that lets us inspect the representation.

02

Tagged integers and block headers

The garbage collector must identify values and their sizes. Aligned pointers, low-bit integer tagging and block headers supply that information.

How does the runtime distinguish an integer from a pointer, and how does it determine the size of a block? This matters not just for inspection: the garbage collector must distinguish immediate values from references and understand the memory they point to.

OCaml uses tagged integers. On the 64-bit layout shown here, heap blocks are word-aligned, so their addresses end in zero bits. The runtime uses the least significant bit as a discriminator: one denotes an immediate integer, while zero denotes a pointer. That leaves 63 bits for the integer representation.

Sizes of boxed structures
スライド 2 / 5Sizes of boxed structuresObj.size reports the array, tuple and record block sizes in words.

Every heap block also has an extra header word. In the layout shown, its size field records the block's length in words; Obj.size reads that field. Two color bits are used by the garbage collector, and a one-byte tag tells the runtime more about the block.

The block header
スライド 3 / 5The block headerThe diagram shows the size, color and tag fields in the header word.
03

Floats, strings and tags

Raw floating-point and string data need special treatment so their bits are not interpreted as pointers. Header tags identify these non-scannable blocks.

A 64-bit floating-point value cannot always reserve a bit to distinguish it from a pointer. In the ordinary boxed representation, a float is stored in a heap block whose tag is Double_tag, 253. The garbage collector recognizes the tag and does not scan the float's bits as pointers.

I can verify that by using Obj.repr and Obj.tag on a float: the reported tag is 253. Strings have a similar issue because their tightly packed bytes can contain arbitrary bit patterns. A string block uses tag 252, so its contents are not mistaken for pointers.

Inspecting float and string tags
スライド 4 / 5Inspecting float and string tagsObj.tag reveals the special tags for boxed float and string values.

More generally, tags at or above 251 identify blocks whose contents the garbage collector does not scan as ordinary pointer-containing fields. The tag has another important use: distinguishing constructors of variant types.

04

Variant constructors

OCaml numbers payload-free and payload-carrying constructors separately. The former use immediate integers and the latter use block tags.

Consider a variant with constructors A, B of int, C, and D of string. To represent a value, the runtime needs both the constructor's identity and any associated payload. OCaml separates constructors without arguments from those with arguments, and numbers the two groups independently from zero.

The constructors without payloads are immediate integers. In this example A is 0 and C is 1; a further payload-free constructor would be 2. For payload-carrying constructors, the block tag records the constructor number: B has tag 0 and D has tag 1.

Variant constructor representations
スライド 5 / 5Variant constructor representationsThe example defines constructors with and without payloads and inspects the immediate values.

Because the tag is finite, the number of payload-carrying constructors in one variant is bounded, though the limit is ample for most uses. This straightforward representation makes it possible to reason about how many types are laid out and helps keep the runtime and garbage collector relatively simple. Future videos will discuss how these value types interact with unboxed types.

同じチャンネルの記事

スライド 6 枚15:33EN
JSJane Street· 2026年10月26日Figgie Strategy: Reading Hands, Winning Majorities and Pricing CardsBradley, Mike · Jane StreetJane Street traders Bradley and Mike analyze three games to show how private information, market competition and timing affect card prices.Decision MakingMathematicsFintech
1:48:29EN
JSJane Street· 2026年10月16日How AI Is Changing Programming: John Krazit and Ron MinskyRon Minsky, John Krazit · Jane StreetJane Street’s AI tooling lead and the Signals and Threads host examine agent infrastructure, security, code review and the changing experience of writing software.コーディングエージェントDeveloper productivity評価(Evals)+2
1:36:37EN
JSJane Street· 2026年9月23日Aaron Bauer on Teaching Software Engineering in the Age of AIRon Minsky, Aaron Bauer · Jane StreetHow learning goals, active practice and editor design shape engineering education when models can generate the code.AI in EducationSoftware engineeringEducation+2
スライド 9 枚1:05:45EN
JSJane Street· 2026年9月11日Cyrus Omar on Live Programming and a Computational Commons for Humans and AICyrus OmarA demonstration of Hazel shows how immediate feedback, structured collaboration and carefully scoped permissions could support people and AI agents working together.Programming LanguagesHuman-AI Collaboration開発ワークフローとテスト+2
1:25:00EN
JSJane Street· 2026年9月2日Eric Mannes on Turning Messy External Data Into Trading ResearchRon, Eric Mannes · Jane StreetFrom commodity futures and an Excel risk system to point-in-time datasets and AI, Eric Mannes explains the domain knowledge behind data engineering at Jane Street.Data quality & curation開発ワークフローとテストInvesting+2
スライド 7 枚1:16:29EN
JSJane Street· 2026年8月26日Grant Sanderson and Alok Puranik: Positional Encodings Through Group TheoryGrant Sanderson, Alok Puranik · 3Blue1BrownStarting with assumptions about attention, they derive matrix exponentials and connect rotations, decay and Jordan blocks to RoPE and ALiBi.Transformers & attentionMathematics機械学習の基礎+1