#javascript #v8
#javascript #v8
Вопрос:
Я читаю эту статью о мономорфизме, и там есть следующий фрагмент кода:
function ff(b, o) {
if (b) {
return o.x
} else {
return o.x
}
}
ff(true, { x: 1 })
ff(false, { x: 2, y: 0 })
ff(true, { x: 1 })
ff(false, { x: 2, y: 0 })
Сколько встроенных кэшей доступа к свойствам находится в функции ff? В каком
состоянии они находятся?
Ответы: существует 2 кэша, оба мономорфны, потому что каждый видит только объекты одной формы.
Я думал, что будет один полиморфный, потому что ранее автор показывает:
f({ x: 4, y: 1 }) // polymorphic, degree 2
f({ x: 5, z: 1 }) // polymorphic, degree 3
f({ x: 6, a: 1 }) // polymorphic, degree 4
f({ x: 7, b: 1 }) // megamorphic
Функции передаются объекты разной структуры, и они мутируют мономорфный кэш в полиморфный. Почему это отличается от рассматриваемого примера?
Комментарии:
1. Я бы сказал, что автор несколько сбит с толку, поскольку
ff
функция выполняет одно и то же независимо от первого аргумента, но, поскольку я не читал всю статью и знаю, что автор работает в Google и раньше был частью команды V8, он, вероятно, знает, что он делаетчто делать?2. @adeneo, да, я предполагаю, что это так. Я просто хочу понять тему)
3. О, это просто пример, показывающий, что
o.x
поиск кэшируется с первого вызова функции и т. Д.4.Верно, но у каждого
o.x
поиска есть свой собственный кэш.5. Я немного удивлен, что компилятор V8 просто не оптимизировал бы это, чтобы функция всегда возвращалась
o.x
. Google мог бы многому научиться у Рослин.
Ответ №1:
Эти вещи «встроенного кэша» существуют при каждой отдельной ссылке на свойство в коде. Таким образом, в функции:
function ff(b, o) {
if (b) {
return o.x // IC here
} else {
return o.x // IC here
}
}
У каждого из этих двух return
операторов есть свой собственный встроенный кэш. Из-за способа вызова функции в примере, первый return
выполняется только с объектами первой формы, а второй — только с объектами второй формы. Таким образом, каждый кэш (после этих четырех вызовов ff()
) будет иметь только 1 форму.
После пятого вызова функции, подобной этой:
ff(true, { x: 1, z: 10 });
этот первый IC видел бы две формы, поэтому его IC был бы полиморфным.
Ответ №2:
Доступ к каждому свойству o.x
имеет свой собственный IC, даже если к одному и тому же свойству одного и того же объекта обращаются несколько раз.
Если вы запустите node --trace-ic someScript.js
, вы сможете увидеть, к какому номеру строки принадлежат ICS.