Pointer Tagging и Oddball
Pointer tagging — техника V8 хранить SMI и pointer-тип в одном слове через младший бит. Oddball — внутренний класс для синглтонов:
undefined,null,true,false.
Pointer Tagging
Слово CPU (64 бит):
[ ... 63 бит ... | 1 бит tag ]
↑
1 → SMI (число хранится в верхних битах)
0 → указатель на объект в куче
Это работает потому что объекты выровнены по 4/8 байт — младший бит всегда был нулём.
Oddball
Все JS-значения, не являющиеся объектами, должны как-то существовать в системе. V8 завёл специальный внутренний тип Oddball для:
undefinednulltruefalsethe hole(для дыр в массивах)
Каждый из них — единственный синглтон в рантайме. Все ссылки на undefined указывают на один и тот же Oddball.
В V8 не одна куча, а три
Старая модель «один stack + один heap» неверна для современного V8. Сейчас несколько сегментов:
- New space — короткоживущие
- Old space — долгоживущие
- Large object space — для крупных объектов
- Code space, Map space, ReadOnly space...
«Куча, о которой он говорит, в современном V8 не одна единственная, их там сейчас три разных. Это сильно упрощённое понимание того, как сейчас работает V8.»
Иммутабельность примитивов — миф
Часто говорят: «строки и числа в JS иммутабельны». Это не совсем так — V8 может переиспользовать один и тот же объект, а может создать новый. Спецификация лишь требует, чтобы пользователь не мог их изменить.
Источники
- Реализация хранения данных. Стек и куча. Oddball и иммутабельные примитивы · AsForJS · 2024-07-27
- Цитата: «Чтобы не выделять новый числовой объект каждый раз, V8 с помощью техники тегирования указателей позволяет хранить маленькие числа.»
- Цитата: «Если он [бит] в единице — перед нами данное, если ноль — ссылка на что-то.»
- Почему в V8 SMI 31 бит · AsForJS · 2023-06-28