Браузер и фронтенд-рантайм
Внутренности V8: тест с множественным выбором
Шесть вопросов, проходящих сквозь весь юнит. Каждый — это решение, которое вы принимаете, читая реальную трассу производительности: не определение для заучивания, а механизм, который надо разобрать под нагрузкой.
Убедитесь, что вы связываете форму hidden class, состояние IC, продвижение по уровням, поведение deopt и барьеры GC — синтез, к которому вели отдельные уроки.
Горячая render-функция выдавала 5µs в тестах, но 250µs в проде. Снимок кучи показывает, что объекты, приходящие в один сайт доступа к свойству, созданы 7 разными конструкторами. В чём причина на уровне V8 и каков настоящий фикс?
Два объекта построены как {x:1, y:2} и {y:2, x:1}. Функция читает .x на обоих в горячем цикле. В какое состояние придёт сайт доступа и почему?
Почему V8 поставляет четыре уровня JIT (Ignition, Sparkplug, Maglev, TurboFan), а не один хороший оптимизатор?
Критичная по производительности функция показывает в --trace-deopt повторяющиеся пары 'optimized' затем 'deoptimized (not a Smi)' в пределах одной секунды. Что происходит и каков самый эффективный фикс?
Почему конкурентная маркировка в Orinoco нуждается в write barrier и что ломается без него?
Анимационный цикл с тяжёлой численностью обрабатывает 10M сущностей за кадр и продолжает уходить с 60fps при прогреве, с deopt на арифметике и растущей частотой minor GC. Какая раскладка данных чинит и IC, и GC сразу?
Сквозная линия юнита — одна цепочка: порядок добавления свойств задаёт hidden class, hidden class задаёт состояние IC, состояние IC (вместе со стабильностью типов) решает, поднимется ли функция до TurboFan или уйдёт в deopt-loop, а барьеры Orinoco держат кучу корректной, пока всё это бурлит. Любая прод-регрессия из юнита — megamorphic-путь рендера, deopt-loop при переполнении Smi, утечка замыканий в old gen — сводится к одному рычагу: стабилизируйте форму и числовой тип выше по потоку, в модели данных, прежде чем браться за любой флаг.